There are two problems here:
What if content is encoded:gzip...
Do I also need to change the header part to make the HTTP packet valid(checksums if any?)
UPDATE
Can someone with actual experience elaborate the steps involved?
I'm using winpcap and bpf tcp and src port 80 to filter the traffic,so my job lies in this callback function:
void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data)
WinPcap doesn't allow you to change a packet that was already sent.
If the packet was sent, WinPcap won't prevent it from reaching its destination.
If you want to send another response - in addition to the response that was sent - I'm not sure what you're trying to achieve.
Decompress it with a GZIP decompresser.
Remove the Content-Encoding header and add a Content-Length header representing the new length in bytes.
That said, for a better answer you'll need to supply more context in the question. This is namely a smell. What is it you're trying to achieve and for which you think that modifying the HTTP response is the right solution?
libpcap is used for capturing. If you want to do modification and injection of network packets you need another library, such as libnet.
winpcap is an odd way to try modifying a TCP stream - you don't explain why you are trying to do this, but you should probably be able to achieve this by writing your own HTTP proxy instead. That way, you get presented with a straight datastream you can intercept, log and modify to your heart's content. Once you do that, strip out Accept-Encoding from the request headers, then you'll never need to deal with gzipped responses in the first place.
There are no HTTP checksums, but the lower layers do have checksums; by operating on the application level as a proxy server, you let the network stack deal with all this for you.
Related
I have a simple networking program for sending and responding to HTTP requests/responses. However, if I wanted to send a HTTP or another request via a SOCKS5 proxy, how would I go about this? I'm using C Unix sockets.
I could solve this by creating a proxy server in Linux. However, my intention is so that I can send this to a proxy server I do not own so that it can be forwarded to the destination server. I couldn't seem to find a library. I found an RFC for it which I've read https://www.rfc-editor.org/rfc/rfc1928.txt , but i'm still not 100% unsure how to format my request.
Am I supposed to send the segments for the handshakes as hex? If so, would I send a string of hex 0F3504 or \x0F \x35 \x04 or 0x0F3504? Another question is do i need to denote that header = value in the message, or does the SOCKS5 server know what header i am referring to by the position of the byte it is looking at from the message I've sent?
Any clear up would be very much appreciated
Some time ago I wrote an open source C library that may help you: https://github.com/brechtsanders/proxysocket
Maybe you can use the library. Its quite easy, just replace the connect() with stuff from the library and for the rest you can keep the rest of your code that uses the socket that is returned.
Or you can take a peek in the code to see how it's done there.
I'm a beginner to C, I've recently decided to make migrate this project to C from using Scapy/Python, solely because I want better performance. I wish to send layer 2 data, specifically beacon frames to advertise an access point.
So far I have found that I need to (or rather could) use libpcap and a Linux header called ieee80211.h that pre-defines packets, that's all I could gather from the other questions. I've found other information which says I should use raw sockets instead of libpcap? I'm not sure if this is all I need. Most of the information and tutorials I have found on Google refer to packet sniffing, not sending.
How do I define a custom frame and/or packet (e.g. a beacon frame or association request) and then simply send it to wlan0 etc.?
Thought I might update this. I used libpcap.
You just need to create a handle with your device, set it to monitor mode successfully (important), check the data link type (e.g. 802.11 with Radiotap for layer 2) then use pcap_sendpacket(handle, packetArrayContainingHex, size);. Hard part is forming legal packets that aren't rejected or dropped, taking a look in wireshark helps.
This link might help. It basically opens the driver at raw packet level and creates the whole packet to send over the wire, as your question suggests.
I want to modify packet header(IP header, TCP Header) before the host send them into the network.
For example, if I'm using firefox for browsing, then I want to intercept all the packets from firefox and modify the IP/TCP header and then send them into the network.
so basically, there are two requirements:
1 intercept all the packets from firefox(but not other programs). if this is not possible, is it possible to intercept the packets from a specific port or ip/port pair
2 modify the IP/TCP header and then inject them into the network
are there ways, APIs to achieve this?
how about libpcap?
are there similar source code snippets?
I'm working with linux c
thanks!
To modify the packets, it is better as simple as injecting the packet which is modified into your network.
C has a library libnet which does every thing related to packet injection.
Python has scapy to inject the packets .
Now you can do quite interesting things , with libent and scapy , instead of modifying your packet ip/tcp headers , perform arp spoofing and then inject falsify packets and redirect them to the victim.
Libpcap is used for capturing packets but not for modifying packets . So you can build your own sniffer using libpcap , but to inject/modify packets you need to use libnet .
To make life simpler , there are tools like burp suite etc..where you can modify the http headers only before forwarding it .
Razorback is an open source API for deep packet injection.
You can find the source at:
http://sourceforge.net/projects/razorbacktm/files/Razorback/
You can also request them for the source code for their proposed system.
http://www.icir.org/vern/papers/pktd-pam03.pdf
it should be for you Network packet capturing for Linux.
But it seems to intercept all process in the system.
maybe you can use
#include <sys/ptrace.h>
long ptrace (enum __ptrace_request request,
pid_t pid,
void *addr,
void *data);
and hook send(2) or recv(2) to modify the tcp header.
I am trying to write a proxy server in C language under Linux. It was working fine (I had the perception that it was working fine) until I tried it for streaming media.
Lemme first tell the problem and then I'll jump onto streaming media.
To read the incoming data from the website and forward it to the actual client I do this
count = read(websitefd,buffer,BUFSIZ);
write(clientfd,buffer,count);`
in a continuous while loop until I read up all the data on that socket.
Now the problem is if the actual website sends an HTTP packet with content length field as 1025 bytes and other part of data in other packets then still I always wait for BUFSIZ(8192 bytes) and then I send 8192 bytes to the client machine all together. for normal octet-stream it works fine even though I know its not the right method, because I should forward the packets same as the actual server. So if actual server sends me 2 packet of sizes 1024 and 1024 bytes I send the client a packet of 2048 bytes with the first packet with the HTTP header saying that the content length is 900 bytes (rest all being the http header assuming) but actually I forward a packet of 2048 bytes to client. For Content Type: application/octet-stream it just downloads the whole thing and displays it either as image or html text or asks me to save it.
When the client request for a streaming media, because of the above reason the client is not able to play the video. So what should I do now ? Thanks for reading my question. Please help me out. :)
First, I strongly recommend using an existing proxy server as the base of any proxy system. The HTTP standard is quite complex, much more than you realize. If you are going to implement a proxy server, read RFC 2616 at least three times first.
Second, your proxy server must parse HTTP headers to figure out how much it must send. The three main ways to know how much data to send are as follows:
If a Content-Length header is present and no Transfer-Encoding header is present: The Content-Length header specifies how much data to relay in bytes. Just go into a loop copying.
If a Transfer-Encoding: chunked header is present: You must parse the chunked transfer encoding chunk headers. This encoding is frequently used for streaming data, where the total size is not known ahead of time. It's also often used for dynamic data generated by scripts.
If some other Transfer-Encoding header is present: Close the connection and report a 500 error, unless you know what that encoding is.
If a Content-Length header is not present, and no Transfer-Encoding header is present: Check for Connection: close (must be present, in HTTP/1.1) and Connection: keep-alive (must NOT be present in HTTP/1.0). If these conditions are violated, trigger a 500 error. Otherwise just keep passing data until the server closes the connection.
I'm deliberately making this a bit vauge - you MUST read the standard if you're implementing a proxy server from scratch, or you will certainly introduce browser incompatibilities and/or security holes! So please, don't do so. Use lighttpd or varnish or something as the core proxy server, and just write a plugin for whatever functionality you need.
I suppose media is transferred in chunks, i.e no Content-Length is present and data is sent until finished.
As bdonlan said please read how chunked data works,
And i agree HTTP is pretty nasty (due to many changes and interpretations in time)
as part of my project, I'm trying to send IP packets that contain HTTP requests to Google. I'm using Winpcap library and VC++. Currently, I have the TCP three-way handshaing packets done, but I'm stuck on sending the actual HTTP request packet after I send the TCP ACK packet. When I capture the packets using wireshark, this packet is marked "TCP segment of a Reassembled PDU". The protocol column is 'TCP' not 'HTTP' also. What's wrong? How would I send HTTP packets in this way?
You aren't necessarily doing anything wrong.
By default, Wireshark hands the TCP data to a higher level protocol handler - in this case, one that tries to reassemble entire HTTP requests and responses. It attaches the reassembled message to the final packet in the sequence, and labels the other packets with "TCP segment of a reassembled PDU":
You can disable this reassembly feature to examine the individual packets:
Edit -> Preferences -> Protocols -> TCP
Uncheck "Allow subdissector to reassemble TCP streams"
Why are you using WinPCap to send the packets? You should be using normal sockets instead. Better, use a socket library that implements the HTTP protocol for you, such as curl, or even Microsoft's own WinInet or WinHTTP APIs.
I would highly recommend that you learn the basis of the HTTP protocol before you try this if you're planning on extending this. Mess with doing raw sockets and throwing get requests; read some source code.
However, I wouldn't really see the point of pcap. You should be able to use the Wininet library if you don't want to have to code the actual socket:Wininet lib
However, if you're wanting to code raw sockets, I would go ahead and use winsocks. The difference between HTTP and TCP is hard for some to understand; HTTP is BASED on TCP, so they are technically all in the same, TCP is used for quite literally thousands of applications. Most of the connections on your computer are TCP.
If you're trying to intercept a connection as a MITM attack with a pcap program to send an HTTP request, I would probably learn some programming in Pcap. There are numerous tutorials for this, such as this one.
PS: Look up a winsocks tutorial as it's quite hard to understand for beginners. Also, winpcap isn't supported on all systems, and it can be (in some cases) a pain to install. It would honestly be better to use winsocks to do this. Wininet has much more support, and I (don't hold me on this) believe that all of the W2K+ builds all have wininet, so for compatability (which I don't really think is a problem for you) issues I would use wininet or winsocks.
Probably you are not finishing the request with \r\n twice.
If you send the GET / HTTP/1.0\r\n string, you will not receive any packets.
You must send this string: GET / HTTP/1.0\r\n\r\n.