目录
0、前言
我在之前发过的帖子力记录过关于方向代理、多重代理的内容,今天测试一下隧道。反向代理用在那些没有映射但可以出网的环境。隧道则是用在出网受限的环境,比如内部的终端、服务器仅允许ICMP、DNS流量通过的情况下。首先从复杂一点的DNS隧道开始测试,因为ICMP、SSL隧道过程节点都可控,DNS隧道要经过第三方的DNS服务器,所以想把这个弄清楚。
之前学习MCSE认证的时候对DNS搞得比较清除,现在好多细节都忘掉了先开始回顾一下DNS的解析过程。
1、DNS解析
1.1 DNS简介
DNS解析是将域名转换为IP地址的过程,使得用户可以通过域名访问网站或服务,而不是直接使用数字IP地址。这一过程涉及到一个分布式的数据库系统,全球有多个服务器协作完成这一转换。以下是关于DNS解析的一些关键点:
定义与功能:DNS是一个分布式数据库,它将人类可读的域名映射到数字IP地址,使得用户可以通过输入容易记忆的域名来访问互联网上的资源。
工作原理:当用户尝试访问一个网站时,他们的设备首先向本地的DNS服务器发送请求。如果本地DNS服务器无法直接解答,它会向其他服务器查询,最终找到正确的IP地址并返回给用户。
1.2 DNS查询类型
DNS递归查询和迭代查询过程是域名解析的两种主要方式,它们在查询过程中扮演的角色和方式有所不同。
DNS递归查询过程:
客户端(如浏览器)发起一个DNS查询请求,通常是通过ISP提供的递归DNS服务器进行的。
递归DNS服务器接收请求后,会代替客户端进行后续的所有查询工作,直到找到正确的IP地址并返回给客户端。
递归DNS服务器可能会查询根DNS服务器、顶级域名服务器(TLD)、以及权威DNS服务器,以逐级解析域名到最终的IP地址。
如果递归DNS服务器在其缓存中找到匹配的记录,则会直接返回结果给客户端,否则会进行一系列的查询直到找到答案。
DNS迭代查询过程:
客户端向本地DNS服务器发起查询请求。
本地DNS服务器不直接提供答案,而是告诉客户端下一个应该查询的DNS服务器的地址。
客户端然后向这个新的DNS服务器发送查询请求,这个过程可能会重复多次,直到找到答案或者确定没有匹配的记录。
迭代查询过程中,客户端和DNS服务器之间的角色不变,客户端负责发起请求并跟踪下一个查询的DNS服务器地址。
总结一下:客户端发起的请求默认是递归查询,DNS服务器之间默认是迭代查询。也就是说我们向DNS提出请求后,会给到最后结果,不会再去反复查询。而域名服务器之间会反复多次查询。
下面做个测试:
1.递归查询:
使用nslookup命令查询某域名:nslookup so.com
使用Wireshark抓包,并过滤展示:
基本上一个请求一个应答,就会得到解析结果,更多的交互内容由DNS服务器完成。其他的反向查询和ipv6查询先忽略。
2.迭代查询:
使用Linux的dig命令加trace参数可以设置迭代查询:
通过抓包也可以看到反复查询的过程,感兴趣自己测试一下,可以看到世界上的13个根域名服务的ip地址。可以看到逐个会向顶级域名服务器、二级域名服务器、NS服务器请求解析的过程。
1.3 DNS解析过程
当我们访问一个网站时,域名解析的过程是这样的:Client(客户端)–> hosts文件 –> DNS Service Local Cache(自己的本地缓存) –> DNS Server(recursion递归) –> Server Cache(缓存) –> iteration(迭代) –>根 –> 顶级域名DNS –> 二级域名DNS…
在这里提一个小问题,也是前几天碰到的。我在客户现场做技术支持,发现某些域名解析不到,现场运维就看我的网卡IP配置,说没有配备用域名解析服务器。 因为主要的DNS是客户自建的,备用的是用外网公用的如114.114.114.114。我说肯定不是这个原因。因为我知道主备的工作机制。
现在有个小问题,就是我们配置本机的主、备DNS服务器的工作机制是什么?也就是说什么情况下备用DNS才会使用?
这个问题答案在最后。
2、DNS隧道准备工作
2.1 DNS隧道介绍
2.1.1 什么是DNS隧道?
DNS隧道(DNS Tunneling)是将其他协议的内容封装在DNS协议中,然后以DNS请求和响应包完成传输数据(通信)的技术。当前网络世界中的DNS是一项必不可少的服务,所以防火墙和入侵检测设备处于可用性和用户友好的考虑大都不会过滤DNS流量,也为DNS成为隐蔽信道创造了条件,因此,DNS隧道在僵尸网络和APT攻击中扮演着重要的角色。
2.1.2 DNS隧道的原理
在进行DNS查询时,如果查询的域名不在DNS服务器本机的缓存中,就会访问互联网进行查询,然后返回结果。如果在互联网上有一台定制的服务器,那么依靠DNS协议即可进行数据包的交换。从DNS协议的角度看,这样的操作只是在一次次查询某个特定的域名并得到解析结果,但其本质问题是,预期的返回结果应该是一个IP地址,而事实上不是——返回的可以是任意字符串,包括加密的C&C指令。
2.1.3 DNS隧道分为类
直连模式:客户端直接向指定IP地址的DNS服务器发起DNS解析请求
中继模式:DNS经过互联网的迭代解析,指向指定的DNS服务器。
2.2 客户端、服务端准备
客户端使用kali,好像默认带iodine。
服务端我用的华为云服务器,操作系统是华为欧拉。
下载安装包:
make 报错时候报错:
安装依赖包:
yum list | grep "zlib"
yum -y install zlib zlib-devel
make
make install
这时候服务端就有了iodine这个命令。
注意VPS安全组需要开启UDP 53端口。
2.3 域名准备
申请一个域名,我看网上有个免费的平台,但是我申请的时候好像暂停服务了。
Freenom - 人人都熟悉的名字https://www.freenom.com/zh/index.html 所以用我以前申请的8元一年的online域名。在域名服务器上添加A记录和ns记录。
2.4 连接隧道
为了贴合真实环境,我使用中继的方式进行配置和测试。
服务端运行命令:
在公网服务器上部署iodine服务端。(需要root权限运行)
iodined -f -c -P 123.com 192.168.200.1 ns.luotuo.online -DD
\-f:在前台运行
\-c:禁止检查所有传入请求的客户端IP地址。
\-P:客户端和服务端之间用于验证身份的密码。
\-D:指定调试级别,-DD指第二级。“D”的数量随级别增加。
这里的192.168.200.1为自定义局域网虚拟IP地址,建议不要与现有网段冲突
注意!填写的地址为NS记录
这时候查看端口开放状态,发现UDP 53端口已经被iodined进程打开。
客户端我使用的kali,kali自带iodine工具。
iodine -f -P 123.com ns.luotuo.online -M 200
-r:iodine有时会自动将DNS隧道切换为UDP隧道,该参数的作用是强制在任何情况下使用DNS隧道
-M:指定上行主机的大小。
-m:调节最大下行分片的大小。
-f:在前台运行
-T:指定DNS请求类型TYPE,可选项有NULL、PRIVATE、TXT、SRV、CNAME、MX、A。
-O:指定数据编码规范。
-P:客户端和服务端之间用于验证身份的密码。
-L:指定是否开启懒惰模式,默认开启。
-I:指定两个请求之间的时间间隔。
2.5 遇坑
在以上准备工作完毕后,始终连接不通。
好像提示找不到域名,明明配置没有问题。
后来查看官方文档,发现以重要的“点”。
加上“.”以后马上联通。
3、隧道确认和利用
3.1 隧道验证
首先在服务端和客户端查看IP地址。
服务端:
客户端:
这时候可以使用ssh登录客户端。
客户端登录服务端:
服务端登录客户端:
抓包会发现很多dns解析流量。
而且请求和响应内容也很多。
3.2 隧道利用
隧道利用的话可以使用frp。
服务端:
客户端:
客户端上没有frp,通过scp命令拷贝frp。
可以看到是龟速,10Kb/s。
使用客户端测试一下端口。
这个使用ssh客户端没有连接成功,连接失败,不知道什么原因。socks5没有测试。回头测试一下。
4、总结
4.1 公布答案
答案:主备DNS的工作机制是主DNS的失效、宕机了才会用备DNS的,而不是主DNS解析不到会去备DNS上面找。
4.2 直连模式测试
以上测试过程使用的是中继方式,后来我又测试了一下直连模式。只需要把客户端的dns服务器设置成为服务端IP即可,这样容易暴露自己的VPS,同时速度也没有快多少。
4.3 其他使用场景
4.3.1 外->内
iodine和dnscat2使用环境:目标是内网,并且只有dns出网的情况下,通过自己的公网服务器搭建到目标的dns隧道,从而通过公网服务器代理进入目标内网,遨游目标内网。
4.3.2 内->外
dns2tcp使用的环境是:自己在一个内网里面,自己所处的环境不出网,但是dns可以出网,就可以用过dns2tcp搭建一个dns隧道,从而可以访问到互联网环境。
典型环境:在学校连接到wifi之后,必须要认证登陆,不然不能上网,但是浏览器又能加载出登陆界面,此情况就是dns出网,可以通过dns2tcp搭建dns隧道绕过认证登陆。
=================================================================