Is pwnat still an applicable solution - network-programming

I need a solution for NAT traversal to transmit RDP data across the internet. I came across the following tool and it's really amazing - pwnat.
I have tried it with the two different machines behind different router, but i am unable to make it work as explained in the above link. So is pwnat still working and if yes what could I have done wrong? It would be very helpful for me.
Note: I am using a Windows machine for testing and downloaded the Windows version from the following link:
http://www.sumitgupta.net/pwnat-windows-complied-version/

No.
I assume you know how it worked:
the server sent ICMP echo request packets to the fixed address(for example, 1.2.3.4) where no echo replies wouldn't be returned from, the client, pretending to be a hop on the Internet, sent an ICMP Time Exceeded packet to the server, expected the NAT in the front of the server to forward the ICMP time exceeded message to the server.
The picture above is from the homepage of pwnat, it's on the premise that client is not behind NAT and the original payload in time exceeded message is typically not checked by NAT implementations. If both client and server are behind NAT like this,
=========================================================================================
| CLIENT | <---> | NAT-C | <---> { internet } <---> | NAT-S | <---> | SERVER |
=========================================================================================
It rarely works nowadays mainly for 2 reasons below:
When the server sends ICMP echo request packets to the fixed address, according to RFC 3022, the identifier field in ICMP echo request header will be uniquely mapped to a query identifier of the registered IP address by NAT-S so that it can route future ICMP Echo Replies with the same query ID to the sender, so ICMP header in ICMP Query packets must be modified to replace the query ID and ICMP header checksum. RFC 3022 ICMP error packet modifications section:
In a NAPT setup, if the IP message embedded within ICMP happens to be
a TCP, UDP or ICMP Query packet, you will also need to modify the
appropriate TU port number within the TCP/UDP header or the Query
Identifier field in the ICMP Query header.
But the client doesn't know the external query ID(the code in pwnat use 0 as the identifier of original request), it sends an ICMP Time Exceeded packet to the server, even if the packet can reach NAT-S in front of the server, NAT-S can't find the active mapping for the embedded packet, most of NAT implementations will drop it.
Moreover, according to rfc 5508, when the NAT-C receives the ICMP Error packet from the Private Realm, NAT-C uses the packet embedded within the ICMP Error message (i.e., the IP packet from the client to the server) to look up the NAT Session to which the embedded packet belongs. If NAT-C does not have an active mapping for the embedded packet, the NAT-C SHOULD silently drop the ICMP Error packet. It means the ICMP Time Exceeded packet from the client wouldn't arrive at NAT-S.
So pwnat only works with basic NAT devices(rfc 1631 describes) which do simple address translation, won't work with any NAPT device which has robust NAPT implementation. And This paper does mention this problem.

Related

Libpcap ICMP Packet never responded to

I'm playing around with Libpcap trying to send a ping but whenever I send the requests they are never responded to, no errors given and it looks identical to a regular ping sent through the ping utility.
The left packet is sent through ping on the terminal and the right through my app. As far as I can tell the data field is optional so I don't include it, and the identifier/sequence numbers can be random, so they are randomised.
Am I missing something obvious here?
I notice you haven't validated your IP header checksum. Are you sure it is in fact correct? If it isn't the next router will silently drop the packet which is consistent with what you've seen. Wireshark should be able to validate the ip header checksum for you if you switch it on.

Wireshark capture suspicious outbound traffic

Norton is telling me. We have detected a large amount of suspicious outbound traffic on your system. What Wireshark filters can I use to find this traffic. How can I tell what port this suspicious outbound traffic is using?
With Wireshark, you can get an idea of the type of traffic leaving your system by first filtering on its IP address, e.g., "ip.src eq 192.168.1.100" ... where 192.168.1.100 represents your system's IP address and then viewing:
Statistics -> Protocol Hierarchy, which will give you a high-level breakdown on the type of traffic present as well as various statistics like bytes, packets, etc.
Statistics -> Conversations -> IPv4, which will tell you the amount of packets, bytes etc per IPv4 "conversation" (you may need to check the box that indicates "Limit to display filter" in order to isolate only the outbound packets from your system) You can right-click on a conversation and "apply as filter -> selected -> ..." to isolate a particular IP conversation for further analysis, and you can also look at the IPv6, TCP or UDP conversations as well by selecting those tabs instead of the IPv4 tab. The data is also sortable by whichever column you're interested in, simply click on the column heading to sort by that column. The TCP or UDP tab will indicate the respective port(s) that the traffic is communicating over.
Statistics -> Endpoints -> ... is similar to Statistics -> Conversations, but lists each endpoint separately. If you "Limit to display filter", then you will see each endpoint your system is communicated with listed on a separate row.
Analyze -> Expert Information may also provide you with some additional information about the traffic you've captured, and you can "Limit to Display Filter" there as well.
Well, this should hopefully get you started.

ICMP Checksum offload

