Grabbing a CA Cert with tcpdump/openssl and the built in WiFi Connection Interface

Here’s the source code first:

#!/usr/bin/python
import base64
import os
import re
import subprocess
import sys
import time
def writepem(certdata):
	f = ""
	e = base64.b64encode(certdata)
	x = 0; l = len(e)
	f += ("-----BEGIN CERTIFICATE-----\n")
	while (x < l):
		f += ("%s\n" % (e[x+0:x+64]))
		x += 64
	f += ("-----END CERTIFICATE-----\n")
	return f
def brutecert(pcapdata):
	l = 900
	while (l <= 1024):
		p = writepem(pcapdata[:l])
		#sys.stderr.write(p+"\n")
		try:
			certchk = subprocess.check_output("echo '%s' | openssl verify 2>&1 | grep '^OK$'" % (p), shell=True)
		except:
			certchk = ""
		if (certchk != ""):
			break
		l += 1
	if (certchk != ""):
		sys.stdout.write(p)
		return 1
	return 0
os.system("killall -9 tcpdump > /dev/null 2>&1 ; killall -9 tcpdump > /dev/null 2>&1")
os.system("rm -fv wifi.pcap > /dev/null 2>&1 ; tcpdump -i %s -w wifi.pcap -U > /dev/null 2>&1 &" % (sys.argv[1]))
sys.stderr.write("Note: If you want to interrupt this script, press Control+Z and killall -9 python\n")
r = 0
while (1):
	try:
		tcpout = subprocess.check_output("tcpdump -xr wifi.pcap 2> /dev/null | tr '\\t' ' ' | sed -e 's/^ [ ]*0x[0-9A-Fa-f][0-9A-Fa-f]*:[ ]*//'", shell=True)
		tcplist = tcpout.split("\n")
		eapdata = ""; eapindx = 0; eapsize = -16
		for x in range(0, len(tcplist)):
			if (eapindx < (eapsize + 4)):
				h = ""
				for c in tcplist[x].strip():
					if (not c in "0123456789ABCDEFabcdef"):
						continue
					h += c
					if (len(h) == 2):
						if (eapindx >= (eapsize + 4)):
							sys.stderr.write("EAP read error [%d] >= [%d]...\n" % (eapindx + 1, eapsize))
						else:
							if (eapindx >= 4):
								eapdata += chr(int(h, 16))
						eapindx += 1; h = ""
			else:
				z = re.match("^[0-9][0-9]:[0-9][0-9]:[0-9][0-9].* EAP packet.* v2.* len ([0-9]+)$", tcplist[x].strip(), re.I)
				if (z):
					eapindx = 0; eapsize = int(str(z.group(1)))
					sys.stderr.write("Possible EAP data: line [%d] len [%d]...\n" % (x, eapsize))
		p = 0; l = len(eapdata)
		tlsdata = ""; tlsindx = 0; tlssize = -16
		while (p < l):
			i = p; m = [["\x01","\x02"],[],[],[],["\x15"],[None],[],[],[],[]]
			for j in m:
				if (i >= l):
					pass
				elif (len(j) < 1):
					i += 1
				elif (None in j):
					if ((ord(eapdata[i]) & 0x80) > 0):
						i += 1
				else:
					for k in j:
						if (eapdata[i] == k):
							i += 1
			if (i == (p + len(m))):
				tlslen = ((ord(eapdata[p+2])<<8) + (ord(eapdata[p+3])<<0))
				tlsmlen = ((ord(eapdata[p+6])<<24) + (ord(eapdata[p+7])<<16) + (ord(eapdata[p+8])<<8) + (ord(eapdata[p+9])<<0))
				sys.stderr.write("Possible TLS data: index [%d] len [%d] mlen [%d]...\n" % (p, tlslen, tlsmlen))
				p += 10
				if (tlssize < 1):
					tlsindx = 0; tlssize = tlsmlen
				for x in range(0, tlslen - 10):
					if ((tlsindx >= tlssize) or (p >= l)):
						pass
					else:
						tlsdata += eapdata[p]
						p += 1
					tlsindx += 1
				if (tlsindx >= tlssize):
					if (tlsindx > tlssize):
						sys.stderr.write("TLS read error [%d] >= [%d]...\n" % (tlsindx, tlssize))
					tlsindx = 0; tlssize = -16
				p -= 1
			p += 1
		p = 0; l = len(tlsdata)
		while (p < l):
			if (r == 0):
				i = p; m = "\x30\x82\x03"
				for j in m:
					if (tlsdata[i] == j):
						i += 1
				if (i == (p + len(m))):
					sys.stderr.write("Possible CA data: index [%d]...\n" % (p))
					r = brutecert(tlsdata[p:])
			p += 1
	except:
		pass
	if (r != 0):
		break
	time.sleep(1)
