Wireshark TLS

From UVOO Tech Wiki
Jump to navigation Jump to search

tshark -l -i any -f 'port 443' -Y "ssl.handshake.ciphersuites" -Vx

tshark -i wlan1mon -l -T fields -e wlan.bssid -e wlan.ssid -e radiotap.dbm_antsignal -Y 'wlan.ssid' | grep -v "ff:ff:ff"

Maybe -e wlan.rsn.pcs.type and -e wlan.rsn.gcs.type are what you're looking for? Those are for the Pairwise Cipher Suite type" and "Group Cipher Suite type", respectively. https://stackoverflow.com/questions/47645051/display-network-encryption-type-in-tshark

https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-4

Client Hello:

ssl.handshake.type == 1

Server Hello:

ssl.handshake.type == 2

NewSessionTicket:

ssl.handshake.type == 4

Certificate:

ssl.handshake.type == 11

CertificateRequest

ssl.handshake.type == 13

ServerHelloDone:

ssl.handshake.type == 14

Note: “ServerHellpDone” means full-handshake TLS session.

Cipher Suites:

ssl.handshake.ciphersuite

TLS handshake message types

Message types
Code    Description
0   HelloRequest
1   ClientHello
2   ServerHello
4   NewSessionTicket
8   EncryptedExtensions (TLS 1.3 only)
11  Certificate
12  ServerKeyExchange
13  CertificateRequest
14  ServerHelloDone
15  CertificateVerify
16  ClientKeyExchange
20  Finished

{code}

include <tins/tins.h>

include

include

include

include

using namespace Tins; using namespace std;

/*

* Container class for the data that is retrieved from the beacon.
/

class Unit { public:

   /
    * Constructor. Parses the Dot11Beacon object and takes all the necessary
    * data from it.
    */
   Unit(Dot11Beacon& beacon);
   Unit() = default;
   unsigned getCount();
   void incrementCount();
/*
 * Prints this object onto the command line, in CSV format
 */
void print();

private:

   string ssid;
   string bssid;
   unsigned channel;
   unsigned count;
string gcs; // Group Cipher Suite
string pcs; // Pairwise Cipher Suite
string akm; // Authentication suite

/*
 * Returns a string representation of a RSNInformation::CypherSuites enum value
 */
string type_to_string(const RSNInformation::CypherSuites& type);

/*
 * Returns a string representation of a RSNInformation::AKMSuites enum value
 */
string type_to_string(const RSNInformation::AKMSuites& type);

};

Unit::Unit(Dot11Beacon& beacon) :

   count {1} /* When this unit is created, it has been seen exactly once */ {
   ssid = beacon.ssid();
   bssid = beacon.addr3().to_string();
   channel = unsigned(beacon.ds_parameter_set());
RSNInformation rsn;
for(const auto &opt : beacon.options()) {
    if (opt.option() == Dot11::RSN) {
        rsn = beacon.rsn_information();

        // Put all authentication suite types in a string
        const RSNInformation::akm_type& akmTypeList = rsn.akm_cyphers();
        for (const auto& akmIt : akmTypeList) {
            if (akm.size() == 0)
                akm += type_to_string(akmIt);
            else
                akm += ";" + type_to_string(akmIt);
        }

        // Put all group cipher types in a string
        const RSNInformation::CypherSuites& gcsType = rsn.group_suite();
        gcs = type_to_string(gcsType);


        // Put all pairwise ciphers in a string
        const RSNInformation::cyphers_type& pcsTypeList = rsn.pairwise_cyphers();
        for (const auto& pcsIt : pcsTypeList) {
            if (pcs.size() == 0)
                pcs += type_to_string(pcsIt);
            else
                pcs += ";" + type_to_string(pcsIt);
        }
    }
}

}

unsigned Unit::getCount() {

   return count;

}

void Unit::incrementCount() {

   count += 1;

}

