dns拦截_防火墙拦截dns解析 - CSDN
  • DNS劫持原理与操作

    万次阅读 多人点赞 2017-08-24 22:14:25
    DNS(域名系统)的作用是把网络地址(域名,以一个字符串的形式)对应到真实的计算机能够识别的网络地址(IP地址),以便计算机能够进一步通信,传递网址和内容等。由于域名劫持往往只能在特定的被劫持的网络范围内...
    DNS(域名系统)的作用是把网络地址(域名,以一个字符串的形式)对应到真实的计算机能够识别的网络地址(IP地址),以便计算机能够进一步通信,传递网址和内容等。由于域名劫持往往只能在特定的被劫持的网络范围内进行,所以在此范围外的域名服务器(DNS)能够返回正常的IP地址,高级用户可以在网络设置把DNS指向这些正常的域名服务器以实现对网址的正常访问。所以域名劫持通常相伴的措施——封锁正常DNS的IP。
    如果知道该域名的真实IP地址,则可以直接用此IP代替域名后进行访问。比如访问百度域名,可以把访问改为202.108.22.5,从而绕开域名劫持 。
    应对方法:
    DNS劫持(DNS钓鱼攻击)十分凶猛且不容易被用户感知,曾导致巴西最大银行巴西银行近1%客户受到攻击而导致账户被盗。黑客利用宽带路由器的缺陷对用户DNS进行篡改——用户只要浏览一下黑客所掌控的WEB页面,其宽带路由器的DNS就会被黑客篡改,因为该WEB页面设有特别的恶意代码,所以可以成功躲过安全软件检测,导致大量用户被DNS钓鱼诈骗。
    由于一些未知原因,在极少数情况下自动修复不成功,建议您手动修改。同时,为了避免再次被攻击,即使修复成功,用户也可按照360或腾讯电脑管家提示的方法修改路由器的登录用户名和密码。下面以用户常用的TP-link路由器为例来说明修改方法(其他品牌路由器与该方法类似)。
    手动修改DNS
    1.在地址栏中输入:http://192.168.1.1 (如果页面不能显示可尝试输入:http://192.168.0.1)
    2.填写您路由器的用户名和密码,点击“确定”
    3.在“DHCP服务器—DHCP”服务中,填写主DNS服务器为百度提供的公共DNS服务IP地址:180.76.76.76,备用DNS服务器为DNSpond提供服务IP为119.29.29.29,点击保存即可。
    修改路由器密码
    1.在地址栏中输入:http://192.168.1.1 (如果页面不能显示可尝试输入:http://192.168.0.1)
    2.填写您路由器的用户名和密码,路由器初始用户名为admin,密码也是admin,如果您修改过,则填写修改后的用户名和密码,点击“确定”
    3.填写正确后,会进入路由器密码修改页面,在系统工具——修改登录口令页面即可完成修改(原用户名和口令和2中填写的一致)
    预防DNS劫持
    其实,DNS劫持并不是什么新鲜事物,也并非无法预防,百度被黑事件的发生再次揭示了全球DNS体系的脆弱性,并说明互联网厂商如果仅有针对自身信息系统的安全预案,就不足以快速应对全面而复杂的威胁。因此,互联网公司应采取以下措施:
    1、互联网公司准备两个以上的域名,一旦黑客进行DNS攻击,用户还可以访问另一个域名。
    2、互联网应该对应急预案进行进一步修正,强化对域名服务商的协调流程。
    3、域名注册商和代理机构特定时期可能成为集中攻击目标,需要加以防范。
    4、国内有关机构之间应该快速建立与境外有关机构的协调和沟通,协助国内企业实现对此事件的快速及时的处理。
    DNS劫持变种
    上周百度搜索上线了一个非常重要的策略,如果发现有网站被植入恶意篡改用户路由DNS的代码时,就会拦截页面,打出提示!据安全联盟的统计发现过万的网站被黑,植入了路由DNS劫持代码,这个数量非常之大。
      过去一段时间,知道创宇安全研究团队就捕获了至少5个变种。这类攻击的模式一般是:
    1.攻击者黑下一批网站;
    2.攻击者往这批网站里植入路由DNS劫持代码(各种变形);
    3.攻击者传播或坐等目标用户访问这批网站;
    4.用户访问这些网站后,浏览器就会执行“路由DNS劫持代码”;
    5.用户的家庭/公司路由器如果存在漏洞就会中招;
    6.用户上网流量被“假DNS服务器”劫持,并出现奇怪的广告等现象;

    虽然这次攻击主要针对Tp-Link路由器,不过中招的路由不仅TP-Link!对此安全联盟推出DNS劫持专题[1] ,为网民及站长提供详细解决方案。

    以上来自百度百科:

    那么了解DNS劫持,相信很多做WEBq前端与JAVA后端,以及运维的中都碰见过DNS劫持,那么有哪些方法以及那么工具,我一一为你们解答!

    第一种:

    运行nslookup
    如果你当前的DNS服务器正常工作,返回的结果应该是你自己的DNS服务器。随便解析一个网站,比如www.microsoft.com
    应该返回的是正常的地址然后再解析一个不存在的网站,比如
    adfasdf.fljalfjsd.com.cn如果返回的结果是DNS request timed out.timeout was 2 seconds.
    那么证明你的DNS没有被劫持如果返回的结果是一个IP地址,比如说网通的返回地址是123.xxx.xxx.xxx,那么证明你的DNS被劫持了。
    请检查以下设置:
    1. 右键点击我的电脑,点击属性
    2. 点击计算机名
    3. 点击其他
    4. 检查“此计算机的主DNS后缀”设置,默认情况下这一设置应该是您的域名(比如Microsoft.com)
    5. 打开网络链接
    6. 右键点击网络链接并点击属性
    7. 双击TCP/IP
    8. 点击高级,并点击DNS属性页
    9. 检查“附加主要的连接特定的DNS后缀”选项,默认“附加主DNS后缀的父后缀”是被选中的
    10.检查此连接的DNS后缀内是否设置了内容,默认为空
    11.HOSTS文件被修改也会这样,你可以在C:\Windows\System32\drivers\etc用记事本打开hosts文件看是否被添加了相关的网址和IP信息,默认的应该只有一个127.0.0.1
    修复:
    由于DNS被强制修改,kaspersky不能访问,可以尝试其它厂商的在线杀毒。DNS上清理缓存,并执行 ipconfig/flushdns,客户端上也执行该命令,在测试看看。
    另:有的时候可以在浏览器中直接输入IP地址,而不是域名。请尝试!如果IP段被劫持,可以更换IP来解决。或者用360或者电脑管家进行修复,或者电脑急救箱。

    第二种:

    这篇文章把Dns分为两种,一种是主机或嵌入式设备dns,一种是网站域名dns,来讲述dns沦陷之后带来的危害。

       你本地的网络连接的dns是通过路由器获取的,假如有一天你家里的路由被黑客入侵了,入侵者修改了你家里路由器的dns,那么他可以对你访问记录非常清楚,如系在文件,流量记录。既然解析都通过dns,我们完全可以自建dns,来进行攻击。

        1.路由器怎么样沦陷

             攻击手法:csrf  路由器漏洞

            CSRF

             IE 出了一个安全补丁,禁止了Http Authentication Url, 使用此方法在IE下攻击是无效的 完美兼容FF chrome。 https://support.microsoft.com/zh-cn/kb/834489

             <img src=http://192.168.1.1/userRpm/LanDhcpServerRpm.htm?dhcpserver=1&ip1=192.168.1.100&ip2=192.168.1.199&Lease=120&gateway=0.0.0.0&domain=&dnsserver=恶意的dns地址&dnsserver2=0.0.0.0&Save=%B1%A3+%B4%E6></img>

            设备漏洞

    烽火通信某款路由器被爆存在漏洞-可远程修改DNS

    http://www.exploit-db.com/exploits/28450/

        2.自建dns(window)

         在这里我使用微软自家产,(完全可以用其他产品代替,个人习惯问题)

         wKioL1ZxVCfDmzBCAABDds_fMBg567.png

            配置劫持域名

             myhack58.com

         wKioL1ZxVFaRrRCUAAAkNCrr8pk332.png

            转发器配置

                 转发器解决这台服务器没有应答的dns查询请求, 如这台主机只有myhack58.com, baidu.com等是不存在的,这种情况把会把baidu.com请求转发到你配置的dns去解析。我配置解析的dns是8.8.8.8

         wKioL1ZxVJPjc6OVAAAlqIu2ruY558.png

            配置劫持域名A记录

                刚才dns填写是跟域,这时候需要对A记录进行解析,比如我劫持www.myhack58.com到本地127.0.0.1。

       wKiom1ZxVP6QDPxnAAAyy247UR8307.png

                我这解析是vps的IP,测试可以写127.0.0.1。但要用起来你解析写公网ip地址,不然别人解析是127.0.0.1,127.0.0.1是你本地,找不到的地址,没办法跟反向代理代理配合。

       wKiom1ZxVSnDbwfRAAA0pfsG_MQ893.png

        

            测试dns是否配置成功

                可以使用dnslookup ping 等去测试

        wKioL1ZxVXOhgTVrAAAnyfn9jO0629.png

                Dns已配置成功,虽然现在解析本地了,我本地难道就只能挂个黑页?当然不是,我的目的是要求是替换页面的内容.比如插入js,修改某个文字等。

    客户端的配置

                由于我在公司没有路由器,直接使用客户端做测试,客户端的dns获取来源还是路由器

        wKioL1ZxVbqSehVZAAAfc5KpWQY299.png

                这时候配置成功,你可以打开baidu.com来测试,是否可以解析,正常打开。

    wKioL1ZxVcjR4-EvAAEiLeIK4Ew281.png

        3.反向代理搭建

            反向代理来这里启到作用是,把dns解析www.myhack58.com的vps的这个请求代理到真实的解析。

            我们要做的事情 要给页面插入一段js。

            Openresty介绍

                在这里我们使用Openresty,Openresty是基于nginx,它打包了标准的 Nginx 核心,很多的常用的第三方模块,nginx第三方模块都需要编译,在window下比较恶心 我直接找了一个Openresty_For_Windows,已打包我想要的是第三方模块http_sub_module。

            下载地址:

            https://github.com/LomoX-Offical/nginx-openresty-windows

            使用nginx  -V 查看已支持的第三方模块 

            http_sub_module缺点

                1.只能使用一条规则

                2.不支持中文

            反向代理配置

                监听端口vps的公网IP的80端口.当dns查询请求解析到本地80的时候,80正好监听vps公网ip,反向代理是myhack58.com。实际上vps公网ip是myhack58.com

             打开/conf/nginx.conf文件进行配置

             使用了http_sub_module,替换了内容把

             </head>换成</head><script sec=safe.js></script>,我故意写错 写成sec=

             wKioL1ZxVsOhpA7kAAAcoCiQ0i8280.png

            测试是否成功

                先前已经把dns设置过去了,现在也可以ping通,那我们就查看源码 是否替换了页面内容。wKiom1ZxVwOB3LuuAADs50t9Tz0802.png

                配置其他功能

                    现在dns加反向代理配置已经完成了,你可以替换他的页面了

                Openresty配置反向代理,你要是需要其他的配置还可以设置很多参数,如proxy_cache proxy_header  proxy_send_timeout  proxy_read_timeout。取决于自己用途。

    二:网站域名dns劫持

            当你通过社工拿到了某个域名权限, 但是你的目的是getshell,这时候你可以做反向代理,可以从两方面下手去做。

        A记录劫持演示

            直接修改域名劫持到A记录的你的恶意反向代理,但是这时候反向代理必须有配置upstream,在upstream指定原域名解析的ip地址,路由器劫持dns没有配置upstream 是因为上层的dns还可以解析到劫持域名的真实ip,而你这时候意见把A记录解析修改到了你的恶意反向代理机器,不去指定解析的地址, 上层找到解析的地址还是恶意的反向代理,形成一个死循环,永远打不开网站。

            域名A记录劫持

            www.sanr.org  192.168.182.128

            反向代理      192.168.182.129

      wKiom1ZxV_iQfIouAAAWKXi2OZs330.png

            为什么要劫持A记录

                如你通过社工之类拿到了域名的控制权限,这时候你想获取他的后台地址,或者cookie等你就需要这样做。

                目前我已经控制sanr.org的域名解析权限,现在我们要做的是把www.sanr.org的A记录解析到192.168.182.129。让反向代理去访问真实的ip(也就是192.168.182.128),在反向代理的时候我们动手脚,插个js代码进去。

            没修改A记录之前

    wKiom1ZxWEmCYkZmAAF0J8BjQ0Q968.png

        修改域名A记录

            修改域名到反向代理服务器 192.168.182.129

     wKioL1ZxWIrDMJ43AAATAFB1rHk556.png

            反向代理服务器搭建(192.168.182.129)

                绑定域名为www.sanr.org 端口80,并指定上游(upstream)地址是192.168.182.128,必须指定上游地址(upstream),只有proxy_pass无upstream他会自动请求解析A记录。

                路由器dns劫持那块没有用upstream是因为域名的A记录的iP地址你可以通过proxy_pass获取到。

                而现在域名A记录解析是反向代理机器也就是本机(192.168.182.129),如不使用upstrema去指定真实的IP地址,proxy_pass直接去解析到的是本地IP,那么就会造成死循环,一直解析的都是本机。

    下面是反向代理配置文件。

    wKioL1ZxWNWQkBOKAAA6QVHP1ZM659.png

            劫持成功

                 成功的给sanr.org的植入safe.js代码

    wKiom1ZxWQDSvk1JAALBDmQnwQM723.png

        dns劫持

            跟路由器劫持dns一样,自建dns,之后把域名的dns解析配置的A记录解析到恶意的反向代理,反向代理中还是要指定upstream,跟a记录劫持一样,不然造成死循环。 

           Dns服务 反向代理软件有很多,完全取决于自己的习惯,用自己最喜欢的。

        Dns win

          WinMyDNS

          微软自家

        Dns linux 

          dnschef   “msfconsole  auxiliary/server/fakedns”

          Powerdns bind 等 linux开源项目太多

        反向代理

         Squid  Varnish nginx 或者nginx 衍生版(Tengine  Openresty)

    wKiom1ZxWffjbySJAASyBJESYFE665.png

        攻击手法不仅仅是替换网页内容 插入js,如劫持你路由器的dns, 连接3389也是输入域名也是通过dns解析的,我完全可以把A记录劫持我本地,连接3389是我本机的机器,之后安装WinlogonHack,来记录密码,WinlogonHack需要改成即使是错误密码也要记录,不然记录不到。

        把www.baidu.com解析到我vps主机的ip

    wKioL1ZxWnrSNHZmAAA0KhGwnOs810.png    Dns已生效,解析baidu.com也返回是vps主机的ip

    wKiom1ZxWpnzToK8AAAgXYtopxY427.png

        连接3389(其实这时候是我vps的IP)

        wKioL1ZxWsPh8RQvAACQeQDHVpc930.png

        只要涉及到域名解析的 本地host  本地客户端dns  路由器dns,都可以这样去劫持,攻击手法变化多样,看你出自于什么目地去做。

    第三种:

    1.Cain进行DNS劫持、ARP欺骗。

    2.小凡顶尖劫持插件程序。

    3.浪花DNS域名劫持。

    4.netfuke劫持工具

    5.修复DNS劫持,使用OpenDNS解决DNS域名劫持。

    6.一次利用社会工程学完成的域名劫持攻击。

    7.入侵DNS解析服务器。

    8.以IP冲突的方法来劫持域名。

    9.openresty+lua在反向代理服务

    10.Squid和Nginx是非常优秀的反向代理。

    (以下来自红客联盟)

    11.假扮域名注册人和域名注册商通信。

    这类域名盗窃包括使用伪造的传真,邮件等来修改域名注册信息,有时候,受害者公司的标识之类的也会用上。增加可信度。
    hushmail.com被盗窃就是一次典型的例子。当时一名域名劫持者使得注册服务提供商相信了他的身份,然后修改了该公司的域名管理员邮件信息。然后攻击者使用管理员邮件提交了密码重设请求。最后。攻击者登录域名服务商。修改密码。更改DNS记录,然后指向自己的服务器。
    12.是伪造域名注册人在注册商处的账户信息。
    攻击者伪造域名注册人的邮件和注册商联系。然后卖掉域名或者是让买家相信自己就是域名管理员。然后可以获利
    13.是伪造域名注册人的域名转移请求。
    这类攻击通常是攻击者提交一个伪造的域名转让请求,来控制域名信息。
    在2001年,攻击者向服务商提交了一封信。谎称原注册人已经被公司解雇,须将域名转移给自己,结果他成功地控制了sex.com域名。最后被判了6500万美元罚款。
    14. 是直接进行一次域名转移请求。
    这类攻击有可能改dns,也有可能不改,如果不改的话。是很隐蔽的。但最终盗窃者的目的就是卖掉域名,当时blogtemplate4u.com 和 dhetemplate.com
    两个域名是由美国一家公司通过godaddy注册管理的。结果某一天,一个盗窃者使用该公司管理员的帐号密码登录到域名管理商,执行了转移请求。注意。他没有更改dns记录。域名在转移期间。一切服务都没有受到影响。
    15.是修改域名的DNS记录。
    未经授权的DNS配置更改导致DNS欺骗攻击。(也称作DNS缓存投毒攻击)。这里。数据被存入域名服务器的缓存数据库里,域名会被解析成一个错误的ip,或是解析到另一个ip,典型的一次攻击是1997年Eugene Kashpureff黑阔通过该方法重定向了InterNIC网站。



    展开全文
  • DNS域名劫持的几种解决方法

    万次阅读 2017-07-20 10:17:33
    现在国内上网的用户,大多家用的都是用的网通或者电信的adsl,这中间还分各省地区的拨号服务器,dns(Domain Name System)就成了上网时,很关键的一环,dns的快慢与稳定与否,关系着浏览时的正常;更有甚者,dns的健康...

    现在国内上网的用户,大多家用的都是用的网通或者电信的adsl,这中间还分各省地区的拨号服务器,dns(Domain Name System)就成了上网时,很关键的一环,dns的快慢与稳定与否,关系着浏览时的正常;更有甚者,dns的健康与否,更会直接影响各个拨号客户端的健康。

    DNS域名劫持的几种解决方法

    dns劫持现在不算新名词了,从理解WWW以后,网络的普及,it知识的丰富积累,大家都知道了能够浏览网络的基本原理:由客户端发送域名请求给 dns,dns通过遍历查询dns数据库,来解析此域名对应的ip,然后反馈至浏览器客户端,客户端通过ip与对方建立数据连接;这时,很关键的一环,就是dns服务,如果dns把你想要解析的地方,解析为错误的另一个地方,这地方是劫持者有自身利益的地方,例:明明访问 www.linwan.net.cn,却被引导至另外一个网址,比如:www.smallit.cn ;另外,还有就是,排除自身电脑问题的弹出窗口这个过程,就称之为dns劫持,至于dns劫持的利益,这就是另外一个话题了。

    遇到dns被劫持,让dns服务提供者解决这个问题,是比较矛盾的;因为,劫持者,最有可能的就是他们;另外一种最直接的解决办法就是换用其他dns。

    国内的dns服务器,全国各地的列表有很多,比如河南网通的是:202.102.224.68 202.102.227.68,河南电信的是:219.150.150.150 219.150.32.132,后面附有列表,有需要的可以查询下;

    另外,国外的dns服务器可用的也非常多,我推荐大家使用OpenDNS提供的DNS服务器,OpenDNS是一个提供免费DNS服务的网站,口号是更安全、更快速、更智能。

    更换dns服务器的方法非常简单,对于宽带拨号用户来说,在“设置”-“网络连接”中找到宽带上网的连接,打开网络连接属性,选择Interner 协议(TCP/IP)的属性页里,不要选择自动获取DNS,而要选择“使用下面的DNS服务器地址”,首选DNS服务器和备用DNS服务器分别设置为 208.67.222.222和208.67.220.220,如下图所示,完成后重新连接上网,就可以摆脱服务商对我们的DNS劫持。

    网络安全:DNS域名劫持的几种解决方法

    网络安全:DNS域名劫持的几种解决方法

    设置完请打开验证地址http://www.opendns.com/welcome/,如出现下面的画面即为设置成功。

    网络安全:DNS域名劫持的几种解决方法

    同时使用openDNS可以访问很多被电信网通屏蔽的站点 我们喜欢gmail的访问也会稳定,好像google.com也可以直接访问不用转到google.cn了

    还有一些其他功能 OpenDNS Shortcut 类似于域名缩写。

    网络安全:DNS域名劫持的几种解决方法


    展开全文
  • 前言 我们经常有这么一个需求,我们可以通过ip地址来登录我们的设备。但是如果ip地址变化,我们又不知道设备的ip地址的时候,就不能够正常登录到设备,或者很难登录到设备(需要查看设备当前的ip地址才可以)。...

    前言

    我们经常有这么一个需求,我们可以通过ip地址来登录我们的设备。但是如果ip地址变化,我们又不知道设备的ip地址的时候,就不能够正常登录到设备,或者很难登录到设备(需要查看设备当前的ip地址才可以)。那么能不能实现我可以通过一个域名来登录设备(即:给设备绑定一个随意的域名,通过域名来访问设备)

    linux内核数据包桥流程分析

    这里引用网上比较好的博客,让大家对于linux桥接有一个直观的认识

    什么是桥接?

    简单来说,桥接就是把一台机器上的若干个网络接口“连接”起来。其结果是,其中一个网口收到的报文会被复制给其他网口并发送出去。以使得网口之间的报文能够互相转发。
    交换机就是这样一个设备,它有若干个网口,并且这些网口是桥接起来的。于是,与交换机相连的若干主机就能够通过交换机的报文转发而互相通信。

    交换机在报文转发的过程中并不会篡改报文数据,只是做原样复制。然而桥接却并不是在物理层实现的,而是在数据链路层。交换机能够理解数据链路层的报文,所以实际上桥接却又不是单纯的报文转发。
    交换机会关心填写在报文的数据链路层头部中的Mac地址信息(包括源地址和目的地址),以便了解每个Mac地址所代表的主机都在什么位置(与本交换机的哪个网口相连)。在报文转发时,交换机就只需要向特定的网口转发即可,从而避免不必要的网络交互。这个就是交换机的“地址学习”。但是如果交换机遇到一个自己未学习到的地址,就不会知道这个报文应该从哪个网口转发,则只好将报文转发给所有网口(接收报文的那个网口除外)。
    比如主机C向主机A发送一个报文,报文来到了交换机S1的eth2网口上。假设S1刚刚启动,还没有学习到任何地址,则它会将报文转发给eth0和eth1。同时,S1会根据报文的源Mac地址,记录下“主机C是通过eth2网口接入的”。于是当主机A向C发送报文时,S1只需要将报文转发到eth2网口即可。而当主机D向C发送报文时,假设交换机S2将报文转发到了S1的eth2网口(实际上S2也多半会因为地址学习而不这么做),则S1会直接将报文丢弃而不做转发(因为主机C就是从eth2接入的)。

    然而,网络拓扑不可能是永不改变的。假设我们将主机B和主机C换个位置,当主机C发出报文时(不管发给谁),交换机S1的eth1口收到报文,于是交换机S1会更新其学习到的地址,将原来的“主机C是通过eth2网口接入的”改为“主机C是通过eth1网口接入的”。
    但是如果主机C一直不发送报文呢?S1将一直认为“主机C是通过eth2网口接入的”,于是将其他主机发送给C的报文都从eth2转发出去,结果报文就发丢了。所以交换机的地址学习需要有超时策略。对于交换机S1来说,如果距离最后一次收到主机C的报文已经过去一定时间了(默认为5分钟),则S1需要忘记“主机C是通过eth2网口接入的”这件事情。这样一来,发往主机C的报文又会被转发到所有网口上去,而其中从eth1转发出去的报文将被主机C收到。

    linux桥接

    linux内核支持网口的桥接(目前只支持以太网接口)。但是与单纯的交换机不同,交换机只是一个二层设备,对于接收到的报文,要么转发、要么丢弃。小型的交换机里面只需要一块交换芯片即可,并不需要CPU。而运行着linux内核的机器本身就是一台主机,有可能就是网络报文的目的地。其收到的报文除了转发和丢弃,还可能被送到网络协议栈的上层(网络层),从而被自己消化。
    linux内核是通过一个虚拟的网桥设备来实现桥接的。这个虚拟设备可以绑定若干个以太网接口设备,从而将它们桥接起来。

    • 数据包接收过程(如下图所示)
      从图中我们可以看到桥虚拟接口br0下面挂载了两个接口eth0和wlan0。当数据包从eth0接口收到后数据包会被送到虚拟网桥接口br0。桥处的代码会判断是否采用二层转发还是3层转发。如果是二层转发,那么数据包就不会送到网络层,直接会在br0下挂的设备寻找匹配的接口,然后从该匹配的接口转发。如果数据包不满足二层转发条件,数据包就会被送到3层。3层代码又会判断是发送到本机还是需要本机转发,如果是发送到本机,则设备本身接收,如果需要路由转发,则查找路由表,然后转发。
      在这里插入图片描述

    • 数据包发送流程
      当本地发送的数据包或者网络转发的数据包会被送到br0。桥相关的代码会判断向挂载到br0下面的哪一个接口转发,将数据包从合适的接口转发出去。
      在这里插入图片描述

    linux桥相关代码

    数据包流向

    • 接收数据包
      netif_rx–>netif_rx_schedule–>net_rx_action–>process_backlog–>netif_receive_skb–>上层协议栈处理
    • 发送数据包
    • fun_xmit–>dev_queue_xmit–>qdisc_run–>qdsic_restart–>net_tx_action–>dev->hard_start_xmit–>发送完成

    桥入口代码行数为int netif_receive_skb(struct sk_buff skb)* //网卡收到包会调用该函数将数据包向协议栈上扔
    int netif_receive_skb(struct sk_buff skb) //网卡收到包会调用该函数将数据包向协议栈上扔,然后会调用br_handle_frame函数,让桥接的代码来处理这个报文。该函数就是桥的入口函数*

    static int __netif_receive_skb(struct sk_buff *skb)
    	static int __netif_receive_skb_core(struct sk_buff *skb, bool pfmemalloc)
    	//这里就会从rcu_dereference获取到rx_handler指向的函数指针,那么该函数又是在什么地方初始化的呢
    	rx_handler = rcu_dereference(skb->dev->rx_handler);
    		if (rx_handler) {
           		if (pt_prev) {
               		ret = deliver_skb(skb, pt_prev, orig_dev);
               		pt_prev = NULL;
           }
           switch (rx_handler(&skb))	//这里就是在调用实际的函数即:br_handle_frame
    

    那么这里产生了一个问题,br_handle_frame是什么时候注册到内核的呢。带着该问题我们来看一下代码。

    int br_add_if(struct net_bridge *br, struct net_device *dev)
    	err = netdev_rx_handler_register(dev, br_handle_frame, p);
    
    
    int netdev_rx_handler_register(struct net_device *dev,
    			       rx_handler_func_t *rx_handler,
    			       void *rx_handler_data)
    {
    	ASSERT_RTNL();
    	
    	if (dev->rx_handler)
    		return -EBUSY;
    
    	/* Note: rx_handler_data must be set before rx_handler */
    	rcu_assign_pointer(dev->rx_handler_data, rx_handler_data);
    	rcu_assign_pointer(dev->rx_handler, rx_handler);
    
    	return 0;
    }
    

    我们可以看到,当调用底层程序br_add_if的时候,会调用netdev_rx_handler_register。netdev_rx_handler_register中初始化了dev->rx_handler处理程序。

    那么又产生了一个问题,什么时候会调用br_add_if函数呢? 在这里我们不妨来看看应用程序初始化桥和给桥添加接口的应用代码。
    brtcl addbr br0 (建立一个网桥br0, 同时在Linux内核里面创建虚拟网卡br0)
    brtcl addif br0 eth0
    brtcl addif br0 wlan0
    通过这里我们可以看到给br0添加接口的时候就会调用操作系统底层的br_add_if。
    我们自己的DNS拦截和修改代码就添加在br_handle_frame代码中

    dns拦截程序及分析

    • 正如上所说,我们的拦截代码是放在br_handle_frame中的,那么下面我们来看一下br_handle_frame的代码实现
    // 下面的两句代码是我加的,因为这里没有hook点,所以自己
    int (*g_fn_dnstrap)(struct sk_buff *skb) = NULL;
    EXPORT_SYMBOL(g_fn_dnstrap);
    rx_handler_result_t br_handle_frame(struct sk_buff **pskb)
    	if (g_fn_dnstrap != NULL)
    	{
    		g_fn_dnstrap(skb);
    	}
    

    在这里我们可以看到如果g_fn_dnstrap函数指针不为空,我们则调用该函数指针指向的函数。那么该函数指针什么时候被赋值呢?下面来看看我们的内核模块的代码。

    dns内核代码

    TODO:该内核模块非常重要,请仔细阅读

    DNS报文结构定义和分析

    DNS占用53号端口,同时使用TCP和UDP协议。那么DNS在什么情况下使用这两种协议?
    DNS在区域传输的时候使用TCP协议,其他时候使用UDP协议。
    DNS区域传输的时候使用TCP协议:

    1.辅域名服务器会定时(一般3小时)向主域名服务器进行查询以便了解数据是否有变动。如有变动,会执行一次区域传送,进行数据同步。区域传送使用TCP而不是UDP,因为数据同步传送的数据量比一个请求应答的数据量要多得多。

    2.TCP是一种可靠连接,保证了数据的准确性。
    域名解析时使用UDP协议:

    客户端向DNS服务器查询域名,一般返回的内容都不超过512字节,用UDP传输即可。不用经过三次握手,这样DNS服务器负载更低,响应更快。理论上说,客户端也可以指定向DNS服务器查询时用TCP,但事实上,很多DNS服务器进行配置的时候,仅支持UDP查询包。

    TODO: 该头部是DNS的头部信息,发送和接收该头部的长度是固定的
    详情查看https://blog.csdn.net/liao152/article/details/45252387

    我们来看看dns头部信息我们是怎么定义的

    typedef struct _header {
    	unsigned short int	id; //id 位
    	unsigned short		u;  //标志位
    	short int	qdcount;    //问题数
    	short int	ancount;    //资源记录数
    	short int	nscount;    //授权资源记录数
    	short int	arcount;    //问题资源记录数
    } dnsheader_t;
    

    对应着下图中的各字段。在这里插入图片描述

    内核模块加载函数分析:

    #include "dns_packet.h"
    #include "dns_proc.h"
    
    typedef int (*fn_dnstrap)(struct sk_buff *skb);
    extern fn_dnstrap g_fn_dnstrap;
    
    
    static int __init dnstrap_init(void) {
      //创建proc文件
      create_dnstrap_proc();
      //我们可以看到这里将g_fn_dnstrap进行了赋值,所以重点函数为br_dns_trap_enter,我们将在后面对于该函数进行分析
      g_fn_dnstrap = br_dns_trap_enter;
      return 0;
    }
    
    static void __exit dnstrap_eixt(void) {
      //销毁proc文件
      destroy_dnstrap_proc();
      g_fn_dnstrap = NULL;
    }
    
    MODULE_LICENSE("GPL");
    
    module_init(dnstrap_init);
    
    module_exit(dnstrap_eixt);
    

    proc文件创建代码分析

    #include "dns_common.h"
    
    #define PROC_ROOT "dns_filter"
    #define PROC_DOMAIN_NAME "domain_name"
    #define PROC_ENABLE "enable"
    
    void create_dnstrap_proc();
    void destroy_dnstrap_proc();
    
    #include "dns_proc.h"
    
    bool g_dns_filter_enable = false;
    // 该全局变量从pro文件中获取用户输入的url域名
    unsigned char g_domain_name[80] = {0};
    
    static struct proc_dir_entry *dnstrap_proc_root = NULL;
    
    static int dnstrap_domain_read(struct seq_file *s, void *v) {
      seq_printf(s, "%s\n", g_domain_name);
      return 0;
    }
    
    static int dnstrap_domain_proc_open(struct inode *inode, struct file *file) {
      return (single_open(file, dnstrap_domain_read, NULL));
    }
    
    static int dnstrap_domain_write(struct file *file, const char *buffer,
                                    unsigned long count, void *data) {
      if (count < 2) return -EFAULT;
    //从用户空间拷贝domain_name
      if (buffer && !copy_from_user(g_domain_name, buffer, 80)) {
        g_domain_name[count - 1] = 0;
        //转化为小写
        str_to_lower(g_domain_name);
        return count;
      }
    
      return -EFAULT;
    }
    
    int dnstrap_domain_proc_write(struct file *file, const char __user *userbuf,
                                  size_t count, loff_t *off) {
      return dnstrap_domain_write(file, userbuf, count, off);
    }
    
    struct file_operations dnstrap_domain_proc_fops = {
        .open = dnstrap_domain_proc_open,
        .write = dnstrap_domain_proc_write,
        .read = seq_read,
        .llseek = seq_lseek,
        .release = single_release,
    };
    
    //该函数是设置是否开启dns trap的功能
    static int dnstrap_en_write(struct file *file, const char *buffer,
                                unsigned long count, void *data) {
      char tmpbuf[80];
    
      if (count < 2) return -EFAULT;
    
      if (buffer && !copy_from_user(tmpbuf, buffer, count)) {
        tmpbuf[count] = '\0';
        if (tmpbuf[0] == '0')
          g_dns_filter_enable = true;
        else if (tmpbuf[0] == '1')
          g_dns_filter_enable = false;
        return count;
      }
      return -EFAULT;
    }
    
    static int dnstrap_en_read(struct seq_file *s, void *v) {
      seq_printf(s, "%d\n", g_dns_filter_enable);
      return 0;
    }
    
    static int dnstrap_en_proc_open(struct inode *inode, struct file *file) {
      return (single_open(file, dnstrap_en_read, NULL));
    }
    static int dnstrap_en_proc_write(struct file *file, const char __user *userbuf,
                                     size_t count, loff_t *off) {
      return dnstrap_en_write(file, userbuf, count, off);
    }
    
    struct file_operations dnstrap_en_proc_fops = {
        .open = dnstrap_en_proc_open,
        .write = dnstrap_en_proc_write,
        .read = seq_read,
        .llseek = seq_lseek,
        .release = single_release,
    };
    
    void create_dnstrap_proc() {
      dnstrap_proc_root = proc_mkdir(PROC_ROOT, NULL);
      if (dnstrap_proc_root) {
        proc_create_data(PROC_DOMAIN_NAME, 0, dnstrap_proc_root,
                         &dnstrap_domain_proc_fops, NULL);
        proc_create_data(PROC_ENABLE, 0, dnstrap_proc_root, &dnstrap_en_proc_fops,
                         NULL);
      }
    }
    
    void destroy_dnstrap_proc() {
      if (dnstrap_proc_root) {
        remove_proc_entry(PROC_DOMAIN_NAME, &dnstrap_proc_root);
        remove_proc_entry(PROC_ENABLE, &dnstrap_proc_root);
        remove_proc_entry(PROC_ROOT, NULL);
      }
    }
    

    DNS TRAP代码(非常关键的代码)

    DNS抓包图
    • dns请求报文
      在这里插入图片描述
    • dns应答报文截图
      在这里插入图片描述
    #include "dns_packet.h"
    extern unsigned char g_domain_name[80];
    //我们可以从dns应答报文截图中可以看到我们访问的www.scdn.com返回了csdn的ip地址。该ip地址和域名在Answers字段中。同时可以抓取其他的数据包可以看到前12个字节是固定的,后4个字节对应的是域名所对应的ip地址。
    static unsigned char dns_answer[] = {0xC0, 0x0C, 0x00, 0x01, 0x00, 0x01,
                                         0x00, 0x00, 0x00, 0x00, 0x00, 0x04};
    
    //该函数没有什么分析的,就是从dns请求报文中截取出访问的url地址。
    static int get_domain_name(unsigned char *dns_body, char *domain_name,
                               int body_len) {
      int offset = 0, token_len = 0;
      char token[64] = {0};
      char domain[128] = {0};
      short type;
      if (!dns_body || !domain_name || body_len <= 0) {
        return -1;
      }
      while (body_len > 0) {
        memset(token, 0, sizeof(token));
        token_len = dns_body[offset];
        if ((token_len > 0) && (token_len <= body_len)) {
          strncpy(token, dns_body + offset + 1, token_len);
          if (!domain[0]) {
            strncpy(domain, token, (sizeof(token) - 1));
          } else {
            strncat(domain, ".", (sizeof(domain) - strlen(domain) - 1));
            strncat(domain, token, (sizeof(domain) - strlen(domain) - 1));
          }
        } else {
          if (token_len > body_len)
            printk("%s[%d], token_len is %d, body_len is %d\n", __FUNCTION__,
                   __LINE__, token_len, body_len);
          break;
        }
        token_len += 1;
        body_len -= token_len;
        offset += token_len;
      }
      strncpy(domain_name, domain, (sizeof(domain) - 1));
      return 0;
    }
    
    //判断是否是合法的dns请求头,关于dns的请求头部的每一个字段,可以查看上面贴出的dns报文信息的链接地址。这里其实可以少些判断,当然判断的越多越准确,主要是按照协议来的。
    static bool is_valid_dns_query_header(dnsheader_t *dns_header) {
      if (dns_header == NULL) {
        return false;
      }
      if (dns_header->qdcount < 1) {
        return false;
      }
      if (((dns_header->u & 0x8000) >> 15) !=
          0) /*QR: query should be 0,answer be 1*/
      {
        return false;
      }
      if (((dns_header->u & 0x7100) >> 11) !=
          0) /*opcode: 0:standard,1:reverse,2:server status*/
      {
        return false;
      }
      if (((dns_header->u & 0x70) >> 4) != 0) /*Z: reserved, should be 0*/
      {
        return false;
      }
      return true;
    }
    
    
    //该函数是判断我们通过应用层下发的proc中的domain_name和我们从dns报文中截取的是否相等
    static bool is_domain_name_equal(char *domain_name1, char *domain_name2) {
      char temp1[128];
      char temp2[128];
      if (!domain_name1 || !domain_name2) {
        return false;
      }
      str_to_lower(domain_name1);
      str_to_lower(domain_name2);
      if (!strncmp(domain_name1, "www.", 4)) {
        strcpy(temp1, domain_name1 + 4);
      } else {
        strcpy(temp1, domain_name1);
      }
      if (!strncmp(domain_name2, "www.", 4)) {
        strcpy(temp2, domain_name2 + 4);
      } else {
        strcpy(temp2, domain_name2);
      }
      if (strcmp(temp1, temp2))
        return false;
      else
        return true;
    }
    
    // TODO: 该函数是核心函数,设计到数据包的修改,该函数是dns报文的修改和重定向函数
    int br_dns_packet_recap(struct sk_buff *skb) {
      struct iphdr *iph;
      struct udphdr *udph;
      struct net_device *br0_dev;
      struct in_device *br0_in_dev;
      dnsheader_t *dns_pkt;
      unsigned char mac[ETH_ALEN];
      unsigned int ip;
      unsigned short port;
      unsigned char *ptr = NULL;
      int extend_len;
      extend_len = EXTEND_LEN_V4;
      /*
      关于net_device和in_device详见https://blog.csdn.net/sinat_20184565/article/details/79898433
      我们这里的需要返回br0当前的ip地址,所以需要获取用户给br0配置的ip地址,所以需要该函数
      TODO: 用完该结构我们必须要调用put来进行释放
      */
      br0_dev = dev_get_by_name(&init_net, "br0");
      br0_in_dev = in_dev_get(br0_dev);
    
      if (!br0_dev || !br0_in_dev) {
        if (br0_in_dev) in_dev_put(br0_in_dev);
        if (br0_dev) dev_put(br0_dev);
        return -1;
      }
      /*
        in_ifaddr表示地址结构,其成员包含了地址,掩码,范围等信息,多个地址连接成链表,主地址在前,从地址在后;
        struct in_ifaddr    *ifa_list;    /* IP ifaddr chain
        如果br0接口配置的有ip地址,子网掩码等,所有的信息都存放在这里(我们可以从该结构中拿到当前的br0的ip地址)
    */
    
      if (!br0_in_dev->ifa_list) {
        in_dev_put(br0_in_dev);
        dev_put(br0_dev);
        return -1;
      }
      iph = ip_hdr(skb);
      udph = (void *)iph + iph->ihl * 4;
    
      dns_pkt = (void *)udph + sizeof(struct udphdr);
    
      // ptr为尾部指针,指向了dns请求报文的尾部
      ptr = (void *)udph + ntohs(udph->len);
      /*
      将数据段向后扩大extend_len的长度(这里是16个字节,ip地址为4个字节,固定长度12个字节)
      该条语句的操作可以参考wireshark抓包。
      TODO:下面这句话是该整个修改数据包函数的核心思想
      TODO:dns的回复报文需要在请求报文(queries字段)的后面添加应答字段(answers),具体可以查看
            上面的博客连接和通过抓包分析
            answers字段中的前12个字段是固定的,12个字段后面接的是ip地址
            所以是16个字节
      */
      skb_put(skb, extend_len);
    
      // TODO:下面的操作其实都是在操作五元组,内核中数据包的流向都是靠五元组(源)
      /*
              源IP地址、目的IP地址、协议号、源端口、目的端口(协议号已经是有的了)
      */
    
      //交换mac地址
      /*
        在网络通信的是否,数据包中的地址变化过程如下:(不在同一局域网)
        源mac地址为当前设备的mac地址,目的mac是下一条设备的mac地址
        目的ip不变,源ip地址是为当前设备的ip地址。
    
        在这里的理解为:
        当pc访问www.baidu.com的时候,首先会向网关发送dns请求。(此时的源mac地址为pc的mac,目的mac地址为网关。源ip地址为pc的ip地址,目的ip地址为网关的ip地址)
        当我们在网关拦截到数据包的时候,需要交换数据报文中的mac地址和ip地址。
      */
      memcpy(mac, eth_hdr(skb)->h_dest, ETH_ALEN);
      memcpy(eth_hdr(skb)->h_dest, eth_hdr(skb)->h_source, ETH_ALEN);
      memcpy(eth_hdr(skb)->h_source, mac, ETH_ALEN);
    
      //交换ip地址
      ip = iph->saddr;
      iph->saddr = iph->daddr;
      iph->daddr = ip;
    
      //重新计算ip头部信心中的tot_len,tot_len代表ip数据包的长度
      iph->tot_len = htons(ntohs(iph->tot_len) + extend_len);
    
      /*  交换udp端口 */
      port = udph->source;
      udph->source = udph->dest;
      udph->dest = port;
    
      //计算udp头部的长度
      udph->len = htons(ntohs(udph->len) + extend_len);
    
      //下面是根据wireshark抓包得到的
      dns_pkt->u = htons(0x8180);
      dns_pkt->qdcount = htons(1);
      dns_pkt->ancount = htons(1);
      dns_pkt->nscount = htons(0);
      dns_pkt->arcount = htons(0);
      
      //填充12位固定的数据,在dns应答报文的截图中可以看到
      memcpy(ptr, dns_answer, 12);
      //将br0的ip地址填充到skb中
      memcpy(ptr + 12, (unsigned char *)&br0_in_dev->ifa_list->ifa_address, 4);
    
      /* ip checksum */
      // TODO: CHECKSUM_NONE表示发送侧已经计算了校验和,协议栈将不会再计算校验和
      skb->ip_summed = CHECKSUM_NONE;
    
      //计算ip头部校验和,在计算之前应该先赋值为0
      iph->check = 0;
      iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl);
    
      /* udp checksum */
      udph->check = 0;
      udph->check =
          csum_tcpudp_magic(iph->saddr, iph->daddr, ntohs(udph->len), IPPROTO_UDP,
                            csum_partial((char *)udph, ntohs(udph->len), 0));
      if (br0_in_dev) {
        in_dev_put(br0_in_dev);
      }
      if (br0_dev) {
        dev_put(br0_dev);
      }
    
      return 1;
    }
    
    /*
        该函数只会判断ipv4的报文,ipv6的报文这里不会涉及
    */
    int br_dns_trap_enter(struct sk_buff *skb) {
      struct iphdr *iph;
      struct udphdr *udph;
    
      iph = (struct iphdr *)skb_network_header(skb);
    
      //判断是否为ipv4的报文
      if (iph->version != 4) {
        return -1;
      }
      //获取udp头部
      udph = (void *)iph + iph->ihl * 4;
      // DNS报文是属于udp数据包,同时端口号为53
      if (iph->protocol != IPPROTO_UDP || ntohs(udph->dest) != 53) {
        return -1;
      }
      //获取DNS报文中的domain_name的长度
      /*
        说明:udp数据包头部信息中的len字段是udp头部信息和数据信息的总长度
        domain_name_len的长度和我们在应用层看到的domain_name的长度不一样,比如应用层我们看到的www.baidu.com他的长度为12个字节。
        但是在数据包中一般为14个字节,因为他会指明域名的长度(具体看wireshark抓包截图)
        ntohs(udph->len) - sizeof(struct udphdr) -
        sizeof(dnsheader_t)代表的是dns请求报文中的Queries字段的长度。该字段也是放在报文的最后面(我们请求的域名就包含在该字段中)
        那么这里为什么还要减去4呢,因Queries中有4个字节是固定的,分别为Type和Class字段,他们一共占据4个字节。减去4之后剩下的,才是我们真正的domain_name_len的长度
      */
      int domain_name_len =
          ntohs(udph->len) - sizeof(struct udphdr) - sizeof(dnsheader_t) - 4;
      if (domain_name_len <= 1) {
        return -1;
      }
      // 获取dns头部信息
      dnsheader_t *dns_hdr = (dnsheader_t *)((void *)udph + sizeof(struct udphdr));
    
      //判断dns头部是否有效
      if (is_valid_dns_query_header(dns_hdr) != true) {
        return -1;
      }
      //获取dns中的数据包
      unsigned char *body =
          (void *)udph + sizeof(struct udphdr) + sizeof(dnsheader_t);
    
      //获取dns数据包中的domain_len(这里是按照wireshark中来解析的)
      unsigned char domain_name[128] = {0};
      if (get_domain_name(body, domain_name, domain_name_len) != 0) {
        return -1;
      }
    
      //判断报文中获取到的domain_name和应用层传入的domain_name是否相等
      if (is_domain_name_equal(domain_name, g_domain_name) == false) {
        return -1;
      }
      //上面的匹配都满足了,证明该数据包我们需要处理,这里处理的核心思想就是改变原有数据包,然后发送。
      br_dns_packet_recap(skb);
    
    
    }
    

    代码地址:代码仓库地址

    未完待续,该代码我会在后续加入ipv6的截图和分析以及劫持。上面的代码已经测试过,能够跳转。这次的代码只是DNS Trap中redirect的一种写法,我会在后面的博客中提供多种redirect写法以及filter写法。欢迎关注博客,欢迎加入QQ群610849576交流

    展开全文
  • 免费小疯dns宽带本地劫持插件v5.0下载
  • DNS 劫持及解决方案之 HTTPDNS

    千次阅读 2018-06-07 21:40:50
    1. 为什么会有 DNS DNS 即域名系统(Domain Name Server),其主要用于将域名解析为对应的 IP 地址。 那么为什么会有域名到 IP 地址的解析这一需要呢?就需要从人的角度和计算机的角度去分析了。 人的角度:网络...

    1. 为什么会有 DNS

    DNS 即域名系统(Domain Name Server),其主要用于将域名解析为对应的 IP 地址。
    那么为什么会有域名到 IP 地址的解析这一需要呢?就需要从人的角度和计算机的角度去分析了。

    • 人的角度:网络上的主机一般是通过 IP 地址唯一确定,但 IP 不便于人们记忆,如果每个人都需要通过 IP 来访问其他主机,那记忆量太大了,因此才借用域名来间接地标识一台主机。比如常见的域名有: www.baidu.com, 其 IP 地址为 202.108.22.5。
    • 计算机的角度:人是方便记忆了,但是计算机的网络通信层(IP 层)只认 IP 地址。人想要访问其他主机必须通过计算机实现,因此光有域名还无法达到目的,于是计算机需要多干一件事,那就是根据人提供的域名去获得相应的 IP。

    2. 为什么会有 DNS 劫持(域名劫持)

    DNS 的来源上面已经解释了,DNS 劫持是指在劫持的网络范围内(类似于白名单)拦截域名解析的请求,分析请求的域名,把审查范围以外(类似于黑名单)的请求放行,否则返回假的IP地址或者什么都不做使请求失去响应,其效果就是对特定的网络不能访问或访问的是假网址。TCP 管发管到,UDP 管发不管到。因此,在安全性方面来说,TCP/IP更具有优越性,DNS 的域名解析基于 UDP 协议实现,极易发生 DNS 劫持。

    传统 DNS 解析过程

    3. 如何解决 DNS 劫持

    传统 DNS 解析域名的最大弊端就是易被劫持,直接降低互联网用户的使用体验。比如你想访问 www.baidu.com,结果发生 DNS 劫持,得到了一个诈骗网站的 IP 或者空的地址,使你无法使用正常的服务(比如百度是搜索服务)。
    HTTPDNS 利用 HTTP 协议与 DNS 服务器交互,代替了传统的基于 UDP 协议的 DNS 交互,绕开了运营商的 Local DNS(本地 DNS 服务器),有效防止了域名劫持,提高域名解析效率。另外,由于 DNS 服务器端获取的是真实客户端 IP 而非 Local DNS 的 IP,能够精确定位客户端地理位置、运营商信息,从而有效改进调度精确性。

    4. 疑问记录

    • 为什么要用 UDP 协议进行 DNS 域名解析?
      UDP 协议通信速度更快。
    • 为什么不直接用 TCP 协议,而要用 HTTP 协议?
      HTTP协议基于 TCP 协议
    • 为什么 HTTPDNS 能解决 DNS 劫持问题?

    参考链接:

    展开全文
  • 【HTTP劫持和DNS劫持】

    万次阅读 2018-11-06 14:39:02
    【HTTP劫持和DNS劫持】  简单介绍一下HTTP劫持和DNS劫持的概念,也就是运营商通过某些方式篡改了用户正常访问的网页,插入广告或者其他一些杂七杂八的东西。    首先对运营商的劫持行为做一些分析,他们的目的...
  • DNS 劫持

    千次阅读 2019-10-30 10:00:16
    《目录》 APR 协议 Ettercap 是个啥 ? Ettercap 常用指令 欺骗,Ettercap !!! 钓鱼 ???? 松风吹解带,山月照弹琴 [免责声明]: DNS 劫持是违法...
  • 运营商劫持(DNS/HTTP302)

    万次阅读 2018-06-03 09:15:44
    本人以网络技术出身,近两年接触CDN网络,处理了一些CDN方面的网络问题,大多数以运营商丢包,延迟抖动为主,也处理一些硬件故障,比如机械硬盘的读写io测试,内存条兼容性测试,服务器IPMI规划等。...
  • 路由器 设置DNS 域名拦截 重定向

    千次阅读 2017-02-13 13:28:46
    我们自己搭建了一个weather.sophia.com,多个版本的软件使用这个server,现在server经过变动,在部署之前,需要测试,因此需要搭建测试环境:如何让测试机器访问的weather.sophia.com都定位到test_server的地址。...
  • 解决手机连接Mac mini 共享的WiFi,mac的hosts不生效的问题 公司工作中遇到的一个问题。Mac端可以修改hosts文件实现访问域名的切换,而对于未越狱的iPhone来说,这是无法实现的。安卓可以通过Root的方式开启修改...
  • 最近在G+上无意发现一个一个好东西——Pcap_DNSProxy,这是一个运行在Windows上的DNS服务程序,主要功能是防止DNS污染。以前我都是在linux系统上使用Pdnsd搭建防污染的DNS服务器,现在家用的Windows电脑单也可以轻松...
  • 通过DNS屏蔽广告

    千次阅读 2019-01-27 16:09:00
    最初级的做法就是直接F12看到页面上插入的广告的iframe的域名 然后修改 host 文件 比如配置百度的几个域名 就能把一些页面上...搭建本地 DNS 服务器, 优点: 已经有很多人贡献了屏蔽广告的配置, 而且支持通配符配...
  • DNS原理及局域网DNS劫持实践 1. DNS原理 1.1 DNS是什么? DNS(Domain Name System)即域名系统。我们常说的DNS是域名解析协议。 1.2 为什么需要DNSDNS协议提供域名到IP地址之间的解析服务。计算机既可以被赋予IP...
  • 之前写过一篇文章 Android 使用OkHttp支持HttpDNS,该文章中使用的是OkHttp的拦截器来实现HttpDNS。在请求发出去之前,将URL中的域名替换成ip,再往Header中添加Host。这种方式有以下优点。 上层方便控制哪些请求...
  • DNS劫持又称域名劫持,是指在劫持的网络范围内拦截域名解析的请求,分析请求的域名,把审查范围以外的请求放行,否则返回假的IP地址或者什么都不做使请求失去响应,其效果就是对特定的网络不能反应或访问的是假网址...
  • 1: DNS劫持又称域名劫持,是指在劫持的网络范围内拦截域名解析的请求 2: 局域网劫持, 攻击者通过伪装成网关, 劫持受害者的网络请求, 将网络请求拦截到指定的服务器 二.DNS劫持详细实验过程 <一> 所需工具 1: ...
  • 局域网内DNS劫持方法

    万次阅读 2019-12-15 22:19:36
    以下讲述本人最近设计的一套基于局域网的dns劫持方法,其最终能实现的目的是:只用一台接入到某个局域网的计算机,该计算机可以对该局域网内指定的计算机发起dns劫持,使被dns劫持的计算机的可以正常的上网,但是...
  • 路由器DNS被劫持 解决办法

    千次阅读 2018-12-09 13:35:09
     DNS劫持又称域名劫持,是指在劫持的网络范围内拦截域名解析的请求,分析请求的域名,把审查范围以外的请求放行,否则返回假的IP地址或者什么都不做使请求失去响应,其效果就是对特定的网络不能访问或访问的是假...
  • DNS反劫持的几种方式

    万次阅读 2016-02-29 08:41:48
    DNS劫持,劫持单条DNS查询信息,返回不正确的结果. 透明DNS代理,劫持所有查询信息,只要是经过运营商网关的发往53端口的UDP类型的DNS协议,全部都转移到自己DNS服务器上去,所以在本机上设置是没用的. 这样一来,即使在...
  • 全封当然是拨电源就可以了,但这不现实。...是暗协议,还是DNS拦截? 对付这个用远程DNS是一种方法,但会减慢网速。用本地DNS吧。但google的可用ipv6地址是在变的,因为封,所以变。这就要更新。用远程...
1 2 3 4 5 ... 20
收藏数 14,292
精华内容 5,716
关键字:

dns拦截