[Winpcap-users] Sending packets to own NIC

Reznicencu Sergiu sergiureznicencu at gmail.com
Wed Sep 26 15:41:44 UTC 2018


compute_tcp_checksum() calculates checksum for tcp. Set to zero the
checksum field before using this function.
getPayload() writes the tcp payload to buffer if a certain threshold is
passed(20bytes).
     header->the header got from pcap_next_ex
     data     ->pointer to where the packet data starts

getPayloadPointer() returns a pointer to where tcp payload starts (same
params as above)
getIp()/getTCP() return pointers to ip header/tcp header.

În mie., 26 sept. 2018 la 18:36, Reznicencu Sergiu <
sergiureznicencu at gmail.com> a scris:

> Yes. I finally did it. I was wrong about resending packets vor
> verification. Once the checksum has been validated on all layers the packet
> is just accepted. I saw that sometimes this conversation is getting posted
> online and I would like to post a very helpful code for the tcp checksum.
> The one I got was wrong in almost two sections. If you see anything wrong
> correct it but for me it worked quite well:
>
> u_short compute_tcp_checksum(IpHeader *pIph, unsigned short  *ipPayload,
> int payload_size) {
>     unsigned short prot_tcp = 6;
>     int len_tcp = payload_size;
>     long sum;
>     int i;
>     sum = 0;
>
>     /* Check if the tcp length is even or odd.  Add padding if odd. */
>     if ((len_tcp % 2) == 1) {
>         ipPayload[len_tcp] = 0;  // Empty space in the ip buffer should be
> 0 anyway.
>         len_tcp += 1; // incrase length to make even.
>     }
>
>     /* add the pseudo header */
>     /*
>     //If src and dest are decalred as int32
>     uint32_t src = ntohl(pIph->src);
>     uint32_t dest = ntohl(pIph->dest);
>     sum += (((unsigned short *)&src)[0]);
>     sum += (((unsigned short *)&src)[1]);
>     sum += (((unsigned short *)&dest)[0]);
>     sum += (((unsigned short *)&dest)[1]);
>     sum += payload_size; // already in host format.
>     sum += prot_tcp; // already in host format.*/
>
>     sum+= (256*pIph->src[0]+pIph->src[1]);//Big endian
>     sum += (256*pIph->src[2] + pIph->src[3]);
>     sum +=(256*pIph->dest[0] +  pIph->dest[1]);
>     sum += (256*pIph->dest[2] +  pIph->dest[3]);
>
>     sum += payload_size; // already in host format....do not replace with
> len_tcp..payload is always payload and len_tcp changes when payload byte
> count is odd
>     sum += prot_tcp; // already in host format.
>     /*
>       calculate the checksum for the tcp header and payload
>       len_tcp represents number of 8-bit bytes,
>       we are working with 16-bit words so divide len_tcp by 2.
>     */
>     for (i = 0; i < (len_tcp / 2); i++) {
>         sum += ntohs(ipPayload[i]);
>     }
>
>     // keep only the last 16 bits of the 32 bit calculated sum and add the
> carries
>     sum = (sum & 0xFFFF) + (sum >> 16);
>     sum += (sum >> 16);
>
>     // Take the bitwise complement of sum
>     sum = ~sum;
>
>     return htons(((unsigned short)sum));
> }
> Other problems with ip header is that is it not always sizeof(struct)!
> There are Options in it that may change it. This applies to tcp too. Here's
> another code to help calculate where these layers begin:
>
> IpHeader* getIp(const uint8_t *data) {
>     return (IpHeader *)(data + sizeof(EthHeader));
> }
> TCPHeader* getTCP(const uint8_t *data) {
>     IpHeader *ip = getIp(data);
>     int ip_len = (ip->ihl & 0xF) * 4;
>     return (TCPHeader*)(data + sizeof(EthHeader) + ip_len);
> }
>
> void getPayload(char buffer[65000], pcap_pkthdr *header, const uint8_t
> *data,IpHeader *ip,TCPHeader *tcp) {
>     uint8_t ip_len = (ip->ihl & 0xF) * 4;
>     uint8_t tcp_len = ((tcp->th_offx2 & 0xF0)>>4) * 4;
>
>     __int64 payload_size = (__int64)header->caplen- (sizeof(EthHeader)+
> ip_len + tcp_len);// (__int64)header->caplen - 0x42;// -sizeof(EthHeader) -
> sizeof(IpHeader) - sizeof(TCPHeader);
>     if (payload_size <= 0 || payload_size < 20) {
>         buffer[0] = 0;
>         return;
>     }
>
>     memcpy(buffer, data + (sizeof(EthHeader) + ip_len + tcp_len),
> min(payload_size, 65000-1));
>     buffer[min(payload_size, 65000-1)] = 0;
> }
> const uint8_t* getPayloadPointer(pcap_pkthdr *header, const uint8_t
> *data,  IpHeader *ip, TCPHeader *tcp) {
>     uint8_t ip_len = (ip->ihl & 0xF) * 4;
>     uint8_t tcp_len = ((tcp->th_offx2 & 0xF0) >> 4) * 4;
>
>     __int64 payload_size = (__int64)header->caplen - (sizeof(EthHeader) +
> ip_len + tcp_len);// (__int64)header->caplen - 0x42;// -sizeof(EthHeader) -
> sizeof(IpHeader) - sizeof(TCPHeader);
>
>     if (payload_size <= 0 || payload_size < 20) {
>         return NULL;
>     }
>
>     return (data + (sizeof(EthHeader) + ip_len + tcp_len));
> }
>
> And these are the structured that I used:
>
> struct EthHeader {
>     uint8_t dest[6];
>     uint8_t src[6];
>     uint16_t ethertype;
> };
>
> struct IpHeader {
>     u_char  ihl;        // Version (4 bits) + Internet header length (4
> bits)
>     u_char  tos;            // Type of service
>     u_short len;           // Total length
>     u_short frag_id; // Identification
>     u_short frag_offs;       // Flags (3 bits) + Fragment offset (13 bits)
>     u_char  ttl;            // Time to live
>     u_char  proto;          // Protocol
>     u_short csum;            // Header checksum
>     uint8_t src[4];      // Source address
>     uint8_t dest[4];     // Destination address
>     //u_int   op_pad;         // Option + Padding
>     /*uint8_t ihl;
>     uint8_t tos;
>     uint16_t len;
>     uint16_t frag_id;
>     uint8_t frag_offs;
>     uint8_t ttl;
>     uint8_t proto;
>     uint16_t csum;*/
>     //uint8_t src[4];
>     //uint8_t dest[4];
> };
>
> struct ArpHeader {
>     uint16_t htype;
>     uint16_t ptype;
>     uint8_t hlen;
>     uint8_t plen;
>     uint16_t op;
>     uint8_t sender_mac[6];
>     uint8_t sender_ip[4];
>     uint8_t target_mac[6];
>     uint8_t target_ip[4];
> };
> // TCP header
> //typedef struct tcp_header
> //{
> //    u_short src_port; // Source port
> //    u_short dest_port; // Destination port
> //    u_int sequence; // Sequence Number
> //    u_int acknum; // Acknowledgement number
> //    u_char th_off; // Header length
> //    u_char flags; // packet flags
> //    u_short win; // Window size
> //    u_short crc; // Header Checksum
> //    u_short urgptr; // Urgent pointer...still don't know what this is...
> //} TCPHeader;
>
> typedef u_int tcp_seq;
>
> struct TCPHeader {
>     u_short source_port;    /* source port */
>     u_short dest_port;    /* destination port */
>     tcp_seq th_seq;        /* sequence number */
>     tcp_seq th_ack;        /* acknowledgement number */
>     u_char th_offx2;    /* data offset, rsvd */
> #define TH_OFF(th)    (((th)->th_offx2 & 0xf0) >> 4)
>     u_char th_flags;
> #define TH_FIN 0x01
> #define TH_SYN 0x02
> #define TH_RST 0x04
> #define TH_PUSH 0x08
> #define TH_ACK 0x10
> #define TH_URG 0x20
> #define TH_ECE 0x40
> #define TH_CWR 0x80
> #define TH_FLAGS (TH_FIN|TH_SYN|TH_RST|TH_ACK|TH_URG|TH_ECE|TH_CWR)
>     u_short th_win;        /* window */
>     u_short th_sum;        /* checksum */
>     u_short th_urp;        /* urgent pointer */
> };
>
>
> În lun., 24 sept. 2018 la 19:21, Reznicencu Sergiu <
> sergiureznicencu at gmail.com> a scris:
>
>> Weird enough: I have managed to even alter the tcp payload. I had some
>> problems with the tcp payload but now I see why before I couldn't change
>> the ip checksum...this would lead to an invalid checksum at the tcp layer
>> because the tcp checksum includes both src and dest ip.
>> When I saw that I could change the tcp payload I injected an redirection
>> http header to divert traffic to my server. I should note that I spoofed
>> one way(I could see all "victim's" packets from the gateway but not the
>> packets sent by the client...so that everything would be faster). Now comes
>> the problem: the injected payload was quicly unrecognized by the other
>> computer
>> . This lead me to think that once a client receives a packet it checks
>> the checksum but it also sends pack the packet for confirmation. This is
>> the only explanation for why the client refused the redirect packet(it
>> would have sent it back to the server and the server would not-acknowldge
>> it...). So this is a dead end.
>>
>> Back to the ip method: Once I realized that I shoud recalculate the tcp
>> checksum I went on to patch the ip layer. Now I have serious problems with
>> this one. I tried every checksum function I could find on internet but none
>> works(don't worry..I am not a copycat-I read and understand the code I
>> copy). I have a strong feeling the checksum is incorrect because on
>> big/little endianness mismatch(this was the case with the code I took for
>> tcp checksum).
>>
>>
>> Update. Actually I solved it. I found a good method for recalculating the
>> checksum it appears to work. About sending packets to own NIC. Another
>> method. Send the packet to router(set dest mac to gateway) and set the dest
>> ip to mine. The router will check the ip and forward the packet back to my
>> computer. My system will think the source is the victim. Is this a good
>> ideea? (I already tried it but it seems I still have problems with tcp
>> checksum and out -of-order packets...I wonder why..).
>>
>>
>> În dum., 23 sept. 2018 la 21:00, Mark Pizzolato - Winpcap-Users <
>> winpcap-users-20040408 at subscriptions.pizzolato.net> a scris:
>>
>>> On Sunday, September 23, 2018 at 10:20 AM, Guy Harris wrote:
>>> > On Sep 23, 2018, at 4:37 AM, Reznicencu Sergiu
>>> > <sergiureznicencu at gmail.com> wrote:
>>> >
>>> > > I forgot to mention that I already recalculate the ip checksum. It
>>> is weird that
>>> > I cann see in wireshark the packets that I modified and resnt.
>>> Shouldn't the
>>> > packets be in "loopback"?
>>> >
>>> > On most UN*Xes, yes; they will show up on the loopback interface (lo0
>>> or lo).
>>> >
>>> > On Windows, there isn't such an interface.  WinPcap doesn't capture
>>> that
>>> > traffic;
>>>
>>> Actually, WinPcap, by default, does capture all traffic you transmit
>>> using
>>> pcap_sendpacket() on a pcap_t handle (unless you're filtering to exclude
>>> it).
>>>
>>> That transmitted traffic will in fact be received by the host system's
>>> network
>>> Stack (presuming matching MAC and IP address values on the interface
>>> your
>>> pcap_t handle is connected to).
>>>
>>> This receipt will be in addition to the fact that the host system's
>>> network
>>> stack will also have received the original traffic which you've
>>> rewritten.
>>>
>>> WinPcap is not a facility that will let you capture traffic and inhibit
>>> its
>>> reception by the host system's network stack.
>>>
>>> - Mark Pizzolato
>>> _______________________________________________
>>> Winpcap-users mailing list
>>> Winpcap-users at winpcap.org
>>> https://www.winpcap.org/mailman/listinfo/winpcap-users
>>>
>>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.winpcap.org/pipermail/winpcap-users/attachments/20180926/f318e114/attachment-0001.html>


More information about the Winpcap-users mailing list