void Unit::print() {

   string ssid_to_print;
   if (ssid.length() == 0) {
       ssid_to_print = "";
   } else if (!isprint(ssid[0])) {
       ssid_to_print = to_string(static_cast(ssid[0]));
   } else {
       ssid_to_print = ssid;
   }
   if (find(ssid_to_print.begin(), ssid_to_print.end(), ',') != ssid_to_print.end()) {
       ssid_to_print = "\"" + ssid_to_print + "\"";
   }
   cout <<  ssid_to_print << ","
        << bssid << ","
        << to_string(channel) << ","
        << to_string(count) << ","
        << gcs << ","
        << pcs << ","
        << akm << endl;

}

string Unit::type_to_string(const RSNInformation::CypherSuites& type) {

   switch (type) {
   case RSNInformation::CypherSuites::CCMP:
       return "CCMP";
       break;
   case RSNInformation::CypherSuites::TKIP:
       return "TKIP";
       break;
   case RSNInformation::CypherSuites::WEP_104:
       return "WEP_104";
       break;
   case RSNInformation::CypherSuites::WEP_40:
       return "WEP_40";
       break;
   }

}

string Unit::type_to_string(const RSNInformation::AKMSuites& type) {

   switch (type) {
   case RSNInformation::AKMSuites::PMKSA:
       return "PMKSA";
       break;
   case RSNInformation::AKMSuites::PSK:
       return "PSK";
       break;
   }

}

/*

* Class that reads the pcap, keeps track of the units and writes out one
* beacon frame in pcap format for each unique AP it finds. This file is called
* "unique_beacons.pcap"
/

class PCAPParser { public:

   /
    * Constructor. It takes the exact parameters that it will pas on to its
    * FileSniffer object (a FileSniffer is actually just a file reader).
    */
   PCAPParser(const string& pcapFilename, const string& filter);
/*
 * Start reading the file.
 */
bool run();

/*
 * Print CSV header and ask all of our collected Unit objects to print themselves
 */
void print();

private:

   FileSniffer sniffer;
   PacketWriter writer;
   map<string, Unit> apMap; // stands for Access Point Map
bool handler(PDU&);

};

PCAPParser::PCAPParser(const string& pcapFilename, const string& filter) :

   sniffer {pcapFilename, filter},
   writer {"unique_beacons.pcap", PacketWriter::RADIOTAP}  {
   for (auto it = apMap.begin(); it != apMap.end(); it++) {
       it->second.print();
   }

}

bool PCAPParser::run() {

   sniffer.sniff_loop( [this] (PDU& pdu) { return (bool) this->handler (pdu); } );
   return true;

}

bool PCAPParser::handler(PDU& pdu) {

   Dot11Beacon& beacon = pdu.rfind_pdu();
// An ESSID may span multiple BSSID's. Also, it's nice to keep track of what
// channels an AP has been on. Therefore, the combination of SSID, BSSID and
// channel is considered key.
const string& ssid = beacon.ssid();
const string& mac = beacon.addr3().to_string();
const unsigned channel = unsigned(beacon.ds_parameter_set());
const string key = ssid + mac + to_string(channel);
if (apMap.find(key) == apMap.end()) { // we've got a new one
    Unit unit(beacon);
    apMap[key] = unit;
    writer.write(pdu);
} else {
    apMap[key].incrementCount();
}
return true;

}

void PCAPParser::print() {

   // Print the headers for the CSV output
   cout << "SSID,BSSID,Current_channel,Count,Group_Cipher,Pairwise_Ciphers,Authentication_Suite" << endl;
// Ask each of the units to print themselves for the CSV output
for (auto it = apMap.begin(); it != apMap.end(); it++) {
    it->second.print();
}

}

int main(int argc, char *argv[]) {

   if(argc != 2) {
       std::cout << "Usage: " << *argv << " \n";
       return 1;
   }
PCAPParser pcapParser(argv[1], "wlan type mgt subtype beacon");
pcapParser.run();
pcapParser.print();

}

{code}