WAF

Fc04dB Lv3

# WAF

WAFWeb Application Firewall ,网页应用防火墙)是一种专门设计用于保护 Web 应用程序的安全设备或软件,旨在通过监控、过滤和分析 HTTP/HTTPS 流量,防止常见的 Web 攻击,如 SQL 注入、跨站脚本(XSS)攻击和跨站请求伪造(CSRF)等

WAF 一般部署在 Web 服务器之前,用来保护 Web 应用

# WAF 与传统安全设备

传统安全设备特点:

  • IPS:针对蠕虫、网络病毒、后门木马防护,不具备 WEB 应用层的安全防护能力

  • 传统 FW:作为内网与外网之间的一种访问控制设备,提供 3-4 层的安全防护能力,不具备 WEB 应用层的安全防护能力

  • UTM/NGFW: 优势,UTM 或者 NGFW 把多种安全能力融合为一体(上网行为管理、IPS、防病毒、WEB 安全防护)

    劣势:各安全引擎模式开启之后设备综合性能势必降低!

    n 多核架构 / MIPS 架构无法实现对 HTTP/HTTPS 数据包的深度检测(包括转换编码、拼接攻击语句、大小写变换、超大报文等),WEB 应用攻击的检出率低、漏报率高!

# 来自 ChatGPT 对于 WAF 与传统安全设备的区别的回答:

# 1. 保护对象

  • WAF:专门保护 Web 应用程序,主要针对 HTTP/HTTPS 流量和应用层攻击,如 SQL 注入、跨站脚本(XSS)、跨站请求伪造(CSRF)等。
  • 传统防火墙:主要保护网络边界,控制网络层的流量,防止未授权访问和攻击,针对 IP、端口、协议等进行过滤。
  • IDS/IPS:监控和分析网络流量以检测和阻止各种网络攻击和异常行为,保护整个网络环境。

# 2. 工作层面

OSI七层网络协议 | Clei's Blog

  • WAF:工作在应用层(OSI 模型的第 7 层),深入分析 Web 请求和响应,理解 HTTP/HTTPS 协议和 Web 应用逻辑。
  • 传统防火墙:工作在网络层(第 3 层)和传输层(第 4 层),关注 IP 地址、端口号和传输协议。
  • IDS/IPS:通常工作在网络层和传输层,有时也涉及应用层,但主要用于广泛的网络流量监控和防护。

# 3. 检测和防护方法

  • WAF:使用签名检测、行为分析、规则引擎、学习模式等方法,针对 Web 特有的攻击进行深度检查和防护。
  • 传统防火墙:使用基于状态的包过滤、访问控制列表(ACL)、NAT 等方法,控制和管理进出网络的流量。
  • IDS/IPS:使用签名检测、异常检测、协议分析等方法,检测并响应各种网络攻击,如 DDoS、端口扫描、恶意流量等。

# 4. 部署位置

  • WAF:通常部署在 Web 服务器前端,保护特定的 Web 应用程序或 Web 服务器。
  • 传统防火墙:部署在网络边界,如企业网络和互联网之间,保护整个网络的进出口。
  • IDS/IPS:可以部署在网络的不同位置,如网络边界、内部网络段之间,或者靠近关键资源,监控并保护整个网络环境。

# 5. 功能和用途

  • WAF:
    • 防护 Web 应用层攻击
    • HTTP/HTTPS 流量分析和过滤
    • Web 应用安全策略管理
    • 输入验证和输出编码
  • 传统防火墙:
    • 网络访问控制和流量过滤
    • VPN 支持和流量加密
    • 基于状态的包过滤
    • 防止未授权访问
  • IDS/IPS:
    • 实时监控和检测网络攻击
    • 自动响应和阻止攻击(IPS)
    • 网络行为分析和异常检测
    • 事件日志记录和报告

# 6. 具体防护场景

  • WAF:保护在线购物网站、Web 服务 API、内容管理系统(CMS)等 Web 应用程序,防止 Web 特有的攻击。
  • 传统防火墙:保护企业网络边界,控制内部网络和外部网络之间的流量,防止未经授权的访问和外部攻击。
  • IDS/IPS:监控整个网络的流量,检测和阻止各种类型的攻击,保护网络中的所有设备和服务。

