LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 3100|回复: 42

如何对抗 ISP HTTP hijacking (阻止推送广告)

[复制链接]
发表于 2010-5-8 22:27:04 | 显示全部楼层 |阅读模式
firefox + noscript + adblockplus 可拦截此类广告,但 firefox 仍会连接到劫持站点,接着或者 noscript 给出警告,或者 stopbadware 给出警告。
很久以前,从来没有,最近一两年,两三天出一次,最近一段时间一天能出两三次,尤其是拨号成功第一次使用浏览器时几率比较高。
看不到广告,仍影响心情。

投诉进行中,客服小妹态度很好,之后客服经理(可能是客服小妹上级)及技术人员分别用不录音电话回话过来,磨讥半天,死不承认,故左右而言它,可能是俺太客气,下次下下次凶点。
投诉不是办法,出国还好说,出差在外仍受异地 ISP 推送广告骚扰。

大家知道 dns 劫持好解决,换可信任 dns 能解决大半,或从加密通道访问权威 dns,再有可自己架 dns relay server 或 dnsmasq 什么的。
大家都知道用类似加密通道方法对抗 http 劫持,代价太大。

http 劫持其实也好解决,将 ISP 广告站点加入 /etc/hosts 中指向不存在地址或 127.0.0.1,只是连不到,这样浏览器上仍会有反应,仍影响心情。
另 /etc/hosts 留下不干净东东也挺恶心。

如果 http 劫持每次都发生,早抓包分析去。
今天终于忍不住动手,抓了 50M 多才碰到一回,罪证不展览,简单分析下:
从 IP、MAC 地址看不出问题;
浏览器向目标主机发送 GET 后,进行劫持的机器伪装成目标主机发送一个伪包,设置 TCP 标志 FIN PSH ACK,TTL 值与真实包不同,可近似确定劫持机器物理位置,并包含一个如下框架页面;
  1. <html>
  2.     <!-- 25 -->
  3.     <script language=JScript>
  4.         <!-- function killErrors(){return true;} window.onerror=killErrors; -->
  5.     </script>
  6.     <frameset rows="*,0">
  7.         <frame src="[color=Red]http://isp_http_hijack.site/path/index.htm[/color]" noresize><frame src="" noresize>
  8.     </frameset>
  9. </html>
复制代码
接着浏览器去连接劫持到的站点 GET 如下;
  1. GET [color=Red]/path/index.htm[/color] HTTP/1.1
  2. Host: [color=Red]isp_http_hijack.site[/color]
  3. User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3
  4. Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
  5. Accept-Language: zh-cn,zh;q=0.5
  6. Accept-Encoding: gzip,deflate
  7. Accept-Charset: GB2312,utf-8;q=0.7,*;q=0.7
  8. Keep-Alive: 115
  9. Connection: keep-alive
  10. Referer: [color=Red]http://real_target.site/[/color]
复制代码
劫持到的站点 回应 如下;
  1. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
  2. <html>
  3. <head>
  4. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  5. <title>无标题文档</title>
  6. </head>
  7. <body style="margin:0;padding:0;height:100%;overflow:hidden;scroll:no">
  8. <script type="text/javascript">
  9. <!--
  10. function killErrors()
  11. {return true;}
  12. window.onerror = killErrors;
  13. -->
  14. </script>
  15. <!--包含公共的脚本代码-->
  16. <script language="javascript" src="pub.js"></script>
  17. <!--设置iframe属性-->
  18. <script language=JavaScript1.2>
  19. <!--
  20. var url=encodeURIComponent([color=Red]getReferer()[/color]);
  21. url="tourl.html?url="+url
  22. document.write("<iframe  id='content'  name='content' src='"+url+"' frameborder='0' width='100%' height='100%' scrolling='yes'><\/iframe>")   
  23. -->
  24. </script>
  25. <!--底部上升广告设置-->
  26. <script language=JavaScript1.2>
  27. <!--
  28. var page_w,page_h;
  29. page_w = 326;
  30. page_h = 200;
  31. if (getArgs("width")!="" && IsInteger(getArgs("width")))
  32.     page_w = parseInt(getArgs("width"),0);
  33. if (getArgs("height")!="" && IsInteger(getArgs("height")))
  34.     page_h=parseInt(getArgs("height"),0);
  35. -->
  36. </script>
  37. <!--包含执行的脚本代码-->
  38. <script language="javascript" src="app.js"></script>
  39. <!--自动适应高度脚本 解决IE7不能适应问题-->
  40. <script language=JavaScript1.2>
  41. <!--
  42. function autoheight(sid) {
  43. var gid=document.getElementById(sid);
  44. gid.height=document.documentElement.offsetHeight-5;
  45. }
  46. if(Browser.isIE) window.setInterval("autoheight("content")",100);
  47. -->
  48. </script>
  49. </body>
  50. </html>
复制代码
进行劫持的机器,不可见,是影子机器,很有可能放置在某个 ISP 能控制的路由器旁路,与劫持到的机器不是同一机器。(一般人没机会这样做,ISP 难逃其责)


PSH 是 TCP 协议中用来主动推送数据的标志。http://www.tcpipguide.com/free/t ... rPushFunction-2.htm
可见 ISP 多么无耻,协议竟然如此滥用。

上面分析结果可能有地方性,同好不妨自己抓包看一下,可使用 wireshark。


