[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