Beede, Michael P | 18 Jul 21:38 2014
Picon

A more focused question about protocol descriptions


I'm still working on adding MPTCP to Scapy and think I have a decent approach.  However, there is a fundamental thing I think I don't understand about ConditionalField. 

Suppose we have a very simple protocol that has one kind of packet.  A FOO packet has 2 bytes of data and an optional two bytes of address, only present if it's a 4-byte packet.  So, it's pretty easy to define:

class FOO(Packet):
    fields_desc = [ ShortField("data",0),
                            ConditionalField(ShortField("addr",None),lambda p:p.addr != None) ]

Now you can specify a packet of either type easily:

>>> a = FOO(data=1234)
>>> b = FOO(data=5678,addr=6666)
>>> a
<FOO  data=1234 |>
>>> b
<FOO  data=5678 addr=6666 |>

But what happens if we dissect the second packet?

>>> c = FOO(str(b))
>>> c
<FOO  data=5678 |<Raw  load='\x1a\n' |>>

Of course, this is just what we described, but i can't figure out how to improve the predicate so it works for a literal packet and for dissection too. We can't refer to the length of the packet, because it hasn't been constructed yet.  So, how do we correctly deal with this simple protocol?  I've come to the conclusion that there must be some simple principle I'm missing entirely.

Thanks for any suggestions.

   Mike Beede

Beede, Michael P | 15 Jul 00:35 2014
Picon

multipath TCP support


I've been thinking of adding MPTCP support to scapy, but I am at a stand as to what it should look like.  I hope to solicit some opinions as to the the scapy-ful way to approach this.

For those that aren't familiar with it, MPTCP is an extension to  TCP with all the "multi-path aware" information carried in TCP option fields.  The problem is that there are a number of different subtypes for the MPTCP option, each with (mostly) different fields.  This would make it awkward to specify a packet, since you'd have to cram things into the option list, and it would make it especially awkward to refer to in code, since (unless I misunderstand things), there's no short way to refer to a specific option field.

Another goal: in order to investigate ill-formed packets, it should be possible to specify packets that have multiple MPTCP options, even ones that the standard doesn't envision occurring together.

To be clear, it would be nice to be able to create a MPTCP packet by saying something like

w = IP(dst="google.com")/TCP(MP_CAPABLE(SenderKey=0x1122334455667788L))

and later refer to the key as

w[TCP].MP_CAPABLE.SenderKey

Or in the ill-formed case say something like

w = IP()/TCP(MP_CAPABLE(SenderKey=0),MP_CAPABLE(SenderKey=0))

Note: I have no idea how you'd distinguish two MP_CAPABLE options when referring to them in code.  Maybe as an array?

It's straightforward to define the various options as Packets (in fact, it's much easier than writing code to parse the options, since parsing packets is  well thought-out in scapy), but it isn't clear to me whether modifying TCP to accept packets as arguments would be contrary to the spirit of things.  I also thought of implementing it as a layer, but that's a bit confusing since it's really contained entirely within the TCP layer.

If anyone has some suggestions for how they think it should look (or even better, how it should work!), I'd appreciate them.

Regards,

    Mike Beede




Harry Trieu | 3 Jul 00:56 2014

Sending IP Fragments Out of 2 Interfaces

Hi guys,

Suppose I have an IP packet that I fragment into 10 fragments using fragment(). Is there a way to send 5 of those fragments out of one interface (let’s say eth0) and the other half out of the other interface (eth1) using sendpfast()?

I think it can be done using sendp() but I’m not sure how it would work using sendpfast() as it spawns tcpreplay.

Any ideas?

Thanks,
Harry
David Imhoff | 27 Jun 10:47 2014
Picon
Picon

Red Hat EL7 RPM download link


Hi,

Are you aware that the link on http://pkgs.repoforge.org/scapy/ to the
Red Hat Enterprise Linux 7 RPM is broken?
It points to:
http://apt.sw.be/redhat/el7/en/i386/rpmforge/RPMS/scapy-2.0.0.10-1.el7.rf.noarch.rpm
but the actual package is on ('i386' vs 'x86_64'):
http://apt.sw.be/redhat/el7/en/x86_64/rpmforge/RPMS/scapy-2.0.0.10-1.el7.rf.noarch.rpm

