In this recipe we will see how to force Tshark to use the correct dissector when a certain protocol runs in an uncommon port. We also see how to decode SSL traffic through a real example.
In the following example, a user has established a SSH connection on port 1865 (instead of 22). If we dump one of these packets, we see that Tshark tries to interpret that protocol as LeCroy VICP instead of SSH:
bmerino@Mordor:/$ tshark -r ssh.pcap -R "frame.number==9" -V | grep "LeCroy VICP" -A 5 LeCroy VICP Operation: 0x35 Protocol version: 54 Sequence number: 44 Unused: 0x61 Data length: 1919116911
This occurs because Tshark has registered in its dissector table that protocol on port 1865. We can verify this by looking at the code of the VICP dissector where the port is defined:
bmerino@Mordor:~/wireshark-1.8.4/epan/dissectors$ grep 1861 packet-vicp.c #define VICP_PORT 1861
We can even check for errors when processing that packet with the following command:
bmerino@Mordor:/$ tshark -r ssh.pcap -R "frame.number==9" -z expert,error
This would generate the following output:
9 0.092346 192.168.1.130 -> 192.168.1.129 VICP 182 Errors (8) ============= Frequency Group Protocol Summary 8 Malformed VICP Malformed Packet
Since Tshark uses the wrong dissector to attempt to decode each of the fields of the application layer, certain errors are generated. To fix this and force Tshark to use the correct dissector, SSH in this case, we can use the
-d
option as follows:bmerino@Mordor:/$ tshark -r ssh.pcap -R "frame.number==9" -xV -d tcp.port==1861,ssh | grep SSH -A 6
This would generate the following output:
SSH Protocol SSH Version 2 Packet Length: 636 Padding Length: 6 Key Exchange Msg code: Key Exchange Init (20) Payload: 9590c35921b9174f1f77e537541d8baa0000009a64696666...
In addition to providing this flexibility with dissectors, Tshark also allows us to decrypt SSL traffic. To decrypt SSL, Tshark requires GnuTLS; thus, if you've compiled it on your own, be sure to count on it before running Tshark. Check it with:
bmerino@Mordor:/$ tshark -v | grep GnuTLS
This would generate the following output:
Python, with GnuTLS 2.12.14, with Gcrypt 1.5.0, with MIT Kerberos, with GeoIP
Later we will need the private key of our web server in PEM format:
root@Mordor:/etc/apache2/sites-available# grep CertificateKeyFile default SSLCertificateKeyFile /etc/ssl/private/server.key
If the key is protected with a passphrase, we have to generate a new file without it so that Tshark can use it. In the event that the key has a passphrase, the beginning of the file will look as follows:
root@Mordor:/tmp# head -3 server.key -----BEGIN RSA PRIVATE KEY----- Proc-Type: 4,ENCRYPTED DEK-Info: DES-EDE3-CBC,8569B93914A0C185
To generate a new key without a passphrase, we can use OpenSSL:
root@Mordor:/tmp# openssl rsa -in server.key -out s.key root@Mordor:/tmp# head -2 s.key
This would generate the following output:
-----BEGIN RSA PRIVATE KEY----- MIICXQIBAAKBgQDCpebxgLv4lndaaVwubDD8+qqE5tfJZ96ECiyXvRbTyQTWRi
If our key is now like the preceding output, we are ready to decrypt SSL traffic. To do it run the following command:
bmerino@Mordor:/tmp$ tshark -o "ssl.keys_list:192.168.1.129,443,http,s.key" -o "ssl.debug_file:rsa_private.log" -r ssl.pcap -R "ssl" -Vx > examine
where 192.168.1.129 is the IP of our web server and 443 the port used by SSL.
We can check the generated log to ensure that the key has been successfully loaded:
bmerino@Mordor:/tmp$ grep loaded rsa_private.log
This would generate the following output:
ssl_init private key file /tmp/s.key successfully loaded.
Now, we can analyze in the file each of the SSL sessions in detail. In the previous capture we can see SQLi attempts against the web server using one of the application parameters via POST requests. We can also see that the attacker did not even bother to remove the User-Agent, which reveals the type of tool used.
Sometimes, Tshark applies the wrong dissector to interpret certain protocols. This happens, for example, when an application protocol runs on a different port than the standard (for example, when we run HTTP over port 4444 instead of port 80). We can force Tshark to use the correct dissector with the –d
parameter. This option has the following syntax: -d <layer type>==<selector>,<decode-as protocol>
.If you want to get a list of valid dissectors, you can run tshark –d .
.
A really nice summary of how Tshark uses the dissector wisely can be read in this thread at http://www.wireshark.org/lists/wireshark-dev/200808/msg00252.html.
On the other hand, to decode SSL traffic we used the –o
option following the syntax -o ssl.keys_list:<ip>,<port>,<proto>,<keyfile> -o ssl.debug_file:<log-file>
.
Thanks to this function, we could see and analyze the payload of SSL traffic directed to our web server in plain text. Some attacks can use SSL data to try to evade firewalls (DPI), IDS/IPS, and so on; therefore, it would not be strange to decrypt SSL packets to investigate certain security incidents. In the previous example, an attacker has used Havij
through Stunnel
to perform SQLi attacks against a web server. After getting a shell, he has eliminated all possible system logs that might give clues to the type of attack conducted. Luckily for us, we got a pcap file of that connection an hour before the incident, so we were able to analyze it.
If you want to check the current preferences for SSL, you can run Tshark with the -G
option followed by defaultprefs
:
bmerino@Mordor:/tmp$ tshark -G defaultprefs | egrep "^#ssl"
This would generate the following output:
#ssl.debug_file: #ssl.keys_list: #ssl.desegment_ssl_records: TRUE #ssl.desegment_ssl_application_data: TRUE #ssl.ignore_ssl_mac_failed: FALSE #ssl.psk: #ssl.keylog_file
Maybe you are wondering how we can know which protocol is traveling in a non-standard port? If we don't know the protocol running, we could not select the right dissector for decoding that traffic. Well, the answer is simple: by investigating the data traffic. A good approach would be to consult the first packets exchanged, as it is in these packets where we could find banners, exchange keys, authentication attempts, or any other clue about the protocol. Here's an example. After seeing a high volume of traffic on port 23 (used by Telnet theoretically) we decided to check its contents. Not only the volume of traffic but the size of the packets made us suspect that possibly someone was using an other protocol over the telnet port. After checking the payload of one of the frames, we could confirm that it was not telnet. However, the payload did not give us any clues about the type of protocol being used so we decided to observe the first frames of the connection (after the "TCP handshake"). Quickly, we found out that a user was using VNC, thanks to the string RFB 004.001
.
Finally, it's important to note that Tshark can also decrypt Kerberos tickets from keytab files. This is possible by using the -K
option (-K krb5.keytab
).