Port-Forwarding with Windows for the Win

Published: 2021-10-14
Last Updated: 2021-10-14 06:16:04 UTC
by Xavier Mertens (Version: 1)
1 comment(s)

A feature that I use often is the port-forwarding capability implemented in the SSH protocol. It’s very convenient for pivoting inside a network or accessing a resource that is not directly reachable. Think about a management console that binds on the loopback interface of a server (which is good from a security point of view). How to access it remotely? SSH to the rescue!

Connect to the server with this command:

$ ssh -L 4443:127.0.0.1:443 user@server

Now, you are able to access the web interface via: https://127.0.0.1:4443/.

If you need to pivot internally, use “server” as a jump host:

$ ssh -L 4443:192.168.10.12:443 user@server

That's nice but what if the host you are jumping into is running Windows? How to achieve the same?

Microsoft provides an interesting tool to play with the network settings: netsh.exe[1]. I like to refer to it as the "Windows network Swiss army knife tool"! You can achieve the same as SSH using the "portproxy" feature.

Example:

C:\> netsh interface portproxy add v4tov4 listenport=8080 connectport=80 connectaddress=127.0.0.1
C:\> netsh advfirewall firewall add rule name="Port Forward 8080" protocol=TCP localport=8080 action=allow dir=IN

This forward incoming requests on port 8080 to the loopback on port 80 (line 1). Note that you need to allow the traffic in the Windows firewall (line2). Let's test by launching a quick Python web server:

C:\> python -m http.server 80
Serving HTTP on :: port 80 (http://[::]:80/) ...

From another computer, try to access the webserver:

$ curl -v http://192.168.131.2:8080
* Trying 192.168.131.2...
* TCP_NODELAY set
* Connected to 192.168.131.2 (192.168.131.2) port 8080 (#0)
> GET / HTTP/1.1
> Host: 192.168.131.2:8080
> User-Agent: User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; .NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)
> Referer: http://www.google.com/search?hl=en&q=web&aq=f&oq=&aqi=g1
> Accept: image/gif, image/jpeg, image/pjpeg, image/pjpeg, application/x-shockwave-flash, application/x-ms-application, application/x-ms-xbap, application/vnd.ms-xpsdocument, application/xaml+xml, */*
> Accept-Language: en-us
> Connection: Keep-Alive
>
* HTTP 1.0, assume close after body
< HTTP/1.0 200 OK
< Server: SimpleHTTP/0.6 Python/3.9.7
< Date: Thu, 14 Oct 2021 05:02:35 GMT
< Content-type: text/html; charset=utf-8
< Content-Length: 253873
<
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
...

The Python webserver will log this:

::ffff:127.0.0.1 - - [14/Oct/2021 06:02:35] "GET / HTTP/1.1" 200 -

Now, let's try to access a remote resource:

C:\> netsh interface portproxy add v4tov4 listenport=4443 connectport=443 connectaddress=142.250.181.238
C:\> netsh advfirewall firewall add rule name="Open port 4443" protocol=TCP localport=4443 action=allow dir=IN

This will allow us to access Google through the Windows host:

$ curl -k https://192.168.131.2:4443
<HTML><HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8">
<TITLE>301 Moved</TITLE></HEAD><BODY>
<H1>301 Moved</H1>
The document has moved
<A HREF="http://www.google.com:4443/">here</A>.
</BODY></HTML>

This technique is interesting for both attackers and defenders! From an attacker's point of view, you can easily pivot inside a network and cover your tracks. From a defender's perspective, you can quickly access a resource without reconfiguring it (for example if listening to the loopback interface only).

From a forensics point of view, keep in mind that an attacker will easily hide suspicious processes because all the connections will appear to come from svchost! (like a native system call doing the job). This is nice to defeat Sysmon rules trying to detect network connections performed by non-regular processes. You will see the connections showing up as:

Service Name : iphlpsvc
Display Name : IP Helper
Binary Path  : svchost.exe -k NetSvcs

When investigating suspicious network traffic, you can always check if portproxy has been configured:

C:\> netsh interface portproxy show all

Listen on ipv4:             Connect to ipv4:

Address         Port        Address         Port
--------------- ----------  --------------- ----------
*               8080        127.0.0.1       80
*               4443        142.250.181.238 443

If you already used this technique or if you've practical cases, feel free to share in the comments!

[1] https://docs.microsoft.com/en-us/windows-server/networking/technologies/netsh/netsh-contexts

Xavier Mertens (@xme)
Senior ISC Handler - Freelance Cyber Security Consultant
PGP Key

1 comment(s)

Comments

Very interesting read! Thanks for that and bringing awareness for that possibility to us!

Diary Archives