一、分段代码审计(3)

十一、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=240610708240610708的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[]=

推荐阅读更多精彩内容

  • 新银报到,多多指教,如有错误,多谢指出 extract变量覆盖 第一次遇到extract()函数,百度一波含义(回...
    yangc随想阅读 4,037评论 5 2
  • PHP:include()``include_once()``require()``require_once() ...
    寻梦xunm阅读 635评论 1 4
  • 运动真的会让人快乐,而跑步是最简单的运动。
    与自己战斗的人阅读 77评论 0 0
  • 词法作用域是指声明的作用域是根据程序正文在编译时就确定的,也称为静态作用域。而动态作用域是在运行的时候确定的。词法...
    尾巴尾巴尾巴阅读 221评论 0 0
  • 文/许三观卖血 这一届奥斯卡奖,小李子莱昂纳多终于凭借《荒野猎人》拿到了奥斯卡小金人,总算摘掉了专业陪跑22年,备...
    许三观卖血阅读 712评论 0 0