tshark piping output results in packet counter - tshark

When I try to pipe tshark output to anything I cannot see the traffic any longer. Tshark just shows a packet counter. How can I prevent this?
sudo tshark -i enp60s0 -f "tcp" -T fields -e ip.src -e ip.dst -e tcp.srcport -e tcp.dstport -e tcp.checksum -e tcp.options -E header=y | column -t

Context
For context, this is the command and output you are talking about:
$ sudo tshark -i enp60s0 -f "tcp" -T fields -e ip.src -e ip.dst -e tcp.srcport \
-e tcp.dstport -e tcp.checksum -e tcp.options -E header=y | column -t
Capturing on 'Eth: enp60s0'
45
Tshark will send control information like where it's capturing and the packet count to stderr instead of stdout. If you don't want to see this control information, send stderr to dev null:
$ sudo tshark ... 2>/dev/null | column -t
Method
We can also continuously generate a new capture every second that we can then read with tshark (see tshark's manpage for full details). This is similar to #ChristopherMaynard's solution, but you don't need to wait for the capture to finish. Saving (-w) with the -b duration:1 will save a new capture every second:
#!/usr/bin/env bash
sudo tshark -w temp.pcap -b duration:1 2>/dev/null &
i=0
while true
do if [ "$i" != "$(ls -1A . | wc -l)" ]; then
newfile="$(ls -t | head -n1)"
sudo tshark -r "$newfile" 2>/dev/null | column -t
fi
sleep 0.1
done
Verification
Running this, we get output like below. Note that we are reading new packet captures, so tshark adds numbers starting at 1 for each new capture it's reading.
1 0.000000 192.168.2.1 → 192.168.2.242 DNS 134 Standard query response 0xfd75 No such name PTR 1.2.168.192.in-addr.arpa SOA localhost 6c:96:cf:d8:7f:e7 ← 78:8a:20:d9:f9:11
2 0.000412 192.168.2.242 → 192.168.2.1 DNS 87 Standard query 0x2a9b PTR 249.249.16.104.in-addr.arpa 78:8a:20:0d:05:e7 ← 6c:96:cf:d8:7f:e7
3 0.023726 192.168.2.1 → 192.168.2.242 DNS 149 Standard query response 0x2a9b No such name PTR 249.249.16.104.in-addr.arpa SOA cruz.ns.cloudflare.com 6c:96:cf:d8:7f:e7 ← 78:8a:20:d9:f9:11
4 0.024091 192.168.2.242 → 192.168.2.1 DNS 85 Standard query 0x2f71 PTR 40.2.168.192.in-addr.arpa 78:8a:20:0d:05:e7 ← 6c:96:cf:d8:7f:e7
1 1.026460 192.168.2.242 → 192.168.2.255 UDP 86 57621 → 57621 Len=44 ff:ff:ff:ff:ff:ff ← 6c:96:cf:d8:7f:e7
2 1.048071 192.168.2.1 → 192.168.2.242 DNS 135 Standard query response 0x2f71 No such name PTR 40.2.168.192.in-addr.arpa SOA localhost 6c:96:cf:d8:7f:e7 ← 78:8a:20:d9:f9:11
3 1.048555 192.168.2.242 → 192.168.2.1 DNS 87 Standard query 0xe77d PTR 25.206.252.198.in-addr.arpa 78:8a:20:0d:05:e7 ← 6c:96:cf:d8:7f:e7
4 1.125073 192.168.2.1 → 192.168.2.242 DNS 118 Standard query response 0xe77d PTR 25.206.252.198.in-addr.arpa PTR stackoverflow.com 6c:96:cf:d8:7f:e7 ← 78:8a:20:d9:f9:11

The column command needs to read all of the input in order to decide how wide to make each column, so you can't use column in this context. (You can test this by issuing your tshark command and then elsewhere issuing a killall tshark and you will then see all your output.
Instead, I think you will have to redirect your output to a file and then once you're finished your tshark capture session, you can cat file | column -t if you want. If you want to see the output on the screen as well as redirect it to a file for later processing, you can pipe it to tee and provide tee with the name of the file to write to. For example, tshark [options] | tee file, but the output you see won't be as nicely formatted until you later do cat file | column -t.

Related

What are tshark's default output fields?

I'm trying to expand tshark's output. On the first round I haven't found simple solution, only that one can extract a field by the -e option, so the following command outputs
frame number
time from beginning of capture
source ip address
destination ip address
http request uri
and the http content lenght, which I want to add to the default output.
tshark -T fields -e frame.number -e frame.time_relative -e ip.src -e ip.dst http.request.uri -e http.content_length
My problem is, that I can't find the default output field names or an option that leaves them and append the desired fields to it.
It's not mandatory, but would be nice to know : )
This is not exactly the default output but comes quite close:
tshark -T fields -e frame.number -e frame.time_delta -e _ws.col.Source -e _ws.col.Destination -e _ws.col.Protocol -e ip.len -e _ws.col.Info

Using /proc/<pid>, how can I identify a network port number's application?

I'm trying to identify what application is running on port 56474 without having root access. I know the application was started by me.
Example:
netstat -tunap
tcp 0 0 0.0.0.0:56474 0.0.0.0:* LISTEN -
I've tried using /proc/pid scripts to walk all using grep on ls -l /proc/pid/fd results. Here is my attempt. NOTE: Not sure if I was heading the right direction
for I in `find /proc/*/fd -exec ls -l {} \; 2>/dev/null | awk -F"->|:" '/socket/ {print $4}' | sort -u | sed -e 's/\[//g' -e 's/\]//g'`; do grep $I /proc/*/net/tcp; done
I had no success. Not sure if there is a way. Thanks.
NOTE: Added another answers as lsof was not satisfactory.
This should work:
#! /bin/bash
port=56474
hex_port=$(echo "obase=16; $port" | bc )
inode=$(cat /proc/net/tcp | grep ":$hex_port" | awk '{print $10}')
for i in $(ps axo pid); do
ls -l /proc/$i/fd 2> /dev/null | grep -q ":\[$inode\]" && echo $i
done
Explanation:
Once we have the port number converted to Hexadecimal, we can get the inode number from /proc/net/tcp (10th field), then we loop through /proc/pids/fd and find a symlink pointing to the inode.
If you're sure the application was started by you then you can use lsof:
/usr/sbin/lsof -nP | grep :56474 | awk '{print $2}'
Another technique to resolve pids and ports of all running apps without root:
1.) Get the pids of running apps. Either use the ActivityManager or parse a ps console output.
2.) iterate through /proc/$pid/net/status files and get the matching uid for a pid.
cat /proc/*pid*/net/status | grep Uid:
3.) Call and parse the output of tcp, tcp6,udp, udp6 files to match ports and uids:
cat /proc/net/tcp
...
4.) match the uids of both matchings, get a port-to-pid map without su access.
Cheers,
goethe

