User Tools

Site Tools


howtos:remote_tcpdumping_and_tls_decryption_of_pcap_file

Tcpdump via API

The script uses the ability to initiate commands on a BigIP via the RESTAPI.

tcpdum has a special flag “–f5 ssl”, introduced in version 15.0, which makes it save the master secret inside the pcap file. This enables Wireshark to decyrpt TLS connections and give access to L7 information.

The flag needs to be turned on via the db variable “tcpdump.sslprovider” before it collects the master secrets and it is automatically reset to off after reboot. As this can pose as a security risk we only have it turned on while running the tcpdump and when the command has finished it gets turned off again.

The script requires that you have an account with admin privileges and the host the script runs from can access the BigIP. The decryption locally is done via tshark, so that needs to be installed as well.

#!/bin/bash

# Utility functions. It takes two parameters, first is the text and the second is the default value.
# If no default value is supplied it will loop until something is entered.
function prompt_user {
    read -p "${1} (default: [${2}]): " input
    echo "${input:-${2}}"
}

function prompt_bigip_address {
    read -p "BIG-IP address [default: https://10.1.1.10]: " BIGIP
    # Assign a default value if nothing is entered
    BIGIP="${BIGIP:-https://10.1.1.10}"
    # Make sure that the address is prefixed with https if only an IP address is entered
    BIGIP="https://${BIGIP#https://}"
}

function prompt_credentials {
    read -p "BIG-IP username [default: admin]: " USER
    USER="${USER:-admin}"
    read -s -p "BIG-IP password: " PASS
    echo ""
}

function get_token {
     # Authenticate and get auth token
    TOKEN=$(curl -skf -H "Content-Type: application/json" -d '{"username":"'$USER'","password":"'$PASS'","loginProviderName":"tmos"}' "$BIGIP/mgmt/shared/authn/login" | grep -oP '(?<="token":")[^"]+')

}

function delete_token {
    # Delete token
    curl -sk -H "X-F5-Auth-Token: $TOKEN" -X DELETE "$BIGIP/mgmt/shared/authz/tokens/$TOKEN"| jq -r  '.|{"Deleted token": .token}'    
}

function toggle_ssl_provider {
    # Toggle the "sys db tcpdump.sslprovider" variable
    local value=${1}
    curl -sk -X PATCH -H "Content-Type: application/json" -H "X-F5-Auth-Token: $TOKEN" "$BIGIP/mgmt/tm/sys/db/tcpdump.sslprovider" -d '{"value": "'$value'"}'
}

function download_file {
    # Download the pcap file from the filesystem "/share/images/encrypt_autocap_*.pcap"
    local file="${1}" message="${2}"
    curl -skf -H "X-F5-Auth-Token: $TOKEN" "$BIGIP/mgmt/cm/autodeploy/software-image-downloads/$file" -o "$file"
    if [ "$?" -eq 0 ]; then
      echo -e "\t$message"
    else
      echo -e "\tDOWNLOAD FAILED!!!"
    fi
}

function delete_file {
    # Delete the pcap file from the filesystem "/share/images/encrypt_autocap_*.pcap"
    local file="${1}" message="${2}"
    curl -skf -X POST -H "X-F5-Auth-Token: $TOKEN" -H "Content-Type: application/json" "$BIGIP/mgmt/tm/util/unix-rm" -d '{"command": "run", "utilCmdArgs": "/shared/images/'$file'"}'
    if [ "$?" -eq 0 ]; then
      echo -e "\t$message"
    else
      echo -e "\tDELETE FAILED!!!"
    fi
}

# Main function
function main {
    # Get user inputs
    partition=$(prompt_user "Which partition: " "Common")
    
    vip_name=""
    while [[ -z $vip_name ]]; do
        vip_name=$(prompt_user "Virtual name" "")
    done
    
    duration=$(prompt_user "Duration in seconds for capture: " "30")
    filters=$(prompt_user "Capture filters in addition to vip [ex. \"and (port 80 or port 443)\"]: ")
       
    
    # Prep variables for execution
    datestring=$(date +%Y%m%d-%H%M%S)
    tcpdump_file="autocap_$datestring.pcap"
    tcpdump_file_encrypt="encrypt_$tcpdump_file"
    tcpdump_file_decrypt="decrypt_$tcpdump_file"
    pms_file="pms_$datestring.key"
    payload="payload.json"
    
    # Regular expression to match an IP address
    IP_REGEX='^((25[0-5]|2[0-4][0-9]|1?[0-9]{1,2})\.){3}(25[0-5]|2[0-4][0-9]|1?[0-9]{1,2})$'

    # Get the IP of the virtual server
    virtual_ip=$(curl -skf -H "X-F5-Auth-Token: $TOKEN" "$BIGIP/mgmt/tm/ltm/virtual/~$partition~$vip_name" | jq -r '.destination | split(":") | .[0]'|awk -F/ '{print $3}')
    # Check if virtual IP is a valid IP address
    if [[ ! $virtual_ip =~ $IP_REGEX ]]; then
      echo "Error: virtual IP '$virtual_ip' is not a valid IP address - Did you spell the VS correctly?"
      exit 1
    fi
    
    # Build command execution string and dump it into a payload file as a json array to be read by curl
    tcpdump_bash_string=(timeout -s SIGKILL $duration tcpdump -s0 -nni 0.0:nnnp --f5 ssl:v host $virtual_ip $filters -w /shared/images/$tcpdump_file_encrypt)
    echo "{\"command\":\"run\",\"utilCmdArgs\":\"-c '${tcpdump_bash_string[@]}'\"}" > $payload

    # Run tcpdump
    echo -e "\tStarting tcpdump...please reproduce your issue now."
    output=$(curl -sk -X POST -H "Content-Type: application/json" -H "X-F5-Auth-Token: $TOKEN" "$BIGIP/mgmt/tm/util/bash" -d @$payload)

    #curl -skf -X POST -H "Content-Type: application/json" -H "X-F5-Auth-Token: $TOKEN" "$BIGIP/mgmt/tm/util/bash" -d '{"command":"run","utilCmdArgs":"-c "'${tcpdump_bash_string[@]}'""}'
    sleep 5
    echo -e "\ttcpdump complete...continuing."
    

    # Download tcpdump capture from BIG-IP
    echo -e "\nDownloading tcpdump capture from BIG-IP..."
    download_file $tcpdump_file_encrypt "\tDownload complete!"
    
    # Delete tcpdump capture on BIG-IP
    echo -e "\nDeleting tcpdump capture on BIG-IP..."
    delete_file $tcpdump_file_encrypt "\tDeletion complete!"
    
    # Extract session keys from tcpdump capture
    echo -e "\nExtracting session keys from tcpdump capture..."
    tshark -r $tcpdump_file_encrypt -Y f5ethtrailer.tls.keylog -Tfields -e f5ethtrailer.tls.keylog > $pms_file
    echo -e "\tSession keys extracted!"
    
    # Create a decrypted tcpdump capture from the encrypted capture + session keys file
    echo -e "\nCreating decrypted tcpdump capture..."
    editcap --inject-secrets tls,$pms_file $tcpdump_file_encrypt $tcpdump_file_decrypt
    echo -e "\tDecrypted tcpdump capture created!"

    echo -e "\nCleanup..."
    rm -f $payload $pms_file
    echo -e "\nComplete!"
}

prompt_bigip_address
prompt_credentials
get_token
main
delete_token
howtos/remote_tcpdumping_and_tls_decryption_of_pcap_file.txt · Last modified: 27/03/2023 07:23 by domingo