July 19, 2005

Network monitoring with ngrep

Author: Mayank Sharma

Constant monitoring and troubleshooting are key to maintaining a network's availability. With ngrep, you can analyze network traffic in a manner similar to that of other network sniffers. However, unlike its brethern, ngrep can match regular expressions within the network packet payloads. By using its advanced string matching capabilities, ngrep can look for packets on specified ports and assist in tracking the usernames and passwords zipping off the network, as well as all Telnet attempts to the server.

Ngrep uses the libpcap library, and can also take hexadecimal expressions for which to capture network traffic. It supports TCP, UDP, ICMP, IGMP, and Raw protocols across Ethernet, PPP, SLIP, FDDI, Token Ring, 802.11, and null interfaces. In addition to listening to live traffic, ngrep can also filter previous tcpdump grabs.

Author Jordan Ritter says that ngrep has traditionally been used to debug plaintext protocol interactions such as HTTP, SMTP, and FTP; to identify and analyze anomalous network communications, such as those between worms, viruses, and zombies; and to store, read, and reprocess pcap dump files while looking for specific data patterns.

You can also use ngrep to do the more mundane plaintext credential collection, as with HTTP basic authentication or FTP or POP3 authentication. Like all tools, it can be useful in the right hands and damaging if used by those with less than admirable intentions.

Before installing the 400-odd KB utility, make sure you have the libpcap library. If you use tcpdump, you have it. Download ngrep, unpack, and install it as root with./configure, make, make install.

Start sniffing

You can run ngrep only as root. If you invoke it without any options, it will listen to all traffic on the current interface. That's no fun, so let's see who's searching Google by specifying a keyword to look for, along with a port. By the way, while all the examples below are valid and will work, real-life situations will likely require complex pattern-matching strings that could span across multiple lines.

# ngrep google port 80
interface: wlan0 (
filter: ip and ( port 80 )
match: google
T -> [AP]
GET / HTTP/1.1..Host: google.com..User-Agent: Mozilla/5.0 (X11; U; Linux i6
86; en-US; rv:1.7.6) Gecko/20050419 OpenLX/1.7.6-1.olx..Accept: text/xml,ap
plication/xml,application/xhtml+xml,text/html;q=0. 9,text/plain;q=0.8,image/
png,*/*;q=0.5..Accept-Language: en-us,en;q=0.5..Accept-Encoding: gzip,defla
te..Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7..Keep-Alive: 300..Connec
tion: keep-alive..Cookie: PREF=ID=6bfa2ae9c8bf1894:CR=1:TM=1118348709:LM=11

The # marks denote traffic that doesn't match our keyword.

Now let's look for people misusing bandwidth:

# ngrep -i 'game*|chat|recipe' -W byline > bad_user.txt

Pipes (|) delimit each key word, one of which is specified with a wildcard. -i makes the search case-insensitive and -W in the byline mode produces a cleaner report which is sent to a file. Here's how it looks:

interface: wlan0 (
match: game*|chat|recipe
T -> [AP]
GET/search?hl=en&safe=off&q=online+games&btnG=Search& meta= HTTP/1.1.
Host: www.google.co.in.
User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.7.6) Gecko/20050419 OpenLX/1.7.
Accept: text/xml,application/xml,application/xhtml+xml,tex t/html;q=0.9,text/plain;q=0.8,
Accept-Language: en-us,en;q=0.5.
Accept-Encoding: gzip,deflate.
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7.
Keep-Alive: 300.
Connection: keep-alive.
Referer: http://www.google.co.in/search?hl=en&q=hello&btnG= Google+Search&meta=.
Cookie: PREF=ID=7c5bf916f28d16c7:FF=4:LD=en:NR=10:TM=11183 48709:LM=1118348731:S=20ZkQG0Y

To monitor current email transactions and print the addresses:

# ngrep -i 'rcpt to|mail from' tcp port smtp
interface: wlan0 (
filter: ip and ( tcp port smtp )
match: rcpt to|mail from
T -> [AP]
MAIL From: SIZE=192..

T -> [AP]
RCPT To:..

Ngrep can resolve a port address by matching the port name in the/etc/services file, so it'll substitute 25 in place of smtp.

You can also timestamp the grabs:

# ngrep -q -t -wi "login" port 23

This command will watch Telnet traffic through port 23 for the word "login" case-insensitively and timestamp it in the YYYY/MM/DD HH:MM:SS.UUUUUU format. -q ensures nothing else is printed.

Let's timestamp all traffic on port 53 (DNS) on all devices (if the box has multiple devices) and send the output to a pcap file specified by the -O switch:

# ngrep -O ~/logs/traffic.dump -d any -T port 53

We use the -I switch to instruct ngrep to match the specified pattern on a file rather than on live traffic. To look for all domains except.net:

# ngrep -tv '*.net' -I ~/logs/traffic.dump

The -v switch inverts the specified pattern, so we get every domain except.net, printed with timestamps because of the -t switch.


For a network administrator familiar with pattern matching with grep, ngrep requires a minimum of training. Wrapping ngrep up in Perl scripts and bundling the scripts in a cron job can help create 5:00p.m. daily system check reports. For an example, see hack #60 from O'Reilly's "Linux Server Hacks" book.

Ngrep can match patterns only within a packet. If you want to detect malicious strings hidden across multiple small packets, use SNORT.

Click Here!