前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >照弹不误:出站端口受限环境下反弹Shell的思考

照弹不误:出站端口受限环境下反弹Shell的思考

作者头像
FB客服
发布2020-04-15 16:56:47
2.6K0
发布2020-04-15 16:56:47
举报
文章被收录于专栏:FreeBufFreeBuf

“是否允许出站”这件事我一直以为无需过多思考,无非限制出站协议,或者限制出站端口,对于限制端口的目标十有八九也会保留 80、443,向这两个端口反弹基本能拿到 shell,直到遇到这个目标,引发我对出站端口受限的环境下,如何成功反弹 shell 的思考。

这次遇到的目标,通过 nday 轻松拿到 webshell,打点的过程毫无波澜,甚至有一丝无聊:

webshell 虽然赋予我执行命令、管理文件的能力,但毕竟不是真正的 shell,无法执行交互式命令、无法控制进程状态、无法补全命令等等,非常不利于提权操作以及横向移动,所以,必须反弹 shell。

肌肉记忆让我没有过多思考,攻击端监听端口 12321:

目标上执行反弹命令:

等待许久,攻击端就是不见回连信息,显然,一定是目标上的某种防御在作祟。导致反弹失败的因素很多,反弹命令不存在、禁止出站 IP、流量审查等等都有可能,于是,我从积累的知识库中搜索所有可能,再逐一验证。比如,我在目标上确认 bash 命令的确存在:

在攻击端能收到目标发起的 ping 探测,攻击端能收到 icmp 记录:

用 SSL 加密回连流量仍然反弹失败:

我陷入沉思,这台内网机器,既然公网可见,说明它的边界处有个防火墙作公网 IP 映射:

一般来说,防火墙可能干两件事,一是限制出站协议、一是限制出站端口。协议方面,前面已经验证过 ICMP 可以出网而 HTTP 不行,所以,我可以尝试用 ICMP 隧道反弹,即便可行,效率肯定也不高;端口方面,目标通过防火墙配置出站端口策略,若限制端口黑名单较大或允许端口白名单较小,则攻击者很难猜测出哪些端口有效。从以往的经验判断,80、443 是两个可能性较大的允许出站的端口,于是我又依次尝试向 80、443 反弹,失败!

捋一捋,通过漏洞获取了 webshell,该主机只开放了 HTTP 服务的 80 端口,要获得 shell 有两种方式,正向连接、反向连接。正向连接,目标上用 nc 监听的端口对攻击端不可见,只得利用类似 reGeorg 建立 HTTP 隧道;反向连接,目标上用 nc 回连攻击端 IP 及端口。前者效率低下,聚焦后者,目标允许向外访问任意 IP,但严格限制只能访问外部某几个特定端口,攻击者必须找出有效端口,否则反弹 shell 的流量无法通过防火墙到达攻击端。所以,我需要猜解出站端口。

猜解出站端口,思路与 SQLi 或 CMDi 盲注的带外信道手法差不多,即,攻击端监听某个端口,目标访问攻击端的该端口,若攻击端出现端口访问记录则说明该端口是目标允许的出站端口。思路简单,但实现不一定容易,要成功猜解出有效端口,需要关注三方面事宜:目标的端口探测命令、猜测的端口范围、攻击端的端口请求记录。

目标的端口探测命令

说到端口状态探测,第一时间想到的肯定是 nmap、masscan、nc 这类专用工具。看下目标上有没有:

毫无悬念地没有;自己装个 masscan 试试:

权限又不够,即便有权限,估计也连接内网的镜像源;那我上传个与目标架构、发行套件一致的 nmap 呢:

缺失依赖出现段错误而无法运行。

没事,除了以上那些专用工具外,linux 中还有其他挺多可选的方式,可以利用 python、perl各类脚本语言探测端口,也能借助 curl、wget 这类 HTTP 客户端实现,只要能请求服务的命令均可,但是,环境就是那么苛刻,我要啥它没啥:

好嘛,这时,我觉得基本无解,不借助第三方命令不可能达到端口探测的目的。休息一会,是喝口水去打乒乓球哇,还是去打乒乓球喝口水呢。回过头,检查之前的反弹命令是否有误:

突然,我注意到 /dev/tcp 后面的 12321 端口,( ⊙ o ⊙ )#,这不就是在探测端口么。一切皆文件!linux 下探测端口状态竟如此简单,比如,探测 baidu.com 的 443 端口,一定存活:

但由于这不是专门的端口探测工具,所以存在三个问题,一是如何批量输入端口,二是如何控制任务超时,三是如何查看探测结果。于是,我开始在本地探索解决思路。

批量端口问题。这个不难,使用 bash 的 for 语句即可:

若目标过滤大括号,可考虑:

若目标过滤小于号,可考虑:

甚至无需任何特殊字符:

解决了第一个问题。

