7

Is it possible to use pwnat and SSH to establish a "peer-to-peer" SSH connection between two machines that are behind two separate firewalls/NATs?

If this is possible, what are the steps that would need to be taken to set up this functionality on a Linux machine inside of a NAT that is running an OpenSSH server, and how would a client behind a separate NAT connect?

Also, if this is possible, is this setup a major security risk? Could any arbitrary SSH client connect to the server running pwnat?

2 Answers2

4

Yes. Suppose your network looks like this:

network diagram

You want to SSH from A to B. You have sshd running on B; it is listening on on tcp://127.0.0.1:22.

B$ pwnat -s 0.0.0.0 2022 127.0.0.1:22

pwnat on B is now listening on udp://0.0.0.0:2022 and is configured to allow connections to tcp://127.0.0.1:22. It is also sending periodic ICMP echo requests to 3.3.3.3 (hardcoded IP).

A$ pwnat -c 127.0.0.1 3022 104.16.111.208 2022 127.0.0.1 22

pwnat on A is now listening on tcp://127.0.0.1:3022.

pwnat on A sends an ICMP time exceeded packet to 104.16.111.208 whose payload matches the outgoing ICMP echo requests coming from NAT B. NAT B sees that the payload matches the outgoing ICMP echo requests and forwards the ICMP time exceeded packet to B. Note that the IP header for the ICMP time exceeded packet contains NAT A's IP, 151.101.193.69, as the source address.

pwnat on B sends a UDP packet to udp://151.101.193.69:2022 with source port 2022. NAT B adds an entry in its table so in the future it will forward any UDP packets it receives from udp://151.101.193.69:2022 at udp://104.16.111.208:2022 to udp://192.168.2.10:2022. Note that many NATs will assign a different port on the external interface. If this is the case, pwnat doesn't work.

pwnat on A sends a UDP packet to udp://104.16.111.208:2022 with source port 2022. NAT A adds an entry in its table so in the future it will forward any UDP packets it receives from udp://104.16.111.208:2022 at udp://151.101.193.69:2022 to udp://192.168.1.10:2022.

NAT A receives the UDP packet that B sent, matches it in its table, and forwards it to A. NAT B receives the UDP packet that A sent, matches it in its table, and forwards it to B. A and B can now communicate freely over UDP.

A$ ssh -p 3022 127.0.0.1

pwnat on A, which is listening on tcp://127.0.0.1:3022, accepts the connection from ssh. pwnat on A sends a request to pwnat on B (via UDP) to open a tunnel to tcp://127.0.0.1:22. As this was listed as an allowed host/port pair when the pwnat on B was started, it makes the connection. The tunnel is now complete:

ssh on A --[tcp]--> pwnat on A --[udp]--> pwnat on B --[tcp]--> sshd on B

If pwnat has no bugs, then this is no different security-wise from exposing sshd to the world on a server that isn't behind a NAT. However, glancing through the source code, pwnat seems kind of hacked together and I wouldn't rely on it being secure. The worse case scenario would be arbitrary code execution on A and B as the user who's running pwnat.

Snowball
  • 533
-1

Pwnat seems to be unauthenticated which I'd consider a major security risk. If you control at least one of the two NAT/Firewalls just setup port forwarding/translation for a much more secure setup.

MacLemon
  • 502