How I hacked into a Telecom Network — Part 3 (Playing with Tunnels: Stealthy SSH & Dynamic Tunnels)
TLDR; Red Team Engagement for a telecom company. Got a foothold on the company’s Network Monitoring System (NMS). Sorted reverse shell issue with tunneling SSH over HTTP. Went full-on Ninja when getting SSH over HTTP. Proxied inside the network to get for internal network scan. Got access to CDRs and VLR with SS7 application.
Recap: Red Team Engagement for a Telecom company. Found interesting subdomain, did a full port scan on that subdomain, found port 12000/tcp, 14000/tcp, and 14100/tcp found a running instance of JBoss (lucky me!), exploited JBoss for RCE, implemented TCP tunnel over HTTP for Shell Stability.
For detailed information, you can check out the following links:
Part 1 — Getting the RCE
Part 2 — Playing with Tunnels: TCP Tunneling
Part 4 — Getting Access to CDRs, SS7 applications & VLRs
DISCLAIMER: This post is quite lengthy so just sit back,be patient and enjoy the ride!
In the previous part, I mentioned the steps I followed and I configured TCP Tunnel over HTTP and SSH port forwarding to access port 22/tcp of NMS server from my server using port 2222/tcp. In this blog post, I’ll show how I implemented SSH Dynamic Tunnels for further network exploitation.
Stealthy SSH Access
When you’re connected to an SSH server, the connection details are saved in a log file. To check these connection details, you can execute the ‘w’ command in *nix systems.
The command w on many Unix-like operating systems provides a quick summary of every user logged into a computer, what each user is currently doing, and what load all the activity is imposing on the computer itself. The command is a one-command combination of several other Unix programs: who, uptime, and ps -a. Source: Wikipedia
So basically, the source IP is saved which is dangerous for a red teamer. As this was a RTE, I could not take the chance of letting the admin know about my C2 location. (don’t worry, the ABPTTS shell that I used was connected from my server and I already bought a domain for IDN Homograph attacks to reduce my chances of detection)
For the stealthy connection to work, I checked the hosts file to gather more information and I found that this server is being used quite heavily inside the network.
Such a server was already being monitored so I was thinking of ways to be as stealthy as possible in such a scenario. NMS was already monitoring the network so I thought it must be monitoring itself that includes all the network connections to/from the server. This means I can’t use a normal port scan using the TCP tunnel over HTTP.
How about encrypting the communication between my server and the NMS server using SSH? But for SSH connection, my hostname/IP will be stored in the log files, and also the username would be easy to identify.
In this case, my server’s username was ‘harry’, and generating a key for this user which I’ll store in the authorized_keys file was not a good option.
And then I came up with an Idea (in steps),
- Create the user ‘nms’ (this user was already created in the NMS server) on my server.
- Change my server’s hostname from OPENVPN to [REDACTED]_NMS[REDACTED]. (the same as the NMS server)
- Generate SSH keys for ‘nms’ user on my server and copy the public key in the NMS server. (authorized_keys)
- Configure the SSH server running on NMS to enable root login (PermitRootLogin), TCP port forwarding & gateway ports. (SSH -g switch just in case)
- Configure the NMS server to act as a SOCKS proxy for my further network exploitation. (Dynamic SSH Tunnel)
- The SOCKS tunnel is encrypted now and I can use this tunnel to do an internal network scan using Metasploit.
I began by first adding the user ‘nms’ on my server so that I could generate the user-specific SSH keys.
I even changed the hostname of my server with the exact same for the NMS server so that when I log in using SSH, the logs will show a user login entry as nms@[REDACTED]_NMS[REDACTED]
Next, I generated the SSH Keys for ‘nms’ user on my server.
I also had to change the SSH configurations on the NMS server so I downloaded the sshd_config file from the server and changed few things inside.
AllowTCPForwarding: This option is used to enable TCP port forwarding via SSH.
GatewayPorts: This option enables the port binding to interfaces other than loopback on remote ports. (I’m enabling this option just in case if I want a reverse shell from other internal systems on this server which will forward the shell to me via Reverse Port Forwarding)
PermitRootLogin: This option permits the client to connect to the SSH server using ‘root’.
StrictModes: This option specifies whether SSH should check the user’s permissions in their home directory before accepting login.
Now that the configuration was done, I quickly uploaded (more like overwrite) the sshd_config file on to the NMS server.
And I also copied the SSH public key to ‘root’ user’s authorized_keys file
After everything was set, I then tried a test connection just to check if I’m able to do SSH using ‘root’ on the NMS server or not!
SSH over TCP over HTTP (SSH port forward over TCP Tunnel created over HTTP connection via ABPTTS shell (JSP))
Dynamic Port Forwarding (Dynamic SSH Tunnels)
Let’s see what Wikipedia had to say about this —
Dynamic port forwarding (DPF) is an on-demand method of traversing a firewall or NAT through the use of firewall pinholes. The goal is to enable clients to connect securely to a trusted server that acts as an intermediary for the purpose of sending/receiving data to one or many destination servers.
DPF can be implemented by setting up a local application, such as SSH, as a SOCKS proxy server, which can be used to process data transmissions through the network or over the Internet.
Once the connection is established, DPF can be used to provide additional security for a user connected to an untrusted network. Since data must pass through the secure tunnel to another server before being forwarded to its original destination, the user is protected from packet sniffing that may occur on the LAN.
So all I had to do was create a Dynamic SSH Tunnel so that the NMS server would act as a SOCKS proxy server. Some of the benefits I had for using a SOCKS tunnel:
- Got indirect access to other network devices/servers through the NMS server (NMS server becomes the gateway for me)
- Because of the Dynamic SSH Tunnel, all the traffic originating from my server to the NMS server got encrypted (used SSH connection, remember?)
- Even if a server admin sits on the NMS server and monitors the network, he won’t be able to exactly find the root cause right away. (A dedicated one would definitely join the dots)
- The connection was stable (thanks to HTTP Keep-Alive), now all these recursive tunnels were running smoothly without any connection drop because of the TCP Tunnel that I implemented over HTTP.
When I logged in to the NMS server over SSH, here’s what the ‘w’ command showed me:
Now all I had to do was create the SOCKS tunnel and which I did using the command: ssh -NfCq -D 9090 -i <private key/identity file> <user@host> -p <ssh custom port>
The ‘PermitRootLogin’ was changed in sshd_config file for this purpose (to log in to the NMS server as root).
Worried what the server admin would think about the setup? Generally, when SSH connections are opened, server admin sometimes checks the username that logged in, the authorized keys that were used to log in but most of the time, he checks the hostname/IP from where the connection was initiated.
In my case, I initiated the connection from my server where the address was 127.0.0.1 using port 2222/tcp (thanks to TCP tunnel over HTTP) to the NMS server with destination address as 127.0.0.1 (again!). Now because of this setup, all he would see is a connection initiated by the NMS server to the NMS server SSH using the authorized keys (the public key) stored as user ‘nms’ (that’s why I created the same user on my host to generate the keys) and even if the admin checked the known_hosts file, all he would see is ‘nms@[REDACTED]_NMS[REDACTED]’ user connected to the SSH with IP as 127.0.0.1 which was already a user profile in the NMS server.
To confirm the SOCKS tunnel, I checked the connection table on my server and port 9090/tcp was in the LISTEN state.
Awesome! The SOCKS Tunnel is ready!
All that was left for me was to use the SOCKS tunnel for Metasploit for further network exploitation which I’ll cover in the next post.
When you connect to a server over SSH, a pseudo TTY is automatically allocated. Of course, this doesn’t happen when you’re executing commands via SSH (one-liners). So whenever you want to tunnel through SSH or create a SOCKS tunnel, try the -T switch to disable the pseudo TTY allocation. You can also use the below command:
ssh -NTfCq -L <local port forwarding> <user@host>
ssh -NTfCq -D <Dynamic port forwarding> <user@host>
To check all the SSH switches you can refer to the SSH manual (HIGHLY RECOMMENDED!). When creating a tunnel with the switches (showed above), you can create a tunnel without a TTY allocation and the tunneled port will work just fine!
If you guys want to learn more about the techniques I used and the basic concepts behind it, you can read my books (co-authored with @himanshu_hax)