home page (more projects) || twitter @samykamkar || email || samy kamkar
DESCRIPTION
pwnat, pronounced "poe-nat", is a tool that allows any number of clients behind NATs to communicate with a server behind a separate NAT with *no* port forwarding *no* DMZ setup, and *no* 3rd party involvement. The server does not need to know anything about the clients trying to connect. Simply put, this is a proxy server that works behind a NAT, even when the client is behind a different NAT, without any 3rd party or network changes. There is no middle man, no proxy, no 3rd party, no UPnP/STUN/ICE required, no spoofing, and no DNS tricks. More importantly, the client can then connect to any host or port on any remote host or to a fixed host and port decided by the server. Researched and developed by Samy Kamkar. Read the paper, "Autonomous NAT Traversal", joint work with Christian Grothoff, Nathan S. Evans, and Andreas Müller published by IEEE at the IEEE P2P'10 Conference (bib, pdf) pwnat is based off of the UDP tunneling software by Daniel Meekins, udptunnel, and my original chownat.DOWNLOAD
pwnat will work on most *nix operating systems, and potentially Windows via cygwin. Tested on Linux and OS X. latest source available from github or download the zipSYNOPSIS
usage: ./pwnat <-s | -c> <args> -c client mode <args>: [local ip] <local port> <proxy host> [proxy port (def:2222)] <remote host> <remote port> -s server mode <args>: [local ip] [proxy port (def:2222)] [[allowed host]:[allowed port] ...] -6 use IPv6 -v show debug output (up to 2) -h show help and exit Example usage below.FAQ
Ok, so does this really work? Yes. Try it! I'm confused. This can't work. You should be, and it does work. But it can't. My NAT blocks incoming packets and so will the other. I know. But how?! Great question! I thought you'd never ask. Look below at HOW DOES IT WORK? Does this use DNS for anything? No. Do I need to setup port forwarding or a DMZ on either end? No. Is there some sort of proxy or 3rd party that tunnels information between the two NATs at any point? No. The connection is entirely direct, client to server. Will this work behind my corporate NAT and firewall? This will work behind many NATs and firewalls, but not all. What uses does this have? This will allow you to tunnel any service that you want to run (http, ssh, VPN, quake server, IRC, ftp, etc.) through your NAT, or proxy into other remote servers. What if one or both ends aren't behind a NAT? Everything will work just as well. You can use pwnat to tunnel TCP payload over UDP if you wish; no NATs are necessary. Does the server have to specify the client host? No! The server doesn't know the client IP address until the client attempts to connect, penetrating the NAT using this unique method. The server does need to have any unique prior knowledge about the client.HOW DOES IT WORK?
My method of penetrating NATs is two-fold which I will describe below. In order for the full tunnel to be established, the client side needs to know the public IP address of the server, and the server needs to learn the public IP address of the client. However, in a true client-server model, the server doesn't know the client IP until the client connects, and NATs will normally drop unknown incoming packets. In pwnat, the configuration is the same, the server does not need to know the client IP address. Here is how the pwnat server first learns the IP address of the client: I get around this by having the client "pretend" to be a random hop on the Internet. I'm essentially using the same technology a traceroute uses to detect hops on the Internet, but I'm doing the reverse in order to penetrate the NAT exploiting the stateful translation tables. Specifically, when the server starts up, it begins sending fixed ICMP echo request packets to the fixed address 3.3.3.3. We expect that these packets won't be returned. Now, 3.3.3.3 is *not* a host we have any access to, nor will we end up spoofing it. Instead, when a client wants to connect, the client (which knows the server IP address) sends an ICMP Time Exceeded packet to the server. The ICMP packet includes the "original" fixed packet that the server was sending to 3.3.3.3. The packet is INSIDE the computer. This harcoded packet is built into pwnat and acts as an identifier for pwnat. Why? Well, the client is pretending to be a hop on the Internet, politely telling the server that its original "ICMP echo request" packet couldn't be delivered. Your NAT, being the gapingly open device it is, is nice enough to notice that the packet *inside* the ICMP time exceeded packet matches the packet the server sent out. Your NAT then forwards the ICMP time exceeded back to the server behind the NAT, *including* the full IP header from the client, thus allowing the server to know what the client IP address is! Server (1.2.3.4): ICMP Echo Request -> 3.3.3.3 ... Server (1.2.3.4): ICMP Echo Request -> 3.3.3.3 ... Server (1.2.3.4): ICMP Echo Request -> 3.3.3.3 ... every 30 seconds ... At this stage, a client wishes to connect Client (6.7.8.9): ICMP Time Exceeded (includes ICMP Echo Request to 3.3.3.3) -> 1.2.3.4 Server's NAT: Sees server's Echo Request in client's Time Exceeded packet, sends entire packet to server because it matches server's outgoing packet Unsure if this works? Just traceroute any host while behind your NAT. You'll notice incoming packets coming in from random IP addresses your router knows nothing about. Your router knows to send those back to you, rather than another client on your network, based off of the data inside the ICMP time exceeded packet.