超时控制问题。当我用 /dev/tcp 去探测某个存在的端口时,命令将立即返回,而探测某个不存活端口时,命令将挂起,直到强制退出:

所以,必须得想个法子让它超时时自动结束。超时,timeout,哇,这么简单啊。比如,本来要执行 8s 的命令:

借助 timeout命令可以实现超时控制:

第二个问题搞定。

查看探测结果。你知道,在 bash 中命令执行结果可以通过环境变量 ? 查看,成功为 0、是否非 0,换言之,我需要找个方式判断 ? 是否为 0,常规方式用 if 语句,或者,更优的方式,短路运算符 && 和 ||:

第三个问题也不是问题了。

解决了以上三个问题,我在不借助任何外部命令情况下,实现了批量探测端口:

虽然这次关于出站端口探测的思考是由 linux 的目标引起的,但从知识体系完整性考虑,我应该把 windows 系统也考虑进去。windows 命令行环境条件苛刻,几乎没有专门用于端口探测的内部命令,只能借助那些访问服务的命令间接实现,另外,我仍然需要解决批量端口、超时控制等问题。

批量输入端口,cmd 中的 for 语句可以实现:

控制任务超时,linux 有 timeout 命令,本质上,一旦超时则向目标进程发送 KILL 信号,达到控制进程运行时长的目的。win 也有 timeout,但语义完全不同,类似 linux 的 sleep 命令,没关系,参考 linux 版 timeout 原理,搭配 taskkill 命令也能间接实现:

其中,ping -n 32 127.0.0.1 模拟长时间运行的进程,timeout /t 1 为等待时长,一旦等待时长到期则用 taskkill /im ping.exe 杀死进程。虽然不及 linux 优雅,聊胜于无。

具体到端口探测,大概有 tnc 模块和 telnet 命令两种方式。

tnc 模块方式。tnc 也就是 powershell 的 Test-NetConnection 模块,专门用于网络连接性测试:

其中,tnc 默认先用 ICMP 探测 IP 存活性,通过指定 -InformationLevel 选项为 Quiet 参数,可忽略 IP 探测,只关注端口是否存活,类似 nmap 的 -Pn 选项,以提高端口探测效率。

telnet 命令方式。服务器上基本安装了 telnet,也可用于探测端口状态:

用 telnet 命令访问攻击端的 [440, 445] 的端口,每次访问限时 1s。

猜测的端口范围

目标既然允许访问外部的几个端口,一定是那些端口提供目标所需服务,那么,我没必要一开始就到 [1, 65535] 中去找有效端口,而是根据服务的常见程度,将所有端口划为几个层次,依次逐层猜解。

第一层,最常见端口。经验来看,DNS 的 53、HTTP 服务的默认端口 80、HTTPS 的 443 是三个最常见的出站端口。

win 下执行如下命令行确认出站端口:

linux 下执行:

第二层,较常见端口。大概包括如下几类:

web 服务, HTTP 的 80、HTTPS 的 443; 中间件服务,weblogic 的 7001/7002、webshpere 的 9080/9090、jboss 的 8080; 远程管理服务,SSH 的 22、telnet 的 23、SNMP 的 161、RDP 的 3389; 数据传输服务,FTP 的 21、SCP/SFTP 的 22、SMB 的 137/138/139/445; 数据库服务,mssql 的 1433、mysql 的 3306、oracle 的 1521、LDAP 的 389; 缓存服务,redis 的 6379、memcached 的 11211; 邮件服务,SMTP 的 25、POP3 的 110、IMAP 的 143; 其他服务,DNS 的 53、NTP 的 123、kerberos 的 88;

win 下探测:

linux 下探测:

第三层,top100 常见端口。nmap 默认扫描 top1000 常见端口,通过 —top-ports 选项可以指定扫描更多常见端口:

也就是说,nmap 内部梳理了一份已知服务默认端口列表,并且还能按常见程度排序,简直巴适,要获取 top100 常见端口:

win 下探测:

linux 下探测:

采用相同思路,我可以持续探测 top200、top400 常见端口。

攻击端的端口请求记录

从目标发起的端口访问请求,攻击端必须得配合记录,否则即便找到有效的出站端口,我也无法获悉。

思路一,单个逐次监听端口。对于少量端口的探测,攻击端很容易记录。比如,要验证 windows 目标的 8088 端口是否为出站端口,我先在攻击端用 nc -n -v -lp 8088 监听 8088,指定 -v 选项观察实时访问记录,再在目标上用 telnet 192.168.56.8 8088 连接攻击端的 8088 端口,最后在攻击端查看端口访问记录,若有则该端口是有效出站端口:

若无则重复以上步骤继续验证其他端口。

对于 top100 甚至 top1000 这样大规模的端口探测,当前验证目标的 80 端口,那么攻击端也要联动监听 80,验证 81 则联动监听 81,手工执行 nc 不断监听不同端口是不现实的,这就需要一个脚本,控制攻击端的监听动作和目标端的探测动作,倒是可以写个这样的脚本,但通用性不强,我得找寻更加普适性的方法。

