[BUUOJ记录] [GXYCTF2019]BabySQli

有点脑洞的题,题目不难,主要考察注入和联合查询的一个小特点

进入题目是一个登录框,看看源代码,在search.php文件中发现了这个

大写的字母和数字很明显是base32,先用base32解码一下,发现还有一层base64,继续解码得到后端处理的SQL语句:

select * from user where username = '$name'

发现没有验证密码,并且注入点是在username上的,admin测试一下,随便输入一个密码,返回wrong pass!

换一个用户名试试,返回wrong user!

所以可以确定的是用户名是admin,并且后端对password还是有验证的,但不是进行数据库查询,想了半天没想出来,想起来BUU题目描述中给出了Github源代码:

<!--MMZFM422K5HDASKDN5TVU3SKOZRFGQRRMMZFM6KJJBSG6WSYJJWESSCWPJNFQSTVLFLTC3CJIQYGOSTZKJ2VSVZRNRFHOPJ5-->
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 
<title>Do you know who am I?</title>
<?php
require "config.php";
require "flag.php";

// 去除转义
if (get_magic_quotes_gpc()) {
    function stripslashes_deep($value)
    {
        $value = is_array($value) ?
        array_map('stripslashes_deep', $value) :
        stripslashes($value);
        return $value;
    }

    $_POST = array_map('stripslashes_deep', $_POST);
    $_GET = array_map('stripslashes_deep', $_GET);
    $_COOKIE = array_map('stripslashes_deep', $_COOKIE);
    $_REQUEST = array_map('stripslashes_deep', $_REQUEST);
}

mysqli_query($con,'SET NAMES UTF8');
$name = $_POST['name'];
$password = $_POST['pw'];
$t_pw = md5($password);
$sql = "select * from user where username = '".$name."'";
$result = mysqli_query($con, $sql);


if(preg_match("/\(|\)|\=|or/", $name)){
    die("do not hack me!");
}
else{
    if (!$result) {
        printf("Error: %s\n", mysqli_error($con));
        exit();
    }
    else{
        $arr = mysqli_fetch_row($result);
        if($arr[1] == "admin"){
            if(md5($password) == $arr[2]){
                echo $flag;
            }
            else{
                die("wrong pass!");
            }
        }
        else{
            die("wrong user!");
        }
    }
}

?>

重点关注这里:

if($arr[1] == "admin"){
    if(md5($password) == $arr[2]){
        echo $flag;
    }
    else{
        die("wrong pass!");
    }
}
else{
    die("wrong user!");

发现这里对password的验证时是先将我们提交的password进行md5加密,然后和数据库返回的密码进行比较

这里了解一下union select语句的一个特点:

 union select会把查询结果接在前一个查询结果后面,前面如果查到了东西,那么取得还是第一行,除非有limit 这种取第几行

所以这里我们们直接构造Payload即可:

' order by 3#   //判断出三个字段
' union select 1,'admin','e10adc3949ba59abbe56e057f20f883e'#   //这里后面的password明文是123456,因为后端对我们传值进行了md5加密

然后密码填写123456即可获得Flag

猜你喜欢

转载自www.cnblogs.com/yesec/p/12470573.html