I have been experimenting with ARP spoofing on my local LAN.
Now, I would like to try to write in C a simple sniffer, but I have some questions:
If the ARP spoofing has been a success my NIC will receive and not drop packets that have my MAC ADDRESS (Layer 2) but a DST IP (Layer 3) which is not mine. What kind of sockets can I use to take those packets? I think some sort of RAW sockets, but an example or a good reference would be appreciated.
Is there a way (throw C) to put my NIC in promiscuous mode in order to force it to pick up packets with different MAC?
After some investigation I think the best way is to use libcap http://man7.org/linux/man-pages/man3/libcap.3.html, which comes with good routine to call.
Related
I'm an Automation Developer and lately I've taken it upon myself to control an IP Phone on my desk (Cisco 7940).
I have a third party application that can control the IP phone with SCCP (Skinny) packets. Through Wireshark, I see that the application will send 4 unique SCCP packets and then receives a TCP ACK message.
SCCP is not very well known, but it looks like this:
Ethernet( IP( TCP( SCCP( ))))
Using a Python packet builder: Scapy, I've been able to send the same 4 packets to the IP Phone, however I never get the ACK. In my packets, I have correctly set the sequence, port and acknowledge values in the TCP header. The ID field in the IP header is also correct.
The only thing I can imagine wrong is that it takes Python a little more than a full second to send the four packets. Whereas the application takes significantly less time. I've tried raising the priority for the Python shell with no luck.
Does anyone have an idea why I may not be receiving the ACK back?
This website may be helpful in debugging why on your machine you aren't seeing the traffic you expect, and taking steps to modify your environment to produce the desired output.
Normally, the Linux kernel takes care of setting up and sending and
receiving network traffic. It automatically sets appropriate header
values and even knows how to complete a TCP 3 way handshake. Uising
the kernel services in this way is using a "cooked" socket.
Scapy does not use these kernel services. It creates a "raw" socket. The
entire TCP/IP stack of the OS is circumvented. Because of this, Scapy
give us compete control over the traffic. Traffic to and from Scapy
will not be filtered by iptables. Also, we will have to take care of
the TCP 3 way handshake ourselves.
http://www.packetlevel.ch/html/scapy/scapy3way.html
I have a Linux router on which I use CONFIG_IP_NF_QUEUE, iptables userland and Perl module IPTables::IPv4::IPQueue to examine H323 - H.225 packets and pass or drop then. I have need to not only accept or drop the packet but to modify it, to be more specific I would like to change the IP address of the MCU (in the packet) returned from the H323 gatekeeper to the client.
This would require me to examine the TCP packet body and change the IP address in the packet body. Anyone know how can I accomplish this? Is there any open source layer 7 router capable of doing this?
In the old days I've used "ip masquerade" to do something similar to what you are describing.
http://www.tldp.org/HOWTO/IP-Masquerade-HOWTO/supported-client-software.html
But the best solution is to place a gatekeeper as a proxy. In that way you are not fooling the protocol, you are actually remaking the call.
I would look for gnugk routed mode here:
http://www.gnugk.org/h323-proxy.html
If you have already got the IP packet, which from your statement you have succeeded in doing so, I don't see the problem to change the IP address of the packet before passing it on.
Just do some bits manipulation to change the IP address in IP header (also update the IP checksum). Also note that you have to update the TCP header checksum as its calculation involves a pseudo-header that includes IP addresses.
Just read RFC 791 and RFC 793 would give you an idea on how to do this. It's pretty straightforward.
For reasons I can't go into, our system uses a very small MTU (128 bytes). These embedded devices are on a completely separate network so no internet access or interaction with other devices.
Obviously, TCP takes up 66 bytes per packet leaving not very much for payload.
After some googling, I came across IPCOMP which looks like it may help in reducing the amount of traffic on the network.
My question is how can I enable this? Is there a setsockopt, or do I need a special driver?
The only example I've seen is:
socket(PF_INET, SOCK_RAW, IPPROTO_COMP)
but this means I need to create the IP/TCP/payload manually.
Anyone have experience with this.
EDIT: Perhaps a better method would be to enable cslip or ppp on this connection. I can find tutorials on enabling PPP on a serial port (for dial-up modem), but nothing on enabling PPP on ethernet.
I've seen articles on PPPoE, but this seems to add MORE to the payload rather than reducing it.
Can anyone help with this?
I've played around with IP xfrm in the past but I've never tried the comp option. If you want all outgoing traffic compressed, something like this would work.
ip xfrm policy add dev eth0 dir out tmpl proto comp
Assuming that you have determined that for a given niche case, neither TCP or UDP are ideal, how would you go about writing your own IP based protocol?
For example, if you're developing on Linux, where would you look in the kernel to "hook" your protocol in?
Where would you start?
You can do this through a kernel module. I would start by reading how arp works for example. That is a simpler protocol since userspace doesn't send packets out with it directly.
The entry point for creating a new network protocol is dev_add_pack, and the code for arp can be found here.
If your protocol can be implemented directly on top of IP, then it can also be implemented wrapped in UDP packets - and the latter has the advantage that it'll pass through existing NAT devices and firewalls that would simply drop your custom protocol.
Read up on UNIX sockets and networking. It's not so much 'hooking' into the kernel, as it is opening a socket and sending your binary data over that.
I need to write a packet sniffer in Linux that detects HTTPS packet that are sent and save the url from the request. I found code for this in security-freak and ran it. This code runs and only sniffs the received packet but I need to get the sent packet in the sniffer.
How do I get the sent packet in this code?
I can't use any library like libcap (forbidden).
The code is :sniffer.c
You should be using ETH_P_ALL instead of ETH_P_IP as the protocol. ETH_P_IP only listens for incoming IP packets.
Why can't you use any library? Homework?
It's hard to answer without having examples from your code, for example how you set sll_pkttype.
The urlsnarf tool in the dnsiff suite could be worth a look.
With appropriate libpcap or DNET usage You should be able to get all network
traffic on the desired layer (protocol - 5) (also this outgoing).
But You should know that already.
You need to go through the above libraries manuals and find the appropriate filtering.