Tshark logging by local username

RogueKnight :

I'm trying to attribute network traffic in a tshark dump with the logged in user that the respective traffic is associated with.

I'm running an Ubuntu server on a corporate network in which users log into either via RDP or SSH with x-forwarding. My application is written in bash and uses tshark to log all network traffic using the following command:

 tshark -b filesize:1024 -w traffic.pcap

I then have a while loop that runs on a chron job to parse through the pcap files, extract the fields I want, and save them to json:

for f in *.pcap
do
    tshark -r $f -T json > $f.json
    cat $f.json | jq .[]._source.layers | jq -r '.frame_time_epoch[],.frame_number[],.tcp_stream[],.ip_src[],.tcp_srcport[],.ip_dst[],.tcp_dstport[],.frame_len[],.frame_protocols[],.http_host[],.http_request_uri[],.http_request_method[],.http_user_agent[],.http_referer[],.dns_qry_name[],.dns_resp_name[],.ssl_handshake_extensions_server_name[],.x509sat_uTF8String[],.x509ce_dNSName,"END"' > injest.json
done

The output json which looks like the following is then sent to an Elasticsearch cluster I have set up:

{
"layers": {
    "frame.time_epoch": ["1579755811.545369005"],
    "frame.number": ["3508"],
    "tcp.stream": ["0"],
    "ip.src": ["10.0.10.10"],
    "tcp.srcport": ["22"],
    "ip.dst": ["1.1.1.1"],
    "tcp.dstport": ["54116"],
    "frame.len": ["102"],
    "frame.protocols": ["eth:ethertype:ip:tcp:ssh"]
    }
}

I'd like to know if there is anyway I can have the Linux username added to the packet capture or as an additional field in the final json before it is sent to ELK.

In other words if 'user_a' and 'user_b' are both logged into the server I'd like their respective internet traffic to log there usernames. Is this at all possible with tshark? I've read that iptables can "tag" traffic but I'm not sure exactly how it works and if it would accomplish what I'm trying to do.

Ross Jacobs :

Logging users by packets sent

I'd like to know if there is anyway I can have the Linux username added to the packet capture

This is possible by adding a capture comment as detailed below

or as an additional field in the final json before it is sent to ELK.

while this is not because tshark does not know how to show you pcapng header options, even though it can read them (Wireshark can do this with reload as file format/capture).

In other words if 'user_a' and 'user_b' are both logged into the server I'd like their respective internet traffic to log their usernames. Is this at all possible with tshark?

No, this is not possible with tshark. It looks like it's possible to use auditctl to get the PIDs, and then find the users that created the PIDs. With the usernames thusly gathered, you could integrate into the flow below.

Adding a capture comment

To get the active usernames, you can use something like this:

names="$(who | cut -d ' ' -f 1 | sort | uniq)"

To save as part of the packet capture, use tshark's --capture-comment to add additional information. Note that this option is only available if you save as pcapng. The default save-type is pcapng. If you're unsure, you can use captype $file, where captype comes with Wireshark.

tshark -b filesize:1024 -w traffic.pcap --capture-comment "$names"

Extracting the capture comment

tshark doesn't have a way to extract a capture-level comment, so I'm using python, with knowledge of pcapng's binary format to extract the comment:

import struct

def read_header(infile, header_code):
  with open(infile, "rb") as f:
      filebytes = f.read()
  header_len = struct.unpack("iill", filebytes[:24])[1]
  header = filebytes[24:24+header_len]
  seek = 24
  while seek < header_len:
      opt_code, opt_length = struct.unpack("hh", filebytes[seek:seek+4])
      if opt_code == header_code:
          value = filebytes[seek+4:seek+4+opt_length].decode('utf-8')
          return value
      seek += 4 + opt_length
  return ""

comment_option_code = 1
comment = read_header("traffic.pcap", comment_option_code)
print(comment)

Provided a user_a and user_b in $names, this would then print

user_a user_b

Adding to the JSON

You can then append the data to your existing json like so:

echo '{"data": "values"}' | jq --arg names "${names}" '. + {users:$names}'
{
  "data": "values",
  "users": "user_a user_b"
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=21854&siteId=1