Discussion:
Issue with passing hex value into Scapy IP Options field
Colin Ross
2008-06-27 18:13:44 UTC
Permalink
Hi,
I wonder if you can help me. I am trying to use Scapy to pass ICMP
packets with an incrementing IP Option.

To do this I am:
a=IP()
b=ICMP()

What I want to do from here is to pass on to a.options the value in hex,
starting with "\x00\x00\x00\x00"

My problem is that if I set a.option="\x00\x00\x00\x00", this works fine.
However, If I attempt to make each octet a variable and create this option,
When I send the packet, it comes out as "\\x00\\x00\\x00\\x00", and does not
get translated correctly.

Here is a simplified version of my script, with all looping taken out.
################################
a=IP()
b=ICMP()

a.dst='10.211.55.2'

#Set int variables to increment
O1 = 0

O2 = 0

O3 = 0

O4 = 0

#Convert int to hex
o1 = '%x'%(O1)

o2 = '%x'%(O2)

o3 = '%x'%(O3)

o4 = '%x'%(O4)


#Add in leading 0 if hex string is single digit (i.e. Less than 0x10)
if O1 < 16:

o1 = '''0%x'''%(O1)

else:

o1 = '''%x'''%(O1)

if O2 < 16:

o2 = '''0%x'''%(O2)

else:

o2 = '''%x'''%(O2)

if O3 < 16:

o3 = '''0%x'''%(O3)

else:

o3 = '''%x'''%(O3)

if O4 < 16:

o4 = '''0%x'''%(O4)

else:

o4 = '''%x'''%(O4)

#Set IP options
a.options=r'\x%s\x%s\x%s\x%s'%(o1,o2,o3,o4)

ls(a)

send(a/b)
###########################

The output of the IPoptionsField of the ls(a) command at this point is:
options : IPoptionsField = '\\x00\\x00\\x00\\x00' ('')

In my actual IP Packet on the wire, my hex output is the ASCII equivalent to
the string (beginning with 5c 78 30 30, which is the hex ASCII of \x00),
when my goal at this point is to have it 00 00 00 00

How can I get around this and achieve my goal of incrementing a hex value in
the IP Options field?

Cheers
Colin




------ End of Forwarded Message


---------------------------------------------------------------------
To unsubscribe, send a mail to scapy.ml-***@secdev.org
Wim Lewis
2008-06-27 18:54:15 UTC
Permalink
Post by Colin Ross
What I want to do from here is to pass on to a.options the value in hex,
starting with "\x00\x00\x00\x00"
My problem is that if I set a.option="\x00\x00\x00\x00", this works fine.
However, If I attempt to make each octet a variable and create this option,
When I send the packet, it comes out as "\\x00\\x00\\x00\\x00", and does not
get translated correctly.
[code snipped]
Post by Colin Ross
In my actual IP Packet on the wire, my hex output is the ASCII
equivalent to
the string (beginning with 5c 78 30 30, which is the hex ASCII of \x00),
when my goal at this point is to have it 00 00 00 00
To convert a Python integer into a 1-byte-long string with that byte
value, use the chr() function. Using '%x' will (as you've discovered)
produce a string with an ascii hexadecimal representation of the
integer.
Post by Colin Ross
chr(0)
'\x00'

You could also look into the "struct" module which will do some more
Post by Colin Ross
struct.pack('!i', 3)
'\x00\x00\x00\x03'
Post by Colin Ross
struct.pack('!i', 65535)
'\x00\x00\xff\xff'

etc.




---------------------------------------------------------------------
To unsubscribe, send a mail to scapy.ml-***@secdev.org
lobo
2008-06-27 19:03:03 UTC
Permalink
Hi Colin,

I'm not sure if this is the most elegant solution to your problem, but
it should work. You can use the struct module to fill in values into
the options field.
struct.pack("B", 1) + struct.pack("B", 2) + struct.pack("B", 3) +
struct.pack("B", 4)
'\x01\x02\x03\x04'
struct.pack("B", 1) + struct.pack("B", 4) + struct.pack("B", 3) +
struct.pack("B", 4)
'\x01\x04\x03\x04'
struct.pack("B", 0) + struct.pack("B", 0) + struct.pack("B", 0) +
struct.pack("B", 0)
'\x00\x00\x00\x00'
struct.pack("B", 4) + struct.pack("B", 3) + struct.pack("B", 2) +
struct.pack("B", 1)
'\x04\x03\x02\x01'
a=struct.pack("B", 4) + struct.pack("B", 3) + struct.pack("B", 2) +
struct.pack("B", 1)
pkt = IP()
pkt.options
''
pkt.options = struct.pack("B", 4) + struct.pack("B", 3) +
struct.pack("B", 2) + struct.pack("B", 1)
pkt.show2()
###[ IP ]###
version= 4L
ihl= 6L
tos= 0x0
len= 24
id= 1
flags=
frag= 0L
ttl= 64
proto= ip
chksum= 0x75df
src= 127.0.0.1
dst= 127.0.0.1
options= '\x04\x03\x02\x01'
pkt.options = struct.pack("B", 0) + struct.pack("B", 0) +
struct.pack("B", 0) + struct.pack("B", 0)
pkt.show2()
###[ IP ]###
version= 4L
ihl= 6L
tos= 0x0
len= 24
id= 1
flags=
frag= 0L
ttl= 64
proto= ip
chksum= 0x7be3
src= 127.0.0.1
dst= 127.0.0.1
options= '\x00\x00\x00\x00'
best regards,

jochen
Dirk Loss
2008-06-27 20:02:34 UTC
Permalink
I am trying to use Scapy to pass ICMP packets with an incrementing IP Option.
As Wim and Jochen have already suggested, using the struct module and a
for loop may be the easiest way to do it.

But remember that IP options have an internal type-length-value
structure and can be of variable length. So just cycling through a fixed
4 byte field -- which would generate more than 4 billion packets --
might not be exactly what you want... See RFC 791 and [1] for more
details. At least, I suggest using little-endian integers
(struct.pack("<I", val)), so that the first bytes start changing first.

Best regards
Dirk

[1] http://www.iana.org/assignments/ip-parameters

---------------------------------------------------------------------
To unsubscribe, send a mail to scapy.ml-***@secdev.org
Colin Ross
2008-06-27 20:34:53 UTC
Permalink
Thank you all ­ this is exactly what I needed.

Cheers
Colin
Post by Dirk Loss
RFC 791
Loading...