Creating a raw packet

Dec 30, 2010 at 6:46 AM

Hi

I am trying to create a raw packet.I got the contents of the packet from wireshark.

The code snippet is:

//Contents of the raw packet

byte[] data = new byte[] { 0x00, 0x12, 0xea, 0x00, 0x00, 0xf0, 0x00, 0x01, 0x6c, 0x89, 0x30, 0xb1, 0x08, 0x00, 0x45, 0x00, 0x00, 0x46, 0x77, 0xc8, 0x00, 0x00, 0x80, 0x11, 0x3c, 0x57, 0x0a, 0xa8, 0x32, 0x65, 0x0a, 0xa8, 0x32, 0x79, 0xba, 0xc0, 0x00, 0x32, 0xcf, 0x18, 0x81, 0x0a, 0x00, 0x2a, 0x01, 0x04, 0x02, 0x03, 0xc2, 0x10, 0x0c, 0x01, 0x00, 0x00, 0x01, 0x1e, 0x0a, 0x00, 0x2a, 0x01, 0x04, 0x02, 0x03, 0xc2, 0x10, 0x0c, 0x01, 0x00, 0x00, 0x01, 0x1e, 0x0a, 0x03, 0xee, 0x19, 0x0c, 0x2e, 0x0c, 0x02, 0x00, 0x00, 0x50, 0x1c, 0x30, 0x00, 0x00, 0x03, 0x2f, 0x09, 0x55, 0x2e, 0x91, 0x00, 0x2f, 0x39, 0x0c, 0x1f };

//Raw packet is of 84 bytes but I have allocated more space

PacketSendBuffer spoofPacket = new PacketSendBuffer(100);

Packet packet = new Packet(data, DateTime.Now, DataLinkKind.Ethernet);

spoofPacket.Enqueue(packet);

communicator.Transmit(spoofPacket, true); 

--------------------------------------------------------------

For the above I am getting a System.InValidOperationException:Failed enqueueing to queue.

Can you please help me out?

Thanks


Coordinator
Dec 30, 2010 at 6:27 PM

Hi sunnynagpal,

 

First, you can send a packet directly using the communicator without a PacketSendBuffer using SendPacket().

It is more efficient to use PacketSendBuffer if you want to send multiple packets at once.

 

