Alter packet to secure it with AEH/ ESP - c

I am currently new to this field and did some research on raw socket programming and packet injection and sniffing but could come across my requirement which is to inject a packet with ESP and AEH headers. (To intercept an insecure packet and apply either ESP or AEH).
The tutorials I found mostly talks about injecting packets into networks/ altering the header such as, https://gist.github.com/securitytube/5325122 , http://www.youtube.com/watch?v=V6CohFrRNTo , how to modify packet header(IP header, TCP Header) before the host send them into the network . I must be looking at the wrong topics.
I would be really grateful if you experts could point me to any API or opensource project that could be used to perform this task.

First you need to capture an IP packet then mangle it and then send it and avoid the original packet be sent.
You can use libpcap library to capture packets, then mangle them and add your ESP and AH headers (and do all the work IPSec does) and then send it using raw INET sockets (instead of packet sockets, which one of your links shows, with packet socket you need to add your own IP headers). For raw INET sockets:
socket(AF_INET, SOCK_RAW, int protocol);
You can also use Netfilter and add iptable rules to drop outgoing/incoming packets or send them to your handler. This is a very strong tool and you can do everything with it.
I assume you know you will have to implement management of Security Associations and directly handle hash algorithms, authentications algorithms, encryption algorithms, etc.

Related

When using PF_PACKET type of socket, what does PACKET_ADD_MEMBERSHIP?

