HexInject
The power of raw hex network access...

News

Jan 04 2017

After so many years of silence, HexInject version 1.6 has been released (Jan 04 2017).

With this release many non-portable code portions have been rewritten to improve portability and adherence to standards. For this I must thank several people: the Kali Linux and FreshPorts maintainers for their packaging efforts, the ParrotSec project and Simmesson for their patches, and many others for their suggestions.

But this release also extends the number of protocols supported by the automatic checksumming and sizing engine. In particular support for the IPv6 protocol has been added, even when encapsulated in an IPv4 packet (and vice-versa).

These are the protocols supported by the checksumming engine at the moment:

  • ipv4
  • ipv6
  • tcp
  • udp
  • icmp
  • icmp6
  • igmp
  • ipv6 encapsulated in ipv4
  • ipv4 encapsulated in ipv6

Examples of new protocols have been included in prettypacket, that now can also just dump the hexstring of packets instead of dissecting them. This is useful if you want to quickly modify example packets, and pipe them to hexinject.

If you have suggestions do not hesitate to contact me. Enjoy this new release! :-)

Feb 21 2013

HexInject has now reached version 1.5 (Feb 21 2013) and a few changes have been made. In particular the features have been redistributed between multiple tools, following the unix philosophy.

  • hexinject remains the main sniffer and injector.
  • prettypacket disassembles raw packets (received on its standard input) and print their field. It can also print example packets (useful if you want to know the structure of an header).
  • hex2raw converts hexstring (the textual format used by hexinject) to raw data, and vice-versa. A basic xxd tool.
  • packets.tcl is an experimental packet forger, written in TCL. It uses a simple packet representation format based on APD (http://wiki.hping.org/26). The output of the tool can be piped to hexinject raw inject mode.

With this new organization it is easier to create powerful shell pipelines, including also external tools.

Intro

HexInject is a very versatile packet injector and sniffer, that provide a command-line framework for raw network access.

It's designed to work together with others command-line utilities, and for this reason it facilitates the creation of powerful shell scripts capable of reading, intercepting and modifying network traffic in a transparent manner.

usage

In a single line, why should you consider hexinject? Because it's able to inject anything into the network, and, for the TCP/IP protocols, it automatically calculates the checksum and the packet size fields.

There are few tools that provide this functionality, and fewer that can be combined with the standard command-line utilities. Try it out!

HexInject as sniffer

Hexinject can be used as sniffer when the options "-s" is provided. It can print network traffic in both hexadecimal and raw format.
Example:

root@backtrack-base# hexinject -s -i eth0
1C AF F7 6B 0E 4D AA 00 04 00 0A 04 08 00 45 00 00 3C 9A 88 40 00 40 06 51 04 C0 A8 01 09 5B 05 32 79 C9 45 01 BB 61 5E 85 79 00 00 00 00 A0 02 16 D0 0D 2F 00 00 02 04 05 B4 04 02 08 0A 00 0D 22 EC 00 00 00 00 01 03 03 07 FF FF FF FF FF FF AA 00 04 00 0A 04 08 06 00 01 08 00 06 04 00 01 AA 00 04 00 0A 04 C0 A8 01 09 00 00 00 00 00 00 C0 A8 01 04
AB 00 00 03 00 00 AA 00 04 00 0A 04 60 03 22 00 0D 02 00 00 AA 00 04 00 0A 04 03 DA 05 00 00 00 00 00 00 00 00 00 AA 00 04 00 00 00 0A 00 00 02 AA AA FF FF FF FF FF FF AA 00 04 00 0A 04 08 06 00 01 08 00 06 04 00 01 AA 00 04 00 0A 04 C0 A8 01 09 00 00 00 00 00 00 C0 A8 01 04


But what about reading in real time what passes for the network? For example we can print in readable format some HTTP headers:

root@backtrack-base# hexinject -s -i eth0 -r | strings | grep 'Host:'
Host: youtube.com
Host: www.youtube.com
Host: s.ytimg.com
...


In this case the "raw dump" mode must be used. With "strings" we extract all the readable text from the network, and then it's easy to "grep" what we need...

HexInject as injector

Hexinject can be used as injector when the options "-p" is provided. It can inject network traffic in both hexadecimal and raw format.
Example:

root@backtrack-base# echo "01 02 03 04" | hexinject -p -i eth0

produce the following result in wireshark:

usage

Let's do some magic

With hexinject we can easily modify network packets on-the-fly. For example we can transform an ARP request in an ARP response just changing one bit of the packet:

root@backtrack-base# hexinject -s -i eth0 -c 1 -f 'arp' | replace '06 04 00 01' '06 04 00 02' | hexinject -p -i eth0

Wireshark dump:

usage

We have only piped two hexinject (one sniffer and one injector) and the command-line utility "replace". In this example the option "-f" is used to provide a custom pcap filter (more info here).

Here's one last example to conclude the presentation of the tool. A simple transparent bridge built using only two lines of bash:

root@backtrack-base# hexinject -s -i eth0 -c 1 -f 'src host 192.168.1.9' | hexinject -p -i eth1
root@backtrack-base# hexinject -s -i eth1 -c 1 -f 'dst host 192.168.1.9' | hexinject -p -i eth0

Et voila! A transparent bridge for the host 192.168.1.9. Actually this example can surely be improved, it just demonstrate the versatility of the tools.
usage
It's even possible to emulate NAT opportunely replacing the IP:

root@backtrack-base# hexinject -s -i eth0 -c 1 -f 'src host 192.168.1.9' | replace 'C0 A8 01 09' 'C0 A8 01 04' | hexinject -p -i eth1
root@backtrack-base# hexinject -s -i eth1 -c 1 -f 'dst host 192.168.1.9' | replace 'C0 A8 01 04' 'C0 A8 01 09' | hexinject -p -i eth0

Note: these two examples lack the management of MAC addresses, that can be implemented as a script placed in the middle of the pipe. Nevertheless the examples give an idea of what is possible to do.

Raw wireless access

Do you think that accessing raw wireless traffic require strange and complex libraries and is difficulto to implement? This is not true at all: with hexinject even a simple bash script can read raw wireless traffic on a monitor interface.

wifi
First of all the interface must be put in monitor mode:

root@backtrack-base# airmon-ng start wlan1
Interface Chipset Driver

wlan1 RTL8187 rtl8187 - [phy0]
(monitor mode enabled on mon0)
Then it's possible to capture, for example, beacon frames generated by an access point:

root@backtrack-base# hexinject -s -i mon0
00 00 0D 00 04 80 02 00 02 00 00 00 00 80 00 00 00 FF FF FF FF FF FF AA BB CC DD EE FF AA BB CC DD EE FF 70 01 42 BB 6B EB AC A6 04 00 64 00 01 04 00 07 44 45 46 41 55 4C 54 01 04 02 04 0B 16 32 08 0C 12 18 24 30 48 60 6C 03 01 01
00 00 0C 00 04 80 00 00 02 00 18 00 80 00 00 00 FF FF FF FF FF FF AA BB CC DD EE FF AA BB CC DD EE FF 80 01 CD 46 6D EB AC A6 04 00 64 00 01 04 00 00 01 04 02 04 0B 16 32 08 0C 12 18 24 30 48 60 6C 03 01 01

The access point has ESSID "DEFAULT".
To extract this information we can use a feature introduced with hexinject v1.3, the conversion modes. These operation modes simply convert and hexadecimal string to a raw string and vice-versa.
Let's suppose we saved the last packet in the file wifi_frame.hex (the ESSID will be clearly printed out with some garbage data...):

root@backtrack-base# cat wifi_frame.hex | hexinject -y | strings
DEFAULT
$0H`l

The possibilities are not limited to sniff, what's most interesting is the injection of raw wireless frames. To inject a frame we need a minimal valid preamble (otherwise the injerface will not inject anything):

root@backtrack-base# cat minimal_beacon.hex
00 00 0D 00 04 80 02 00 02 00 00 00 00 80 00 00 00

To remain simple, we prepare a raw ascii message to inject and convert it to an hexstring (adding a 00 at the end to terminate the string):

root@backtrack-base# echo 'Hello, world!' | hexinject -x
48 65 6C 6C 6F 2C 20 77 6F 72 6C 64 21 0A 00

We can now inject everything in the air:

root@backtrack-base# cat assembled_packet.hex | hexinject -p -i mon0

If another machine wants to read the message:

root@backtrack-base# hexinject -s -r -i mon1 | strings
Hello, world!

It's very easy to write, even in bash, a simple messaging tool that uses raw wireless frames (even if such a tool sounds weird).
Or you can use hexinject as a wireless fuzzer to search vulnerabilities in operating system wireless drivers.
It's easy: don't hesitate to experiment!

Other possibilities: USB

Since pcap libraries can capture raw USB traffic, hexinject is able to sniff on your USB ports. You can capture raw USB packets, in the same way you use hexinject on your network interfaces:

root@backtrack-base# hexinject -s -i usbmon3
80 3A DF 2A 01 88 FF FF 43 01 81 02 03 00 2D 00 8D 43 E7 4D 00 00 00 00 AA 38 00 00 00 00 00 00 06 00 00 00 06 00 00 00 00 00 00 00 00 00 00 00 08 00 00 00 00 00 00 00 04 02 00 00 00 00 00 00 01 00 00 00 00 00
80 3A DF 2A 01 88 FF FF 53 01 81 02 03 00 2D 3C 8D 43 E7 4D 00 00 00 00 BD 38 00 00 8D FF FF FF 06 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 08 00 00 00 00 00 00 00 04 02 00 00 00 00 00 00


usb
I've written an article on the recognition of mouse clicks using hexinject and awk. Just a brief excerpt:

root@backtrack-base# sudo hexinject -s -i usbmon3 | awk -f mouse_click.awk
left click
click released
central click
click released
left+right click
click released


If you want to read the article: Fun with HexInject and USB protocols

Packet disassembling and pretty printing

Since version 1.4, hexinject can disassemble and print the fields of captured packets, and from version 1.5 it's the tool prettypacket that do the actual packet disassembling and printing.
This feature is very simple to use, and allows to inspect in detail every part of the supported protocols:

root@backtrack-base# hexinject -s -r | prettypacket 
           
Ethernet Header:
 AA 00 04 00 0A 04        Destination hardware address
 1C AF F7 6B 0E 4D        Source hardware address
 08 00                    Type

IP Header:
 45                       Version / Header length
 00                       ToS / DFS
 00 3E                    Total length
 00 00                    ID
 40 00                    Flags / Fragment offset
 35                       TTL
 11                       Protocol
 D6 DD                    Checksum
 D0 43 DC DC              Source address
 C0 A8 01 09              Destination address

UDP Header:
 00 35                    Source port
 EA 94                    Destination port
 00 2A                    Length
 38 01                    Checksum

Payload:
 5D 5B 81 80 00 01 00 00 00 00 00 00 03 77 77 77 01
 6C 06 67 6F 6F 67 6C 65 03 63 6F 6D 00 00 0F 00 01

 ----------- 

Ethernet Header:
 1C AF F7 6B 0E 4D        Destination hardware address
 AA 00 04 00 0A 04        Source hardware address
 08 00                    Type

IP Header:
 45                       Version / Header length
 00                       ToS / DFS
 00 54                    Total length
 00 00                    ID
 40 00                    Flags / Fragment offset
 40                       TTL
 01                       Protocol
 54 4E                    Checksum
 C0 A8 01 09              Source address
 C0 A8 64 01              Destination address

ICMP Header:
 08                       Type
 00                       Code
 4C 66                    Checksum
 3A 48                    ID
 00 01                    Sequence number

Payload:
 0D 1F DE 4E 00 00 00 00 B8 0F 0F 00 00 00 00 00 10
 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20 21
 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32
 33 34 35 36 37

 ----------- 

  ...
With the option -x, prettypacket can print a single disassembled packet of the specified protocol, reading it from its collection of example packets. I use this feature to have a quick reference of various protocol headers.

So, if you need to know the size of the TCP Sequence Number field, you no longer need to capture a packet or search a diagram on the web, just use:

root@backtrack-base# prettypacket -x tcp

Currently supported protocols are: tcp, udp, icmp, igmp, arp, stp (and, of course, protocols on lower layers: ethernet, ip).

Adding a new protocol is easy: you can add your disassemble function in the file prettypacket.c, using the simple interface provided.

Conclusion

The possibilities are virtually endless. Enjoy! ;)