os.system("killall -9 tcpdump > /dev/null 2>&1 ; killall -9 tcpdump > /dev/null 2>&1")

Then you run the command:

# python cagrab.py wlan0 | tee ca.crt
Note: If you want to interrupt this script, press Control+Z and killall -9 python
Possible EAP data: line [0] len [5]...
Possible EAP data: line [4] len [6]...
Possible EAP data: line [22] len [1024]...
Possible EAP data: line [90] len [1024]...
Possible EAP data: line [158] len [480]...
Possible EAP data: line [204] len [69]...
Possible EAP data: line [219] len [4]...
Possible TLS data: index [11] len [1024] mlen [2498]...
Possible TLS data: index [1035] len [1024] mlen [2498]...
Possible TLS data: index [2059] len [480] mlen [2498]...
Possible TLS data: index [2539] len [69] mlen [59]...
Possible CA data: index [74]...
Possible CA data: index [1006]...
-----BEGIN CERTIFICATE-----
MIIDtTCCAp2gAwIBAgIJAKhl2tXce/J4MA0GCSqGSIb3DQEBBQUAMHExCzAJBgNV
BAYTAkNBMRAwDgYDVQQIDAdPbnRhcmlvMRAwDgYDVQQHDAdUb3JvbnRvMQ8wDQYD
VQQKDAZzdG9vcHMxEjAQBgNVBAMMCXJhZHNydi1jYTEZMBcGCSqGSIb3DQEJARYK
cm9vdEBsb2NhbDAeFw0xNDAzMjYwMTQ1MjJaFw0yNDAzMjMwMTQ1MjJaMHExCzAJ
BgNVBAYTAkNBMRAwDgYDVQQIDAdPbnRhcmlvMRAwDgYDVQQHDAdUb3JvbnRvMQ8w
DQYDVQQKDAZzdG9vcHMxEjAQBgNVBAMMCXJhZHNydi1jYTEZMBcGCSqGSIb3DQEJ
ARYKcm9vdEBsb2NhbDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMh2
sAnJApatDY+2IjWUmdvMuBmNBXP29FAKUfO6D6EY90MBVPShzaOsr/p4Il7oUDqy
rs3wdeCBRLvGV+cHsgyMBlHh2jS6PKHMvVEh3n2kaTb+BAXe6Q2dDdkpGz5BSr31
mYfGuDvBtDop7fE/HQH6NwMM7qHKv8yO433JPPN3E6l7ln1WXRberFkGS39CTA0j
dpAzjz2+J8Wfm2zGd/z22ggf1PGw2VukbC+o0TOQpKb05sprLQmqDykMmzv3V5N2
Sa9KUFtQNihGOjHgjRwmys5gniV52cJnAU0hSickMBiWDXp65MEXBaPCqaaqj3DM
eHkRArBOcCMnfL7KwWMCAwEAAaNQME4wHQYDVR0OBBYEFO3bA+BXWeWip7bIjvXq
vzi3AvshMB8GA1UdIwQYMBaAFO3bA+BXWeWip7bIjvXqvzi3AvshMAwGA1UdEwQF
MAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAJlRk1MPGGONHKmU8WnryvnrhFr+KPfO
5eBzn+7HOSjK27FEmCRoYM3gk6SJJbIX0BtLgtz6o/E+WX7A611Jf5jXbNNOOz1L
d8F9NxmcbA3nYXaeTm2/BBOIF4diizQjHIkNS8R+MMOchKMV6WpAb7Ia7W849IbM
pQ1I5RxoTMjMy6hdpr1YUYqbTeq6X8z2P9AxiH0cKHxshQVkXFan8JTp290l2IIX
tCzIzOCqPWBcScrrhCYTbJl+9YZ1CSRwdos5/XWpCvCHI9cRA9qPLjkoiaZ8ZCHY
pxnYlLauxJnCmyk2HW00V5bUJ1vIb1mDV78Y/1kekSwZAvhOW9M1Pag=
-----END CERTIFICATE-----

Then you attempt a real connection to the WPA Enterprise access point (with fake credentials!) and wait for the script above to write out the CA Certificate file (verify it against a hash first!). You can then move this file to a user’s directory and point to it with a Wi-Fi connection client. This helps because the built-in Wi-Fi clients on Linux don’t seem to present any server certificate when connecting initially which forces one to manually transfer it around everywhere which is annoying when you have no network connection to begin with!

2 thoughts on “Grabbing a CA Cert with tcpdump/openssl and the built in WiFi Connection Interface

Leave a comment