思路二,批量捆绑监听端口。试想一下,如果能够把攻击端的多个端口流量转发至单个汇聚端口,就只需监听单个汇聚端口,目标上发起多个端口探测,只要在攻击端转发的多个端口的范围内,那么,一旦找到有效出站端口,攻击端的汇聚端口一定有访问记录。说到端口转发,系统自带的 ssh、iptables,三方的 frp、nps,这些工具都能高效实现,于是,我从这四个工具中找寻具备端口捆绑能力的那位,简单查阅资料,iptables 就是我需要的。只需一条命令行即可实现端口捆绑,如下:

sudo iptables -A PREROUTING -t nat -p tcp --dport 1:65535 -j REDIRECT --to-port 4442

这样,就把 65535 个全量端口捆绑至 4442 端口。

验证下,在攻击端将全量端口捆绑至 4442 端口:

监听 10086 端口:

靶机目标取消所有出站限制,访问攻击端的 10086 端口:

显示端口不存活!这正是端口捆绑的必然结果,因为攻击端接收到的 10086 端口访问流量已被转发至 4442 端口,而 nc 并未监听 4442,所以没有访问记录。接下来,nc 监听 4442:

目标端再次访问 10086:

你看,攻击端收到访问记录了:

验证完毕,不再需要端口捆绑,恢复先前规则:

安逸哇,这样我监听单个端口即可获取全量端口的探测记录。如果再结合结合 MSF 的 reverse_tcp_allports 载荷,甚至可以省去找寻有效端口的步骤,直接反弹 shell。

windows 环境的模拟实验

简单模拟实战中反弹 shell 的场景。先看 windows 环境。

第一步,查看环境信息。靶机 IP 为 192.168.56.9,如下:

攻击端 IP 为 192.168.56.8,如下:

第二步,配置出站策略。在操作系统自带防火墙中增加出站策略,只允许 2048 端口出站,即禁止 1-2047 及 2049-65535,规则管理界面中配置即可:

攻击端监听 2047 端口:

从目标访问攻击端的 2047 端口,结果为不存活:

攻击端重新监听 2048 端口:

从目标访问攻击端的 2048 端口,结果为存活:

说明只放行 2048 端口的出站策略已生效。

第三步,攻击端端口捆绑。为了便于接收目标发起的端口探测,将攻击端的全量端口捆绑至 4442 端口:

并在攻击端监听汇聚端口 4442:

第四步,目标端猜解出站端口。现在,我的身份恢复为攻击者,假定先前通过漏洞拿到目标 192.168.56.9 的命令执行权限,且执行结果有回显。尝试在 nmap 定义的 top100 常见端口范围内找寻允许出站的端口,很快找到 2048 为有效端口:

第五步,反弹 shell。首先,攻击端取消端口捆绑:

然后,攻击端生成反弹端口为 2048 的 ps1 脚本木马:

并启动 MSF 监听 2048 端口:

接着目标上执行 ps1 木马:

最后顺利反弹 shell:

拿下真实目标

现在,我把本地推演的思路应用到目标环境中。

第一步,攻击端捆绑端口至 12321,并监听该端口:

第二步,目标上探测 top100 常见端口,执行:

啊( ⊙ o ⊙ )啊!居然报错,不应该,难道是 webshell 中无法执行复杂的 shell 语句?不急,把它写入个脚本文件中执行看看,新建脚本文件 x.sh:

写入完整命令行:

赋予执行权限后执行:

很快即可查看到结果:

无一存活!

第三步,继续尝试 top200、top300 的端口,仍然没找到;尝试 top400:

哈哈哈哈,还真找到了它,42510,唯一允许出站的那个端口!

第四步,反弹 shell。攻击端取消端口捆绑,监听 42510 端口接收 shell:

目标向攻击端的 42510 端口反弹:

攻击端成功接收 shell:

呵呵,这下心情舒畅了,晚上整火锅。

好了,以后遇到能 ping 通外网但无法反弹的目标,得多个心眼考虑是否限制了出站端口,用上述手法尝试猜解,或许,能找到唯一的答案!

*本文原创作者:yangyangwithgnu,本文属于FreeBuf原创奖励计划,未经许可禁止转载

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-04-13,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 FreeBuf 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 目标的端口探测命令
  • 猜测的端口范围
  • 攻击端的端口请求记录
  • windows 环境的模拟实验
  • 拿下真实目标
相关产品与服务
消息队列 TDMQ
消息队列 TDMQ (Tencent Distributed Message Queue)是腾讯基于 Apache Pulsar 自研的一个云原生消息中间件系列,其中包含兼容Pulsar、RabbitMQ、RocketMQ 等协议的消息队列子产品,得益于其底层计算与存储分离的架构,TDMQ 具备良好的弹性伸缩以及故障恢复能力。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档