<div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div>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:</div><div><br>u_short compute_tcp_checksum(IpHeader *pIph, unsigned short  *ipPayload, int payload_size) {<br>    unsigned short prot_tcp = 6;<br>    int len_tcp = payload_size;<br>    long sum;<br>    int i;<br>    sum = 0;<br><br>    /* Check if the tcp length is even or odd.  Add padding if odd. */<br>    if ((len_tcp % 2) == 1) {<br>        ipPayload[len_tcp] = 0;  // Empty space in the ip buffer should be 0 anyway.<br>        len_tcp += 1; // incrase length to make even.<br>    }<br><br>    /* add the pseudo header */<br>    /*<br>    //If src and dest are decalred as int32 <br>    uint32_t src = ntohl(pIph->src);<br>    uint32_t dest = ntohl(pIph->dest);<br>    sum += (((unsigned short *)&src)[0]);<br>    sum += (((unsigned short *)&src)[1]);<br>    sum += (((unsigned short *)&dest)[0]);<br>    sum += (((unsigned short *)&dest)[1]);<br>    sum += payload_size; // already in host format.<br>    sum += prot_tcp; // already in host format.*/<br><br>    sum+= (256*pIph->src[0]+pIph->src[1]);//Big endian<br>    sum += (256*pIph->src[2] + pIph->src[3]);<br>    sum +=(256*pIph->dest[0] +  pIph->dest[1]);<br>    sum += (256*pIph->dest[2] +  pIph->dest[3]);<br><br>    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<br>    sum += prot_tcp; // already in host format.<br>    /*<br>      calculate the checksum for the tcp header and payload<br>      len_tcp represents number of 8-bit bytes,<br>      we are working with 16-bit words so divide len_tcp by 2.<br>    */<br>    for (i = 0; i < (len_tcp / 2); i++) {<br>        sum += ntohs(ipPayload[i]);<br>    }<br><br>    // keep only the last 16 bits of the 32 bit calculated sum and add the carries<br>    sum = (sum & 0xFFFF) + (sum >> 16);<br>    sum += (sum >> 16);<br><br>    // Take the bitwise complement of sum<br>    sum = ~sum;<br><br>    return htons(((unsigned short)sum));<br>}<br></div><div>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:</div><div><br>IpHeader* getIp(const uint8_t *data) {<br>    return (IpHeader *)(data + sizeof(EthHeader));<br>}<br>TCPHeader* getTCP(const uint8_t *data) {<br>    IpHeader *ip = getIp(data);<br>    int ip_len = (ip->ihl & 0xF) * 4;<br>    return (TCPHeader*)(data + sizeof(EthHeader) + ip_len);<br>}<br><br>void getPayload(char buffer[65000], pcap_pkthdr *header, const uint8_t *data,IpHeader *ip,TCPHeader *tcp) {<br>    uint8_t ip_len = (ip->ihl & 0xF) * 4;<br>    uint8_t tcp_len = ((tcp->th_offx2 & 0xF0)>>4) * 4;<br><br>    __int64 payload_size = (__int64)header->caplen- (sizeof(EthHeader)+ ip_len + tcp_len);// (__int64)header->caplen - 0x42;// -sizeof(EthHeader) - sizeof(IpHeader) - sizeof(TCPHeader);<br>    if (payload_size <= 0 || payload_size < 20) {<br>        buffer[0] = 0;<br>        return;<br>    }<br><br>    memcpy(buffer, data + (sizeof(EthHeader) + ip_len + tcp_len), min(payload_size, 65000-1));<br>    buffer[min(payload_size, 65000-1)] = 0;<br>}<br>const uint8_t* getPayloadPointer(pcap_pkthdr *header, const uint8_t *data,  IpHeader *ip, TCPHeader *tcp) {<br>    uint8_t ip_len = (ip->ihl & 0xF) * 4;<br>    uint8_t tcp_len = ((tcp->th_offx2 & 0xF0) >> 4) * 4;<br><br>    __int64 payload_size = (__int64)header->caplen - (sizeof(EthHeader) + ip_len + tcp_len);// (__int64)header->caplen - 0x42;// -sizeof(EthHeader) - sizeof(IpHeader) - sizeof(TCPHeader);<br>    <br>    if (payload_size <= 0 || payload_size < 20) {<br>        return NULL;<br>    }<br><br>    return (data + (sizeof(EthHeader) + ip_len + tcp_len));<br>}</div><div><br></div><div>And these are the structured that I used:</div><div><br>struct EthHeader {<br>    uint8_t dest[6];<br>    uint8_t src[6];<br>    uint16_t ethertype;<br>};<br><br>struct IpHeader {<br>    u_char  ihl;        // Version (4 bits) + Internet header length (4 bits)<br>    u_char  tos;            // Type of service <br>    u_short len;           // Total length <br>    u_short frag_id; // Identification<br>    u_short frag_offs;       // Flags (3 bits) + Fragment offset (13 bits)<br>    u_char  ttl;            // Time to live<br>    u_char  proto;          // Protocol<br>    u_short csum;            // Header checksum<br>    uint8_t src[4];      // Source address<br>    uint8_t dest[4];     // Destination address<br>    //u_int   op_pad;         // Option + Padding<br>    /*uint8_t ihl;<br>    uint8_t tos;<br>    uint16_t len;<br>    uint16_t frag_id;<br>    uint8_t frag_offs;<br>    uint8_t ttl;<br>    uint8_t proto;<br>    uint16_t csum;*/<br>    //uint8_t src[4];<br>    //uint8_t dest[4];<br>};<br><br>struct ArpHeader {<br>    uint16_t htype;<br>    uint16_t ptype;<br>    uint8_t hlen;<br>    uint8_t plen;<br>    uint16_t op;<br>    uint8_t sender_mac[6];<br>    uint8_t sender_ip[4];<br>    uint8_t target_mac[6];<br>    uint8_t target_ip[4];<br>};<br>// TCP header<br>//typedef struct tcp_header<br>//{<br>//    u_short src_port; // Source port<br>//    u_short dest_port; // Destination port<br>//    u_int sequence; // Sequence Number<br>//    u_int acknum; // Acknowledgement number<br>//    u_char th_off; // Header length<br>//    u_char flags; // packet flags<br>//    u_short win; // Window size<br>//    u_short crc; // Header Checksum<br>//    u_short urgptr; // Urgent pointer...still don't know what this is...<br>//} TCPHeader;<br><br>typedef u_int tcp_seq;<br><br>struct TCPHeader {<br>    u_short source_port;    /* source port */<br>    u_short dest_port;    /* destination port */<br>    tcp_seq th_seq;        /* sequence number */<br>    tcp_seq th_ack;        /* acknowledgement number */<br>    u_char th_offx2;    /* data offset, rsvd */<br>#define TH_OFF(th)    (((th)->th_offx2 & 0xf0) >> 4)<br>    u_char th_flags;<br>#define TH_FIN 0x01<br>#define TH_SYN 0x02<br>#define TH_RST 0x04<br>#define TH_PUSH 0x08<br>#define TH_ACK 0x10<br>#define TH_URG 0x20<br>#define TH_ECE 0x40<br>#define TH_CWR 0x80<br>#define TH_FLAGS (TH_FIN|TH_SYN|TH_RST|TH_ACK|TH_URG|TH_ECE|TH_CWR)<br>    u_short th_win;        /* window */<br>    u_short th_sum;        /* checksum */<br>    u_short th_urp;        /* urgent pointer */<br>};</div><div><br></div></div></div></div></div></div><br><div class="gmail_quote"><div dir="ltr">În lun., 24 sept. 2018 la 19:21, Reznicencu Sergiu <<a href="mailto:sergiureznicencu@gmail.com">sergiureznicencu@gmail.com</a>> a scris:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div>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.</div><div>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<br></div><div>. 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.</div><div><br></div><div>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). <br></div><div><br></div><div><br></div><div>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..).<br></div><br></div></div></div><br><div class="gmail_quote"><div dir="ltr">În dum., 23 sept. 2018 la 21:00, Mark Pizzolato - Winpcap-Users <<a href="mailto:winpcap-users-20040408@subscriptions.pizzolato.net" target="_blank">winpcap-users-20040408@subscriptions.pizzolato.net</a>> a scris:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">On Sunday, September 23, 2018 at 10:20 AM, Guy Harris wrote:<br>
> On Sep 23, 2018, at 4:37 AM, Reznicencu Sergiu<br>
> <<a href="mailto:sergiureznicencu@gmail.com" target="_blank">sergiureznicencu@gmail.com</a>> wrote:<br>
> <br>
> > I forgot to mention that I already recalculate the ip checksum. It is weird that<br>
> I cann see in wireshark the packets that I modified and resnt. Shouldn't the<br>
> packets be in "loopback"?<br>
> <br>
> On most UN*Xes, yes; they will show up on the loopback interface (lo0 or lo).<br>
> <br>
> On Windows, there isn't such an interface.  WinPcap doesn't capture that<br>
> traffic; <br>
<br>
Actually, WinPcap, by default, does capture all traffic you transmit using <br>
pcap_sendpacket() on a pcap_t handle (unless you're filtering to exclude it).<br>
<br>
That transmitted traffic will in fact be received by the host system's network <br>
Stack (presuming matching MAC and IP address values on the interface your <br>
pcap_t handle is connected to).<br>
<br>
This receipt will be in addition to the fact that the host system's network<br>
stack will also have received the original traffic which you've rewritten.<br>
<br>
WinPcap is not a facility that will let you capture traffic and inhibit its <br>
reception by the host system's network stack.<br>
<br>
- Mark Pizzolato<br>
_______________________________________________<br>
Winpcap-users mailing list<br>
<a href="mailto:Winpcap-users@winpcap.org" target="_blank">Winpcap-users@winpcap.org</a><br>
<a href="https://www.winpcap.org/mailman/listinfo/winpcap-users" rel="noreferrer" target="_blank">https://www.winpcap.org/mailman/listinfo/winpcap-users</a><br>
</blockquote></div>
</blockquote></div>