Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ack number to acknowledge data in scapy

I'm playing around with scapy, trying to do a nmap-like, I succeeded doing a three way handshake and I automatically receive data if I connect to a smtp server but I can't acknowledge it.

I have connected to it via netcat to see why it wouldn't work and nc actually send an ACK packet with the TCP ack field set to the length of the data segment received + 1. So I am trying to do the same with scapy but I don't know where to find the length of a TCP segment. I tried a lsc(TCP) but I can not see the field.

Here is a wireshark capture of the netcat connection :

enter image description here

And the detail of the packet :

enter image description here

As you can see, the ack field of the packet just below the data is 37 + 1 = 38.

Does someone knows where or how it can be found ?

EDIT:

There is actually no field that gives the segment length but it can be calculated with two methods:

    tcp_seg_len = len(rp.getlayer(Raw).load)
    # or
    ip_total_len = rp.getlayer(IP).len
    ip_header_len = rp.getlayer(IP).ihl * 32 / 8
    tcp_header_len = rp.getlayer(TCP).dataofs * 32 / 8
    tcp_seg_len = ip_total_len - ip_header_len - tcp_header_len

    ans_ack,unans_ack = sr(IP(dst=ip)/TCP(sport=pkt[1].dport, \
                                          dport=pkt[1].sport, \
                                          seq=rp[1].ack, \
                                          ack=tcp_seg_len + 1, \
                                          flags="A"), \
                           verbose=0, timeout=1)

However, when I print the values I get the good ack number but when I watch the wireshark capture, I have a huge ack number and the packet is marked as "ACKed unseen segment". When I look at the bytes in hexa, I got the right value though. Does anyone knows why that happens and how to solve it?

like image 290
Jeff Bencteux Avatar asked Nov 02 '15 11:11

Jeff Bencteux


1 Answers

Wireshark uses relative numbers in its display so the right scapy line is :

    ans_ack,unans_ack = sr(IP(dst=ip)/TCP(sport=pkt[1].dport, \
                                      dport=pkt[1].sport, \
                                      seq=rp[1].ack, \
                                      ack=rp[1].seq + tcp_seg_len, \
                                      flags="A"), \
                       verbose=0, timeout=1)

And the following code (see EDIT in the question) does work :

ip_total_len = rp.getlayer(IP).len
ip_header_len = rp.getlayer(IP).ihl * 32 / 8
tcp_header_len = rp.getlayer(TCP).dataofs * 32 / 8
tcp_seg_len = ip_total_len - ip_header_len - tcp_header_len
ans_ack,unans_ack = sr(IP(dst=ip)/TCP(sport=pkt[1].dport, \
                                      dport=pkt[1].sport, \
                                      seq=rp[1].ack, \
                                      ack=rp[1].seq + tcp_seg_len, \
                                      flags="A"), \
                           verbose=0, timeout=1)
like image 72
Jeff Bencteux Avatar answered Oct 12 '22 03:10

Jeff Bencteux