As far as I know (I haven't found documentation for that in WinPcap), you need to allocate 16 bytes extra for each packet in the PacketSendBuffer.

You seem to have done that, but I suggest you may try to allocate more.

 

Other than that, I can say that the WinPcap function that failed is pcap_sendqueue_queue() documented here: http://www.winpcap.org/docs/docs_412/html/group__wpcapfunc.html#ga4c57ea320d71dbfe55c5665af9db1297

It's hard to say why did it fail.

Have you tried different packets? Have you tried sending packets without PacketSendBuffer? Can you try and isolate the problem?

 

I hope this helps,

 

Boaz.

Jan 13, 2011 at 9:10 AM
Edited Jan 13, 2011 at 9:16 AM

Hi Boaz,

I'm also looking at this, but I can't figure it out right now, can you provide a sample how to send using SendPacket with TCP packets?

 

Cheers!

techguy0727

Jan 13, 2011 at 1:54 PM

Hello,

I'm quite near the same situation.

I need to send packets to my web site to test for security reasons.

In fact, its seem that i can send one packet, at least when i sniff my network, i can see the outgoing packet using the following code for sending:

 

string strContent = "GET / HTTP/1.1" + Environment.NewLine;
                strContent += "Host: mysite.com" + Environment.NewLine;
                strContent += "User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.1; fr; rv:1.9.2.13) Gecko/20101203 Firefox/3.6.13" + Environment.NewLine;
                strContent += "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8" + Environment.NewLine;
                strContent += "Accept-Language: fr,fr-fr;q=0.8,en-us;q=0.5,en;q=0.3" + Environment.NewLine;
                strContent += "Accept-Encoding: gzip,deflate " + Environment.NewLine;
                strContent += "Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7 " + Environment.NewLine;
                strContent += "Keep-Alive: 115" + Environment.NewLine;
                strContent += "Connection: keep-alive";  

byte[] data = StrToByteArray(strContent);

 

 

 

 Packet packet =
PacketBuilder.Build(DateTime.Now,
new EthernetLayer
{
Source = new MacAddress(LivePacketDeviceExtensions.GetMacAddress(myLiveDevice).ToString()),
Destination = new MacAddress("11:22:33:44:55:67"),
},
new IpV4Layer
{
Source = new IpV4Address("xx.xx.xx.xx"), // i put there my correct ip public address
Destination = new IpV4Address("xx.xx.xx.xx"),
Ttl = 64,
Identification = 100,
Protocol = IpV4Protocol.Tcp
},
                       new TcpLayer
                       {
                           DestinationPort = 80,
                           SourcePort = 55319, //SHOULD I OPEN TCPLISTENER ON THAT PORT???
                            //SequenceNumber = 3345266516, HOW TO KNOW IT???
                           //Checksum = (ushort)4102, HOW TO CALCUL IT???
                           Window = (ushort)256 //???
                       },
                       new PayloadLayer
{
Data = new Datagram(data)
});

communicator.SendPacket(packet);

 

But its seem that my server never receive this packet (no trace in server logs).

I would like to see my server respond to my tcp request.

I'm not really familiar with http protocol or other internet protocol. In fact, i'm not sure to do it the right way.

For examples, should i need to use the correct MacAddress of the destination (server)?

SequenceNumber, Checksum, what to do?

Is my string for sended data correctly formatted? 

Hope im not out of topic and hoping some answers.

Cheers


xx.xx.xx.xx
Coordinator
Jan 13, 2011 at 6:09 PM

Hi,

 

roster67 shows an example to send a packet.

Build it and send it using the PacketCommunicator. More example are available in the Developer's Guide.

 

Regarding TCP, it's a bit more tricky.

TCP is a protocol that has sessions. To open a session you need to send a TCP SYN packet (with no data), the server will reply with TCP SYN-ACK packet and then you can ACK his packet with data.

The initial sequence number can be random.

The checksum is automatically calculated if you don't put there anything and leave it null.

The window size should be set according to some TCP performance issues.

 

I suggest you read more about TCP, there are is a lot of information in the web about it.

 

Regarding HTTP, I suggest using the new HttpLayer (version 0.8.0) to build it over TCP. It should be easier.

 

Boaz.

Jan 13, 2011 at 8:29 PM

Ok for HttpLayer, i've downloaded version 0.8.0.

My problem, i've no idea how to use the abstract class HttLayer or HttpDatagram.

Could you provide a simple code for how to use HttpLayer? It will be very helpful and appreciated.

Thx

Jan 14, 2011 at 3:32 PM

Someone point me to the right direction (reflector).

There is already two derivated class from HttpLayer:

HttpRequestLayer and HttpResponseLayer.

This is the way to go, i think.

Next time, i will open my eyes for intellisense suggestion...

 

 

 

Jan 14, 2011 at 9:44 PM

Hi roster67 did you manage to get your code running? I'm also creating a component that sends a captured packets somewhat like a packet replay. Please do share me some idea how to send raw packets and correctly use the packetbuilder class.

 

Jan 15, 2011 at 8:14 AM

Hello Boaz,

Is it required that in every packet I send out to a certain host I need to send a TCP SYN first? It would not create a TCP SYN flooding detection from remote host?

Hope you can help me out from this issue.

 

Cheers!

 

Coordinator
Jan 15, 2011 at 8:19 AM

Hi techguy0727,

 

TCP SYN is needed to start a session, not during the session.

I suggest you read some TCP protocol description before trying to send such packets, TCP can be non-trivial.

 

Boaz.

Jan 15, 2011 at 9:37 AM

Hi Boaz,

Thanks from your response, however since I need to replay TCP packets how can I perform a callback whenever the remote host responded to my requests?

Also how can I set from the TcpLayer this value: Flags: 0x18 (PSH, ACK)

 

techguy0727

Jan 15, 2011 at 2:22 PM

I will quote Wiki:

<<To establish a connection, TCP uses a three-way handshake. Before a client attempts to connect with a server, the server must first bind to a port to open it up for connections: this is called a passive open. Once the passive open is established, a client may initiate an active open. To establish a connection, the three-way (or 3-step) handshake occurs:

  1. SYN: The active open is performed by the client sending a SYN to the server. It sets the segment's sequence number to a random value A.
  2. SYN-ACK: In response, the server replies with a SYN-ACK. The acknowledgment number is set to one more than the received sequence number (A + 1), and the sequence number that the server chooses for the packet is another random number, B.
  3. ACK: Finally, the client sends an ACK back to the server. The sequence number is set to the received acknowledgement value i.e. A + 1, and the acknowledgement number is set to one more than the received sequence number i.e. B + 1.

At this point, both the client and server have received an acknowledgment of the connection.>>


I'm able to send the first SYN packet using random sequence number and without Acknowledgment Number, something like that:

 

Packet packet =
        PacketBuilder.Build(DateTime.Now,
                            new EthernetLayer
                            {
                               Source = new MacAddress(LivePacketDeviceExtensions.GetMacAddress(allDevices[deviceIndex - 1]).ToString()),
                                Destination = new MacAddress(destMac)
                            },
                            new IpV4Layer
                            {
                                Source = new IpV4Address(sourceIp),
                                Destination = new IpV4Address("xx.xx.xx.xx"),
                                Ttl = 64,
                                Identification = 100,
                                Protocol = IpV4Protocol.Tcp
                            },
                            new TcpLayer
                            {
                                DestinationPort = 80,
                                SourcePort = (ushort)sourcePort,
                                ControlBits = TcpControlBits.Synchronize,
                                SequenceNumber = (uint)RandomNumber.Next(),                               
                                Window = (ushort)256 //???
                            });
                   
                    communicator.SendPacket(packet);

My server respond to this tcp request, send me a Acknowledgment Number and a sequence number (SYN-ACK).

By using an other communicator to sniff incoming packets, im able to check theses numbers.

So now, i need to send a ACK packet correctly formatted (this is how i understand it from wiki!), with the following:

 
//*** From sniffer: AcknowledgmentNumber, SequenceNumber, Mac destination in case Of...
sendAck(packet.Ethernet.IpV4.Tcp.AcknowledgmentNumber, packet.Ethernet.IpV4.Tcp.SequenceNumber, packet.Ethernet.Source);
//***

 public static void sendAck(uint sequenceNumber, uint numAccuse, MacAddress destMac)
        {
            using (communicator = selectedDevice.Open(100, // name of the device
                                                                        PacketDeviceOpenAttributes.Promiscuous, // promiscuous mode
                                                                        1000)) // read timeout
            {

                Packet packetAck =
    PacketBuilder.Build(DateTime.Now,
                       new EthernetLayer
                       {
                           Source = new MacAddress(LivePacketDeviceExtensions.GetMacAddress(allDevices[deviceIndex - 1]).ToString()),
                           Destination =destMac
                       },
                       new IpV4Layer
                       {
                           Source = new IpV4Address(myIp),
                           Destination = new IpV4Address("xx.xx.xx.xx"),
                           Ttl = 64,
                           Identification = 100,
                           Protocol = IpV4Protocol.Tcp
                       },
                       new TcpLayer
                       {
                           AcknowledgmentNumber = sequenceNumber + 1,
                           DestinationPort = 80,
                           SourcePort = 55319,
                           ControlBits = TcpControlBits.Acknowledgment,
                           SequenceNumber = numAccuse,
                           Window = (ushort)256 //???
                       });

                communicator.SendPacket(packetAck);

}

Still sniffing my network, i can see that the server keep sending me the SYN-ACK packet. Its like he never receive my ACK response or its not correctly formatted. Maybe something to do with Window property of TcpLayer.

So here Iam!

@Techguy, i think you should do it that way:

-open tcp connection with server (send a SYN packet)
-get the sequence and aknowledgment numbers
-send back the ACK correctly formatted
- then send all your saved data packets reformatted (right acknow and sequence for each, can be hard cause they seem to change?!) using this time sendbuffer

I would appreciate BOAZ if you could point me on what i do bad for the ACK response.

 

 

 

Jan 15, 2011 at 3:13 PM

Hi Roster67,

Thanks from your valuable inputs this is great! Actually I followed the same 3-way handshake process the challenge for me is to create an async call to catch the server response without creating additional communicator listener for incoming packets so that I can track down SEQ & ACK numbers correctly.

I hope sendBuffer method is a straight forward implementation.

 

 

 

 

 

 

Jan 17, 2011 at 3:17 PM

Hi Roaster67,

I followed the steps as you elaborated however I was wondering why I'm still getting the same packet after sending it to destination remote host IP where I sniffed the packets from the remote it was simply generating SYN/ACK response.

I follow this code sample:

Packet packet;
                do
                {
                    PacketCommunicatorReceiveResult result = communicator.ReceivePacket(out packet);
                    switch (result)
                    {
                        case PacketCommunicatorReceiveResult.Timeout:
                            // Timeout elapsed
                            continue;
                        case PacketCommunicatorReceiveResult.Ok:
                            Console.WriteLine(packet.Timestamp.ToString("yyyy-MM-dd hh:mm:ss.fff") + " length:" +
                                              packet.Length);
                            break;
                        default:
                            throw new InvalidOperationException("The result " + result + " shoudl never be reached here");
                    }
                } while (true);


Do I miss something here?
Coordinator
Jan 21, 2011 at 9:50 AM

Hi roster67,

 

Looking at your code, it seems your mixing ack number and sequence number.

Please make sure you send the right sequence number and acknowledgment number.

I suggest using Wireshark to look at a regular TCP connection and make sure you send the same kind of packets.

 

techguy0727,

I'm not sure I understand what problem exactly do you have.

 

Boaz