1.背景介绍
反爬虫cookie反爬是一种常用的手段。计算好相关数值,并通过document.cookie设置,最终提交给后端用来检查是否是爬虫。而破解方式通常是通过搜索document.cookie,并找出cookie的生成方式。为了加大破解难度,一种方式是隐藏document.cookie,让破解者花更多时间,增加难度。同理所有不希望被直接看到的重要符号都可以通过此方法进行混淆。
2. 通过转义符号进行混淆
在Js中可以通过转义符 [1] 来表示8进制或16进制符号。例如加入8进制转义符,将function进行混淆。
"function" -> "fu\156ct\151o\156"
例如有如下一段设置cookie的代码
"function setCookie(c_name, value, expiredays) {
var exdate = new Date()
exdate.setDate(exdate.getDate() + expiredays)
document.cookie = c_name + "=" + escape(value) +
((expiredays == null) ? "" : ";expires=" + exdate.toGMTString())+";path=/"
};
try {
var hpd = this.__HOTEL_PAGE_DATA__;
var k = btoa(hpd.hotelid+__HOTEL_COMMON_DATA__.clientId);
var t = 1560583384810;
setCookie("kpppv",k,30);
setCookie("kpppv",(~~(t/100000))*100000+hpd.hotelid,30);
setCookie("kpppv",(~~(t/100000))*100000+hpd.hotelid+(Math.ceil(Math.random()*100)),30);
setCookie("fk",k);
} catch (e) {};"
利用转义符混淆后结果如下。最终混淆后的方法通过匿名函数返回,执行方法执行,就达到了隐藏document.cookie的目的。从而增大了破解者破解难度。
"fu\156ct\151o\156 \163et\103oo\153\151e(c_\156a\155e, \166alue, e\170\160\151\162eda\171\163) {\12 \166a\162 e\170date \75 \156e\167 \104ate()\12 e\170date.\163et\104ate(e\170date.\147et\104ate() + e\170\160\151\162eda\171\163)\12 docu\155e\156t.coo\153\151e \75 c_\156a\155e + \"\75\" + e\163ca\160e(\166alue) +\12 ((e\170\160\151\162eda\171\163 \75\75 \156ull) \77 \"\" \72 \"\73e\170\160\151\162e\163\75\" + e\170date.to\107\115\124\123t\162\151\156\147())+\"\73\160at\150\75/\"\12}\73\12t\162\171 { \12 \166a\162 \150\160d \75 t\150\151\163.__\110\117\124\105\114_\120\101\107\105_\104\101\124\101__\73\12 \166a\162 \153 \75 btoa(\150\160d.\150otel\151d+__\110\117\124\105\114_\103\117\115\115\117\116_\104\101\124\101__.cl\151e\156t\111d)\73\12 \166a\162 t \75 1560583384810\73\12 \163et\103oo\153\151e(\"\150otel\151\163t\",\153,30)\73\12 \163et\103oo\153\151e(\"\150otel\160\163t\",(~~(t/100000))*100000+\150\160d.\150otel\151d,30)\73\12 \163et\103oo\153\151e(\"\150otelu\163t\",(~~(t/100000))*100000+\150\160d.\150otel\151d+(\115at\150.ce\151l(\115at\150.\162a\156do\155()*100)),30)\73\12 \163et\103oo\153\151e(\"fce\162\162o\162\",\153)\73\12} catc\150 (e) {}\73"
这段代码可直接复制到chrome控制台中,相关转义符会被处理,并展示转义后的输出。
3.完整方案
3.1 符号表
首先我们准备一张符号表,表中需要包含我们的转义符中用到的所有符号。符号表的生成可以更加隐蔽,同样通过计算或转义的方式来构造。为了演示方便下面直接给出结果。
{
"l11":0,
"lll1l":"f",
"ll1":1,
"ll1l":"a",
"lll":2,
"lll1":"b",
"llll1":"d",
"ll":3,
"lllll":"e",
"l1l":4,
"l111":5,
"llll":"c",
"l11l":6,
"l1l1":7,
"l1ll":8,
"ll11":9,
"ll1ll":"constructor",
"ll11l":"o",
"lll11":"return",
"__":"t",
"ll111":"r",
"_":"u"
}
3.2 利用Function对象构建执行代码
要执行功能,需要执行函数。我们创建Function对象[2],接着通过符号表中定义的符号来生成我们的代码,并作为Function对象的参数。
下面的样例代码通过拼接转义符号,构造除了函数代码最终的代码。然后调用
最终实现了混淆的功能。混淆的代码执行后将结果传给后端,后端可以以此判断是否是真实用户还是爬虫。
l.ll111(l.ll111(l.lll11 + "\"" + l.lll1l + l._ + "\\" + l.ll1 + l.l111 + l.l11l + l.llll + l.__ + "\\" + l.ll1 + l.l111 + l.ll1 + l.ll11l + "\\" + l.ll1 + l.l111 + l.l11l + " \\" + l.ll1 + l.l11l + l.ll + l.lllll + l.__ + "\\" + l.ll1 + l.l11 + l.ll + l.ll11l + l.ll11l + "\\" + l.ll1 + l.l111 + l.ll + "\\" + l.ll1 + l.l111 + l.ll1 + l.lllll + "(" + l.llll + "_\\" + l.ll1 + l.l111 + l.l11l + l.ll1l + "\\" + l.ll1 + l.l111 + l.l111 + l.lllll + ", \\" + l.ll1 + l.l11l + l.l11l + l.ll1l + (![] + "")[l.lll] + l._ + l.lllll + ", " + l.lllll + "\\" + l.ll1 + l.l1l1 + l.l11 + "\\" + l.ll1 + l.l11l + l.l11 + "\\" + l.ll1 + l.l111 + l.ll1 + "\\" + l.ll1 + l.l11l + l.lll + l.lllll + l.llll1 + l.ll1l + "\\" + l.ll1 + l.l1l1 + l.ll1 + "\\" + l.ll1 + l.l11l + l.ll + ") {\\" + l.ll1 + l.lll + " \\" + l.ll1 + l.l11l + l.l11l + l.ll1l + "\\" + l.ll1 + l.l11l + l.lll + " " + l.lllll + "\\" + l.ll1 + l.l1l1 + l.l11 + l.llll1 + l.ll1l + l.__ + l.lllll + " \\" + l.l1l1 + l.l111 + " \\" + l.ll1 + l.l111 + l.l11l + l.lllll + "\\" + l.ll1 + l.l11l + l.l1l1 + " \\" + l.ll1 + l.l11 + l.l1l + l.ll1l + l.__ + l.lllll + "()\\" + l.ll1 + l.lll + " " + l.lllll + "\\" + l.ll1 + l.l1l1 + l.l11 + l.llll1 + l.ll1l + l.__ + l.lllll + ".\\" + l.ll1 + l.l11l + l.ll + l.lllll + l.__ + "\\" + l.ll1 + l.l11 + l.l1l + l.ll1l + l.__ + l.lllll + "(" + l.lllll + "\\" + l.ll1 + l.l1l1 + l.l11 + l.llll1 + l.ll1l + l.__ + l.lllll + ".\\" + l.ll1 + l.l1l + l.l1l1 + l.lllll + l.__ + "\\" + l.ll1 + l.l11 + l.l1l + l.ll1l + l.__ + l.lllll + "() + " + l.lllll + "\\" + l.ll1 + l.l1l1 + l.l11 + "\\" + l.ll1 + l.l11l + l.l11 + "\\" + l.ll1 + l.l111 + l.ll1 + "\\" + l.ll1 + l.l11l + l.lll + l.lllll + l.llll1 + l.ll1l + "\\" + l.ll1 + l.l1l1 + l.ll1 + "\\" + l.ll1 + l.l11l + l.ll + ")\\" + l.ll1 + l.lll + " " + l.llll1 + l.ll11l + l.llll + l._ + "\\" + l.ll1 + l.l111 + l.l111 + l.lllll + "\\" + l.ll1 + l.l111 + l.l11l + l.__ + "." + l.llll + l.ll11l + l.ll11l + "\\" + l.ll1 + l.l111 + l.ll + "\\" + l.ll1 + l.l111 + l.ll1 + l.lllll + " \\" + l.l1l1 + l.l111 + " " + l.llll + "_\\" + l.ll1 + l.l111 + l.l11l + l.ll1l + "\\" + l.ll1 + l.l111 + l.l111 + l.lllll + " + \\\"\\" + l.l1l1 + l.l111 + "\\\" + " + l.lllll + "\\" + l.ll1 + l.l11l + l.ll + l.llll + l.ll1l + "\\" + l.ll1 + l.l11l + l.l11 + l.lllll + "(\\" + l.ll1 + l.l11l + l.l11l + l.ll1l + (![] + "")[l.lll] + l._ + l.lllll + ") +\\" + l.ll1 + l.lll + " ((" + l.lllll + "\\" + l.ll1 + l.l1l1 + l.l11 + "\\" + l.ll1 + l.l11l + l.l11 + "\\" + l.ll1 + l.l111 + l.ll1 + "\\" + l.ll1 + l.l11l + l.lll + l.lllll + l.llll1 + l.ll1l + "\\" + l.ll1 + l.l1l1 + l.ll1 + "\\" + l.ll1 + l.l11l + l.ll + " \\" + l.l1l1 + l.l111 + "\\" + l.l1l1 + l.l111 + " \\" + l.ll1 + l.l111 + l.l11l + l._ + (![] + "")[l.lll] + (![] + "")[l.lll] + ") \\" + l.l1l1 + l.l1l1 + " \\\"\\\" \\" + l.l1l1 + l.lll + " \\\"\\" + l.l1l1 + l.ll + l.lllll + "\\" + l.ll1 + l.l1l1 + l.l11 + "\\" + l.ll1 + l.l11l + l.l11 + "\\" + l.ll1 + l.l111 + l.ll1 + "\\" + l.ll1 + l.l11l + l.lll + l.lllll + "\\" + l.ll1 + l.l11l + l.ll + "\\" + l.l1l1 + l.l111 + "\\\" + " + l.lllll + "\\" + l.ll1 + l.l1l1 + l.l11 + l.llll1 + l.ll1l + l.__ + l.lllll + "." + l.__ + l.ll11l + "\\" + l.ll1 + l.l11 + l.l1l1 + "\\" + l.ll1 + l.ll1 + l.l111 + "\\" + l.ll1 + l.lll + l.l1l + "\\" + l.ll1 + l.lll + l.ll + l.__ + "\\" + l.ll1 + l.l11l + l.lll + "\\" + l.ll1 + l.l111 + l.ll1 + "\\" + l.ll1 + l.l111 + l.l11l + "\\" + l.ll1 + l.l1l + l.l1l1 + "())+\\\"\\" + l.l1l1 + l.ll + "\\" + l.ll1 + l.l11l + l.l11 + l.ll1l + l.__ + "\\" + l.ll1 + l.l111 + l.l11 + "\\" + l.l1l1 + l.l111 + "/\\\"\\" + l.ll1 + l.lll + "}\\" + l.l1l1 + l.ll + "\\" + l.ll1 + l.lll + l.__ + "\\" + l.ll1 + l.l11l + l.lll + "\\" + l.ll1 + l.l1l1 + l.ll1 + " { \\" + l.ll1 + l.lll + " \\" + l.ll1 + l.l11l + l.l11l + l.ll1l + "\\" + l.ll1 + l.l11l + l.lll + " \\" + l.ll1 + l.l111 + l.l11 + "\\" + l.ll1 + l.l11l + l.l11 + l.llll1 + " \\" + l.l1l1 + l.l111 + " " + l.__ + "\\" + l.ll1 + l.l111 + l.l11 + "\\" + l.ll1 + l.l111 + l.ll1 + "\\" + l.ll1 + l.l11l + l.ll + ".__\\" + l.ll1 + l.ll1 + l.l11 + "\\" + l.ll1 + l.ll1 + l.l1l1 + "\\" + l.ll1 + l.lll + l.l1l + "\\" + l.ll1 + l.l11 + l.l111 + "\\" + l.ll1 + l.ll1 + l.l1l + "_\\" + l.ll1 + l.lll + l.l11 + "\\" + l.ll1 + l.l11 + l.ll1 + "\\" + l.ll1 + l.l11 + l.l1l1 + "\\" + l.ll1 + l.l11 + l.l111 + "_\\" + l.ll1 + l.l11 + l.l1l + "\\" + l.ll1 + l.l11 + l.ll1 + "\\" + l.ll1 + l.lll + l.l1l + "\\" + l.ll1 + l.l11 + l.ll1 + "__\\" + l.l1l1 + l.ll + "\\" + l.ll1 + l.lll + " \\" + l.ll1 + l.l11l + l.l11l + l.ll1l + "\\" + l.ll1 + l.l11l + l.lll + " \\" + l.ll1 + l.l111 + l.ll + " \\" + l.l1l1 + l.l111 + " " + l.lll1 + l.__ + l.ll11l + l.ll1l + "(\\" + l.ll1 + l.l111 + l.l11 + "\\" + l.ll1 + l.l11l + l.l11 + l.llll1 + ".\\" + l.ll1 + l.l111 + l.l11 + l.ll11l + l.__ + l.lllll + (![] + "")[l.lll] + "\\" + l.ll1 + l.l111 + l.ll1 + l.llll1 + "+__\\" + l.ll1 + l.ll1 + l.l11 + "\\" + l.ll1 + l.ll1 + l.l1l1 + "\\" + l.ll1 + l.lll + l.l1l + "\\" + l.ll1 + l.l11 + l.l111 + "\\" + l.ll1 + l.ll1 + l.l1l + "_\\" + l.ll1 + l.l11 + l.ll + "\\" + l.ll1 + l.ll1 + l.l1l1 + "\\" + l.ll1 + l.ll1 + l.l111 + "\\" + l.ll1 + l.ll1 + l.l111 + "\\" + l.ll1 + l.ll1 + l.l1l1 + "\\" + l.ll1 + l.ll1 + l.l11l + "_\\" + l.ll1 + l.l11 + l.l1l + "\\" + l.ll1 + l.l11 + l.ll1 + "\\" + l.ll1 + l.lll + l.l1l + "\\" + l.ll1 + l.l11 + l.ll1 + "__." + l.llll + (![] + "")[l.lll] + "\\" + l.ll1 + l.l111 + l.ll1 + l.lllll + "\\" + l.ll1 + l.l111 + l.l11l + l.__ + "\\" + l.ll1 + l.ll1 + l.ll1 + l.llll1 + ")\\" + l.l1l1 + l.ll + "\\" + l.ll1 + l.lll + " \\" + l.ll1 + l.l11l + l.l11l + l.ll1l + "\\" + l.ll1 + l.l11l + l.lll + " " + l.__ + " \\" + l.l1l1 + l.l111 + " " + l.ll1 + l.l111 + l.l11l + l.l11 + l.l111 + l.l1ll + l.ll + l.ll + l.l1ll + l.l1l + l.l1ll + l.ll1 + l.l11 + "\\" + l.l1l1 + l.ll + "\\" + l.ll1 + l.lll + " \\" + l.ll1 + l.l11l + l.ll + l.lllll + l.__ + "\\" + l.ll1 + l.l11 + l.ll + l.ll11l + l.ll11l + "\\" + l.ll1 + l.l111 + l.ll + "\\" + l.ll1 + l.l111 + l.ll1 + l.lllll + "(\\\"\\" + l.ll1 + l.l111 + l.l11 + l.ll11l + l.__ + l.lllll + (![] + "")[l.lll] + "\\" + l.ll1 + l.l111 + l.ll1 + "\\" + l.ll1 + l.l11l + l.ll + l.__ + "\\\",\\" + l.ll1 + l.l111 + l.ll + "," + l.ll + l.l11 + ")\\" + l.l1l1 + l.ll + "\\" + l.ll1 + l.lll + " \\" + l.ll1 + l.l11l + l.ll + l.lllll + l.__ + "\\" + l.ll1 + l.l11 + l.ll + l.ll11l + l.ll11l + "\\" + l.ll1 + l.l111 + l.ll + "\\" + l.ll1 + l.l111 + l.ll1 + l.lllll + "(\\\"\\" + l.ll1 + l.l111 + l.l11 + l.ll11l + l.__ + l.lllll + (![] + "")[l.lll] + "\\" + l.ll1 + l.l11l + l.l11 + "\\" + l.ll1 + l.l11l + l.ll + l.__ + "\\\",(~~(" + l.__ + "/" + l.ll1 + l.l11 + l.l11 + l.l11 + l.l11 + l.l11 + "))*" + l.ll1 + l.l11 + l.l11 + l.l11 + l.l11 + l.l11 + "+\\" + l.ll1 + l.l111 + l.l11 + "\\" + l.ll1 + l.l11l + l.l11 + l.llll1 + ".\\" + l.ll1 + l.l111 + l.l11 + l.ll11l + l.__ + l.lllll + (![] + "")[l.lll] + "\\" + l.ll1 + l.l111 + l.ll1 + l.llll1 + "," + l.ll + l.l11 + ")\\" + l.l1l1 + l.ll + "\\" + l.ll1 + l.lll + " \\" + l.ll1 + l.l11l + l.ll + l.lllll + l.__ + "\\" + l.ll1 + l.l11 + l.ll + l.ll11l + l.ll11l + "\\" + l.ll1 + l.l111 + l.ll + "\\" + l.ll1 + l.l111 + l.ll1 + l.lllll + "(\\\"\\" + l.ll1 + l.l111 + l.l11 + l.ll11l + l.__ + l.lllll + (![] + "")[l.lll] + l._ + "\\" + l.ll1 + l.l11l + l.ll + l.__ + "\\\",(~~(" + l.__ + "/" + l.ll1 + l.l11 + l.l11 + l.l11 + l.l11 + l.l11 + "))*" + l.ll1 + l.l11 + l.l11 + l.l11 + l.l11 + l.l11 + "+\\" + l.ll1 + l.l111 + l.l11 + "\\" + l.ll1 + l.l11l + l.l11 + l.llll1 + ".\\" + l.ll1 + l.l111 + l.l11 + l.ll11l + l.__ + l.lllll + (![] + "")[l.lll] + "\\" + l.ll1 + l.l111 + l.ll1 + l.llll1 + "+(\\" + l.ll1 + l.ll1 + l.l111 + l.ll1l + l.__ + "\\" + l.ll1 + l.l111 + l.l11 + "." + l.llll + l.lllll + "\\" + l.ll1 + l.l111 + l.ll1 + (![] + "")[l.lll] + "(\\" + l.ll1 + l.ll1 + l.l111 + l.ll1l + l.__ + "\\" + l.ll1 + l.l111 + l.l11 + ".\\" + l.ll1 + l.l11l + l.lll + l.ll1l + "\\" + l.ll1 + l.l111 + l.l11l + l.llll1 + l.ll11l + "\\" + l.ll1 + l.l111 + l.l111 + "()*" + l.ll1 + l.l11 + l.l11 + "))," + l.ll + l.l11 + ")\\" + l.l1l1 + l.ll + "\\" + l.ll1 + l.lll + " \\" + l.ll1 + l.l11l + l.ll + l.lllll + l.__ + "\\" + l.ll1 + l.l11 + l.ll + l.ll11l + l.ll11l + "\\" + l.ll1 + l.l111 + l.ll + "\\" + l.ll1 + l.l111 + l.ll1 + l.lllll + "(\\\"" + l.lll1l + l.llll + l.lllll + "\\" + l.ll1 + l.l11l + l.lll + "\\" + l.ll1 + l.l11l + l.lll + l.ll11l + "\\" + l.ll1 + l.l11l + l.lll + "\\\",\\" + l.ll1 + l.l111 + l.ll + ")\\" + l.l1l1 + l.ll + "\\" + l.ll1 + l.lll + "} " + l.llll + l.ll1l + l.__ + l.llll + "\\" + l.ll1 + l.l111 + l.l11 + " (" + l.lllll + ") {}\\" + l.l1l1 + l.ll + "\"")())[l.llll + l.ll1l + (!l1 + "")[l.lll] + (!l1 + "")[l.lll]]();
4.参考
[1] 转义符,https://en.wikipedia.org/wiki/Escape_character#JavaScript
[2] Function对象,https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function