During a recent penetration test I found a Windows host running a web application that let me execute code via an SQL injection error. The host was a Windows 2003 Server with an SQL Server 2005. It was part of a local area network (LAN), and my intention was to use it to pivot to other hosts on the LAN, up to create me an account of “Domain Administrator” and take possession of the entire Network .
At this point, my attack vector was very clear:
- Upload and run a meterpreter payload to get a remote session.
- Escalate privileges on the remote host.
- Capture the “hash” of the Administrator to use it on other hosts.
- Use a “Delegation Auth Token” of a Domain Admin user to impersonate it, and use it to create a Domain Administrator user.
- Use the host as gateway to access other hosts and servers on LAN.
By testing the above attack vector, some problems were detected that had to be solved to achieve the ultimate goal.
The main problem was that after getting up one reverse payload of “meterpreter” in the host and run it, the reverse connection did not reach its destination.
My first thought was that a firewall was blocking access to unusual ports, so I repeated the process this time using a payload trying to connect to port 80 of my machine, but neither worked.
Same test using “netcat” worked, so I figured out that problem was the firewall blocking “meterpreter” packages probably for being a “Deep Inspection Firewall” with the signatures of “meterpreter” in its signature file.
To solve the problem, I used encryption, since a firewall can just inspect the packets in clear, but not encrypted. To ensure packets were encrypted end-to-end (from compromised machine to my local machine), I used an SSH tunnel, successfully achieving my goal of bypass that security barrier.
In this article I will try to explain step by step all the processes involved to bypass the “deep inspection firewall” and achieve a meterpreter session with the remote host.
How to upload the payload?
When we have access to a Linux system, usually have no problem to upload files to, because normally any Linux distribution comes with “wget” or “curl”, so we just need a web server to publish the binaries and download them using any of these tools.
But in Windows, things are different. By default we do not have any of these tools or similar ones. We could try to open “Internet Explorer” or “Firefox” if installed to download the file, but there is a danger that the program remains pending user interaction and not being on the screen would be a problem with that.
So what I did (sure there are more ways) was to use the command “ftp” from windows.
By default the “ftp” is an interactive program. When executed asks for a username and password to log in. Once you logged in, the wanted orders or commands can be introduced, ending the session with a “bye”.
But the “ftp” for Windows provides the ability to use it in a non-interactively way, passing in a text file all the strings that you need to send to the FTP Server. This is achieved with “-s file.txt”.
These are the steps I used to upload the files:
- First I leave a file called “met.exe” (reverse meterpreter payload) in a public ftp.
- Using the SQL injection I found, inject the following system command:
The result of this is the host will connect to the FTP server, authenticate an anonymous session, execute the command “bin”, execute “get met.exe” which will download the file in the system and end the FTP session with the “bye” command.
At this moment we have the payload on the remote host, and we only need to run it with another SQL injection, and put a Metasploit “handler” on the attacker host to get a “meterpreter session”.
This is the SQL injection we would use:
The “/B” switch of the command “start” prevents opening a window of “cmd” while running the program. There could also be called simply by “met.exe”, but this would have left the process running the query, and for another injections we would have to open a new browser window, because if canceled or closed this, the “meterpreter session” would died unless it has migrated to another process.
The target network was protected with a Next Generation Firewall with DPI technology (deep packet inspection). Traffic inspection, is essentially based on signatures (unique patterns to each malware type that IDS or Antivirus manufacturers used to recognize such malware). So if it detects a malware signature in a package, block or reject the current connection and in some cases, warns the administrator.
As usual, the meterpreter “payload” signature can be found in most antivirus databases, as well as in IDS and firewalls signature database. That means in case a meterpreter reverse connection were launched from inside a Network with this type of protection, the payload should be detected and the connection would be rejected.
So, What then? how to get a meterpreter session on the remote host?
Both, firewalls and IDS inspect the packets content in clear. To bypass the inspection, the solution is to encrypt from end to end the data traveling in those packets, so these devices would not understand it.
How to make a meterpreter reverse connection over an encrypted channel from end to end passing the firewall?
This is where SSH tunnels come into play. SSH allow us to send encrypted traffic on a channel that usually firewalls allow. We need to launch an SSH connection from within the LAN to an Internet server and use that channel we created to open a reverse connection (get a shell or session on the remote machine).
First step is to analyze what we can do from the remote machine, where can we connect, what ports and protocols can we use, etc.
Analyze what allow the firewall
We know that the remote host can make connections to the Internet on port 21 (FTP), since it is precisely what we have done to upload our payload before.
Usually, many firewall configurations, block both inbound and outbound traffic on a LAN, except for certain allowed services, such as world wide web, ftp, ssh, etc. Other more permissive configurations allow any connection from inside the LAN to the Internet and just blocks the incoming traffic to a non allowed services.
We need to find what ports can we use to connect. To find out we try to connect from the remote host to our local host (with public IP address) on different ports. Usually we try the most common ports like 80 (http), 443 (https), 53 (dns), 25 (SMTP), 22 (ssh), etc. We try non standard ports like 6666 to find out if there are restrictions on outgoing connections.
To perform this procedure we upload “nc.exe” (netcat) and “plink.exe” (putty ssh client for command line) using “ftp” procedure explained before.
Then, in the local host (attacker host) put a netcat listening on a port we want to try, for example port 21.
|root@kali:~# nc -vvv -l -p 21listening on [any] 21 …|
And in the remote host using the SQL injection:
This opens a connection between remote host (any port) to local host (port 21) and spawns a “cmd.exe”, giving us a “remote shell”.
From this shell, we can execute commands more conveniently than using SQL injection.
To see what ports we can use, just repeat the procedure trying other ports.
To achieve our final goal, we need at least two ports, cause we need two different sessions, one to create the ssh tunnel, and another to execute the payload.
Surely someone asks why would we do this if we already have a remote shell on the victim host?. The answer is easy. There are different techniques that allow us to escalate privileges and pivot to other systems, but a meterpreter session makes things easier, both to escalate (with getsystem) as to pivot, using the session as “gateway” to the victim’s LAN.
In the present case, after making several tests with “netcat” I could see that from inside the LAN had unrestricted access to the Internet.
So we just need to open an SSH tunnel from the LAN (Windows compromised host with plink.exe) to the Internet (OpenSSH server in our attacking Kali Linux) and launch the “meterpreter” payload through that tunnel.
Well, suppose the following scenario (for demo purposes we use two private IP address ranges. 10.10.0.x stands for public addresses):
- Public IP attacker machine: 10.10.0.10
- Firewall public IP: 10.10.0.20
- Network IP LAN: 192.168.65.0/24
- Private IP Firewall: 192.168.65.254
- Private IP from host behind the firewall: 192.168.65.10
- Private IP from second host behind the firewall: 192.168.65.15
First we create our meterpreter payload pointing to port 6666 of 127.0.0.1 (localhost). This “payload” when invoked from a Windows host will make a connection to itself (127.0.0.1) on port 6666.
We upload this payload, “plink.exe” and “nc.exe” to the victim host. Once uploaded the three files, first make a connection with “netcat” to have a console where execute commands cause will always be more comfortable than any “SQL injection” or “PHP Shell”.
Note that the connection to our host comes from 10.10.0.20, but the IP of the remote host is 192.168.65.10. That is cause the host is behind a NAT Firewall.
Now using “plink.exe” we must create an SSH tunnel to connect the port 6666 of the remote host (compromised host) to port 6666 on the local host (port numbers can be any, but then you have to create the payload to use those you decide).
Once the SSH connection established, you can see port 6666 in windows machine in “LISTENING” state.
Now on the local host (attacker), we set up a Metasploit “handler” with the same “payload” that we have created and uploaded to the windows box listening on port 6666 (the port that we configured in the ssh tunnel). As “LHOST” put the IP of the local host because the connection to the “handler” will come through the tunnel and therefore will be from the end of the tunnel on the host itself to port 6666.
Once the entire stage set, just execute the payload “met.exe” on the remote box. Once executed, the “handler” on the local host will receive the connection and send the “stage” for opening the session. The following picture shows it.
BINGO!!! We have a “meterpreter” session on the remote host bypassing the next generation Firewall.
As seen in the image, Metasploit sees the connection coming from 10.10.0.10 (the IP of the host itself). This is because the connection comes through the SSH tunnel.
Once we achieve our goal, we can use this session to pivot and try to attack other boxes on the local network 192.168.65.0/24, but this is out of the scope of this post.
I hope you enjoy the reading.