Musings Through the Lens...

View Original

Using Burp Suite as an Invisible Proxy Tunneled Over SSH

I recently had to test a REST API with Burp Suite with a couple of unusual conditions. The first was I had a thick client to talk to the API that had no understanding of proxies. I could use curl to do the same thing but the client was still something I wanted to test. The second was the only access I had to target server was via SSH to a gateway system to get into the network the target was on. I knew I could tunnel Burp over SSH and I knew I could set up Burp as an invisible proxy. There are how tos out there about doing either thing separately but I didn't find anything about doing them together. It took some trial and error with varying levels of success until I managed land at this solution that gave me the best results.

Setting Up the SSH Tunnel

The first thing to do is set up the SSH tunnel. I was using PuTTY and added dynamic port forwarding on local port 12345. Set the Source Port to 12345 and select the Dynamic radio button and clicked the Add button.

PuTTY Dynamic port forwarding

I saved the session with the other connection details I needed. Once set, I connected to the ssh gateway that allowed me to reach my target.

Setting Burp to Use the SSH Tunnel

To set Burp up to use the SSH tunnel I needed to set up an upstream proxy. This can be in either User Options or Project Options. I used the Project Options in this case. Dynamic port forwarding over SSH works as a SOCK Proxy in Burp. I set Burp to use my localhost on port 12345 as the project's SOCKS proxy.

Burp Upstream SOCKS Proxy

Now everything passing through Burp will pass through the SSH tunnel. Unfortunately, you cannot set up per target upstream proxy rules so everything will pass over the SSH tunnel but in this case that was not a problem.

Because of the way I was going to use an invisible proxy the Do DNS lookups over SOCKS proxy option wasn't going to do anything for me but I set it anyway in case I needed it for any other testing. Using it in the project settings probably meant I wouldn't need it but under user options, it would make it a general-purpose upstream SOCKS proxy I could turn on and off as needed.

What is an Invisible Proxy?

An invisible proxy is a way of fooling a client that doesn't understand proxies into connecting to the proxy instead of the intended target. You do this by editing your local hosts file and creating an entry for the target host that points to your loopback IP address.

Edited host file

Save that and now anything on your system will talk to 127.0.0.1 instead of the real target.

The next step is to set up a listener or listeners on your local system. In this case, only port 443 was needed since the API was only being served over HTTPS. (Already tested and verified in my case.) By setting up a listener on the localhost on port 443 and then forwarding it to the target I would have created an invisible proxy. If I needed other ports I could set up listeners on those ports to do the same thing.

Will an Invisible Proxy Work?

I initially tested if the invisible proxy would work by setting up another SSH tunnel from local port 443 to the target system on port 443. Then I confirmed that the client could communicate with the target via an invisible proxy and it worked well. Once I confirmed an invisible proxy would work I dropped that port 443 tunnel and moved on to setting up Burp.

Setting up Burp to be the Invisible Proxy

There were a number of possible combinations of Burp settings that could have and did work but these worked the best for me.

Set up the listener

Under Burp's Proxy Options I added a second listener. Click the Add button under Proxy Listeners and you will get this dialog box:

Add listener tab 1

Since I needed a listener on port 443 on my loopback address I entered that port and keep the Bind to address option on Loopback only.

Add listener tab 2

On the Request handling select Support invisible proxying (enable only if needed). You might think a redirect to host and port here would work but I did not get great results with that.

You could try setting up certificate options on the Certificate tab but the client I was using didn't like those options and I was able to tell it to not verify the certificates so I left those options blank.

Click OK to add the listener.

Set Hostname Resolution

The next thing I had to do is overcome the fact that everything on my system now thinks the target system's IP address is 127.0.0.1. I did this by setting up Host Name Resolution under Project Options. Hostname Resolution is near the bottom of the page. Click the Add button in this section and this dialog box appears:

Add Hostname Resolution

Enter the target name and its real IP address. (You can either determine it before you modify your hosts file or look it up via your ssh session which is what I did.) Click OK.

Once that hostname resolution was set, I had an invisible proxy setup to tunnel over SSH. The client thinks the target is my localhost. The Burp listener on port 443 intercepted all the traffic destined for the target and directed it to the proper target system via the hostname resolution. Since Burp was set up to use an upstream SOCKS proxy, all the traffic went over the dynamic port forwarding ssh tunnel.

And I was all set to begin testing.