# 7. 优势和劣势

  • WAF:
    • 优势:深度保护 Web 应用程序,针对 Web 特有攻击提供精细化防护。
    • 劣势:只能保护 Web 应用,对非 HTTP/HTTPS 流量无效。
  • 传统防火墙:
    • 优势:提供广泛的网络层和传输层保护,易于部署和管理。
    • 劣势:无法深入检查和理解应用层流量,难以防御复杂的应用层攻击。
  • IDS/IPS:
    • 优势:实时检测和响应各种网络攻击,保护整个网络环境。
    • 劣势:可能产生误报和漏报,配置和管理复杂。

# WAF 的工作原理

# 1. 流量过滤

WAF 通过拦截并检查所有进入和离开 Web 服务器的 HTTP/HTTPS 流量,确保只有合法和安全的请求能够到达应用程序。这包括:

  • 请求过滤:检查每个请求的 URL、头信息、参数和正文内容。
  • 响应过滤:检查服务器返回的响应内容,防止敏感信息泄露。

# 2. 签名检测

WAF 使用预定义的攻击签名库来识别已知的攻击模式。当请求或响应匹配这些签名时,WAF 会采取相应的措施,如阻止请求、记录事件或向管理员发送警报。

  • 例子:SQL 注入签名、XSS 攻击签名。

# 3. 行为分析

通过分析正常流量模式,WAF 可以建立基线并检测异常行为。这有助于识别零日攻击和其他未知威胁。

  • 例子:如果某 IP 地址在短时间内发送了大量的请求,WAF 可以将其视为可能的攻击并阻止其进一步请求。可以防御 CC 攻击(但是无法完全防御 DDos 攻击)

# 4. 规则引擎

管理员可以根据特定需求和安全策略定义自定义规则。WAF 会根据这些规则检测并响应特定类型的流量。

  • 例子:阻止来自某些地理位置的请求、限制特定 IP 地址的访问频率。

# 5. 安全策略管理

WAF 允许管理员定义和管理一系列安全策略,以适应不同的应用场景和需求。这些策略可以涵盖访问控制、输入验证、输出编码等方面。

  • 例子:仅允许特定用户组访问某些敏感功能。

# 6. 学习模式

许多现代 WAF 具备学习模式功能,能够自动学习和适应应用程序的正常行为,并动态调整防护策略以应对不断变化的威胁环境。

  • 例子:通过分析用户行为,自动调整防护规则以减少误报和漏报。

# 7. 日志记录与审计

WAF 记录所有检测到的威胁和采取的响应措施,生成详细的日志和报告,帮助管理员进行分析、审计和改进安全策略。

  • 例子:记录所有阻止的 SQL 注入尝试,并生成每周安全报告。

# 8. 集成与自动化

WAF 可以与其他安全设备和软件集成,如防火墙、入侵检测系统(IDS)、入侵防御系统(IPS)等,以形成综合的安全防护体系。

  • 例子:当 WAF 检测到某个攻击行为时,自动通知 IPS 进行进一步处理。

# WAF 的工作流程

  1. 接收请求:当用户向 Web 服务器发送 HTTP/HTTPS 请求时,WAF 首先接收该请求。
  2. 分析请求:WAF 检查请求的各个部分,包括 URL、参数、头信息和正文内容,进行签名检测和行为分析。
  3. 应用策略:根据预定义的安全策略和规则,决定如何处理该请求。可能的操作包括允许、阻止、记录或向管理员发送警报。
  4. 转发请求:如果请求被允许,WAF 将其转发到 Web 服务器进行处理。
  5. 监控响应:WAF 检查服务器返回的响应,确保没有敏感信息泄露或其他安全问题。
  6. 返回响应:最后,WAF 将安全的响应返回给用户。

# 简单的自定义 WAF

编写代码来捕获和解析 HTTP/HTTPS 流量。可以使用以下库:

  • Python: scapy , dpkt , http.server
  • Node.js: http , https
  • C/C++: libpcap , libnetfilter_queue
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
from http.server import BaseHTTPRequestHandler, HTTPServer
import re

class SimpleWAF(BaseHTTPRequestHandler):
def do_GET(self):
if self.is_malicious_request(self.path):
self.send_response(403)
self.end_headers()
self.wfile.write(b"403 Forbidden")
else:
self.send_response(200)
self.end_headers()
self.wfile.write(b"Hello, World!")

