PHP代码审计系列(三)

PHP代码审计系列(三)

本系列将收集多个PHP代码安全审计项目从易到难,并加入个人详细的源码解读。此系列将进行持续更新。

sql闭合绕过

源码如下



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 "

Logged in! Key: ***********

"
; } if($row['user'] != "admin") { echo("

You are not admin!

"
); } } ?>

通读代码出现漏洞的是这一段sql存在注入,通过’)#闭合可以绕过密码的校验

$sql = "select user from php where (user='$user') and (pw='$pass')"

payload:

user=admin')#&pass=1

PHP代码审计系列(三)_第1张图片

X-Forwarded-For绕过指定IP地址

源码如下


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不在访问列表之内!";
}
?>

通读代码发现只要GetIP()方法返回的IP为1.1.1.1就可以获得flag,这个方法是根据HTTP_CLIENT_IP、HTTP_X_FORWARDED_FOR、REMOTE_ADDR请求头来校验ip的

我用了burp更改请求头,推荐个burp插件fakeip一键生成多种请求头进行绕过

PHP代码审计系列(三)_第2张图片

md5加密相等绕过

源码如下



$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";}

?>

通读代码需要绕过以下条件,我们需要找到一个不等于QNKCDZO的值MD5加密后相等

$a != 'QNKCDZO' && $md51 == $md52

==在进行比较的时候会进行数据转换,字符串与数字进行比较的时候字符串开头数字会被转换为数值进行比较例如

echo '123tpaer' == 123;

结果是1

QNKCDZO经过MD5加密后为0e开头

字符串e0XXX会转换为0,我们只需要找到MD5加密后开头为0e的字符串即可百度有很多

payload:

http://localhost/phpbugs/13.php?a=s155964671a

PHP代码审计系列(三)_第3张图片

intval函数四舍五入

initval函数四舍五入

源码如下



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 "

no! try again

"
; } else{ echo($query[content]); } } ?>

通读代码主要需要绕过以下条件

$_GET[id]==1024

在查询sql之前使用了intval函数

利用intval的四舍五入特性绕过

echo intval('1024.1');
//结果为1024

strpos数组绕过NULL与ereg正则%00截断

源码如下



$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 '骚年,继续努力吧啊~';
    }

 ?>

通读代码逻辑如下:

首先判断GET请求中的nctf字段,对该字段进行校验是否输入的都是数字不是则结束脚本,使用strops判断字符串#biubiubiu中是否存在nctf的字段如果存在输出flag

需要绕过以下条件

strpos ($_GET['nctf'], '#biubiubiu') !== FALSE

可以通过报错使strpos返回NULL,满足条件NULL!== FALSE

PHP代码审计系列(三)_第4张图片

也可以利用erge的截断漏洞,绕过以下条件

@ereg ("^[1-9]+$", $_GET['nctf']) === FALSE

PHP代码审计系列(三)_第5张图片

你可能感兴趣的:(从入门到入狱,php,开发语言,后端,web安全)