Bash: how to make a substitution in a "live" pipe?

In my office firewall I use a command like this:
$ sudo tcpdump -v -s 1500 -i eth0 port 25 | grep 'smtp: S'
to monitor LAN clients sending mail (I need to early detect any possible spammer bot from some client, we have very looooose security policies, here... :-().
So far, so good: I have a continuous output as soon any client sends an email.
But, if I add some filter to get a cleaner output, something like this:
$ sudo tcpdump -v -s 1500 -i eth0 port 25 | grep 'smtp: S' | perl -pe 's/(.*?\)) (.*?)\.\d+ \>(.*)/$2/'
(here I intend to get only source ip/name), I do not get any output until tcpdump output is more than (bash?) buffer size... (or at least I suppose so...).
Nothing changes using 'sed' instead of 'perl'...
Any hint to get a continuous output of filtered data?
Put stdbuf before the first command:
sudo stdbuf -o0 tcpdump ...
But, if I add some filter to get a cleaner output, something like
this:
Use the --line-buffered option for grep:
--line-buffered
Use line buffering on output. This can cause a performance
penalty.
try maybe a sed --unbuffered (or -u sometimes like on AIX) to have a stram version (not waiting the EOF)

Unable to get Grep get information in Terminal

I'm unable to get 'get' in terminal using Grep.
This code used to work on Lion but in Maverick the GET doesn't show...
sudo tcpdump -i en1 -n -s 0 -w - | grep -a -o -E "Host\:\ .*|GET\ \/.*"
Any help or suggestions maybe?
Try:
sudo tcpdump -s 0 -A | egrep --color=never -a -o "Host\: .*|GET\ \/.*"
The -w - writes the raw packets whereas the -A decodes to ASCII; handy for web pages (per man)
I found that if grep was outputting color, the Host: lines were output as empty lines.

Nmap scan range output file problem

Okay, I want to have Nmap scan an IP range for computers with a certain port open (port 80 in this case) and have it output all the IP's it finds into a text file, stored in this format:
192.168.0.1
192.168.0.185
192.168.0.192
192.168.0.195
So to output the file, I tried using this command:
nmap -sT -p 80 -ttl 40 192.168.0.0-255 -oG - | grep "80/open" > output.txt
Where "output.txt" is the output file that contains the results. So a line of output.txt looks
like this:
Host: 192.168.0.1 () Ports: 80/open/tcp//http///
So I basically want it only to output the IP address with port 80 open, and nothing else.
I want it to not output the "Host: " or the "()" and "Ports: 80/open/tcp//http///" lines. So is there anyway I can have Nmap not put that stuff into the output file? Or make it only
output the IP addresses? I tried looking at the map page, it was of little help. And I looked all over the Internet and that wasn't very useful either. So does anyone know how I can do this? Thanks
Awk is your friend!
$ nmap -sT -p 80 192.168.0.0/24 -oG - | awk '/ 80\/open/{print $2}' > output.txt
This will find lines with port 80 open (notice the space before 80, if you plan to scan more than the one port!), and print field 2, splitting on whitespace. Another way to do it would be:
$ nmap -sT -p 80 --open 192.168.0.0/24 -oG - | awk '$4=="Ports:"{print $2}' > output.txt
This one uses the --open argument to Nmap to only produce output for hosts with open ports. The awk command checks that this is a "Ports" line, not a "Status" line (which may only show up when using -v, but I'm not positive) before printing the IP address.
Note that it is usually in your best interests to save the scan results to a file, to avoid needing to repeat the scan if you decide to extract some different information. If you choose to do this, I would recommend using the XML output (-oX), since there are lots of analysis tools that have parsers built for it already.
Having nmap produce exactly what you want would indeed be nice. But as a more general solution:
$ nmap ... | grep ... | tr '/' ' ' | awk '{ print $2,$5; }
192.168.0.1 80
Or maybe:
nmap ... | grep ... | tr '/' ' ' | cut -d' ' -f2,8
I found a script called scanreport.sh very useful. Although its not necessary, you could just use awk as suggested, but thought it might be of interest.
It gives the ability to output the nmap results nicely by service or port (with highlighting). It uses the grep-able output from nmap (-oG) after a quick tidy from grep -v ^# nmapoutput.txt > report.txt
Example
nmap -sS 192.168.1.22 -oG /directory/of/choice/results.txt
grep -v ^# results.txt > report.txt
./scanreport.sh -f report.txt
Host: 192.168.1.22 ()
22 open tcp ssh OpenSSH 5.3p1 Debian 3ubuntu4 (protocol 2.0)
80 open tcp http Apache httpd 2.2.14 ((Ubuntu))
./scanreport.sh -f report.txt -p 80
Host: 192.168.1.22 ()
80 open tcp http Apache httpd 2.2.14 ((Ubuntu))
./scanreport.sh -f report.txt -s ssh
Host: 192.168.1.22 ()
22 open tcp ssh OpenSSH 5.3p1 Debian 3ubuntu4 (protocol 2.0)
Plenty of stuff on google about it but here a link to one ref.
./scanreport.sh