def is_malicious_request(self, path):
patterns = [
re.compile(r"(<|%3C).*script.*(>|%3E)", re.IGNORECASE), # XSS
re.compile(r"(\%27)|(\')|(\-\-)|(\%23)|(#)", re.IGNORECASE), # SQL Injection
]
for pattern in patterns:
if pattern.search(path):
return True
return False

if __name__ == "__main__":
server = HTTPServer(('localhost', 8080), SimpleWAF)
print("Starting server at http://localhost:8080")
server.serve_forever()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
<?php

class SimpleWAF {
private $patterns = [
'/(<|%3C).*script.*(>|%3E)/i', // XSS
'/(\%27)|(\')|(\-\-)|(\%23)|(#)/i', // SQL Injection
'/select\b|insert\b|update\b|delete\b|drop\b|union\b/i' // SQL Keywords
];

public function __construct() {
$this->filterRequest();
}

private function filterRequest() {
foreach ($_GET as $key => $value) {
$this->checkMalicious($value);
}

foreach ($_POST as $key => $value) {
$this->checkMalicious($value);
}

foreach ($_COOKIE as $key => $value) {
$this->checkMalicious($value);
}
}

private function checkMalicious($value) {
foreach ($this->patterns as $pattern) {
if (preg_match($pattern, $value)) {
$this->blockRequest();
}
}
}

private function blockRequest() {
header('HTTP/1.1 403 Forbidden');
echo "403 Forbidden - Your request has been blocked by the WAF.";
exit();
}
}

// 初始化 WAF
new SimpleWAF();

// 继续处理正常请求
echo "Hello, World!";
?>

# WAF Bypass

# 超过 WAF 配额绕过

为不干扰到网站的正常运行,配置 WAF 检测额度内进行过滤,有些 WAF 就会设置如果数据包长度超过所检测的长度,就会对部分数据包或者是数据包的部分内容进行无检测 “放行”。

# 增加参数个数

配置的原因,例如 safedog,只会检测前 100 个参数,把自己的执行语句放在 100 个之后

# 增加参数长度

文件上传漏洞利用时,增加无意义数据,webshell 放在最后面;

SQL 注入时,增加 URL 编码长度,并注释掉;

xss 测试时加入无意义内容

# 增加 WAF 负载

向 WAF 发送大量正常数据包,并发送异常数据包,导致站点流量过大,可能会对部分数据包进行检查,注意分寸,避免造成宕机。

# 构造异常数据包

# 双参数绕过

网站有一个 id 参数,在数据包中包含两个 id 参数进去,WAF 可能只检测第一个,第二个就会被服务器执行

# 请求方式转换

根据对 WAF 配置的不同

如果 WAF 只检验 GET 类型的包,忽略 POST 类型的包,修改数据包类型尝试绕过

如果 WAF 只检验 POST 类型的包,忽略 GET 类型的包,修改数据包类型尝试绕过

有时,也可尝试,把数据包改为 request 类型等或根本就不存在的其他类型

另一方面:POST 在提交数据的时候有两种方式,第一种方式是使用 urlencode 的方式提交,第二种方式是使用 form-data 的方式提交。当我们在测试站点的时候,如果发现 POST 提交的数据被过滤掉了,此时可以考虑使用 form-data 的方式去提交。

# 绕过匹配

# 大小写变换

?id=-1’ UnIOn SeLEct 1,VERsion(),3

# 将关键词进行等价替换

Hex() bin() 等价于 ascii()

Sleep() 等价于 benchmark()

Mid()substring() 等价于 substr()

@@user 等价于 User()

@@Version 等价于 version()

**greatest 替换 > **

greatest 返回两个值中大的那个

?id=-1’ union select greatest(ascii(substr(database(),0,1)),1) --+

least 替换 <

least 返回两个值中小的那个

?id=-1’ union select least(ascii(substr(database(),0,1)),1000000) --+

strcmp 函数

比较两个值大小,相等返回 0 后者比前者大返回 - 1 小返回 1

?id=-1’ union select srtcmp(ascii(substr(database(),0,1)),100) --+

in 替换 =

相等返回 1 不相等返回 0

?id=-1’ union select substr(database()) in (“u”) --+

between and 替换 =

?id=-1’ union select substr(database()) between “a” and “u” --+

form for

盲注过滤逗号

?id=-1’ union select(database() form 0 for 1) --+

limit A offset B

当过滤逗号时,limit 后面只能有一个参数,表示要取的数量,offset 表示跳过数量

