forked from xxgrunge/sqlninja
-
Notifications
You must be signed in to change notification settings - Fork 0
/
sqlninja-howto.html
1115 lines (931 loc) · 71.8 KB
/
sqlninja-howto.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 PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<HTML>
<HEAD>
<META NAME="GENERATOR" CONTENT="LinuxDoc-Tools 0.9.21">
<TITLE>Sqlninja user manual</TITLE>
</HEAD>
<BODY>
<H1>Sqlninja user manual</H1>
<H2></H2>rel. svn-0.2.ff
<HR>
<EM>This is the user manual of sqlninja, and you should have received it with the sqlninja tarball. Check
<A HREF="http://sqlninja.sourceforge.net">http://sqlninja.sourceforge.net</A> for the latest version.</EM>
<HR>
<P>
<H2><A NAME="toc1">1.</A> <A HREF="sqlninja-howto.html#s1">Introduction</A></H2>
<UL>
<LI><A NAME="toc1.1">1.1</A> <A HREF="sqlninja-howto.html#ss1.1">Requirements</A>
<LI><A NAME="toc1.2">1.2</A> <A HREF="sqlninja-howto.html#ss1.2">Background</A>
<LI><A NAME="toc1.3">1.3</A> <A HREF="sqlninja-howto.html#ss1.3">How to use it</A>
</UL>
<P>
<H2><A NAME="toc2">2.</A> <A HREF="sqlninja-howto.html#s2">Attack modes</A></H2>
<UL>
<LI><A NAME="toc2.1">2.1</A> <A HREF="sqlninja-howto.html#ss2.1">test</A>
<LI><A NAME="toc2.2">2.2</A> <A HREF="sqlninja-howto.html#ss2.2">fingerprint</A>
<LI><A NAME="toc2.3">2.3</A> <A HREF="sqlninja-howto.html#ss2.3">bruteforce</A>
<LI><A NAME="toc2.4">2.4</A> <A HREF="sqlninja-howto.html#ss2.4">escalation</A>
<LI><A NAME="toc2.5">2.5</A> <A HREF="sqlninja-howto.html#ss2.5">resurrectxp</A>
<LI><A NAME="toc2.6">2.6</A> <A HREF="sqlninja-howto.html#ss2.6">upload</A>
<LI><A NAME="toc2.7">2.7</A> <A HREF="sqlninja-howto.html#ss2.7">dirshell</A>
<LI><A NAME="toc2.8">2.8</A> <A HREF="sqlninja-howto.html#ss2.8">backscan</A>
<LI><A NAME="toc2.9">2.9</A> <A HREF="sqlninja-howto.html#ss2.9">revshell</A>
<LI><A NAME="toc2.10">2.10</A> <A HREF="sqlninja-howto.html#ss2.10">icmpshell</A>
<LI><A NAME="toc2.11">2.11</A> <A HREF="sqlninja-howto.html#ss2.11">dnstunnel</A>
<LI><A NAME="toc2.12">2.12</A> <A HREF="sqlninja-howto.html#ss2.12">metasploit</A>
<LI><A NAME="toc2.13">2.13</A> <A HREF="sqlninja-howto.html#ss2.13">sqlcmd</A>
<LI><A NAME="toc2.14">2.14</A> <A HREF="sqlninja-howto.html#ss2.14">getdata</A>
<LI><A NAME="toc2.15">2.15</A> <A HREF="sqlninja-howto.html#ss2.15">Other attacks</A>
</UL>
<P>
<H2><A NAME="toc3">3.</A> <A HREF="sqlninja-howto.html#s3">Configuration file</A></H2>
<UL>
<LI><A NAME="toc3.1">3.1</A> <A HREF="sqlninja-howto.html#ss3.1">Basic options</A>
<LI><A NAME="toc3.2">3.2</A> <A HREF="sqlninja-howto.html#ss3.2">Data extration options</A>
<LI><A NAME="toc3.3">3.3</A> <A HREF="sqlninja-howto.html#ss3.3">Advanced options</A>
</UL>
<P>
<H2><A NAME="toc4">4.</A> <A HREF="sqlninja-howto.html#s4">Other useful information</A></H2>
<UL>
<LI><A NAME="toc4.1">4.1</A> <A HREF="sqlninja-howto.html#ss4.1">Credits</A>
<LI><A NAME="toc4.2">4.2</A> <A HREF="sqlninja-howto.html#ss4.2">Disclaimer</A>
<LI><A NAME="toc4.3">4.3</A> <A HREF="sqlninja-howto.html#ss4.3">Feedback</A>
<LI><A NAME="toc4.4">4.4</A> <A HREF="sqlninja-howto.html#ss4.4">Wisdom</A>
<LI><A NAME="toc4.5">4.5</A> <A HREF="sqlninja-howto.html#ss4.5">Authors</A>
</UL>
<HR>
<H2><A NAME="s1">1.</A> <A HREF="#toc1">Introduction</A></H2>
<P>Sqlninja's goal is to exploit SQL injection vulnerabilities on web applications that use Microsoft SQL Server as back end. It is released under the
<A HREF="http://www.gnu.org/licenses/gpl.html">GPLv3</A>.</P>
<P>Sqlninja's main goal is to get interactive OS-level access on the remote DB server and to use it as a foothold in the target network. As an experimental feature, it can also extract data from the database. In a nutshell, here's what it does:
<UL>
<LI>Fingerprint of the remote SQL Server (version, user performing the queries, user privileges, xp_cmdshell availability, DB Server authentication mode)</LI>
<LI>Bruteforce of the 'sa' password (SQL Server 2000 only)</LI>
<LI>Privilege escalation to 'sa' (SQL Server 2000 only)</LI>
<LI>Creation of a custom xp_cmdshell if the original one has been disabled</LI>
<LI>Upload of executables</LI>
<LI>Reverse scan in order to look for a port that can be used for a reverse shell</LI>
<LI>Direct and reverse shell, both TCP and UDP</LI>
<LI>DNS tunneled pseudoshell, when no ports are available for a bindshell</LI>
<LI>ICMP tunneled shell, if the target DBMS can communicate via ICMP Echo with the attacking machine</LI>
<LI>Metasploit wrapping, when you want to use Meterpreter or even want to get GUI access on the remote DB server</LI>
<LI>OS privilege escalation on the remote DB server using token kidnapping or through CVE-2010-0232 </LI>
<LI>Extraction of data from the remote DB, using WAITFOR-based inference or DNS-based tunnels </LI>
<LI>All of the above can be done with obfuscated SQL code, in order to confuse IDS/IPS systems</LI>
</UL>
As you probably have figured out, sqlninja does not look for SQL injection vulnerabilities. Again, there are already several tools that perform that task already, like
<A HREF="http://portswigger.net/suite">BurpSuite</A>.</P>
<P>For the latest release and two flash demos, check out the address
<A HREF="http://sqlninja.sourceforge.net">http://sqlninja.sourceforge.net</A>. The demos refer to a previous version but are still perfectly good to get a better understanding of the tool.</P>
<P>Read this manual carefully (yes, I mean all of it), as it will explain you what it is all about and how to make your way through all sqlninja options. Yes, I know that it's terribly long and boring, but since sqlninja has a plethora of options to play with (and no shiny green buttons), try to read the whole thing: it will help you to get the most of the tool and will save you a lot of time later.</P>
<H2><A NAME="ss1.1">1.1</A> <A HREF="#toc1.1">Requirements</A>
</H2>
<P>Since sqlninja is completely written in Perl, there is not much to install, except Perl itself and the following modules, if missing:
<UL>
<LI>NetPacket</LI>
<LI>Net-Pcap</LI>
<LI>Net-DNS</LI>
<LI>Net-RawIP</LI>
<LI>IO-Socket-SSL</LI>
<LI>Net-Pcap</LI>
<LI>DBI</LI>
</UL>
You will also need the Metasploit Framework 3 on your box to use the metasploit attack mode, and also a VNC client if you use the VNC payload.</P>
<P>If something goes wrong, activating verbose output (<CODE>-v</CODE> option) and/or debugging (<CODE>-d</CODE>) should provide some hints. Developed on a Gentoo box, sqlninja has been reported to work on the following operating systems:
<UL>
<LI>Linux</LI>
<LI>FreeBSD</LI>
<LI>Mac OS X</LI>
<LI>iOS </LI>
</UL>
</P>
<H2><A NAME="background_"></A> <A NAME="ss1.2">1.2</A> <A HREF="#toc1.2">Background</A>
</H2>
<P>Sometimes, when you find a SQL Injection vulnerability in a web application which uses SQL Server, it is all 2001 again: you find that your queries are run as 'sa', you verify that xp_cmdshell has not been disabled, then you make the server download netcat (via ftp or tftp) and finally obtain your direct or reverse shell. Most of the time, however, things are different: maybe the firewall filters all inbound/outbound connections, or a reverse shell is only allowed on some obscure service, or xp_cmdshell isn't there, or your queries are executed with low privileges. Or maybe all these things together ;). Sqlninja offers some help in getting the deserved remote shell even in these cases. And if that fails, it can still help you to squeeze some data out of the remote DBMS.</P>
<P>I am assuming that you have a good grasp of SQL Injection techniques and of Microsoft SQL Server internals. If you have trouble understanding what follows, I recommend you that you read
<A HREF="http://www.northernfortress.net/advanced_sql_injection.pdf">this</A>,
<A HREF="http://www.northernfortress.net/more_advanced_sql_injection.pdf">this</A> and
<A HREF="http://www.northernfortress.net/sqlinference.pdf">this</A>. I am also assuming you understand what protocol tunneling is, in particular over ICMP and DNS. If you don't, a good introduction to the concept for DNS is
<A HREF="http://dnstunnel.de/">here</A>. </P>
<H2><A NAME="ss1.3">1.3</A> <A HREF="#toc1.3">How to use it</A>
</H2>
<P>Sqlninja's behaviour is controlled via the
<A HREF="#conf_">configuration file</A> (default: <CODE>sqlninja.conf</CODE>), which tells sqlninja what to attack and how (target host, vulnerable page, exploit strings, ...), and some command line options, which tell sqlninja what action to perform. These command line options are the following:
<UL>
<LI><B>-m <attack mode> :</B> specifies the attack mode. Basically, tells sqlninja what to do. Possible values are:
<UL>
<LI>test</LI>
<LI>fingerprint</LI>
<LI>bruteforce</LI>
<LI>escalation</LI>
<LI>resurrectxp</LI>
<LI>upload</LI>
<LI>dirshell</LI>
<LI>backscan</LI>
<LI>revshell</LI>
<LI>dnstunnel</LI>
<LI>icmpshell</LI>
<LI>metasploit</LI>
<LI>sqlcmd</LI>
<LI>getdata</LI>
</UL>
</LI>
<LI><B>-v :</B> verbose output</LI>
<LI><B>-f <configuration file> :</B> specifies a configuration file to use.</LI>
<LI><B>-p <'sa' password> :</B> used in escalation mode to add current DB user to the sysadmin group, and in other modes to run the query as administrator, if the DB user does not belong to such group. This option is rarely used, as
<A HREF="#bruteforce_">bruteforce mode</A> by default adds the DB user to the sysadmin group when the 'sa' password is found. For more information about when to use this parameter, refer to the
<A HREF="#escalation_">escalation mode</A></LI>
<LI><B>-w <wordlist> :</B> wordlist to use in bruteforce mode</LI>
<LI><B>-g :</B> combined with upload mode, generate debug script and exit</LI>
<LI><B>-d <debug mode> :</B> activates debug, to see what is going on under the hood. Possible values are:
<UL>
<LI>1 : print each SQL command that is being injected</LI>
<LI>2 : print each HTTP request that is sent to the target</LI>
<LI>3 : print each HTTP response that is received from the target</LI>
<LI>all : all of the above</LI>
</UL>
</LI>
</UL>
See the description of the various modes to see when each parameter must be used.</P>
<H2><A NAME="s2">2.</A> <A HREF="#toc2">Attack modes</A></H2>
<P>Sqlninja has currently 14 attack modes. The mode to use can be specified by its name:
<BLOCKQUOTE><CODE>
sqlninja -m upload
</CODE></BLOCKQUOTE>
or by its shortcut:
<BLOCKQUOTE><CODE>
sqlninja -m u
</CODE></BLOCKQUOTE>
The list with the available modes and their corresponding shortcuts can be retrieved by launching sqlninja with no parameters.</P>
<P>To get a first grasp of the different attack modes, here's a typical way of using sqlninja:
<OL>
<LI> Setup the configuration file, and use
<A HREF="#test_">test mode</A> to check that SQL code is being correctly injected</LI>
<LI> Fingerprint the remote DB server, using
<A HREF="#finger_">fingerprint mode</A></LI>
<LI> If needed, use
<A HREF="#bruteforce_">bruteforce mode</A> to find the 'sa' password and escalate privileges (SQL Server 2000 only)</LI>
<LI> If needed, use
<A HREF="#resurrectxp_">resurrectxp mode</A> to re-create the xp_cmdshell extended procedure (SQL Server 2000 only)</LI>
<LI> Upload netcat, using
<A HREF="#upload_">upload mode</A></LI>
<LI> If it is possible to contact the DB Server on some port, use
<A HREF="#dirshell_">dirshell mode</A> and get a direct shell. Alternatively, if the port is TCP, use
<A HREF="#metasploit_">metasploit mode</A> to get graphical access</LI>
<LI> Otherwise, use
<A HREF="#backscan_">backscan mode</A> to find an allowed "outbound" tcp/udp port</LI>
<LI> If step 7 is successful, use
<A HREF="#revshell_">revshell mode</A> to obtain a reverse shell. Alternatively, if the port is TCP, use
<A HREF="#metasploit_">metasploit mode</A> to get graphical access</LI>
<LI> If step 8 failed, upload icmpsh.exe and try
<A HREF="#icmpshell_">icmpshell mode</A> to obtain an icmp-tunneled shell </LI>
<LI> If step 9 failed, upload dnstun.exe and start
<A HREF="#dnstunnel_">dnstunnel mode</A> to obtain a dns-tunneled pseudo-shell</LI>
<LI> If step 10 failed, crank up
<A HREF="#getdata_">getdata</A> mode and start extracting some tables!</LI>
</OL>
</P>
<H2><A NAME="test_"></A> <A NAME="ss2.1">2.1</A> <A HREF="#toc2.1">test</A>
</H2>
<P>
<UL>
<LI>Shortcut: t </LI>
<LI>Parameters: none</LI>
</UL>
This mode simply injects a simple <CODE>WAITFOR DELAY</CODE> and checks whether it is successfully executed by the remote server. Use this mode to test whether your configuration file is correct and the injection is working.</P>
<H2><A NAME="finger_"></A> <A NAME="ss2.2">2.2</A> <A HREF="#toc2.2">fingerprint</A>
</H2>
<P>
<UL>
<LI>Shortcut: f </LI>
<LI>Parameters: -p <sa password> (optional)</LI>
</UL>
Using WAITFOR-based blind injection, this mode fingerprints the remote server. The following pieces of information can be obtained:
<UL>
<LI>Database version (2000/2005/2008/2012) </LI>
<LI>User that is performing the queries</LI>
<LI>Whether that user belongs to the sysadmin group </LI>
<LI>Whether xp_cmdshell is available to that user</LI>
<LI>Whether the remote server uses mixed or Windows-only authentication (you need to know this if you want to bruteforce the 'sa' password)</LI>
<LI>Whether the remote SQL Server runs as SYSTEM. This can also be used to check whether
<A HREF="#usechurrasco_">churrasco.exe</A> has been correctly uploaded and is able to escalate privileges through token kidnapping.</LI>
<LI>Name of current DB</LI>
</UL>
</P>
<P>If you are attacking SQL Server 2000, the current DB user does not belong to the sysadmin group, but the right 'sa' password is specified as a parameter, the fingerprint is performed with administrative rights. The WAITFOR technique is much slower compared to other inference methods, but it's by far the most flexible. However, since external factors like network traffic and server load could interfere with the time measurements, you might want to repeat the fingerprint a couple of times, if the first result doesn't look right, or play with the <CODE>blindtime</CODE> parameter in the
<A HREF="#conf_">configuration file</A>. Note that in order to use fingerprint the user running SQL Server the following must be available on the remote box:
<UL>
<LI>xp_cmdshell (or an equivalent procedure)</LI>
<LI><CODE>whoami.exe</CODE>. This is present by default on Windows 2003, but if you suspect that this utility is not on the remote box, just download it from microsoft.com and
<A HREF="#upload_">upload</A> it.</LI>
</UL>
</P>
<H2><A NAME="bruteforce_"></A> <A NAME="ss2.3">2.3</A> <A HREF="#toc2.3">bruteforce</A>
</H2>
<P>
<UL>
<LI>Shortcut: b</LI>
<LI>Parameters: -w <wordlist> (optional)</LI>
</UL>
</P>
<P>This mode is to be used if the user that performs the queries does not belong to the sysadmin group (see
<A HREF="#finger_">fingerprint mode</A>). If this is the case, we need to escalate our privileges. Since by using OPENROWSET we can make the target database connect to itself with alternate credentials, we can attempt to bruteforce the 'sa' password. If the correct password is found, current user is automatically added to the sysadmin group. For this attack to work, the remote SQL Server must use "mixed authentication". Use
<A HREF="#finger_">fingerprint mode</A> to check if this is the case.</P>
<P>This attack mode can use two different methods: "dictionary" and "incremental". You are free to use the method that best suits your needs. </P>
<H3>Dictionary</H3>
<P>This method is used when a wordlist is specified, using the <CODE>-w</CODE> option. Using this method, potential passwords are fetched from the wordlist, and each one is tried in a separate request. Be sure that your wordlist contains 'sa' and the empty password, two all-times favourites for MS SQL Server installations.</P>
<P>Pros:
<UL>
<LI>Very effective if the password is a dictionary word </LI>
<LI>Does not put a heavy load on the DB Server </LI>
</UL>
Cons:
<UL>
<LI>Not effective against passwords that are not dictionary based. If the password is not in your wordlist, you are out of the game</LI>
<LI>Needs a lot of network connections, so the attack is very easy to spot by looking at the logs of the web server</LI>
</UL>
</P>
<H3>Incremental</H3>
<P>This method is used when a wordlist is not specified. Sqlninja submits a set of queries that try *ALL* possible combinations of characters up to a certain length that is specified by the user. The cool aspect of this tactic is that since the queries run on the DB server, the bruteforce is actually performed using the target's CPU resources.</P>
<P>Pros:
<UL>
<LI>Extremely effective in finding passwords that are not dictionary based</LI>
<LI>Needs relatively few connections, so there are very few entries in the web server logs </LI>
</UL>
</P>
<P>Cons:
<UL>
<LI>If the password is long, it might take ages</LI>
<LI>It might push the CPU usage of the DB Server up to 100% for the whole time, which can be dangerous with a live application. Also keep in mind that critical servers have alarms that are triggered if the CPU usage remains very high for a certain time. As a security measure, sqlninja splits the task in small chunks (each chunk trying <I>n^3</I> passwords, with <I>n</I> being the length of the charset used). If something goes wrong, just stop sqlninja, and the remote bruteforce will stop at the end of the current chunk </LI>
<LI>Depending on how the application connects to the DB Server, this technique might not work (e.g.: ODBC is known to create trouble). Sqlninja tries to figure it out almost immediately and alerts the user, so no precious time is lost</LI>
</UL>
</P>
<H3>Important notes</H3>
<P>
<UL>
<LI>Starting with SQL Server 2005, OPENROWSET is disabled by default for non-administrative users. If the fingerprint mode told you that you are dealing with SQL Server 2005/2008/2012 and that you are not 'sa', then you are likely out of luck (but you can still extract data with the
<A HREF="#getdata_">getdata</A> mode</LI>
<LI>In SQL Server 2000, passwords are case insensitive, which massively simplifies the cracking job.</LI>
<LI>The escalation bit might be impacted if the application uses ODBC (see
<A HREF="#escalation_">escalation mode</A>)</LI>
</UL>
</P>
<H2><A NAME="escalation_"></A> <A NAME="ss2.4">2.4</A> <A HREF="#toc2.4">escalation</A>
</H2>
<P>
<UL>
<LI>Shortcut: e </LI>
<LI>Parameters: -p <sa password> (required)</LI>
</UL>
When the correct 'sa' password is specified, the current DB user is added to the sysadmin group. </P>
<P>In general, you should not need this method, as sqlninja takes care of the escalation in the bruteforce mode already. However, there might be cases in which you need to perform this bit independently (maybe you found the password with a social engineering attack).</P>
<P>If you want to know how the escalation works, or if you have found the 'sa' password but the escalation seems not to work, keep reading. Otherwise, you can skip to
<A HREF="#resurrectxp_">resurrectxp mode</A>.</P>
<P>The escalation is performed combining OPENROWSET, the right 'sa' password, and sp_addsrvrolemember, by adding the current DB user to the sysadmin group. It is quite unlikely that sp_addsrvrolemember has been disabled, so the trick should work pretty much always. If it doesn't work, there might be 2 cases:
<OL>
<LI>The server uses ODBC, and you are using old ODBC connections from the connection pool, which still use the old privileges</LI>
<LI>The sp_addsrvrolemember procedure has been disabled</LI>
</OL>
In the first case, you can just have a couple of pints waiting for the old ODBC connection to timeout and be dropped: by default, an ODBC connection is dropped after 60 idle seconds, and the chance of such an event depends on how many clients are connecting to the web application and how this number varies over time.</P>
<P>In the second case (or also in the first, if you don't want to wait), you only need to specify the <CODE>-p <sa password></CODE> parameter in <I>all</I> the following steps of the attack: that will tell sqlninja to use OPENROWSET in each connection, running each command as 'sa' rather than as the current user. </P>
<H2><A NAME="resurrectxp_"></A> <A NAME="ss2.5">2.5</A> <A HREF="#toc2.5">resurrectxp</A>
</H2>
<P>
<UL>
<LI>Shortcut: x</LI>
<LI>Parameters: -p <sa password> (optional)</LI>
</UL>
This mode is to be used when the following conditions are both met:
<UL>
<LI>We have sysadmin privileges or we know the 'sa' password </LI>
<LI>xp_cmdshell has been disabled</LI>
</UL>
The goal of this mode is, of course, to recreate the xp_cmdshell extended procedure. There are quite a lot of variables that come to play here and depending on them this mode will behave in different ways. So read carefully, as here are the things you must keep in mind:
<UL>
<LI><B>The methods:</B> there are two ways to get the xp_cmdshell back:
<OL>
<LI>restore it with a stored procedure (sp_addextendedproc on SQLServer 2000 and sp_configure on SQLServer 2005). This method requires one simple SQL command, but requires xplog70.dll to still be there</LI>
<LI>create a custom one with "CREATE PROCEDURE", sp_oacreate, sp_oamethod and sp_oadestroy. This method requires more code, but works no matter if xplog70.dll has been removed for security reasons.</LI>
</OL>
</LI>
<LI><B>The xp_cmdshell name:</B> re-enabling xp_cmdshell might not go unnoticed. Or maybe the application developers might have strictly followed what MS recommends, which is to filter the "xp_*" string, without saying nothing about "sp_*" (check
<A HREF="http://msdn.microsoft.com/library/en-us/bldgapps/ba_highprog_11kk.asp">http://msdn.microsoft.com/library/en-us/bldgapps/ba_highprog_11kk.asp</A>). In these cases, we can use CREATE PROCEDURE and a more discrete name (e.g.: "sp_sqlbackup"). You can choose the procedure name with the
<A HREF="#xp_name_">xp_name option</A> of the configuration file. </LI>
<LI><B>The user privileges:</B> if the privilege escalation didn't work (see
<A HREF="#escalation_">escalation mode</A> for the possible reasons), then you must use the <CODE>-p <sa password></CODE> parameter, in order to use OPENROWSET to escalate privileges in each connection, and this leads to the following point</LI>
<LI><B>OPENROWSET and CREATE PROCEDURE cannot be combined.</B> Therefore, if you are using the <CODE>-p</CODE> parameter you cannot use the "CREATE PROCEDURE" trick. However, there is a workaround: you can include the whole procedure code <I>in each request</I> that is sent to the DB Server, without creating an extended procedure at all. Let's call this trick <B>"inline procedure injection"</B>.</LI>
</UL>
That said, here are the steps that sqlninja follows when this method is used:
<OL>
<LI>If the extended procedure name, specified in the configuration file, is <CODE>xp_cmdshell</CODE> (which is the default value), then sqlninja starts by trying to re-enable it with sp_addextendedproc/sp_configure. You will be asked the version of the remote SQL Server. If you forgot to use fingerprint mode, sqlninja will find this info on its own. If this whole thing works, we have our xp_cmdshell back.</LI>
<LI>If the extended procedure name is not set to <CODE>xp_cmdshell</CODE> (maybe because you want to be more sneaky) in the configuration file, or step #1 has failed (e.g.: because xplog70.dll has been removed), then:
<UL>
<LI>if we have native admin privileges (meaning we didn't have to specify the password in the command line) the CREATE PROCEDURE method is attempted. If it works, we have our custom procedure, whatever we have named it </LI>
<LI>if we do not have native admin privileges (meaning we had to specify the password in the command line) the inline procedure injection is tried. If it works, then you will have to set xp_name to <CODE>NULL</CODE> in the configuration file. This will tell sqlninja to use the inline procedure injection in all subsequent steps</LI>
</UL>
</LI>
</OL>
I hope it is clear. If it is, you should not have any problem in having back your xp_cmdshell (or something perfectly equivalent) in almost every situation. If it is not clear, I am afraid you will have to read the whole thing again.</P>
<P>Note: the code used by sqlninja for the custom procedure is a slight modification of Antonin Foller's code, that you can find at the address
<A HREF="http://www.motobit.com/tips/detpg_cmdshell/">http://www.motobit.com/tips/detpg_cmdshell/</A></P>
<H2><A NAME="upload_"></A> <A NAME="ss2.6">2.6</A> <A HREF="#toc2.6">upload</A>
</H2>
<P>
<UL>
<LI>Shortcut: u </LI>
<LI>Parameters: -p <sa password> (optional)</LI>
<LI>Parameterd: -g (optional)</LI>
</UL>
This mode uploads a binary file using only GET or POST HTTP requests to the web server, so no FTP/TFTP or whatever other connection is needed. The file is uploaded to the directory specified by the server's <CODE>%TEMP%</CODE> variable, so that the attack works even when MSSQL cannot write on the default directory (which seems to be sometimes the case with MSDE). There are two upload methods available, controlled by the
<A HREF="#uploadmethod_">upload_method</A> option:
<UL>
<LI><B>debug script:</B> This method is the traditional one, and uses the old <CODE>DEBUG.EXE</CODE> 16bits debugger. The binary file is encoded as a debug script (<CODE>.scr</CODE> extension) the script is uploaded and feeded to the debugger. The script basically allocates an area of memory, writes the needed bytes in it, and saves the result to disk. Being a 16bits debugger there is obviously a 64k bytes limitation in the size, but sqlninja bypasses it by splitting the original executable in chunks of 64k bytes, uploading them separately, and then finally merging them together. Sqlninja uses the same algorithm used in Jussi's great dbgtool.exe (which you can find at the address http://www.toolcrypt.org) which is capable of creating very compact scripts.</LI>
<LI><B>vbscript:</B> This is the new method: basically, it encodes the binary file in base64 format, uploads it, and then feeds it to a tiny vbscript decoder previously uploaded. On average it uses fewer requests, it does not need to split the original file, and has higher chances to work on recent systems. Therefore, although the old method is much </LI>
</UL>
</P>
<P>No matter what method you select for the upload, you will be prompted for the file name to upload and things will be completely automated. If the file appears to be already in <CODE>.scr</CODE> or <CODE>.base64</CODE> format, sqlninja will perform the upload anyway, but some checks (e.g.: the uploaded binary file has the correct size) will not be possible. In general, it is always better to provide sqlninja with the original binary.</P>
<P>For your comfort, netcat.exe, dnstun.exe, icmpsh.exe, churrasco.exe, vdmallowed.exe and vdmexploit.dll are already available in the <CODE>apps</CODE> and <CODE>scripts</CODE> directories, respectively in binary and debug+base64 format. The executables have been packed with
<A HREF="http://upx.sourceforge.net">UPX</A> in order to minimize their size (and the upload time). You need to upload netcat to use backscan/dirshell/revshell, whereas dnstun.exe and icmpsh.exe are used to create a DNS and ICMP tunneled pseudoshell respectively. Churrasco.exe is used to attempt a privilege escalation via token kidnapping if SQL Server is not running as SYSTEM. Vdmallowed.exe and vdmexploit.dll attempt the same attack using CVE-2010-0232. </P>
<P>Keep in mind that a lot of things can go wrong here: if a single line of the encoded file fails to get uploaded, the executable will not be correctly generated. Therefore, at the end of the process sqlninja checks whether the executable file is there, and if it is not it also tries to figure out how many lines have been uploaded: this should provide some hints on what went wrong. For instance, during a pen-test it turned out that the resulting number of lines was exactly twice the correct value, meaning that each injected query was executed twice. The trick was to create a temporary table that acted as a counter, appending the line to the script file only when the counter was even.</P>
<P>If you only want to generate the debug script or the base64 file without uploading it (for instance to use it with some other tool), start the upload mode with the <CODE>-g</CODE> option, and sqlninja will generate the file in the <CODE>/tmp</CODE> directory and exit. You need to specify the password parameter when you do not have native sysadmin privileges (see
<A HREF="#escalation_">escalation mode</A>).</P>
<H2><A NAME="dirshell_"></A> <A NAME="ss2.7">2.7</A> <A HREF="#toc2.7">dirshell</A>
</H2>
<P>
<UL>
<LI>Shortcut: s </LI>
<LI>Parameters: -p <sa password> (optional)</LI>
</UL>
Use this method when the remote DB Server is directly reachable on some TCP or UDP port. Sqlninja asks for the remote port, the protocol, tells the DB server to bind a command prompt to such port and then starts the connection. Of course, netcat must have been uploaded on the remote server. The password parameter is to be used when we do not have native sysadmin privileges (see
<A HREF="#escalation_">escalation mode</A>).</P>
<H2><A NAME="backscan_"></A> <A NAME="ss2.8">2.8</A> <A HREF="#toc2.8">backscan</A>
</H2>
<P>
<UL>
<LI>Shortcut: k</LI>
<LI>Parameters: -p <sa password> (optional) </LI>
</UL>
Tipically, when the DB Server is behind a firewall it is not possible to directly contact it. However, it might be possible that the server is allowed to access the outside world on some port (e.g.: DNS, HTTP). This mode tells the DB Server to send SYN packets or UDP packets to our machine on a range of ports, in order to look for one that is allowed. Sqlninja will tell the user whether packets are received and on which port(s). </P>
<P>You need to specify, in the configuration file, the IP address of your machine (
<A HREF="#lhost_">lhost parameter</A>) and the interface to listen on
(
<A HREF="#device_">device parameter</A>).
Sqlninja will ask you about the protocol to use (TCP/UDP) and for the ports, that must be
specified with the common netcat syntax (e.g.: "23 25 80-100" will try ports 23,
25 and all ports between 80 to 100).
The password parameter is to be used when
we do not have native sysadmin privileges (see
<A HREF="#escalation_">escalation</A>). In order to use this mode, netcat must have been uploaded first, and since pcap libraries need to be used you also need to be root.</P>
<H2><A NAME="revshell_"></A> <A NAME="ss2.9">2.9</A> <A HREF="#toc2.9">revshell</A>
</H2>
<P>
<UL>
<LI>Shortcut: r </LI>
<LI>Parameters: -p <sa password> (optional) </LI>
</UL>
If a direct shell is not possible but backscan mode found an open port from the DB Server to our machine, then a reverse shell is possible. When using this mode, sqlninja asks for the local port, the protocol and then starts the connection. You need to specify, in the configuration file, the IP address of your machine (
<A HREF="#lhost_">lhost parameter</A>). Of course, netcat must have been uploaded on the remote server. As usual, the password parameter is to be used when we do not have native sysadmin privileges (see
<A HREF="#escalation_">escalation mode</A>).</P>
<H2><A NAME="icmpshell_"></A> <A NAME="ss2.10">2.10</A> <A HREF="#toc2.10">icmpshell</A>
</H2>
<P>
<UL>
<LI>Shortcut: i</LI>
<LI>Parameters: -p <sa password> (optional)</LI>
</UL>
When no direct or reverse shell are allowed by the firewall, but the remote DBMS can ping our box, we can tunnel our shell into an ICMP tunnel. Just
<A HREF="#upload_">upload</A> icmpsh.exe, start icmpshell mode, and enjoy your shell. All the traffic from and to the remote DBMS will be tunneled through ICMP packets.</P>
<P>When starting this attack mode, sqlninja will ask the following information:
<UL>
<LI>Data buffer size: the amount of data that will be encapsulated into a single ICMP packet. The default is 64 bytes, but you can use larger values to obtain a faster tunnel. Just be careful to the maximum MTU (Maximum Transfer Unit) between you and the DBMS. A value up to 1300-1400 bytes should be considered, by today's standards, fairly reliable. Use smaller packets if you want to play safe</LI>
<LI>Send delay: the amount of time between contiguous ICMP Echo requests. The default is 300 milliseconds, but you can use lower values to obtain a faster tunnel. Keep in mind that a very low value might generate a ping flood that might be noticed, or automatically throttled down by some anti-DoS device between you and your target.</LI>
<LI>Response timeout: the amount of time that will be waited by icmpshell.exe before re-sending an ICMP request. The default is 3000 milliseconds</LI>
</UL>
<B>Important:</B> make sure that your box is configured to <B>not</B> respond to ICMP Echo requests. For instance, on Linux the following command will do the trick:</P>
<P><CODE>sysctl -w net.ipv4.icmp_echo_ignore_all=1</CODE></P>
<H2><A NAME="dnstunnel_"></A> <A NAME="ss2.11">2.11</A> <A HREF="#toc2.11">dnstunnel</A>
</H2>
<P>
<UL>
<LI>Shortcut: d</LI>
<LI>Parameters: -p <sa password> (optional)</LI>
</UL>
When no direct or reverse shell are allowed by the firewall, and the ICMP shell does not work either, we can try to establish a DNS tunnel. The only requirements are:
<UL>
<LI>The DB server must be able to resolve external hostnames (which is very often the case)</LI>
<LI>Our IP must be the authoritative DNS server of some domain (you can buy one for a few bucks). We will use <CODE>sqlninja.net</CODE> in our example</LI>
</UL>
If both conditions are met,
<A HREF="#upload_">upload</A> dnstun.exe, start dnstunnel mode, and launch your commands. What happens is more or less the following:
<OL>
<LI>The command is passed via SQL Injection to dnstun.exe (which acts as our remote agent) and is executed by the remote DB Server. The output is intercepted and encoded in a slightly modified
<A HREF="http://en.wikipedia.org/wiki/Base_32">base32</A> format </LI>
<LI>The encoded output is split in a series of hostnames of the domain we control (e.g.: <CODE>encoded_output.sqlninja.net</CODE>) </LI>
<LI>Those hostnames are passed to <CODE>gethostbyname()</CODE>, so that the DB server contacts its DNS Server to resolve them </LI>
<LI>The DNS Server looks for the authoritative server of sqlninja.net (our IP) and forwards the requests to our workstation </LI>
<LI>sqlninja receives the requests, re-orders them if necessary, decodes the hostnames and finally prints the command output. Of course, sqlninja also responds to the DNS requests (with a fake IP address) in order to make <CODE>gethostbyname()</CODE> quickly return.</LI>
</OL>
</P>
<P>The whole process is streamed, which means that if the command output is very long you will start seeing its output before the command has finished. </P>
<P>The domain to use must be specified in the
<A HREF="#domain_">configuration file</A>. Of course, since sqlninja must create a fake DNS server and bind port 53, you need root privileges to use this mode. Keep in mind that DNS uses UDP, so packet loss might be an issue, here. </P>
<P>The executable version of the agent has been compiled with
<A HREF="http://www.mingw.org">Msys</A>. As always, the password parameter is to be used when we do not have native sysadmin privileges (see
<A HREF="#escalation_">escalation mode</A>).</P>
<H2><A NAME="metasploit_"></A> <A NAME="ss2.12">2.12</A> <A HREF="#toc2.12">metasploit</A>
</H2>
<P>
<UL>
<LI>Shortcut: m</LI>
<LI>Parameters: none</LI>
</UL>
Not happy with a simple DOS prompt? Want to impress your friends with a full GUI access? If you have administrative privileges, xp_cmdshell works and you have found an allowed TCP port (either inbound or outbound), you can also use sqlninja as a wrapper for Metasploit, in order to either use Meterpreter or inject a VNC server. Think of Meterpreter as a DOS prompt but far more powerful, providing you with an almost complete control over the remote OS, including immediate access to password hashes, the possibility of changing routing tables, perform port forwarding and even more. Alternatively, if you have enough bandwidth, you can also inject a VNC server and be provided with a nice graphical access to the remote DB.</P>
<P>This attack mode is fully automated, and in a nutshell here's what happens:
<OL>
<LI>Sqlninja asks you to specify if you want to use Meterpreter or VNC, whether the connection will be direct or inverse, and the host/port to connect to (or local port to bind, in case of a reverse connection)</LI>
<LI>Sqlninja will call <CODE>msfpayload</CODE> to create an appropriate executable that will act as a stager</LI>
<LI>Sqlninja will then convert it to a debug script and upload it</LI>
<LI>Since we will need to inject a DLL, we might need to disable Data Execution Prevention (aka 'DEP', enabled by default starting from Windows 2003 SP1) on the remote box. Recent versions of Metasploit handle this bit automatically, but you can also tell sqlninja will try to do it for you, by accessing the registry and whitelisting our executable (see the <CODE>checkdep</CODE> parameter)</LI>
<LI>Finally, Sqlninja will call <CODE>msfcli</CODE> to inject the needed DLL and complete the exploitation</LI>
</OL>
</P>
<P>You can watch a flash demo of this attack on the sqlninja website.</P>
<P>Of course, in order to use this attack mode you need to have Metasploit3 available on your box. If Metasploit executables (namely <CODE>msfpayload</CODE>, <CODE>msfcli</CODE> and <CODE>msfencode</CODE>) are not in your path, you can specify their absolute location in the configuration file. Also, if you use the VNC mode, be sure to have a VNC client installed.</P>
<H2><A NAME="sqlcmd_"></A> <A NAME="ss2.13">2.13</A> <A HREF="#toc2.13">sqlcmd</A>
</H2>
<P>
<UL>
<LI>Shortcut: c</LI>
<LI>Parameters: none</LI>
</UL>
Sometimes, even if we have sysadmin privileges and xp_cmdshell works, it is still not possible to get a shell, maybe because the executable upload fails, or because ports are all filtered and external DNS resolving is not allowed. In these cases, it can still be useful to issue single commands to the DB server, even without being able to see the output. For instance, you might want to add a local user (maybe you can RDP to the box), or a domain user, if SQL Server runs with such privileges (yes, it happens more often than one would expect). In such cases, you can use this mode: simply enter a DOS command and let sqlninja execute it remotely. Just remember: it gets executed even if you don't see its output. </P>
<P>Of course, you can still use timing to know what is going on:
<BLOCKQUOTE><CODE>
if exist filename (ping -n 5 127.0.0.1)
</CODE></BLOCKQUOTE>
If the command takes around 5 seconds to execute, the file is there.</P>
<P>To know whether a command succeeded, also check the value of the ERRORLEVEL variable, which is usually set to 0 if the last command did not produce an error. So, for instance, if we want to know whether the remote SQL Server is running as SYSTEM, we can use the following command:
<BLOCKQUOTE><CODE>
whoami > who.txt & find /i "\system " who.txt & if not errorlevel = 1 ping -n 5 127.0.0.1 & del who.txt
</CODE></BLOCKQUOTE>
If the command takes around 5 seconds to execute, you know that SQL Server is running as SYSTEM (<CODE>whoami.exe</CODE> is installed by default on Windows 2003 and can be found on Windows 2000 if the Resource Kit has been installed). Refresh your DOS-shaolin skills and use your fantasy: from appending commands in <CODE>AUTOEXEC.BAT</CODE> to starting/stopping services and adding rogue users, you can get pretty far with this!</P>
<P>This mode can also be useful when some other mode fails, in order to understand what went wrong and how to fix the problem. Finally, this command is also very useful to show a client that you owned their DB server even if you didn't get the shell:
<BLOCKQUOTE><CODE>
echo You have been owned by sqlninja > c:\sqlninja.txt
</CODE></BLOCKQUOTE>
</P>
<H2><A NAME="getdata_"></A> <A NAME="ss2.14">2.14</A> <A HREF="#toc2.14">getdata</A>
</H2>
<P>
<UL>
<LI>Shortcut: g</LI>
<LI>Parameters: -s <filename> (optional)</LI>
</UL>
Let us start by pointing out that this is still very experimental, it is likely to contain more bugs than a Win95 beta, and therefore you should not expect its reliability to be bomb-proof.
With that out of the way, let's get down to business: this module is 100% interactive, so it should be fairly intuitive. Sqlninja currently supports two extraction channels, <B>time-based</B> and <B>DNS-based</B>, described below. </P>
<H3><A NAME="timedata_"></A> Time-based</H3>
<P>This channel is used when <CODE>
<A HREF="#data_channel_">data_channel</A></CODE> is set to <CODE>time</CODE> in the configuration file, and uses the slow but reliable WAITFOR DELAY command to extract information. Sqlninja can exploit time-based injection in two ways, detailed in the following paragraphs.</P>
<P><B>Time-based binary search</B>
<A NAME="timedatabinary_"></A> </P>
<P>This method is activated when <CODE>
<A HREF="#data_extraction_">data_extraction</A></CODE> is set to <CODE>binary</CODE> in the configuration file. If you are even marginally into computers, you should know how a binary search algorithm works, so we am not going to get much into detail here. Basically, this method minimizes the number of requests to the application, which makes it useful if you want to keep your footprint to a minimum. However, approximately half of the queries will trigger a delay, which means that this method might not be the fastest.</P>
<P><B>Time-based serial/optimized search</B>
<A NAME="timedatabinary_"></A> </P>
<P>This method is activated when <CODE>
<A HREF="#data_extraction_">data_extraction</A></CODE> is set to <CODE>optimized</CODE> (default) or <CODE>serial</CODE> in the configuration file. With this method, all possible values are tried in sequence until the right one is guessed. The difference between <CODE>serial</CODE> and <CODE>optimized</CODE> is in the order of the attempts: while the former just tries all values following their ASCII value, the latter starts with the most common values. The exact order is specified with the <CODE>
<A HREF="#language_map_">language_map</A></CODE> parameter, and such order is modified in real-time, adapting to the actual frequency of characters being extracted, if the <CODE>
<A HREF="#language_map_adaptive_">language_map_adaptive</A></CODE> parameter is set to to <CODE>yes</CODE>.</P>
<P><B>DNS-based extraction</B>
<A NAME="dnsdata_"></A> </P>
<P>You have control over a DNS domain or subdomain? You can get DNS servers to shoot "Type A" requests to your box? Does the remote DBMS resolve external names? If so, you can forget about that sluggish inference-based extraction and start pulling data almost at light speed (well, comparatively speaking). Make sure you run sqlninja as root, set <CODE>
<A HREF="#domain_">domain</A></CODE> in the configuration file, and you are ready to go.</P>
<P><B>Additional info</B></P>
<P>By default, sqlninja stores all extracted information in a local SQLite database, whose filename is specified via command line with the <CODE>-s</CODE> parameter. The default name is <CODE>session.db</CODE>. For all other parameters and details, see
<A HREF="#dataextractionoptions_">data extraction options</A>.</P>
<H2><A NAME="other_"></A> <A NAME="ss2.15">2.15</A> <A HREF="#toc2.15">Other attacks</A>
</H2>
<P>Quite often, SQL Server does not run as SYSTEM but as a less-privileged user (very often "Network Service").
This creates limitations in what the attacker can do (e.g.: extract password hashes). It also creates problems with the VNC Injection,
causing a black screen to be returned. However, with sqlninja we can try to escalate privileges to SYSTEM, using two different attacks techniques.</P>
<H3><A NAME="kitrap0d_"></A> CVE-2010-0232</H3>
<P>If SQL Server runs as a low-privileged user, and the machine is not patched against CVE-2010-0232, we can try to elevate its privileges to SYSTEM. Sqlninja ships with a version of the original exploit by Tavis Ormandy that has been specifically customized: while the original exploit spawns a DOS prompt, our version looks for the sqlservr.exe process and forces it to run as SYSTEM.
In order to launch the attack, the following steps are required:
<OL>
<LI>
<A HREF="#upload_">Upload</A> <CODE>vdmallowed.exe</CODE> and <CODE>vdmexploit.dll</CODE>, which are available in the <CODE>apps</CODE> directory in executable format and in the <CODE>scripts</CODE> directory (in debug script format)</LI>
<LI>Using the
<A HREF="#sqlcmd_">sqlcmd attack mode</A>, run the following command:
<CODE>%TEMP%\vdmallowed sql</CODE>
</LI>
<LI>If the attack was successful,
<A HREF="#finger_">fingerprint mode</A> should tell you that SQL Server is now running as SYSTEM</LI>
</OL>
</P>
<H3><A NAME="token_"></A> Token kidnapping</H3>
<P>On Windows 2003 we can also attempt to escalate our privileges using token kidnapping, a technique researched by
<A HREF="http://www.argeniss.com/research/TokenKidnapping.pdf">Cesar Cerrudo</A>.
As a proof of concept he developed
<A HREF="http://www.argeniss.com/research/Churrasco.zip">churrasco.exe</A>,
which is included in the sqlninja tarball in a slightly modified version. If you need to escalate to SYSTEM simply upload it
to the remote server using the <CODE>upload</CODE> mode and then set the
<A HREF="#usechurrasco_">usechurrasco</A> option to <CODE>yes</CODE>: all commands will then be wrapped with churrasco.exe. Keep in mind that this will not work if the remote DBMS has been patched
against the attack, but you can check whether things are working using the
<A HREF="#finger_">fingerprint mode</A> while this option
is enabled.</P>
<P>Important: be sure to use the modified version of churrasco (yes, the one in the sqlninja tarball), or things are likely to break. You can see the differences in the C source in the <CODE>sources</CODE> directory, but basically they boil down to:
<OL>
<LI>No verbose output unless the <CODE>-d</CODE> option is used. Verbose output would interfere with option 5 of the fingerprint mode, which uses a temporary table to store the results of a churrasco.exe execution.</LI>
<LI><CODE>CreateProcessAsUser()</CODE> is called passing the original (unprivileged) user's %TEMP% directory as the <CODE>lpCurrentDirectory</CODE> parameter, which is where our executables (e.g.: netcat) are uploaded (and not in the %TEMP% directory of SYSTEM).</LI>
</OL>
</P>
<H2><A NAME="conf_"></A> <A NAME="s3">3.</A> <A HREF="#toc3">Configuration file</A></H2>
<P>The configuration file (default: <CODE>sqlninja.conf</CODE>) controls most of sqlninja behaviour. All options are in the form:
<BLOCKQUOTE><CODE>
option_name = option_value
</CODE></BLOCKQUOTE>
The only exception is <CODE>httprequest</CODE>, which defines the HTTP request and the injection point and which spans multiple lines (see below).</P>
<P>Options can be roughly divided into the following categories:
<UL>
<LI>
<A HREF="#basic_">Basic</A>: used to configure the attack</LI>
<LI>
<A HREF="#dataextractionoptions_">Data extraction</A>: used to configure the data extraction mode</LI>
<LI>
<A HREF="#advanced_">Advanced</A>: used for additional fine-tuning</LI>
</UL>
</P>
<P>Options are, more often than not, case sensitive (e.g.: URL values). The same option can be used multiple times: sqlninja does not care and will simply use the last declaration, overriding the previous ones.
Comments are allowed anywhere except between <CODE>--httprequest_start--</CODE> and <CODE>--httprequest_end--</CODE> (see below), and they are prepended by the '#' character. A quick recap of what follows can also be found in <CODE>sqlninja.conf.example</CODE>.</P>
<H2><A NAME="basic_"></A> <A NAME="ss3.1">3.1</A> <A HREF="#toc3.1">Basic options</A>
</H2>
<H3>httprequest</H3>
<P>Starting from version 0.2.6, sqlninja uses a new way to configure the HTTP request and the relative injection string. Instead of separate parameters for host, port, page, HTTP method, exploitation string and additional headers, the whole HTTP request is specified at once, with a marker (by default <CODE>__SQL2INJECT__</CODE>) that indicates where the SQL commands need to be injected.
This simplifies things a lot, and most importantly allows complete freedom in where the injection vector can be: now you are not limited to a GET or POST parameter, but you can inject wherever you need (e.g.: in a cookie).
Sqlninja will consider as the HTTP request everything that is included between the lines <CODE>--httprequest_start--</CODE> and <CODE>--httprequest_end--</CODE>.</P>
<P>In general, the following elements must be included:
<UL>
<LI>The HTTP Method (usually POST or GET)</LI>
<LI>The full URL to the resources, including <CODE>http://</CODE> or <CODE>https://</CODE></LI>
<LI>The port, if not standard (e.g.: <CODE>http://www.victim.com:8080</CODE>)</LI>
<LI>The HTTP version</LI>
<LI>All necessary headers</LI>
<LI>The body after an empty line, if the request uses POST</LI>
</UL>
</P>
<P>In general, the best strategy is just to use a proxy (e.g. Burpsuite) to intercept the request that triggers the SQL Injection and copy it into <CODE>sqlninja.conf</CODE></P>
<P>For instance, a GET-based injection over plaintext HTTP will look like the following:
<BLOCKQUOTE><CODE>
<PRE>
--httprequest_start--
GET http://www.victim.com/page.asp?string_param=aaa';__SQL2INJECT__&other_param=blah HTTP/1.1
Host: www.victim.com
User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.7.13) Gecko/20060418 Firefox/1.0.8
Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*
Accept-Language: en-us,en;q=0.7,it;q=0.3
Accept-Charset: ISO-8859-15,utf-8;q=0.7,*;q=0.7
Connection: close
--httprequest_end--
</PRE>
</CODE></BLOCKQUOTE>
</P>
<P>Alternatively, a POST-based injection over HTTPS will probably look like the following (note the Content-Type header and the empty line between headers and body):
<BLOCKQUOTE><CODE>
<PRE>
--httprequest_start--
POST https://www.victim.com/page.asp HTTP/1.0
Host: www.victim.com
User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.7.13) Gecko/20060418 Firefox/1.0.8
Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*
Accept-Language: en-us,en;q=0.7,it;q=0.3
Accept-Charset: ISO-8859-15,utf-8;q=0.7,*;q=0.7
Content-Type: application/x-www-form-urlencoded
Cookie: ASPSESSIONID=xxxxxxxxxxxxxxxxxxxx
Connection: close
</PRE>
</CODE></BLOCKQUOTE>
</P>
<P>
<BLOCKQUOTE><CODE>
<PRE>
numeric_param=12;__SQL2INJECT__
--httprequest_end--
</PRE>
</CODE></BLOCKQUOTE>
Note that the Content-Length header is not included: sqlninja will calculate the appropriate value and add the header automatically.</P>
<P>Finally, a cookie-based injection will look like the following:
<BLOCKQUOTE><CODE>
<PRE>
--httprequest_start--
GET http://www.victim.com:8080/page.asp?param1=aaa&param2=blah HTTP/1.0
Host: www.victim.com
User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.7.13) Gecko/20060418 Firefox/1.0.8
Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*
Accept-Language: en-us,en;q=0.7,it;q=0.3
Accept-Charset: ISO-8859-15,utf-8;q=0.7,*;q=0.7
Cookie: ASPSESSIONID=xxxxx'%3B__SQL2INJECT__
Connection: close
--httprequest_end--
</PRE>
</CODE></BLOCKQUOTE>
</P>
<P>Note how the semicolon after the apostrophe has been encoded to %3B: this is because otherwise the server would parse the semicolon as a separator between different cookies.</P>
<P>Before the <CODE>__SQL2INJECT__</CODE> marker, you need to include everything that is needed to close the original query and start a new one, such as the vulnerable parameter and the character sequence that allows us to start injecting commands. This usually means, at least:
<OL>
<LI>the vulnerable parameter (name+value)</LI>
<LI>a single quote (if the parameter is a string)</LI>
<LI>a semicolon (to end the original query)</LI>
</OL>
It must also include everything that is needed to properly close the original query, as an appropriate number of closing brackets. For instance, if want to inject the following TSQL command:
<BLOCKQUOTE><CODE>
param1=1&param2=x'));exec+master..xp_cmdshell+'dir+c:'
</CODE></BLOCKQUOTE>
the HTTP request in the configuration file should contain the following:
<BLOCKQUOTE><CODE>
param1=1&param2=x'));__SQL2INJECT__
</CODE></BLOCKQUOTE>
</P>
<P>Important things to remember:
<UL>
<LI>In general, a good technique is to replicate as closely as possible the HTTP request that you used to originally detect the SQL Injection flaw (with a web browser or another tool), as in some edge cases a slightly different header can make a big difference. The only suggested and usually safe modification is to use HTTP/1.0 in order to avoid problems with connections remaining open</LI>
<LI>In order to give you full power and flexibility in crafting your exploit, sqlninja does not try to meddle in any way: this means that it will not modify your HTTP request (apart from the code to inject where the marker is, obviously), but it also means that it will not try to correct your syntax, so make sure your HTTP request is correct (including all needed URL-encoding). For more information, see RFC 1945, RFC 2068 and RFC 2616.</LI>
<LI>Sometimes you might also need to add some more SQL code after the injected query (and therefore after the marker). Usually this is not needed, since sqlninja simply appends two hyphens and comments out the remainder of the original query, but there are some (rare) cases when you need to append additional SQL code for the batched queries to work correctly. In this case, don't forget to also set <CODE>appendcomment = no</CODE>, otherwise the two hyphens will be appended and the SQL code specified here will be considered a comment</LI>
<LI>If you are injecting in a cookie, and you need a semicolon to close the original query, remember to encode it (%3B), otherwise it will be parsed as the end of the cookie value</LI>
<LI>Do not leave spaces at the beginning of each line!</LI>
<LI>Do not leave comment lines! They would be parsed as part of the request!</LI>
<LI>Finally, if you don't specify the port to connect to, sqlninja will assume 80 for HTTP and 443 for HTTPS</LI>
</UL>
</P>
<H3><A NAME="proxyhost_"></A> proxyhost</H3>
<P>An HTTP proxy to connect to the target host, if needed. For example:
<BLOCKQUOTE><CODE>
proxyhost = 192.168.1.233
</CODE></BLOCKQUOTE>
</P>
<H3><A NAME="proxyport_"></A> proxyport</H3>
<P>The port of the HTTP proxy that we connect to. Default is 8080. For example:
<BLOCKQUOTE><CODE>
proxyport = 3128
</CODE></BLOCKQUOTE>
</P>
<H3><A NAME="domain_"></A> domain</H3>
<P>The attacker's controlled domain or subdomain to be used with the dnstunnel mode and DNS-based data extraction mode. The IP address from which sqlninja is launched must be the authoritative DNS server for
that domain. For example:
<BLOCKQUOTE><CODE>
domain = sqlninja.net
</CODE></BLOCKQUOTE>
</P>
<H3><A NAME="msfpath_"></A> msfpath</H3>
<P>The absolute path to Metasploit executables (<CODE>msfpayload</CODE> and <CODE>msfcli</CODE>). You don't need this if they are already in your default path. For example:
<BLOCKQUOTE><CODE>
msfpath = /home/icesurfer/tools/framework-3.1
</CODE></BLOCKQUOTE>
</P>
<H3><A NAME="evasion_"></A> evasion</H3>
<P>Sqlninja can use a few evasion techniques, in order to confuse and bypass signature-based IPS/IDS. Currently, four techniques are implemented, which can be freely combined together:
<OL>
<LI>Query hex-encoding: the query is hex-encoded before being run</LI>
<LI>Comments as separators: all spaces are substituted by the string <CODE>/**/</CODE></LI>
<LI>Random case</LI>
<LI>Random URI encoding </LI>
</OL>
</P>
<P>The first technique is particularly useful. For instance, if we want to inject the following command:
<BLOCKQUOTE><CODE>
exec master..xp_cmdshell 'cmd /C ping 127.0.0.1'
</CODE></BLOCKQUOTE>
The actual query will become:
<BLOCKQUOTE><CODE>
declare @a varchar(8000) set @a=0x65786563206d61737465722e2e78705f636d647368656c6c2027636d64202f432070696e67203132372e302e302e31273b exec (@a)
</CODE></BLOCKQUOTE>
A much longer string, but notice the following:
<UL>
<LI>No SQL commands except DECLARE and EXEC, so bye-bye IPS's looking for xp_cmdshell and the like</LI>
<LI>No single quotes either! This evasion technique is therefore extremely useful if you find a vulnerable numeric parameter and single quotes are filtered</LI>
</UL>
</P>
<P>As mentioned, you can combine all the techniques together with the following option:
<BLOCKQUOTE><CODE>
evasion = 1234
</CODE></BLOCKQUOTE>
This will generate quite cryptic code, as the following one:
<BLOCKQUOTE><CODE>
%64ECl%41RE%2F%2A%2A%2F%40%61%2F%2A%2A%2F%76Ar%63%48aR%288000%29%2F%2A%2A%2F%73
ET%2F%2A%2A%2F%40A%3D%30%586%35786%3563%3206d617%33746%35%372%32e2%457870%35F63
6d647368%36%35%36%63%36c2%302%37636D%3642%30%32f%34320%37%3069%36%65%36720%331%
332372E%330%32E3%30%32%45%3312%373b%2F%2A%2A%2FeX%65%43%2F%2A%2A%2F%28%40A%29
</CODE></BLOCKQUOTE>
As a default, sqlninja sets <CODE>evasion</CODE> to zero, and no evasion technique will be used.</P>
<P><B>Important:</B> avoid using unnecessary obfuscation if you are using GET requests, as this might lead to URLs that are too long and that are not successfully parsed by the web server!</P>
<H3><A NAME="msfencoder_"></A> msfencoder</H3>
<P>The encoder to use for the Metasploit stager. If not specified, no encoding is performed. However, a good encoder is always recommended. For example:
<BLOCKQUOTE><CODE>
msfencoder = x86/shikata_ga_nai
</CODE></BLOCKQUOTE>
</P>
<H3><A NAME="uploadmethod_"></A> upload_method</H3>
<P>The method to use to upload binary files. Possible values are <CODE>debug</CODE> or <CODE>vbscript</CODE> (default). For example:
<BLOCKQUOTE><CODE>
upload_method = vbscript
</CODE></BLOCKQUOTE>
</P>
<H2><A NAME="dataextractionoptions_"></A> <A NAME="ss3.2">3.2</A> <A HREF="#toc3.2">Data extration options</A>
</H2>
<H3><A NAME="data_channel_"></A> data_channel</H3>
<P>The channel to use to extract data. It can be <CODE>time</CODE> (default) to use a WAITFOR-based extraction channel (very slow, but always works) or <CODE>dns</CODE> (much faster, but you need to control a domain or subdomain to be resolved to your public IP address. For example:
<BLOCKQUOTE><CODE>
data_channel = time
</CODE></BLOCKQUOTE>
</P>
<H3><A NAME="data_extraction_"></A> data_extraction</H3>
<P>When using time-based extraction, there are three possible extraction methods. When choosing <CODE>binary</CODE>, sqlninja will perform a binary search, minimizing the number of requests. When choosing <CODE>serial</CODE>, sqlninja will try all possible values, which will probably be faster (since WAITFOR will be triggered only once) but will leave more entries in the remote logs. When choosing <CODE>serial_optimized</CODE>, sqlninja will try all possible values, starting from most likely candidates. The default is <CODE>serial_optimized</CODE></P>
<H3><A NAME="language_map_"></A> language_map</H3>
<P>If you are using time-based extraction and you have selected <CODE>serial_optimized</CODE> as your extraction method, you can specify a language map where you can specify the orders of characters that should be tried when extracting data. You can find some pre-defined maps under lib/langs, where included maps for English, French, Italian, German, Spanish and Portuguese. Such maps are based on the letter frequency in the respective languages and include also a whitespace and some common punctuation characters. If you need a custom map, just list the characters in a single line. You don't need to specify all possible characters: the ones not in the map will simply be tried if none of the specified ones is successful. For example:
<BLOCKQUOTE><CODE>
language_map = lib/langs/en.maps
</CODE></BLOCKQUOTE>
</P>
<H3><A NAME="language_map_adaptive_"></A> language_map_adaptive</H3>
<P>When using a serial-optimized extraction, sqlninja can use an adaptive approach: basically, each character in the language map is given a "weight" and every time a character is successfully extracted by the remote database, the weight of this character in the language map is increased by one. When the weight of the caracter in position N is higher than the weight of the character in position N-1, their places are switched in the map itself, so that the character with the higher weight (which is therefore more frequent) will be tried first when extracting following characters. Values here are either <CODE>yes</CODE> or <CODE>no</CODE>, but in general you should always stick to <CODE>yes</CODE> for better results. For example:
<BLOCKQUOTE><CODE>
language_map_adaptive = yes
</CODE></BLOCKQUOTE>
</P>
<H3><A NAME="store_session_"></A> store_session</H3>
<P>By default, sqlninja stores all extracted information in a local SQLite database, specified via command line (default: session.db). This allows you locally save all extracted data and to retrieve it at a later moment. In general, leave this to <CODE>yes</CODE>. For instance:
<BLOCKQUOTE><CODE>
store_session = yes
</CODE></BLOCKQUOTE>
</P>
<H3><A NAME="sanity_check_"></A> sanity_check</H3>
<P>When using time-based extraction, network latency can limit the accuracy if extracted data. Sqlninja can check the accuracy of extracted information (currently DBs, users, tables, columns but not rows yet) and retry to extract the same piece of information if a problem is detected. The check involves only one query, is performed at the end of the extraction of a whole string (e.g.: a column name), and uses a WAITFOR that is executed only if the information is incorrect. Therefore, the check has a very limited performance impact. In general, leave this to <CODE>yes</CODE>. For example:
<BLOCKQUOTE><CODE>
sanity_check = yes
</CODE></BLOCKQUOTE>
</P>
<H2><A NAME="advanced_"></A> <A NAME="ss3.3">3.3</A> <A HREF="#toc3.3">Advanced options</A>
</H2>
<H3><A NAME="lhost_"></A> lhost</H3>
<P>The IP addresses or hostname that the target must try to contact in backscan and revshell mode. That is *your* machine. Of course, if the attack is performed over the Internet, this must be a public address. For example:
<BLOCKQUOTE><CODE>
lhost = tester.sqlninja.net
</CODE></BLOCKQUOTE>
</P>
<H3><A NAME="device_"></A> device</H3>
<P>The device to use for sniffing packets when in backscan mode (default: eth0).
For example:
<BLOCKQUOTE><CODE>
device = ppp0
</CODE></BLOCKQUOTE>
</P>
<H3>filter</H3>
<P>A valid pcap expression to filter incoming packets in backscan mode. By default, when performing such attack, sqlninja listens for packets coming from the IP address of the remote web server and directed to the host specified in <CODE>lhost</CODE>. This might not work in all cases: for instance, the outbound connections of the DB server could be NATed to an IP address which is different from the IP address of the web server. Therefore, we need to override the default pcap filter with this parameter, for instance indicating the whole public subnet of the target. You only need to specify hosts/networks here, as the protocol details (e.g.: tcp flags) are handled by sqlninja. For example:
<BLOCKQUOTE><CODE>
filter = src host nat.victim.com
</CODE></BLOCKQUOTE>
</P>
<H3>timeout</H3>
<P>This parameter is used when in backscan mode. It specifies how many seconds to wait for further packets
after the web request has completed (default: 5 seconds). This is especially useful when specifying a very large range of ports to scan, because the web request might timeout before netcat has completed. In this case, you should increase this value. For example:
<BLOCKQUOTE><CODE>
timeout = 30
</CODE></BLOCKQUOTE>
However, try to avoid very large port ranges: better to split the job in multiple scans.</P>
<H3>hostnamelength</H3>
<P>Maximum length of FQDN of the fake hostnames that the target will try to resolve in dnstunnel mode. RFCs state that 255 characters is the limit, but I bumped into a few DNS servers that refused names longer than 253. The default value is therefore 250, which should be accepted by every DNS server, and at the same time keep an almost optimal tunnel speed. Minimum value is 40. Maximum is obviously 255.
For example:
<BLOCKQUOTE><CODE>
hostnamelength = 250
</CODE></BLOCKQUOTE>
</P>
<P>You can also tune this parameter to lower values when you think that very long DNS requests might be spotted. Of course, shorter values mean a slower tunnel. If unsure, leave the default value.</P>
<H3><A NAME="msfencodecount_"></A> msfencodecount</H3>
<P>Number of times that the stager must be encoded. Default is 5. For example:
<BLOCKQUOTE><CODE>
msfencodecount = 8
</CODE></BLOCKQUOTE>
</P>
<H3><A NAME="usechurrasco_"></A> usechurrasco</H3>
<P>This setting is used to escalate privileges through
<A HREF="#token_">token kidnapping</A>. The default of this setting is <CODE>no</CODE>. For example:
<BLOCKQUOTE><CODE>
usechurrasco = yes
</CODE></BLOCKQUOTE>
</P>
<H3>resolvedip</H3>
<P>In dnstunnel mode, the IP address that is sent back to each DNS request (since we don't want gethostbyname() to hang). In general, it is advisable to set this to 127.0.0.1 (which is the default), to avoid spurious network traffic generated after the remote DBMS receives a fake DNS response.
<BLOCKQUOTE><CODE>
resolvedip = 10.255.255.254
</CODE></BLOCKQUOTE>
</P>
<H3><A NAME="xp_name_"></A> xp_name</H3>
<P>Name of the extended procedure that executes our commands. The default is obviously <CODE>xp_cmdshell</CODE>.
This parameter is used in two different ways, depending on the current attack mode:
<UL>
<LI>resurrectxp: <CODE>xp_name</CODE> contains the name of the extended procedure to create. If you believe that re-enabling xp_cmdshell might be spotted, use another name here (e.g.: <CODE>sp_sqlbackup</CODE>)</LI>
<LI>all other modes: the extended procedure name to use. It goes without saying that it must be the same name previously used with the resurrectxp mode.</LI>
</UL>
xp_name can be set to <CODE>NULL</CODE> to use the inline procedure injection technique (see
<A HREF="#resurrectxp_">resurrect_xp</A> mode for more details). For example:
<BLOCKQUOTE><CODE>
xp_name = sp_sqlbackup
</CODE></BLOCKQUOTE>
</P>
<H3>blindtime</H3>
<P>The value for the WAITFOR DELAY calls that are used in fingerprint and bruteforce modes for the
inference-based injection. Default value is 5 seconds, but this might be too low for very slow servers and lead to wrong results. If that happens, try increasing this value. On the other hand, if the server response time is very short, you can set a lower value to make things faster (minimum: 3). For example:
<BLOCKQUOTE><CODE>
blindtime = 4
</CODE></BLOCKQUOTE>
If you have no clue about what inference-based injection means, enjoy some time in the
<A HREF="#background_">background section</A>.</P>