Grepping Packets With ngrep
By stretch | Friday, May 14, 2010 at 3:51 a.m. UTC
If Wireshark and tcpdump can be considered packet sniffing toolboxes, ngrep is a handy little multi-tool. Short for "network grep," ngrep can be used to extract from the wire packets which match a given regular expression. For example, suppose you're in the midst of troubleshooting and need to look for all (non-secured) HTTP connections. You can use ngrep to match for tell-tale HTTP requests:
stretch@Sandbox ~ $ ngrep -q -W byline "GET|POST HTTP" interface: eth0 (192.168.10.0/255.255.255.0) match: GET|POST HTTP T 192.168.10.101:52965 -> 126.96.36.199:80 [AP] GET / HTTP/1.1. Host: packetlife.net. User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:188.8.131.52) Gecko/20100402 Ubuntu/9.10 (karmic) Firefox/3.5.9. Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;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. .
By default, ngrep will output a hash (#) for every packet it receives; this can be suppressed with the
-W byline formats the output into a more legible format.
The match expression can be combined with a pcap filter. For example, suppose we wanted to look for DNS traffic mentioning packetlife.net:
stretch@Sandbox ~ $ ngrep -q -W byline packetlife.net udp port 53 interface: eth0 (192.168.10.0/255.255.255.0) filter: (ip or ip6) and ( udp port 53 ) match: packetlife.net U 192.168.10.101:58325 -> 184.108.40.206:53 .i.......... packetlife.net..... U 220.127.116.11:53 -> 192.168.10.101:58325 .i.......... packetlife.net..................................dns2.stabletransit.com..............dns1.A.`..........E._..<..........A=..
ngrep also sports the ability to reset the TCP session of a matching packet. For example, if we wanted to detect and terminate cleartext passwords being sent over Telnet we could do something like this:
stretch@Sandbox ~ $ sudo ngrep -q -K 1 -i password tcp interface: eth0 (192.168.10.0/255.255.255.0) filter: (ip or ip6) and ( tcp ) match: password T 192.168.20.2:23 -> 192.168.10.101:44262 [AP] Password: 192.168.20.2:23 > 192.168.10.101:44262: R 2167814027:2167814027(0) win 0
-K specifies the number of RST packets to spoof, and
-i is used to ignore letter case.
Obviously this isn't a permanent filtering solution, but it can be quite handy should one need to improvise a solution on the spot.
About the Author
Jeremy Stretch is a network engineer living in the Raleigh-Durham, North Carolina area. He is known for his blog and cheat sheets here at Packet Life. You can reach him by email or follow him on Twitter.
Posted in Resources
May 14, 2010 at 8:17 a.m. UTC
That is rather awesome, just having a play with it now, I can see this being VERY useful
May 14, 2010 at 2:07 p.m. UTC
That's awesome! I'll definitely nab this today and give it a go.
May 14, 2010 at 10:40 p.m. UTC
It's very useful post... Thanks ! very nice tool...
May 15, 2010 at 3:05 p.m. UTC
Thanks for sharing, works great on MAC OS X !
May 19, 2010 at 9:38 p.m. UTC
Pretty nice command and really very useful to filter the large package data.
May 23, 2013 at 7:38 p.m. UTC
scary app of the day :)
April 2, 2014 at 6:37 p.m. UTC
You should also try out CapLoader. It can extract all packets from a matched TCP/UDP flow, i.e. not just the packet that matched. CapLoader also supports several different encodings, which minimizes the risk of not finding what you're looking for.
CapLoader is available at http://caploader.com
May 19, 2014 at 6:04 a.m. UTC
Hi there, Thanks for the post. I'm just wondering if ngrep could count tcp flags (e.g syn). Do you have any idea?