select * from users limit 3 offset 2

# 使用嵌套

对某些关键字替换为空,尝试采用嵌套双写进行绕过

SELselectECT、UNunionION

# 使用编码

Json
Unicode
base64
urlencode
html
Serialize

双重编码:

WAF 又是会解码后过滤

# 特殊符号:

*+(-)(@)(!) 等替代空格 *

select+database()

select@database()

xor 逻辑异或

任意一个数为 NULL 时,返回 NULL

非 NULL 的数,逻辑真假值相异,返回 1,否则为 0

database()=“admin” xor 0

/**/ () %0a `` 2个空格 替代 空格

select/**/database()

替换 and or not xor

and ----> && ,or ------> || ,xor ------> | ,not -----> !

替换 =

like rlike

where id rlike 1

where id like “admin”

union all select

select password from users where id rlike 1 union all select version();

注释符加换行绕过

image-20240607201043694

select #a database()

selelct %23%0a database()

(%23 表示注释 %0a 表示换行)

空字节

有的过滤会碰到空字节会中止过滤

?id=1 a%00nd 1=2……

?id=1 %00 and 1=2……

宽字节

union = uю%69яю这里把 i 不用宽字节 直接 url 编码 其他的字符都用对应的宽字节
select = こхlх%уt //t 不编码 其他的都宽字节 中间插上 %
from = цR%яэ // 宽字节 +%
空格 =%20=%ва //в是 2 的款字符 а是 0 的宽字符
,= Ь //, 号的宽字节

# http 参数污染

利用参数污染来导致网站和安全狗接受数据的不一致性,实现绕过的操作。当 get 方式进行传参时,经过 & 符号传入多个参数,WAF 可能只检测第一个参数的值,然后台却检测最后一个传入的值,此时能够绕过 WAF 的防护

下图即每种服务器获得到的参数

image-20240607202628738

?id=1/**&id=-1' union select 1,database(),3 #*/

安全狗收到的: 1/**&id=-1' union select 1,database(),3 #*/

被注释,没法执行,安全狗会忽略

网站收到的: -1' union select 1,database(),3 #*/

被带入执行

# 构造畸形请求包

(1) 删掉 content-type

(2) 构造多个 filename

(3) content-type 后面加 TABLE 键

(4) 换行 boundary

(5) 文件名前面加空格

(6) 文件名前面加单引号

# 白名单 Bypass

方式一:IP 白名单

从网络层获取的 ip,这种一般伪造不来,如果是应用层的获取的 IP,这样就可能存在伪造白名单 IP 造成 bypass。

测试方法:修改 http 的 header 来 bypass WAF

1
2
3
4
5
X-forwarded-for
X-remote-IP
X-originating-IP
x-remote-addr
X-Real-ip

方式二:静态资源

特定的静态资源后缀请求,常见的静态文件 (.js .jpg .swf .css 等等),类似白名单机制,WAF 为了检测效率,不去检测这样一些静态文件名后缀的请求。

1
2
http://10.9.9.201/sql.php/1.js?id=1
# Aspx/php只识别到前面的.aspx/.php 后面基本不识别

方式三:url 白名单

为了防止误拦,部分 WAF 内置默认的白名单列表,如 admin/manager/system 等管理后台。只要 url 中存在白名单的字符串,就作为白名单不进行检测。常见的 url 构造姿势:

1
2
3
http://10.9.9.201/sql.php/admin.php?id=1
http://10.9.9.201/sql.php?a=/manage/&b=../etc/passwd
http://10.9.9.201/../../../manage/../sql.asp?id=2

WAF 通过 /manage/" 进行比较,只要 uri 中存在 /manage/ 就作为白名单不进行检测,这样我们可以通过 /sql.php?a=/manage/&b=…/etc/passwd 绕过防御规则。

方式四:爬虫白名单

部分 WAF 有提供爬虫白名单的功能,识别爬虫的技术一般有两种:

1、 根据 UserAgent 2、通过行为来判断

UserAgent 可以很容易欺骗,我们可以伪装成爬虫尝试绕过。

  • Title: WAF
  • Author: Fc04dB
  • Created at : 2024-06-07 00:12:45
  • Updated at : 2024-07-04 23:15:42
  • Link: https://redefine.ohevan.com/2024/06/07/WAF/
  • License: This work is licensed under CC BY-NC-SA 4.0.
Comments