Last active
July 10, 2026 07:38
-
-
Save singe/40bda2a1772aaf4903515cc4e436afe5 to your computer and use it in GitHub Desktop.
A simple tshark EAP certificate extractor and new certificate hierarchy creator.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/bin/bash | |
| # Simple CA cert generator & leaf cert signer | |
| # By dominic@sensepost.com | |
| # All rights reserved 2019 | |
| set -euo pipefail | |
| ca_prefix="ca" | |
| leaf_prefix="host" | |
| ca_validity="1825" # days | |
| leaf_validity="730" # days | |
| size=2048 | |
| ca_cert="" | |
| ca_key="" | |
| dns_name="" | |
| ip_addr="" | |
| usage() { | |
| echo "Simple CA & leaf cert generator & signer" | |
| echo | |
| echo "Usage:" | |
| echo " $0 [-h] [-c <ca.cert.pem> -k <ca.key.pem>] [-l <leaf_prefix>] [-a <ca_prefix>] [-d <dns_name>] [-i <ip_addr>]" | |
| echo | |
| echo "Options:" | |
| echo " -h This help" | |
| echo " -c <ca.cert.pem> Specify a CA cert to use instead of generating one. Requires -k" | |
| echo " -k <ca.key.pem> Specify the key for the CA cert. Requires -c" | |
| echo " -l <leaf_prefix> Specify the name prefix of the leaf certificate and key" | |
| echo " -a <ca_prefix> Specify the name prefix of the CA certificate and key" | |
| echo " -d <dns_name> DNS SAN for the leaf cert, e.g. design.orbitonline.com" | |
| echo " -i <ip_addr> IP SAN for the leaf cert, e.g. 127.0.0.1" | |
| echo | |
| echo "Examples:" | |
| echo " $0 -l sub.example.com -d sub.example.com -i 127.0.0.1" | |
| echo " $0 -c ca.cert.pem -k ca.key.pem -l localhost -d localhost -i 127.0.0.1" | |
| exit 1 | |
| } | |
| while getopts "hc:k:l:a:d:i:" OPTIONS; do | |
| case "${OPTIONS}" in | |
| h) | |
| usage | |
| ;; | |
| c) | |
| ca_cert="${OPTARG}" | |
| ;; | |
| k) | |
| ca_key="${OPTARG}" | |
| ;; | |
| l) | |
| leaf_prefix="${OPTARG}" | |
| ;; | |
| a) | |
| ca_prefix="${OPTARG}" | |
| ;; | |
| d) | |
| dns_name="${OPTARG}" | |
| ;; | |
| i) | |
| ip_addr="${OPTARG}" | |
| ;; | |
| *) | |
| usage | |
| ;; | |
| esac | |
| done | |
| shift $((OPTIND - 1)) | |
| if [ "${OPTIND}" -eq 1 ]; then | |
| echo "Using defaults -a ca -l host" | |
| fi | |
| if { [ -z "${ca_cert}" ] && [ -n "${ca_key}" ]; } || { [ -n "${ca_cert}" ] && [ -z "${ca_key}" ]; }; then | |
| echo "[!] -c and -k are required together; you cannot provide just one." | |
| usage | |
| fi | |
| if [ -z "${dns_name}" ]; then | |
| dns_name="${leaf_prefix}" | |
| fi | |
| if [ -z "${ip_addr}" ]; then | |
| ip_addr="127.0.0.1" | |
| fi | |
| ca_ext_file="${ca_prefix}.ca.ext" | |
| leaf_ext_file="${leaf_prefix}.leaf.ext" | |
| if [ -z "${ca_cert}" ] && [ -z "${ca_key}" ]; then | |
| ca_cert="${ca_prefix}.cert.pem" | |
| ca_key="${ca_prefix}.key.pem" | |
| if [ -f "${ca_cert}" ] || [ -f "${ca_key}" ]; then | |
| echo "[*] Cowardly refusing to overwrite files ${ca_cert} or ${ca_key}" | |
| exit 1 | |
| fi | |
| if [ -f "${ca_ext_file}" ]; then | |
| echo "[*] Cowardly refusing to overwrite file ${ca_ext_file}" | |
| exit 1 | |
| fi | |
| echo "[-] CREATING CA KEY" | |
| openssl genrsa \ | |
| -out "${ca_key}" \ | |
| "${size}" | |
| echo "[+] CREATED CA KEY" | |
| echo "[-] CREATING CA EXTENSION FILE" | |
| cat > "${ca_ext_file}" <<EOF | |
| basicConstraints = critical, CA:TRUE | |
| keyUsage = critical, keyCertSign, cRLSign | |
| subjectKeyIdentifier = hash | |
| authorityKeyIdentifier = keyid:always,issuer | |
| EOF | |
| echo "[-] CREATING CA CERT" | |
| openssl req -x509 -new -nodes \ | |
| -key "${ca_key}" \ | |
| -sha256 \ | |
| -days "${ca_validity}" \ | |
| -out "${ca_cert}" \ | |
| -subj "/CN=${ca_prefix} Local Test CA" \ | |
| -extensions v3_ca \ | |
| -config <(cat /etc/ssl/openssl.cnf 2>/dev/null || printf "[req]\ndistinguished_name=dn\n[dn]\n"; printf "\n[v3_ca]\n"; cat "${ca_ext_file}") | |
| echo "[+] CREATED CA CERT: ${ca_cert}" | |
| fi | |
| if [ ! -f "${ca_cert}" ]; then | |
| echo "[!] CA cert not found: ${ca_cert}" | |
| exit 1 | |
| fi | |
| if [ ! -f "${ca_key}" ]; then | |
| echo "[!] CA key not found: ${ca_key}" | |
| exit 1 | |
| fi | |
| if [ -f "${leaf_prefix}.key.pem" ] || [ -f "${leaf_prefix}.cert.pem" ] || [ -f "${leaf_prefix}.csr" ] || [ -f "${leaf_ext_file}" ]; then | |
| echo "[*] Cowardly refusing to overwrite one of:" | |
| echo " ${leaf_prefix}.key.pem" | |
| echo " ${leaf_prefix}.cert.pem" | |
| echo " ${leaf_prefix}.csr" | |
| echo " ${leaf_ext_file}" | |
| exit 1 | |
| fi | |
| echo "[-] CREATING LEAF KEY" | |
| openssl genrsa \ | |
| -out "${leaf_prefix}.key.pem" \ | |
| "${size}" | |
| echo "[+] CREATED LEAF KEY: ${leaf_prefix}.key.pem" | |
| echo "[-] CREATING LEAF EXTENSION FILE" | |
| cat > "${leaf_ext_file}" <<EOF | |
| basicConstraints = CA:FALSE | |
| keyUsage = digitalSignature, keyEncipherment | |
| extendedKeyUsage = serverAuth | |
| subjectKeyIdentifier = hash | |
| authorityKeyIdentifier = keyid,issuer | |
| subjectAltName = @alt_names | |
| [alt_names] | |
| DNS.1 = ${dns_name} | |
| IP.1 = ${ip_addr} | |
| EOF | |
| echo "[+] CREATED LEAF EXTENSION FILE: ${leaf_ext_file}" | |
| echo "[-] CREATING LEAF CSR" | |
| openssl req -new \ | |
| -key "${leaf_prefix}.key.pem" \ | |
| -out "${leaf_prefix}.csr" \ | |
| -subj "/CN=${dns_name}" | |
| echo "[+] CREATED LEAF CSR: ${leaf_prefix}.csr" | |
| echo "[-] SIGNING LEAF CERTIFICATE" | |
| openssl x509 -req \ | |
| -in "${leaf_prefix}.csr" \ | |
| -CA "${ca_cert}" \ | |
| -CAkey "${ca_key}" \ | |
| -CAcreateserial \ | |
| -out "${leaf_prefix}.cert.pem" \ | |
| -days "${leaf_validity}" \ | |
| -sha256 \ | |
| -extfile "${leaf_ext_file}" | |
| echo "[+] CREATED LEAF CERTIFICATE: ${leaf_prefix}.cert.pem" | |
| echo | |
| echo "Certificate details:" | |
| openssl x509 \ | |
| -in "${leaf_prefix}.cert.pem" \ | |
| -noout \ | |
| -subject \ | |
| -issuer \ | |
| -dates \ | |
| -ext subjectAltName | |
| echo | |
| echo "Done." |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/bin/sh | |
| # Simple tshark WiFi EAP certificate extractor | |
| # By dominic@sensepost.com | |
| # All rights reserved 2020 | |
| function trap_ctrlc () | |
| { | |
| echo "Ctrl-C caught...performing clean up" | |
| killall tshark | |
| exit 2 | |
| } | |
| trap "trap_ctrlc" 2 | |
| if [ ! -x $(which tshark) ]; then | |
| echo "tshark not installed" | |
| exit 1 | |
| fi | |
| if [ -z ${1} ]; then | |
| echo "Usage: $0 [-r file.cap] [-i interface]" | |
| echo "Extracted certificates will be written to <file|int>.cert.rand.der" | |
| exit 1 | |
| fi | |
| # Newer versions of tshark use tls not ssl | |
| filter="ssl.handshake.certificate" | |
| tshark -r /etc/resolv.conf $filter 2>/dev/null | |
| if [[ $? -eq 2 ]]; then | |
| filter="tls.handshake.certificate" | |
| fi | |
| tmpbase=$(basename $2) | |
| for x in $(tshark $1 $2 \ | |
| -Y "$filter and eapol" \ | |
| -T fields -e "ssl.handshake.certificate"); do | |
| echo $x | \ | |
| sed "s/://g" | \ | |
| xxd -ps -r | \ | |
| tee $(mktemp $tmpbase.cert.XXXX.der) | \ | |
| openssl x509 -inform der -text; | |
| done |
Author
In case it wasn't clear to others, I updated the script to incorporate the fix sometime ago.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Yup. Same issue as @bashbanana and the fix recommended by @GOAT-FARM3R is valid and working.