十一、sql闭合绕过
<?php
if($_POST[user] && $_POST[pass]) {
$conn = mysql_connect("*******", "****", "****");
mysql_select_db("****") or die("Could not select database");
if ($conn->connect_error) {
die("Connection failed: " . mysql_error($conn));
}
$user = $_POST[user];
$pass = md5($_POST[pass]);
//select user from php where (user='admin')#
//exp:admin')#
$sql = "select user from php where (user='$user') and (pw='$pass')";
$query = mysql_query($sql);
if (!$query) {
printf("Error: %s\n", mysql_error($conn));
exit();
}
$row = mysql_fetch_array($query, MYSQL_ASSOC);
//echo $row["pw"];
if($row['user']=="admin") {
echo "<p>Logged in! Key: *********** </p>";
}
if($row['user'] != "admin") {
echo("<p>You are not admin!</p>");
}
}
?>
很简单的登陆sql闭合绕过,闭合掉'和)然后将后面的东西注释掉。payload:admin')#
十二、X-Forwarded-For绕过指定IP地址
<?php
function GetIP(){
if(!empty($_SERVER["HTTP_CLIENT_IP"]))
$cip = $_SERVER["HTTP_CLIENT_IP"];
else if(!empty($_SERVER["HTTP_X_FORWARDED_FOR"]))
$cip = $_SERVER["HTTP_X_FORWARDED_FOR"];
else if(!empty($_SERVER["REMOTE_ADDR"]))
$cip = $_SERVER["REMOTE_ADDR"];
else
$cip = "0.0.0.0";
return $cip;
}
$GetIPs = GetIP();
if ($GetIPs=="1.1.1.1"){
echo "Great! Key is *********";
}
else{
echo "错误!你的IP不在访问列表之内!";
}
?>
如果HTTP_CLIENT_IP
不存在就使用HTTP_X_FORWARDED_FOR
获取ip,如果也不存在就使用REMOTE_ADDR
获取ip。
REMOTE_ADDR
是比较靠谱的获取ip的方式,无法通过http请求头伪装。HTTP_CLIENT_IP和HTTP_X_FORWARDED_FOR都可以通过伪造请求头伪装,只要合适使用http请求头就可以使$GetIPs=="1.1.1.1"
。这里可以HTTP头添加X-Forwarded-For:1.1.1.1
十三、md5加密相等绕过
<?php
$md51 = md5('QNKCDZO');
$a = @$_GET['a'];
$md52 = @md5($a);
if(isset($a)){
if ($a != 'QNKCDZO' && $md51 == $md52) {
echo "nctf{*****************}";
} else {
echo "false!!!";
}}
else{echo "please input a";}
?>
这道题的问题在于$md51 == $md52
这里使用的使==而不是===。
==对比的时候会进行数据转换,0eXXXXXXXXXX 转成0了(科学记数法)。QNKCDZO的md5值为0e830400451993494058024219903391
,只要再找一个加密后0e开头的字符串就好,可以写个小程序跑一下,这里用?a=240610708
240610708的md5值为0e462097431906509019562988736854
。
十四、intval函数四舍五入
<?php
if($_GET[id]) {
mysql_connect(SAE_MYSQL_HOST_M . ':' . SAE_MYSQL_PORT,SAE_MYSQL_USER,SAE_MYSQL_PASS);
mysql_select_db(SAE_MYSQL_DB);
$id = intval($_GET[id]);
$query = @mysql_fetch_array(mysql_query("select content from ctf2 where id='$id'"));
if ($_GET[id]==1024) {
echo "<p>no! try again</p>";
}
else{
echo($query[content]);
}
}
?>
intval() 函数通过使用指定的进制 base 转换(默认是十进制),返回变量 var 的 integer 数值。 intval() 不能用于 object,否则会产生 E_NOTICE 错误并返回 1。
这个题为啥叫四舍五入不是很懂,intval()函数不是直接去掉小数位吗?这里绕过也很容易直接id=1024.1
就可以了,这样$_GET[id]
不等于1024而intval($_GET[id])
等于1024
十五、strpos数组绕过NULL与ereg正则%00截断
<?php
$flag = "flag";
if (isset ($_GET['nctf'])) {
if (@ereg ("^[1-9]+$", $_GET['nctf']) === FALSE)
echo '必须输入数字才行';
else if (strpos ($_GET['nctf'], '#biubiubiu') !== FALSE)
die('Flag: '.$flag);
else
echo '骚年,继续努力吧啊~';
}
?>
方法一 %00截断 ereg()可以被%00截断(详见例五)
使用%00截断后加上#biubiubiu
,payload:?nctf=1%00#biubiubiu
方法二 strpos(),ereg()出错返回null
当输入数组strpos(),ereg()出错返回null,又因为null!==false,所以可以满足条件返回flag,payload:?nctf[]=