Kind regards,

David

---------------------------------------------------------------------
To unsubscribe, send a mail to scapy.ml-unsubscribe <at> secdev.org

Jacek Wielemborek | 22 Jun 14:46 2014
Picon

How to spoof a TCP handshake in scapy?

Hello,

(This post is based on my StackOverflow question, which can be 
found here: http://stackoverflow.com/q/24340455/1091116)

I was recently trying to write a Scapy script that performs a 
full TCP handshake. The idea was that I connect two Qemu VMs 
using `-net socket` userspace interface (which seems to handle 
raw IP/ethernet fine) and instruct machine B to block all input 
from A (to prevent it from sending the RSTs). Then, I used telnet 
to `connect()` from machine A to B and ran the following script 
on machine B:

    #!/usr/bin/python

    import scapy.all as scapy

    filter = "port 31337"
    iface = "eth0"

    def prepare_response(t):
        print("Received: %s" % repr(t))
        t.src, t.dst = t.dst, t.src  # swap ethernet addresses
        ip = t.getlayer("IP")
        ip.src, ip.dst = ip.dst, ip.src
        t.dport, t.sport = t.sport, t.dport
        t.ack = t.seq
        t.ack += 1

    syn = scapy.sniff(filter=filter, count=1, iface=iface)[0]
    print(syn.sprintf('%TCP.flags%'))

    syn_ack = syn
    prepare_response(syn_ack)
    syn_ack.getlayer("TCP").flags |= 0x10  # set the ACK flag
    print(syn_ack.sprintf('%TCP.flags%'))

    print("Sending: %s" % repr(syn_ack))
    scapy.sendp(syn_ack, iface=iface, verbose=False)

    ack = scapy.sniff(filter=filter, count=1, iface=iface)[0]
    assert(ack.flags & 0x10)

The problem is that instead of receiving an ACK from A to B, I 
seem to get a SYN retransmission as if SYN+ACK wasn't interpreted 
correctly:

(A Wireshark screenshot can be found here:  
https://imgur.com/kv7A3Hr )

tcp on machine A confirms that SYN+ACK reached the machine:

    05:47:03.925100 IP 10.0.0.1.39634 > debian.31337: Flags [S], 
seq 2426802888, win 14600, options [mss 
1460,nop,nop,sackOK,nop,wscale 4], length 0
    05:47:03.927515 IP debian.31337 > 10.0.0.1.39634: Flags [S.], 
seq 2426802888, ack 2426802889, win 14600, options [mss 
1460,nop,nop,sackOK,nop,wscale 4], length 0

Here's the PCAP file from machine B's perspective in Base64 form:

1MOyoQIABAAAAAAAAAAAAP//AAABAAAAYlilUwieDgARAQAAEQEAAAEAXgAA+1J
UABI0VggARQABA2UUQAD/ESrYCgAAAuAAAPsU6RTpAO/r/QAAAAAAAwAAAAUAAA
E2ATUBNAEzATIBMQFlAWYBZgFmATABMAE0ATUBMAE1ATABMAEwATABMAEwATABM
AEwATABMAEwATABOAFlAWYDaXA2BGFycGEAAP8AAQtkZWJpYW4tMTA5MwVsb2Nh
bAAA/wABATIBMAEwAjEwB2luLWFkZHLAUAD/AAHAWgANAAEAAAB4AAsESTY4NgV
MSU5VWMBaAAEAAQAAAHgABAoAAALAcQAMAAEAAAB4AALAWsBaABwAAQAAAHgAEP
6AAAAAAAAAUFQA//4SNFbADAAMAAEAAAB4AALAWmJYpVMJoA4AnAAAAJwAAAABA
F4AAPtSVAASNFYIAEUAAI4GlEAA/xGJzgoAAAHgAAD7FOkU6QB6hFgAAIQAAAAA
AQAAAAABNgE1ATQBMwEyATEBZQFmAWYBZgEwATABNAE1ATABNQEwATABMAEwATA
BMAEwATABMAEwATABMAEwATgBZQFmA2lwNgRhcnBhAAAMgAEAAAB4ABIKZGViaW
FuLTQwNwVsb2NhbABnWKVTvIYIAEIAAABCAAAAUlQAEjRWUlQAEjRWCABFAAA0H
dtAAEAGCOcKAAABCgAAAprbemmul/p8AAAAAIACOQhjsAAAAgQFtAEBBAIBAwME
Z1ilU5COCABCAAAAQgAAAFJUABI0VlJUABI0VggARQAANB3bQABABgjnCgAAAgo
AAAF6aZrbrpf6fK6X+n2AEjkIY7AAAAIEBbQBAQQCAQMDBGhYpVPTfggAQgAAAE
IAAABSVAASNFZSVAASNFYIAEUAADQd3EAAQAYI5goAAAEKAAACmtt6aa6X+nwAA
AAAgAI5CGOwAAACBAW0AQEEAgEDAwRqWKVTrI4IAEIAAABCAAAAUlQAEjRWUlQA
EjRWCABFAAA0Hd1AAEAGCOUKAAABCgAAAprbemmul/p8AAAAAIACOQhjsAAAAgQ
FtAEBBAIBAwME

And one from A to B's perspective:

1MOyoQIABAAAAAAAAAAAAP//AAABAAAAVVilU9NXCABCAAAAQgAAAFJUABI0VlJ
UABI0VggARQAANB3bQABABgjnCgAAAQoAAAKa23pprpf6fAAAAACAAjkIFCkAAA
IEBbQBAQQCAQMDBFVYpVPIYAgAQgAAAEIAAABSVAASNFZSVAASNFYIAEUAADQd2
0AAQAYI5woAAAIKAAABemma266X+nyul/p9gBI5CGOwAAACBAW0AQEEAgEDAwRW
WKVT008IAEIAAABCAAAAUlQAEjRWUlQAEjRWCABFAAA0HdxAAEAGCOYKAAABCgA
AAprbemmul/p8AAAAAIACOQgUKQAAAgQFtAEBBAIBAwMEWFilU4FfCABCAAAAQg
AAAFJUABI0VlJUABI0VggARQAANB3dQABABgjlCgAAAQoAAAKa23pprpf6fAAAA
ACAAjkIFCkAAAIEBbQBAQQCAQMDBA==

At first I thought that this is somehow related to some Linux 
TCP/IP quirk, so I experimented with turning off TCP timestamps 
and SYN cookies. I also tried increasing IP ID, which didn't help 
either. Both machines are running Debian 7.5 with linux-
image-3.2.0-4-686-pae under qemu 1.6.2. 

What am I missing?

Yours,
Jacek Wielemborek
Sushrut Mair | 10 Jun 07:14 2014
Picon

Problems while sending a string as tcp payload

Hi,

I am trying to send out an EICAR string via scapy. It gets sent out but it seems like scapy maybe 
modifying the string. Here is my code:

.
.
.
actualdata="X5O!P% <at> AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*"
ip=IP(src=ipsrc,dst=ipdst)
tcp=TCP(sport=srcp,dport=dstp,flags="PA",seq=last_packets_seqnum,ack=last_packets_acknum)
raw=Raw(actualdata.encode('utf-8','strict'))
data=ip/tcp/raw
print ls(data)        ---> #1
print actualdata   ---> #2
ACK=sr1(data)
.
.
.


#1 prints out he packet and the payload string. the string is printed out as,
"'X5O!P% <at> AP[4\\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*'". Note the extra 
'\'. I have tried to escape the \ and tried other recommended stuff but to no avail.

#2 prints out the correct string as provided in actualdata.

The only difference between both, afaik, are that ls(data) is controlled by scapy while actualdata is a 
python string.

Can anyone help me with the same? The issue is that while the destination receives the string, it is 
unable to detect it as an eicar string.

Rgds,
Sushrut.

James Woolley | 5 Jun 17:58 2014

Missing payload

Hello,

I'm having some trouble getting a full UDP payload to be sent over a network.

I'm running on 1 machine the following:

send(IP(dst='192.168.66.1')/UDP(dport=2600)/'12345678901234567890')

And on the other machine:

receivedData = sniff(filter='udp and port 2600', iface='wlan1', count = 1)
receivedData[0]

and it returns:

<Ether  dst=00:0f:55:a2:3d:b5 src=00:0f:55:a2:38:c5 type=0x800 |<IP  version=4L ihl=5L tos=0x0 len=48 id=1 flags= frag=0L ttl=64 proto=udp chksum=0x7564 src=192.168.66.6 dst=192.168.66.1 options=[] |<UDP  sport=domain dport=2600 len=28 chksum=0xdbf6 |<DNS  id=12594 qr=0L opcode=6L aa=0L tc=1L rd=1L ra=0L z=3L rcode=not-implemented qdcount=13622 ancount=14136 nscount=14640 arcount=12594 qd='' an='' ns='' ar='' |<Raw  load='34567890' |>>>>>

As you can see the payload received is just the end section of the original payload. Is there something i am doing incorrectly.

The communication is done over a wireless network and it has at one point worked correctly. It must have been something i have changed to have it stop working.

Thank you in advance for your help.
Sushrut Mair | 5 Jun 13:13 2014
Picon

ACK for a TCP segment that is fragmented at IP level

Hi,

I am trying to send some data that is fragmented at IP level. Here is my code snippet for the same:

fg=fragment((IP(src=ipsrc,dst=ipdst)/TCP(sport=srcp,dport=dstp,flags="PA",seq=last_packets_seqnum,ack=last_packets_acknum)/('a'*2048)),16)

srcp,dstp,ipsrc,ipdst are all valid and correct. So are last_packets_seqnum (sequence number) and last_packets_acknum (acknowledgement number). All of these are filled in after a successfull 3 way tcp connection setup handshake (again verified via wireshark).

Here are my queries:
  - I see the packets go out successfully in wireshark but they do not reach the destination. I am not sure why. I dont see any errors in wireshark or the script run.
  - Another query is that if I am to close this tcp connection gracefully, I will need the sequence num and the acknowledgement num of the last packet in this connection. If I am sending out 'fg' above via sr1(), will I receive the ACK from the server for the TCP segment that was reassembled at the destination from these fragments?

Rgds,
Sushrut.
P.Fiterau-Brostean | 26 May 23:51 2014
Picon

Re: Potential bug when sending R over RawSocket, and occasional response miss

Hello. The matter is still important to me, especially in terms of 
understanding. Straight to the question:
> I am a bit confused. Aren't the RST packets to 127.0.0.1 that you DON'T
> want to drop ?
>
> iptables -A OUTPUT -p tcp -d X.X.X.X --tcp-flags RST RST  -j DROP
>
> where X.X.X.X is the server where you actually want to drop the RST
> packets.
The server is listening over localhost. Both client and server are
communicating over localhost, so the rule ought to have X = localhost.

Since I do realize my previous post wasn't very intelligible, I will
rephrase.

I have a server listening on a port and a "scapy" driven client, both
linux based. I want the client to be able to send, undisturbed,  all types
of TCP packets to the  server and see how it reacts. There are some
obstacles to this.  Normally, whenever you would attempt at connecting to
the server, (SYN =>), once the server responds (SYN+ACK <=) the operating
system would send a RST message to the server and close the connection. 
To prevent this from happening, you can use the iptables rule to drop RST
packets.

Now, in the scenario where communication is done over a network interface,
then everything functions, regardless of the type of socket used.
If, however, both the client and the server are in the same environment,
communicating over localhost, then, as mentioned in the Scapy manual, you
need to use L3 raw sockets. If I use this type of sockets, I can send all
packets apart from the ones I filter out with the drop rule. For those, I
get "operation not permitted". If I set a drop rule on RST packets I am
just not allowed to send RST packets with my fake client. BTW, This only
applies to the localhost scenario.

I was wondering if there's a way for the client to communicate freely in
this scenario. Also, was wondering why iptables does not interfere when
communication is done over non-loopback network interfaces. Basically, the
rule dropping resets only affects scapy packet sending through the
loopback interface.

I attached a python script with both the client and the server
highlighting the "operation not permitted" issue. In order to kill
leftover connections you can use the bash:

sudo netstat -lnp | grep 799[0-9] | awk '{print substr($7,0,6)}' | xargs
kill -9

It is more of a puzzlement than a bug. Thanks for the feedback.
Paul.
Attachment (serverclient.py): application/octet-stream, 3003 bytes
---------------------------------------------------------------------
To unsubscribe, send a mail to scapy.ml-unsubscribe <at> secdev.org
P.Fiterau-Brostean | 15 May 13:11 2014
Picon

Potential bug when sending R over RawSocket, and occasional response miss

Hello. I have been using Scapy extensively for the past 2 months. I am
running the latest version, Scapy 2.2.0 with Python 2.7 on Ubuntu 12.10 LTS.

I noticed a bug when using L3RawSockets (I use them so I can communicate
over localhost).

Here is a python code example that showcase it.

from scapy.all import *

if __name__ == "__main__":
    conf.L3socket=L3RawSocket
    serverIP = "127.0.0.1"
    clientIP = "127.0.0.1"
    pIP = IP(src=clientIP,dst=serverIP, flags="DF")
    pTCP = TCP(sport=2000, dport = 1000, seq = 10, ack = 10, flags="R")
    p = pIP/pTCP
    response = sr1(p,timeout = 0.1)

Running this gives me the error:
ERROR: --- Error in child 28951
Traceback (most recent call last):
  File "/usr/local/lib/python2.7/dist-packages/scapy/sendrecv.py", line
89, in sndrcv
    pks.send(p)
  File "/usr/local/lib/python2.7/dist-packages/scapy/supersocket.py", line
103, in send
    log_runtime.error(msg)
NameError: global name 'log_runtime' is not defined

This only occurs when sending a reset message (flags="R") with the
L3RawSocket set. It does not occur with the default Socket. The fix is
adding another import in scapy/supersocket.py:
"from scapy.error import warning, log_runtime"

Then it states "operation not permitted". Is it not possible to send RST
packets over raw sockets?

I also had issues with scapy response receipt when sending a certain
sequence of packets. I attached a client script that sends a SYN and an
SYN+ACK. Scapy/sr1 does not catch the resulting RST response packet
following the SYN+ACK. I cannot really figure out why. For this example
you need a running listening server on the port the client is
communicating. For this, I attached a mock python server.

Other than that, scapy has performed great for me.

Thanks!
Paul.
Attachment (slow.py): application/octet-stream, 3392 bytes
Attachment (server.py): application/octet-stream, 390 bytes
---------------------------------------------------------------------
To unsubscribe, send a mail to scapy.ml-unsubscribe <at> secdev.org
Antonios Atlasis | 11 May 20:15 2014
Picon

How to use fuzz() function in a Scapy script

Dear all,

I want to implement a script which incorporates some fuzzing capabilities, let's say for the TCP protocol. The parameters that will be used for TCP should be passed as arguments to the script. For instance, if "mysport" is the argument regarding the source port and "mydport" the destination port, the layer4 is implemented in the script as:

layer4=TCP(sport=mysport, dport=mydport)

Now, if I want to fuzz it, I include it in the Scapy fuzz function, as for example:

layer4=fuzz(TCP(sport=mysport, dport=mydport))

If I wan to define both sport and dport, that's OK, it fuzzes all the other parameters.

What if I want to define just the sport and not the dport, or vice versa? What value should be passed as argument in order to cause the fuzzing of this parameter? I tried to use None, but it doesn't work (it uses the default value for the corresponding parameter and it doesn't fuzz it).

Of course, I could implemented it manually in various ways (using if/else, or RandNum(), etc), but  I am wondering if there is a neat trick to do it with fuzz().

Thanks in advance for any help

Best

Antonios

Gmane