针对上面结果,偶决定用 iptables 一了百了封堵推送广告:
用于路由器,请把 INPUT 换 FORWARD 并开启 内核转发。
经一天时间试用,拦截有效,没有明显副作用,可去掉日志部分。
  1. iptables -I INPUT -p tcp --sport 80 --tcp-flags FIN,PSH,ACK FIN,PSH,ACK -j DROP
  2. iptables -I INPUT -p tcp --sport 80 --tcp-flags FIN,PSH,ACK FIN,PSH,ACK -j LOG --log-level info --log-prefix="illegal_PSH: "
复制代码


FreeBSD ipfw 防火墙 对应 iptables 封 FIN,PSH,ACK tcp 伪包命令:
红色部分请换合适编号,日志可去掉。
  1. ipfw add [color=Red]00001[/color] deny log tcp from any 80 to me in established tcpflags fin,ack,psh
复制代码


对 M$ 不感冒,但查了下 FreeBSD ipfw 防火墙有移植,名曰 wipfw。
所以可以把 M$ 当 FreeBSD 对待。


或者针对 TTL 变化过滤,TCP 建立连接后,TTL 不变是一个合理假设:
用于路由器,请把 INPUT 换 FORWARD 并开启 内核转发。
经测试此规则有效,此规则不适于单独使用,日志部分可去掉。
注:与前面过滤 FIN PSH ACK 规则并用时,此规则要放在前面。
  1. iptables -I INPUT -p tcp --sport 80 -m state --state ESTABLISHED -m recent --set -j ACCEPT
  2. iptables -I INPUT -p tcp --sport 80 -m state --state ESTABLISHED -m recent --update --seconds 60 -j DROP
  3. iptables -I INPUT -p tcp --sport 80 -m state --state ESTABLISHED -m recent --update --seconds 60 -j LOG --log-level info --log-prefix="ttl_unmatch: "
  4. iptables -I INPUT -p tcp --sport 80 -m state --state ESTABLISHED -m recent --update --seconds 60 --rttl -j ACCEPT
复制代码


或者在上面方法基础上多判断一下特征字符串 frame:
经测试确定此法无效。
  1. [color=Silver]iptables -I INPUT -p tcp --sport 80 --tcp-flags FIN,PSH,ACK FIN,PSH,ACK -m string --algo bm --string "frame" -j DROP
  2. iptables -I INPUT -p tcp --sport 80 --tcp-flags FIN,PSH,ACK FIN,PSH,ACK -m string --algo bm --string "frame" -j LOG[/color]
复制代码
http://netfilter.org/documentation/HOWTO/netfilter-extensions-HOWTO-3.html#ss3.18 指出 string 模块用来传送包包给用户空间程序,如 IDS 程序。

如果您遇到不同类型 http 劫持,请提供抓包结果,希望大家一起努力共建一个全面适用 iptables、ipfw 规则。

如果您有更好方法,请赐教。
 楼主| 发表于 2010-5-8 23:04:23 | 显示全部楼层
string 模块确实木起作用。
FIN,PSH,ACK 起作用,不会连到劫持站点,但劫持发生时,会连不上目标站点一段时间,查看日志,进行劫持的机器疯狂发送劫持伪包,这样也好,如果真准备投诉到底,方便取证。
回复 支持 反对

使用道具 举报

发表于 2010-5-9 00:51:44 | 显示全部楼层
广东电信这边。我是用iptables DROP掉五个ip.

写进/etc/conf.d/local.start里面。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
回复 支持 反对

使用道具 举报

 楼主| 发表于 2010-5-9 11:15:10 | 显示全部楼层
直接封广告站点 ip 想过,非常干脆,只是这样浏览器上仍有反应,所以类似改 /etc/hosts 方法一直没做。

大家不妨把自己遇到的 ISP 广告站点枚举下,用 ipset 设置 广告 ip 集,接着用一条 iptables 规则统统干掉最好不过。
回复 支持 反对

使用道具 举报

发表于 2010-5-9 11:16:46 | 显示全部楼层
反正我的hosts文件三万行...... 虽然不爽,但是win/Lin都能用
回复 支持 反对

使用道具 举报

 楼主| 发表于 2010-5-9 11:22:50 | 显示全部楼层
Post by MeaCulpa_;2088876
反正我的hosts文件三万行...... 虽然不爽,但是win/Lin都能用

广告相关部分可否共享下,麻烦的话,请直接共享下。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2010-5-9 11:32:14 | 显示全部楼层
[color="Silver"]FreeBSD ipfw 防火墙 对应 iptables 封 FIN,PSH,ACK tcp 伪包命令:
  1. ipfw add [color="Red"]00001[/color] deny log tcp from any to any in established tcpflags fin,ack,psh
复制代码

红色部分请换合适编号。

对 M$ 不感冒,但查了下 FreeBSD ipfw 防火墙有移植,名曰 wipfw。
所以可以把 M$ 当 FreeBSD 对待。
回复 支持 反对

使用道具 举报

发表于 2010-5-9 11:43:17 | 显示全部楼层
http://meaculpa.info/pub/hosts

注: adsense和statcounter未拦截, baidu被指向了google
回复 支持 反对

使用道具 举报

 楼主| 发表于 2010-5-9 11:49:27 | 显示全部楼层
Post by MeaCulpa_;2088881
http://meaculpa.info/pub/hosts

注: adsense和statcounter未拦截, baidu被指向了google

多谢,好主意。
回复 支持 反对

使用道具 举报

发表于 2010-5-9 12:21:58 | 显示全部楼层
Post by 聚焦深空;2088882
多谢,好主意。

这方法真的会有效吗?我一直以为路由器旁路广告是无路可逃的。
----------------------------------------------------------------------------------
包进了自己机器但浏览器不显示不算逃掉。投诉估计不会生效,几年前就有这现象了。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表