I have a simple custom ping program echo request / echo reply....Server part is deployed in Linux and client is in Windows machine....
Both client and server side programatically calculating ICMP check sum and setting it ..All are ok .
Now I want to enable ICMP check sum offload to Network card for Server module ....I have already enabled it using ethtool
I can see for TCP, Check sum offloading happening ......But when I comment out ICMP check sum calculation part from server program hoping Network card will do for me But I am not getting any Echo reply....Though Server is receiving Echo request....It must be for wrong check sum packet being dropped...
Can anybody show me the way.
Thank you
As far as i know the NIC checksum offloading can only mangle IP/TCP/UDP frames.
I don't think ICMP frame is covered.

Request/response conversation using UDPConn

I'm trying to implement the following UDP protocol, but I'm having a little trouble figuring exactly how I should approach this.
The protocol states that I should send a particular UDP packet to a certain server, after which the server will stream (several UDP packets that are related) a response back to me, also as UDP packets. I have managed to send the UDP packet fine using the following code:
connection, error := net.DialUDP("udp", nil, endpoint)
...
if written, error := connection.Write(query.ToBytes()); error != nil {
...
} else {
log.Printf("Successfully wrote %d bytes to %s", written, connection.RemoteAddr())
}
When I use Wireshark and take a look at what's going over the wire, it looks like it sent the packet just fine (the only issue here is that I never get a reply from the server, but that's unrelated to this question).
What's the best way for me to handle the server reply in this case? Can I use the previously established connection to read server responses back (this seems unlikely to me, as it's UDP so connectionless) or should I use net.ListenUDP(...) to establish a server on the correct local address and port to read whatever the server sends back to me?
The intent of the protocol is clearly that you just use the same UDP socket to receive the reply that you used to send the request. If you have a client-side firewall, you will have to explicitly open a UDP port and bind the UDP socket to that port before you send. Otherwise just let the system choose the local port, by not binding at all.
The phrase 'the same port as was established by the intial packet' is misleading. Are they your words, or the protocol specification's? What really happens when you do the first send is that if you haven't bound the socket yet, it is automatically bound to a system-chosen port, exactly as if you had bound it to port zero.
Because of the specific protocol design, it's impossible to know on which port the server will send its reply packets. After taking a second look at the packet dumps, I noticed that the server in fact does reply, only the client immediately replies back with an ICMP message saying Destination port unreachable. So the server was trying to reply, but it couldn't because the client would not accept the packets on that port.
To solve this, I have used net.ListenUDP to listen for incoming packets immediately after the client sends the initial packet using the established connection's local address:
incomingConnection, _ := net.ListenUDP("udp", connection.LocalAddr().(*net.UDPAddr))
log.Printf("Listening for packets on %s", incomingConnection.LocalAddr())
defer incomingConnection.Close()
After which incomingConnection can be used as a Reader - for example - read the packets that the server is sending.

Why DHCP client listens on port 68?

If suppose client does not listen on 68 port,when DHCP server receives the request, it can send it to the address from where it received request (with ephemeral port chosen by client at time of sending), then why does protocol specifies client to be listening on port 68?
The main reason is that the DHCP server might broadcast the "DHCP offer" on the mac level, instead of sending it unicast to the mac address it had received the request.
If the port wasn't constant, some hosts that are listening by chance to the this same random port, will accept the packet to layer 5 - the application layer.
In other words, an application will get message from completely different application, not an healthy situation.
I just had to face the same question myself, and after some research, I found the following on the RFC 2131, which describes the DHCP protocol, under section 1.6 Design Goals:
DHCP must provide service to existing BOOTP clients
Also on the RFC 951, which describe the BOOTP protocol, we can find the following:
The UDP header contains source and destination port numbers. The
BOOTP protocol uses two reserved port numbers, 'BOOTP client' (68)
and 'BOOTP server' (67). The client sends requests using 'BOOTP
server' as the destination port; this is usually a broadcast. The
server sends replies using 'BOOTP client' as the destination port;
depending on the kernel or driver facilities in the server, this may
or may not be a broadcast (this is explained further in the section
titled 'Chicken/Egg issues' below). The reason TWO reserved ports
are used, is to avoid 'waking up' and scheduling the BOOTP server
daemons, when a bootreply must be broadcast to a client. Since the
server and other hosts won't be listening on the 'BOOTP client' port,
any such incoming broadcasts will be filtered out at the kernel
level. We could not simply allow the client to pick a 'random' port
number for the UDP source port field; since the server reply may be
broadcast, a randomly chosen port number could confuse other hosts
that happened to be listening on that port.
So the answer to the question comes from the above. DHCP clients need to use the UDP port 68, in order for the DHCP to be compatible with the BOOTP protocol and the BOOTP protocol requires a specific port for the client, since BOOTPREPLIES can be broadcasted, and if a random port was chosen for the client, it could result in the confusion of other hosts listening on the same port.
Because it's in the RFC (Request for Comments) that specifies how DHCP behaves. RFC 2131 is the document that specifies how a DHCP client and server must behave.
See here for more info on DHCP (section 4.1 in particular). See here for info on what the RFCs are.

Resources