Re: libnet_build_icmpv4_unreach is horribly broken
Mike Schiffman <[email protected]>
| Newsgroups | gmane.comp.security.libnet |
|---|---|
| Message-ID | <[email protected]> |
Hrm, yah. This is a problem. The unreachable builders build the
original IP header portion of the packet in their own pblock:
/*
* Build the original IPv4 header in its own pblock. We stick the
* payload here.
*/
ipv4 = libnet_build_ipv4(orig_len, orig_tos, orig_id, orig_frag,
orig_ttl,
orig_prot, orig_check, orig_src, orig_dst, payload, payload_s,
l, 0);
Each time a new pblock is allocated. So the error with the link
interface is that it's finding no link header the second time around
because a new pblock is allocated
each time libnet_build_icmpv4_unreach() is called... We can see this
using libnet's diagnostic interface; a call to
libnet_diag_dump_pblock() is added just prior to each call to
libnet_write() in your icmp_unreach.c program. (Yes this is all
documented in 1.1.2!).
[rounder:Projects/libnet/sample] root# ./icmp_unreach -s 4.2.2.2 -d
4.2.2.2
libnet 1.1 packet shaping: ICMP unreachable[link]
pblock type: ip data
ptag number: 2
pblock address: 0x300330
next pblock 0x3002f0 (ipv4 header)
prev pblock 0x0
buf: 111122220008c6a5
buffer length: 8
checksum flag: No
bytes copied: 8
pblock type: ipv4 header
ptag number: 1
pblock address: 0x3002f0
next pblock 0x300350 (icmpv4 unreachable header)
prev pblock 0x300330 (ip data)
buf: 4518001c0001000040116eb10402020204020202
buffer length: 20
checksum flag: Yes
chksum length: 20
bytes copied: 20
pblock type: icmpv4 unreachable header
ptag number: 3
pblock address: 0x300350
next pblock 0x300370 (ipv4 header)
prev pblock 0x3002f0 (ipv4 header)
buf: 0303000000000000
buffer length: 8
checksum flag: Yes
chksum length: 36
bytes copied: 8
pblock type: ipv4 header
ptag number: 4
pblock address: 0x300370
next pblock 0x3003b0 (ethernet header)
prev pblock 0x300350 (icmpv4 unreachable header)
buf: 4518003800010000400100000402020204020202
buffer length: 20
checksum flag: Yes
chksum length: 20
bytes copied: 20
pblock type: ethernet header
ptag number: 5
pblock address: 0x3003b0
next pblock 0x0
prev pblock 0x300370 (ipv4 header)
buf: 00106700b1860d0e0a0d00000800
buffer length: 14
checksum flag: No
bytes copied: 14
Wrote 70 byte ICMP packet; check the wire.
pblock type: ip data
ptag number: 2
pblock address: 0x300330
next pblock 0x3002f0 (ipv4 header)
prev pblock 0x0
buf: 111122220008c6a5
buffer length: 8
checksum flag: No
bytes copied: 8
pblock type: ipv4 header
ptag number: 1
pblock address: 0x3002f0
next pblock 0x300350 (icmpv4 unreachable header)
prev pblock 0x300330 (ip data)
buf: 4518001c0001000040116eb10402020204020202
buffer length: 20
checksum flag: Yes
chksum length: 20
bytes copied: 20
pblock type: icmpv4 unreachable header
ptag number: 3
pblock address: 0x300350
next pblock 0x300370 (ipv4 header)
prev pblock 0x3002f0 (ipv4 header)
buf: 0303000000000000
buffer length: 8
checksum flag: Yes
chksum length: 36
bytes copied: 8
pblock type: ipv4 header
ptag number: 4
pblock address: 0x300370
next pblock 0x3003b0 (ethernet header)
prev pblock 0x300350 (icmpv4 unreachable header)
buf: 4518003800020000400100000402020204020202
buffer length: 20
checksum flag: Yes
chksum length: 20
bytes copied: 20
pblock type: ethernet header
ptag number: 5
pblock address: 0x3003b0
next pblock 0x300470 (ip data)
prev pblock 0x300370 (ipv4 header)
buf: 00106700b1860d0e0a0d00000800
buffer length: 14
checksum flag: No
bytes copied: 14
pblock type: ip data
ptag number: 7
pblock address: 0x300470
next pblock 0x300430 (ipv4 header)
prev pblock 0x3003b0 (ethernet header)
buf: 111122220008c6a5
buffer length: 8
checksum flag: No
bytes copied: 8
pblock type: ipv4 header
ptag number: 6
pblock address: 0x300430
next pblock 0x0
prev pblock 0x300470 (ip data)
buf: 4518001c0002000040116eb00402020204020202
buffer length: 20
checksum flag: Yes
chksum length: 20
bytes copied: 20
Write error: libnet_pblock_coalesce(): packet assembly cannot find a
layer 2 header
[rounder:Projects/libnet/sample] root#
You can see that after the first packet is built and written correctly,
the second packet has another IP header (with IP data pblock) tacked on
at the end. I'm not sure how I'm going to solve this problem just yet
-- probably get crafty with either saving these ptags internally or by
using the payload interface (probably how it should be done in the
first place). If anyone gets inspired and fixes this in the short term
please let me know...
On Mar 1, 2004, at 4:54 PM, Aaron Turner wrote:
> So I've been trying to craft some icmp port unreachable packets using
> libnet 1.1.1 and 1.1.2-rc4, but either I've lost my mind, or
> there's some ugly bug hiding somewhere deep in libnet.
>
> Anyways, I've attached a slightly hacked copy of sample/icmp_unreach.c
> which illustrates the two errors which occur when you try to send a
> series of icmp_unreach's:
>
> 1) you can only send 1 packet when using LIBNET_LINK (libnet can't find
> the ether header on subsequent calls to libnet_write())
>
> 2) when using LIBNET_RAW4, only the first packet is actually sent
> (contrary to libnet_write indicating success) AND subseqent calls to
> libnet_write() indicates that the packet is growing. (use -r)
>
> --
> Aaron Turner <aturner at pobox.com|synfin.net> http://synfin.net/
> They that can give up essential liberty to obtain a little temporary
> safety deserve neither liberty nor safety. -- Benjamin Franklin
> All emails are PGP signed; a lack of a signature indicates a forgery.
> <icmp_unreach.c>
--
Mike Schiffman, CISSP
http://www.packetfactory.net/schiffman
Doveryay No Proveryay