When using a PF_PACKET type of socket with protocol type ETH_P_IP, the man packet documentation talks about a socket option for multicast. The socket option is PACKET_ADD_MEMBERSHIP.
Assuming you use PACKET_ADD_MEMBERSHIP socket option on a PF_PACKET socket correctly, what features and benefits and use cases is this socket option for?
Right now I receive all incoming IP packets so I look at each packet to see if it has the correct IP dst-address and UDP dst-port and I skip over all the other packets. Would using PACKET_ADD_MEMBERSHIP socket option mean I don't need to do my own filter because the kernel or driver would filter for me?
I dug into the linux-kernel source and traced down the code a little bit. I found that the ethernet-mac-address you pass in via setsockopt() is added to a list of ethernet-mac-addresses. And then the list is sent to the network-device hardware to do something... but I can't find any authoritative documentation telling me what happens next.
My educated guess is that the ethernet-mac-address list is used by the hardware to filter at the layer-2 ethernet protocol (i.e. the hardware only accepts packets that have a destination ethernet-address that matches one on the list). If there is some good documentation I would welcome that.
(I'm more familiar with TCP/UDP sockets and so this looks very similar to AF_INET type of socket's IP_ADD_MEMBERSHIP socket option... so I was expecting IGMP reports to be generated which would start multicast traffic from the router... but I found out experimentally that no IGMP reports are generated when you use this socket option.)
Your guess is correct. PACKET_ADD_MEMBERSHIP should add addresses to the NIC's hardware filter. As you've surmised, it's intended to allow you to receive multicasts for a number of different addresses without incurring the load(*) of full promiscuous mode.
(* With modern full duplex ethernet, there's generally not a lot of traffic coming to the NIC that it wouldn't want to receive anyway, unless it's in a virtualized environment.)
Note that there is also a separate PACKET_MR_UNICAST which does not appear in the packet(7) man page but works analogously. I would use the appropriate one (unicast vs multicast) for the type of address you're filtering on, as it's conceivable (though unlikely) that a driver would refuse to put a unicast address into the multicast filtering table.
All that being said, you'll still need to keep your software filtering as backup. There are some older drivers that don't implement MAC filtering at all (particularly for multiple unicast addresses). The core kernel or the driver handles this by simply turning on promiscuous mode if the feature isn't available.
As for the relationship with IP_ADD_MEMBERSHIP, the IP_ADD_MEMBERSHIP code will automatically construct the appropriate multicast MAC address and add it to the interface. See ip_mc_filter_add.

Raw sockets linux

May be the question is a bit stupid, but I'll ask it. I read a lot about raw sockets in network, have seen several examples. So, basically with raw sockets it's possible to build own stack of headers, like stack = IP + TCP/UDP + OWN_HEADER. My question is, is it possible to get some kind of ready frame of first two(IP + TCP/UDP) from the linux kernel and then just append own header to them? The operating system in question is linux and the language is C.
I cannot find any function which can do such a thing, but may be I'm digging in a wrong direction.
I would rely on existing protocols (i.e., UDP for best-effort and TCP for reliable) and encapsulate my own header inside them. In practice, this means embed your own protocol over a standard UDP/TCP connection. This way, you can use existing kernel and user-level tools.
If you want to do the other way around (i.e., UDP/TCP encapsulated in your own header) you have to design/implement your own protocol in the linux kernel, which is quite complicated.
No, that is not possible for raw sockets.
You either sit on top of TCP/UDP, in which case the IP stack takes care of the headers and the operation of the protocol(e.g. in the case of TCP how to slice up your data into segments),
So, if you want to add stuff on top of TCP or UDP, that's what a normal TCP or UDP socket is for.
Or you sit on top of IP, in which case it is your responsibility to craft whatever you want on top of IP - That's what a raw socket is for. Though in this case you can construct the IP header as well, or opt in to have the IP stack generate the IP header too.
I don't think you understand what RAW sockets are for. With RAW sockets (s = socket (AF_INET, SOCK_RAW, IPPROTO_RAW)) you have to build everything above the physical layer yourself.
That means you build the IP header (if you want to build your protocol on top of IP of course), you could do your own thing here with AF_PACKET. And if you want TCP, you build the TCP header yourself, and add it to the IP header. In most cases when you use RAW sockets, this is where you would start building your own protocol in place of TCP or UDP, otherwise why use RAW Sockets in the first place? IF you wanted to build your own ICMP or SCTP implementation for example, you would use RAW Sockets.
If you really want to understand how this works I suggest building your own version of "ping" (ICMP echo request implementation, in other words). Its easy to do and easy to test and will force you to get your hands a little dirty.
The man pages cover this entire topic quite well if you ask me. Start at socket.

How to bind a Raw Socket to a specific port?

I am currently working on a programming assignment. The assignment is to implement a client,network emulator, and server. The client passes packets to a network emulator, and the network emulator passes to the server. Vice-versa applies as well. The prerequisite for the assignment is that I may only use raw sockets. So I will create my own IP and UDP headers. I have tested my packets with wireshark. They are all correct and in the proper format(it reads them properly).
Another requirement is that the emulator, client and server all have specific ports they must be bound to. Now, I do not understand how to bind a raw socket to a specific port. All my raw sockets receive all traffic on the host address they are bound to. According to man pages, and everywhere else on the internet, including "Unix Network Programming" by Richard Stevens, this is how they are supposed to work. My teacher has not responded to any of my emails and I probably will not be able to ask him until Tuesday.I see two options in front of me. First I can use libpcap to filter from a specific device and then output to my raw socket. I feel this is way out of scope for our assignment though. Or I can filter them after I receive them from the socket. This apparently has a lot of overhead because all the packets are being copied/moved through the kernel. At least, that is my understanding(please feel free to correct me if i'm wrong).
So my question is:
Is their an option or something I can set for this? Where the raw socket will bind to a port? Have I missed something obvious?
Thank you for your time.
--
The man page for raw(7) says:
A raw socket can be bound to a specific local address using the bind(2) call. If it isn't bound all packets with the specified IP protocol are received. In addition a RAW socket can be bound to a specific network device using SO_BINDTODEVICE; see socket(7).
Edit: You cannot bind a raw socket to a specific port because "port" is a concept in TCP and UDP, not IP. Look at the header diagrams for those three protocols and it should become obvious: you are working at a lower level, where the concept of port is not known.
I would think you're expected to filter the packets in your software. It sounds like the exercise is to learn what the different components of the IP stack do by recreating a simplified piece of it in user space. Normally in the kernel, the IP code would process all packets, verify the IP headers, reassemble fragments, and check the protocol field. If the protocol field is 17 (udp), then it passes it to the UDP code (every UDP packet). It's up to the UDP code to then validate the UDP header and determine if any applications are interested in them based on the destination port.
I imagine your project is expected to more or less mimic this process. Obviously none of it will be as efficient as doing it in the kernel, but since the assignment is to write (part of) an IP stack in user-space, I'd guess efficiency isn't the point of the exercise.

Accessing data link layer packets

I want to create a socket for accessing IPv4 packets from data link layer. From unix network programming V1,
socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_IP))
1)I am implementing a dhcp client, is this the correct way of doing that? (means without accessing data link layer, i cannot receive reply from dhcp server) or is there any other easier way?
also, since this socket will receive all IPv4 packets destined for my system, how should I distinguish dhcp reply packet from other packets?
2)please suggest me a good link/tuorial for network programming with data link layer access. In the above book, it is not detailed description.
This is my code
Did you tried looking at PCAP libraries?
It provides nice filtering functions on IP, port and other things.
Do you need the link layer headers too? If so, You need to use SOCK_RAW—SOCK_DGRAM will remove the link layer header before feeding it to your application.
You can identify DHCP requests by the source and destination ports, since DHCP generates traffic on UDP ports 67 and 68.

Filtering UDP loopback on Linux in C

I have an application bound to eth0, sending UDP packets on port A to 255.255.255.255. At the same time, I have a UDP server bound to eth0, 0.0.0.0 and port A.
What I want to do is to make sure that the server won't receive messages generated by the application (handled purely in software by the kernel) but it will receive messages generated by other hosts in the network.
I can't change the payload of UDP packets nor add any headers to it.
I've already implemented a solution using RTNETLINK to fetch all IP addresses of the machine I'm sitting on (and filter basing on address from recvfrom()), but I'm wondering if there might be a simpler and cleaner solution.
EDIT: I thought about something like tagging the skb - the tag would disappear after leaving a physical interface, but wouldn't if it's just routed in the software.
Any ideas?
If you can patch your Linux kernel, you could use a setsockopt() option for choosing if you want to loopback the broadcast packets you're sending or not.
This patch reuse the IP_MULTICAST_LOOP option exactly for this purpose.
Also, instead of "messing" with the IP_MULTICAST_LOOP option, you could easily add your own setsockopt() option, maybe called IP_BROADCAST_NO_LOOP. This would guarantee that you're not changing the behavior for any other application.
You can compute a checksum or CRC (better) over the payload and filter against this.
You can do this at the firewall level by dropping packets to broadcast address port A with source address of the eth0.

Resources