kerling

热爱安全。php python 低级coder 。爱美食爱电影爱二次元。0.3阶狼人杀玩家

ISCC 200WEB SQLI

    Part1 题目解析

这道题目是我出的,作为去年决赛时候的评分标准之一,没想到被主办方拿出来当了今年的题目用。源码找不到只能po一张半成品时候的图



代码po在这里就很明白了,就是一个简单的注入修改过的代码是md5(password)了的。 不过我在前端加了个验证码,代码如下:

function getCaptcha($length){

$str = null;

$strPol = "0123456789abcdef";

$max = strlen($strPol)-1;

 

for($i=0;$i<$length;$i++){

$str.=$strPol[rand(0,$max)];

}

 

return $str;

}

然后验证码为md5($_POST['captcha']), 0, 3

也就是需要选手找到一个string 使其前三位为生成的captcha

而跑验证码的代码如下



<?php

 

@$a=$_GET['a'];

$i=0;

while(1) {

if (substr(md5($i), 0, 3)===$a) {echo $i;die;}

$i++;

 

}

 

}

 

通过数字来寻找答案

其实这个验证码当时的设计思路是通过反锁的操作让人无法使用sqlmap等工具 第二点则是让选手通过使用 union select ‘xxx’ as password 来注入密码并且使万能密码无法奏效最后getflag




由于源代码我删除了所以这里我在mysql环境下还原题目

新建一个test表 内容如下

比如我们输入username=admin时 根据 代码 执行的sql语句应为 “select password from test where username='admin'”

 

根据代码 那么输入的密码应该是password 等于select password from test where username='admin' 的结果则算登入成功所以我构造的payload则是 username=’ union select ‘a’ as password # 首先让用户名为空 这样就没有返回数值 然后我们把密码注入为一个指定的数值a 

这时候我们只需要输入密码a即可登入成功

Part 2 其他解法

因为题目太快被K 所以我想到可能别人想到了其他的解决方法。因为就算写爬虫爆破脚本也需要一定的时间。所以只有直接构造payload才是最快的方法。

这时候先查看了下select的语句语法ELECT
    [ALL | DISTINCT | DISTINCTROW ]
      [HIGH_PRIORITY]
      [STRAIGHT_JOIN]
      [SQL_SMALL_RESULT] [SQL_BIG_RESULT] [SQL_BUFFER_RESULT]
      [SQL_CACHE | SQL_NO_CACHE] [SQL_CALC_FOUND_ROWS]
    select_expr [, select_expr ...]
    [FROM table_references
      [PARTITION partition_list]
    [WHERE where_condition]
    [GROUP BY {col_name | expr | position}
      [ASC | DESC], ... [WITH ROLLUP]]
    [HAVING where_condition]
    [ORDER BY {col_name | expr | position}
      [ASC | DESC], ...]
    [LIMIT {[offset,] row_count | row_count OFFSET offset}]
    [PROCEDURE procedure_name(argument_list)]
    [INTO OUTFILE 'file_name'
        [CHARACTER SET charset_name]
        export_options
      | INTO DUMPFILE 'file_name'
      | INTO var_name [, var_name]]
    [FOR UPDATE | LOCK IN SHARE MODE]]

 

其中group语法有一个用法GROUP BY WITH ROLLUP 可以增加一个空列由于 fetch_array是要判断空的 所以我们需要账户名admin

最后构造的payload为

Username = admin’ group by password with rollup #

执行代码如下



由于源码中使用了while循环 所以第一句话会报错 第二句话则会显示如图的flag



评论 ( 1 )

© kerling | Powered by LOFTER