[Winpcap-users] Sending packets to own NIC

Reznicencu Sergiu sergiureznicencu at gmail.com
Wed Sep 26 15:36:10 UTC 2018


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/d2c72d81/attachment.html>


More information about the Winpcap-users mailing list