我正在检查涉及XSS(link)的安全竞赛的结果,并发现了一些精彩且可怕的JS XSS payloas。获胜者(@kinugawamasato)使用了一种javascript压缩技术,这对我来说似乎完全不同于世界:
压缩有效载荷:
https://cure53.de/xmas2013/?xss=<scriPt>document.write(unescape(escape(location)
.replace(/u(..)/g,'$1%')))<\/scriPt>㱯扪散琠楤㵥污獳楤㵣汳楤㨳㌳䌷䉃㐭㐶うⴱㅄ〭
䉃〴ⴰ〸ぃ㜰㔵䄸㌠潮牯睥湴敲㵡汥牴⠯繷⸪ℱ⼮數散⡲散潲摳整⠰⤩⤾㱳癧湬潡搽攮摡瑡畲氽慬汛攮
牯睤敬業㴳㍝⬧㽳慮瑡㵀Ⅱ汬潷彤潭慩湳㴧⭤潭慩渻攮捨慲獥琽❵瑦ⴷ✾
真正发生的事情:
<object id=e classid=clsid:333C7BC4-460F-11D0-BC04-0080C7055A83 onrowenter=alert(/~w.*!1/.exec(recordset(0)))><svg onload=e.dataurl=all[e.rowdelim=33]+'?santa=@!allow_domains='+domain;e.charset='utf-7'>
这项技术是否已在某处记录,以便我可以研究它?这件事有多么可行?是否已经有一些javascript压缩器以自动方式执行此操作? WAF将如何对这样的有效载荷作出反应?
您可以看到更多示例here。
答案 0 :(得分:3)
每当将任何数据放入localStorage
时,我都会使用lz-string库进行JS压缩。我只是这个库的用户 - 而不是压缩专家。但这是可以在该工具周围找到的信息......
lz-string目标:
lz-string旨在满足
localStorage
中存储大量数据的需求,特别是在移动设备上。 localStorage通常限制为5MB,您可以压缩的是您可以存储的更多数据。... 我(注意:&#34;我&#34;意思是,Pieroxy,lz-string的作者)从LZW实现开始(没有更多的专利),这非常简单..
所以,基础,这个实现的基础是LZW,Javascript client-data compression在Andy E提到Wikipedia article on LZW。让我指出
Welch的1984描述的场景将8位数据序列编码为固定长度的12位代码。从0到255的代码表示由相应的8位字符组成的1字符序列,并且在字典中为编码时在数据中遇到的序列创建代码256到4095。在压缩的每个阶段,输入字节被收集到一个序列中,直到下一个字符生成一个序列,而该字典中还没有代码。序列的代码(没有该字符)被添加到输出中,并且新的代码(具有该字符的序列)被添加到字典中。
此处显示了编码算法的高级视图:
- 初始化字典以包含长度为1的所有字符串。
- 在字典中找到与当前输入匹配的最长字符串W.
- 发出W的字典索引以输出并从输入中删除W.
- 添加W,然后在字典输入中添加下一个符号。
- 转到第2步。
醇>
如果我们可以在这里观察lz-string,它是如何工作的:
让我引用已经提及的http://pieroxy.net/blog/pages/lz-string/demo.html:
中的几个步骤我做的是:
- localStorage只能包含JavaScript字符串。 JavaScript中的字符串内部存储在UTF-16中,这意味着每个字符的权重为16位。我修改了实现以使用16位宽的令牌空间。
- 我必须删除默认的字典初始化,在16位宽的令牌空间上完全没用。
- 我用三个标记初始化字典:
- 生成16位令牌的条目。
- 一个产生8位令牌的条目,因为我将存储的大部分内容都在iso-latin-1空间中,这意味着令牌低于256。
- 标记流结束的条目。
- 输出由比特流处理,该比特流在输出字符串中每个字符有效存储16位。
- 每个令牌都存储有根据字典大小所需的位数。因此,第一个令牌占用2位,第二个占用第7位,等等....
嗯,现在我们知道,通过这些压缩技术,我们得到16位信息。我们可以在此演示中测试它:here (或/和另一个{{3}})
将Hello, world.
转换为
85 04 36 30 f6 60 40 03 0e 04 01 e9 80 39 03 26
00 a2
所以我们需要最后一步,让我再说一次:
好吧,这个lib产生的东西不是真正的字符串。通过使用UTF-16位空间的所有16位,这些字符串不是完全有效的UTF-16。在版本1.3.0中,我添加了两个辅助编码器来生成我们可以使用的东西:
- 解压缩
compress
生成无效的UTF-16字符串。这些只能存储在localStorage
的webkit浏览器上(在Android,Chrome,Safari上测试)。可以使用decompress
继续我们的示例,Hello, world.
将转换为
҅〶惶̀Ў㦀☃ꈀ
最后它就是这样。我们可以看到,所有 ...其他拉丁字符...... 的集合来自最终转换为UTF-16。希望,这会给出一些提示......