Week 1
Q1 axb_2019_brop64(这题本来是盲打,buuoj给了源文件难度减少了很多)
IDA分析发现,read函数长度存在栈溢出
checksec结果,没有Canary和PIE,可直接利用栈溢出构造rop
本题靶机使用的是Ubuntu16
使用libc-2.23.so (或者可使用LibcSearcher 寻找对应libc)
构造rop思路:
在此之前 puts函数已被调用,其GOT表被覆盖为真实的函数地址,可利用ROPgadget 得到real_puts_addr, 进而 libc_base = real_puts_addr - libc.symbols[“puts”]
rop回到原函数,继续利用栈溢出,调用system(“bin/sh”),获得shell
cat flag
flag{c8d8e2f2-b554-414d-a815-8a285f96d118}
盲打策略:(盲打由于运行环境的限制,一般很少出现)
1.测量栈溢出的padding
while 循环,每次多发送1byte,直到覆盖到rip,程序返回出错时,则为padding_length
2.得到main函数地址
(1)得到原先返回地址(通过padding长度的string,调用puts时连同ret_addr打印出来)
(2)ret_addr=0x400834 进一步缩小暴力搜索范围,从0x400834往下找
while 循环每次rip 每次-1 最终成功返回main函数不报错 得main_addr=0x4007d6
3. 寻找blind_rop_gadget_addr
(1)寻找libc_csu_init 函数中的gadget地址
该处调用6次pop,构造以下payload
payload = ‘A’ * padding_length
payload += p64(libc_csu_init_address)
payload += p64(0) * 6
payload += p64(main_addr) + p64(0) * 10
使得运行流程正常回到main函数,此时覆盖rip的地址即为rop_gadget_add
3.寻找 puts@plt
find main_addr … not change -> No ASLR addr_base = 0x400000
(1) rop_gadget +9 = pop rdi; ret
(2) 0x400000处的内容为’ELF’,尝试利用rop打印出ELF,若成功,则找到puts_plt
4.利用 puts dump file
利用puts特性 rop 输出binary文件
从0x400000开始,每次只能打印到’\x00’,更新当前打印地址,直到远程server puts 打印出错(addr 已经超过界限)
5.获得puts_got 泄露libc_base
根据dump 的binary 获得puts_got
同样的方法 rop -> leak puts_addr -> leak libc_base -> ret2libc system("/bin/sh\x00")
获得shell
Q2 jarvisoj_level1
得到二进制文件,checksec发现无任何保护
使用ida 反汇编,查看伪代码,发现漏洞函数
其中存在栈溢出和栈地址泄露的漏洞。
由于程序没有开NX,可将shellcode放入栈中,同时控制ret_addr到栈地址
在栈中执行shellcode,获得shell
Q3 bbys_tu_2016
使用ida 反汇编,发现栈溢出点
无canary,可直接溢出
在二进制文件中,发现可查看flag的函数
目标可转化为,覆盖ret_addr 为 printFlag_addr,不用获取shell,即可读取flag
gdb测试输入字符串,比较和返回地址的距离padding=0xbc-0xa4 = 0x18
构造payload = “A”*(0x18)+p32(elf.sym[“printFlag”])
调用printFlag函数,打印flag