A Slight Modification Of The CPU-Based Random Number Generator

Just a little update of a previous script I posted here, it’s still very slow to run but it doesn’t rely on a hash function to create the final set of random data…

import signal
import sys

c = 0; f = 0
r = ""; t = 0; b = 0

def handler(signum, frame):
	global c, f
	global r, t, b
	f = 1
	s = str(c); m = len(s)
	if ((m % 2) == 1):
		s = s[1:]; m = len(s)
	#print(c)
	p = (m / 2)
	for x in range(0, p):
		d = ((int(s[x]) + int(s[x + p])) % 10)
		if (d > 7):
			if (int(s[x + p]) > 7):
				continue
			d = int(s[x + p])
		u = min(8 - b, 3)
		w = (3 - u)
		#print("\t(%s + %s) = (%d >> %d) <> w) <= 8):
			r += chr(t); t = 0; b = 0
		if (u < 3):
			u = (3 - u)
			w = ((2 ** u) - 1)
			#print("\t\t(%s + %s) = (%d & %d) << %d \t %d , %d" % (s[x], s[x + p], d, w, 8 - b - u, b, u))
			t += (((d & 7) & w) << (8 - b - u)); b += u

def srnd(size):
	global c, f
	global r, t, b
	r = ""; t = 0; b = 0
	signal.signal(signal.SIGALRM, handler)
	while (len(r) < size):
		signal.alarm(1)
		c = 0; f = 0
		while (f == 0):
			c += 1
		signal.alarm(0)
	o = r[0:size]
	c = 0; f = 0
	r = ""; t = 0; b = 0
	return o

def stoh(inpt):
	h = ""
	for d in inpt:
		a = hex(ord(d))
		a = a[2:]
		if (len(a) < 2):
			a = ("0" + a)
		h += a
	return h

e = stoh(srnd(32))
print(e)
$ python sigrnd.py > test.rnd
e178c23644435d209a98623f67b39bd94124c4a03bb3f8e2d871954330ffda40
2b566db93a55190affef100972cf54f42440f225fc1f0f2ebb14062485c1bd87
dd9de46a255410fe9925ac634c1c5d90b48511486700f3c9f4666d97610d7f96
1fb232f334d4a15404d97e72fa39bc0bd70831d558ee46420944ee1475dc33cf
9f8ac9c0668f5f0bf816560413eb8d465fdf86e07a1c3cd039f5c35ca65688a1
111ee2fcb3729e6886534b261a4b3d7afb0e62dc0e6c18153fc0cef15d161ff4
7ce0411de8f635d08b1b2a5f7080893f94279637c614aca13d4136bff17f9ba6
a1e7f3592a4d5c07c56c84d4f1448928b910d1051a8e4f7113b536e941ddea72
3433453f211492348e4154bd3427d079ac8f5e4d1522cdff323fe30aaa6bcda1
00f4ff6b5337690def4ec26e832a6a032cbb024ac7d9d224712422b2e4dc41fc
361cb649e81cbe5c9ad970db125cd2309f8e196140e28d4ec5f16ea1bd3551c8
7283d4e8c0a42c400fa5f5db3573df1f446a09779ddc30ffa2b84153a3ec4c7b
86ec7f80766be8d27b24c7db7b609288c7c0ac5e6345dcf6207555c605f9222d
6595417501a0df5c0339705e3c471d5bec7a880c81e1295556dd2db8c8104323
bf166eb924ad195a028dee22a36e87b487e5c83f2d9b1fa2a6ada5b35c0192c0
b5bdc471b5d7b2f0f6b08db4274e3e1ec1e2eb5b20e450bfa25b79e8e8059d19
6e0d5ba936fc630d257c25fd27c3b99c3616ce17e470066a107cf9f56d74ced7
aaa12055cc5e6629c2ef17fa398b5aaffe24ebb01cd81edde2c5b79b75b1a2ae
06c83d2d79c64d5ee206c48efe15841224a4b4279efbbca2f47dc1d8a40bc5bd
daf5cc2d164e3bae9fcc4a8e698169556e96d19e47eaae842f5fa77d0342f00d
57095f3ed4445c0331bff1b86f883fc589437dcc8b45a0900bee2cf44609da99
95c522a66f0984cb9382ff737f340a8cec5434fe573d3fb6c48f13133eea6f9f
3ef172617d41b1ca588ba7ff28e242dd6488bf5a9ba41b2a8834b9a3cf35f752
1135a16689629f2560a8c4390a908ec345d5bcd82f78210597c99ee34eb15e94
dc9d4be19a93b602cf3bdeb0baf913c5273d020f75162e30636dfb0fcb80d121
a214d021f98d2f028e780747deb7bc9a368ec36e9d226f029f89d85325d6cf02
3dfe96a7bef6c8dcff22b163d8407fee1f8d52ff39144433d72da6918ee6c853
4097d09af9abfeaecd46bf8eb49933c0e8a903719cb21a0688e4d5e544fd1e11
e1616e89980c450022236a9b9bf05dd2e03f15b5e0af17674ffca56e6138c9d3
78193776e694cac8a8c3a219b06cb70918ef29151e54828bbc4a05ad1b8598ff
1279d3a8090e0a037feebe271445e27617c0cc41165bfd8a1cfac7830d7149dc
ea3321da8408630db9dbaf945eca0e05c8dde069cf6669ed112593e7dd66573b
e0c384c87016c273a81d7001aa8977eb0d6d2447fcffae13e43c5f46a2eae4ee
c1584801c2183baf511058a8cc329f8da81455824b4a8a3f4e5c9ff891ac3466
84164902fe12ff530e7c4345fc793a695986f1edc8432a94f993c687edc31a9e
c3a195f8800150eb8c0098422fd4c31d6fdbee7bca4715ea0cde8b1b83579d47
5dc80e604deb964dfab71c8c206ac4dcf5922fb53a5824b3406c9399bbd7fcba
25bbd158ed7623fb42656d29e9b56e9a2d1a763b7a00fcca1b02d262479f5a48
20bcc8976207c0a06aba765f0aa768db58c6c1ac36f9734f57a12969f55d7297
7ab12a2982aa2974092df7ef0813c8f1827d2fabf781b4de3f8c7d42720783c1
68dc9f744bd8794919c7abcbb0a7b3737b9f0caf974e0d6a2688241aa0559cd4
731e9f253a0c8827a10639066169ac33dfc9c9a5ddb85e8def8ec151ab352469
096ac68f4d62eaac2476977a498a362b5b45e18e5dbbb0f78c5649ec94817e76
0245dd2c4ef49382546aa06c3929ba4e70f210af3bedfc4c5eebc46bd9391683
bf7110c1e15f178ab1171c5f938ab1e2d0a1b9b29677b9f362b3132ef56dabbf
1643830ba06963161eaa04b9f8e088a4687d09e438e41d2a5466d6f78b274c9e
c9def9205f496b010ce2892135fef94fe2deb7f62640dff9f30994fd5f46e4de
938d483ed34deb033207ed1ec4cadbf8c3d9e8d86f93717575b4cd17eeb725c1
f96f1a0e38c9f7a2fe6a623fb3b62a151dc9b0f51b34861b7730b4058b1ded9b
6c7e48582ded238178c1036be88b7583803ece4127781b3cded024925e4c9e6b
6810854b6219e191fff2f7623c0827045fa4f097e043277d45260aeeb512c128
3512bb2fa47c1b3808f9b1109bd5cdc1506d9f472534c89f0433ab2d286f5cdd
ab8a7ad4fea0b0391fd162dfb975dfc190dfb200a6e2f9b70959c3dc4147416e
1824ac1a6806ac85ec8618426173bf1f77004d51446dc0cae18df7bd4d9da3df
fff792348efa02f21f40af926f1cda6bc3b486623aff46d9c13a6e14309fe2dd
28005590a0639de926f891c5e805d252375dc4602b0579c1cf7e64d06d83ce7c
951757ab8747578b690e490a306e94265912e43b2302c5d7476f98c29b667e7a
a91a3aa632cb30320b6097ae58051b58be361ab1682b2ecde9d74592592d2f1f
9c528fd8ec7c03467239cca5394038c61986ffe9bb60afd4d315781d5b2a09ec
759b5d68c9a6d0b0204f38b0d65de468cd5578f5d864ceb7f41ef10fa1b62802

Edit: A Linux entropy command line tester: http://www.fourmilab.ch/random/

As you can see below, we got up to 7.90 bits of entropy per byte while generating less than 2048 bytes of random data. We also almost hit the arithmetic mean value of 127.5 by scoring a 125. This process, however, took a really long time to run, but, all that was needed was a CPU, a counter, and a alarm signal interrupt.

$ ./ent test.rnd 
Entropy = 7.900037 bits per byte.

Optimum compression would reduce the size
of this 1920 byte file by 1 percent.

Chi square distribution for 1920 samples is 262.13, and randomly
would exceed this value 36.60 percent of the times.

Arithmetic mean value of data bytes is 125.3578 (127.5 = random).
Monte Carlo value for Pi is 3.187500000 (error 1.46 percent).
Serial correlation coefficient is 0.013566 (totally uncorrelated = 0.0).

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!

Finally Able To Run My Own WPA2-AES EAP-TTLS FreeRADIUS Server (RasPi)

I should have posted these pre-steps: First download the latest stable freeradius source code, extract and change directory, ./configure && make, su and make install. Also, the post-config to run the service itself: /usr/local/sbin/radiusd

And here are my example configuration notes in case anyone else is interested:

cd /usr/local/etc/raddb/certs

export D=`pwd` ; export KEY_CONFIG=$D/openssl.cnf
cat /etc/ssl/openssl.cnf | tr '\t' ' ' | sed -e "s@^dir .*\$@dir = `pwd`@g" -e "s@^countryName_default .*\$@countryName_default = CA@g" -e "s@^stateOrProvinceName_default .*\$@stateOrProvinceName_default = Ontario@g" -e "s@^0.organizationName_default .*\[email protected]_default = stoops@g" > openssl.cnf

sed -i -e 's@demoCA@@g' -e 's@/newcerts@@g' /usr/lib/ssl/openssl.cnf

rm -fv index.txt ; touch index.txt
rm -fv serial ; echo 01 > serial
mkdir -p ./newcerts

openssl dhparam -out dh 2048
openssl req -days 3650 -nodes -new -x509 -keyout ca.key -out ca.crt -config $KEY_CONFIG
openssl req -days 3650 -nodes -new -keyout server.key -out server.csr -config $KEY_CONFIG
openssl ca -extensions v3_ca -days 3650 -out server.crt -in server.csr -cert ca.crt -keyfile ca.key -config $KEY_CONFIG

cat ca.crt ca.key > ca.pem
cat server.crt server.key > server.pem


#cd /etc/freeradius/certs

#openssl genrsa -out server.key 2048
#openssl req -new -key server.key -out server.csr
#openssl x509 -req -days 3650 -in server.csr -signkey server.key -out server.crt
#openssl dhparam -outform PEM -out dh 2048

#cat server.crt server.key > server.pem ; cat server.pem > ca.pem
#echo > ../acct_users
#( echo 'client 0.0.0.0/0 {' ; echo '  secret = "pwd"' ; echo '  shortname = "wifi"' ; echo '}' ) > ../clients.conf
#echo 'jon Cleartext-Password := "pwd"' > ../users
vim /usr/local/etc/raddb/eap.conf
vim /usr/local/etc/raddb/modules/inner-eap

eap {
    ...
    default_eap_type = ttls
    ...
    tls {
        ...
        private_key_file = ${certdir}/server.pem
        certificate_file = ${certdir}/server.pem
        CA_file = ${cadir}/ca.pem
        dh_file = ${certdir}/dh
        cipher_list = "DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA"
        ...
    }
    ...
    ttls {
        ...
        default_eap_type = mschapv2
        ...
    }
    ...
    mschapv2 {
        ...
    }
    ...
}
vim /usr/local/etc/raddb/clients.conf

client 0.0.0.0/0 {
    secret    = [long-secret-passphrase-here]
    shortname = homewifi
    nastype   = other
}

Authentication:

vim /usr/local/etc/raddb/users

"jon" Cleartext-Password := "[personal-password-here]"

or

vim /usr/local/etc/raddb/sites-{available,enabled}/{default,inner-tunnel}

authorize {
    ...
    unix
    ...
}

* Note: Make sure to publish/distribute the ca.crt file above for connecting clients to use, it should look something like this:

-----BEGIN CERTIFICATE-----
MIIDzTCCArWgAwIBAgIJAMML9s5w/d4oMA0GCSqGSIb3DQEBBQUAMH0xCzAJBgNV
BAYTAkNBMRAwDgYDVQQIDAdPbnRhcmlvMRAwDgYDVQQHDAdUb3JvbnRvMQ8wDQYD
VQQKDAZzdG9vcHMxDTALBgNVBAsMBHdpZmkxDzANBgNVBAMMBnJhZHNydjEZMBcG
CSqGSIb3DQEJARYKcm9vdEBsb2NhbDAeFw0xMzEyMzAyMjE0MzBaFw0yMzEyMjgy
MjE0MzBaMH0xCzAJBgNVBAYTAkNBMRAwDgYDVQQIDAdPbnRhcmlvMRAwDgYDVQQH
DAdUb3JvbnRvMQ8wDQYDVQQKDAZzdG9vcHMxDTALBgNVBAsMBHdpZmkxDzANBgNV
BAMMBnJhZHNydjEZMBcGCSqGSIb3DQEJARYKcm9vdEBsb2NhbDCCASIwDQYJKoZI
hvcNAQEBBQADggEPADCCAQoCggEBAMsYNqwP+Zd9szkwwEVjxgOPn+d7kIZKbKnh
ZJOhG2poxnlPcv2Ac67xPuJ4tuiU6Xni1+YElkx4uxNa4GNm9EF2M0MRAE/eAwxK
QN9Y4/KN3C3AU8VDyIUXMx+XN38HI48lgZIj1c9HhoB8llTHeL4jGRVDmzqGqOCl
GwSNMh9mCgedTODARyDyJ9tyEayU1D+WDqwQTFbBfvd7VYejCtzo7edjCoMt6Kap
HsB3eE1LRTcE/QWlaDmszBzdFk+jqp2rzP+eKLXNLvalZEPOJ0koGqy9BfI9+fqW
avy/fphcN5+5UhNXadRrYOYJuPBe/AC90NmlFn+ztYmiRwf+GtkCAwEAAaNQME4w
HQYDVR0OBBYEFPE09eFbbSvz8E4uY2F4cA0PJmreMB8GA1UdIwQYMBaAFPE09eFb
bSvz8E4uY2F4cA0PJmreMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEB
AFYN7lTdZjNhHohCul9HzP87vHFiiV0N47eCBeyoujvkKkQHm2fKunxKLfe0ySBa
xOXdHHEhfBiv7Qz1LgryaYjMeJ8OhbktPT3ahGIWnNgyeKJiM3eD0fNVFWxp0ZBO
OlVQh5NYbuHhWafnAP8DDyhgKB99uEpF5iS1KwfkCGBbynYOayqNZGIVIH0c0Bmb
Ps+qNYxLKHQRi3+dnv4/gKPwKFDDiccHrQxiAEMXY+iO0rnPjc35SPri2QMAKdYf
1Nv/lmEPwQutjns1EUHHSmNwuC4O/1AUR54iskxzHy3v3RafOQ9B5aO6fyaMVFQF
iYX2djQzSq9qfOj9lMz5Cww=
-----END CERTIFICATE-----

Note: You can run this command to decode the certificate above: openssl x509 -in ca.crt -text -noout

Edit: For some basic OpenSSH cipher choices: Ignore the randomness

A Python TrueRand-Like Script Based On Signals, Alarms, Clocks, Counters, & SHA256

So I was watching some new Defcon videos from some of my favourite speakers (Jeff Moss, Bruce Schneier, Renderman, Dan Kaminsky, Moxie Marlinspike, Joshua Wright, Johnny Long, Charlie Miller, etc.) and Dan mentioned the ability to generate random numbers on a given system with nothing more than a CPU clock type device. I don’t understand it much but I think the basics includes setting an alarm trap signal and setting an infinite loop to increase a counter variable and then using that resulting integer as a source of randomness. You can repeat this process multiple times in a row to generate a larger amount of random data. Here’s my take on it, however, it is *very* slow and most likely mathematically/statistically wrong:

import hashlib
import signal

c = 0; f = 0
r = ""; l = 0
n = 3

def handler(signum, frame):
	global c, f
	global r, l
	global n
	f = 1
	s = str(c); m = len(s)
	if ((m % 2) == 1):
		s = s[1:]; m = len(s)
	#print(c)
	p = (m / 2)
	for x in range(0, p):
		d = ((int(s[x]) + int(s[x + p])) % 10)
		if (d > 7):
			if (int(s[x + p]) > 7):
				continue
			d = int(s[x + p])
		r += str(d); l += n

def srnd(size):
	global c, f
	global r, l
	global n
	signal.signal(signal.SIGALRM, handler)
	o = ""; m = 0
	while (m < size):
		r = ""; l = 0
		while (l < 256):
			signal.alarm(1)
			c = 0; f = 0
			while (f == 0):
				c += 1
			signal.alarm(0)
		print(r)
		h = hashlib.sha256(r).digest()
		for d in h:
			if (m < size):
				o += d; m += 1
	return o

def stoh(inpt):
	h = ""
	for d in inpt:
		a = hex(ord(d))
		a = a[2:]
		if (len(a) < 2):
			a = ("0" + a)
		h += a
	return h

e = stoh(srnd(32))
print(e)
$ python sigrnd.py 
003052717203640343422444177105135642455155135417632775634425154765734347724627720521226
c2638300e80d2fb7ab0230c4a6534191dda4b86b997508ff445adc577a7426c3

A small whois server and a nice holiday video

So here’s the most basic whois server in Python (connects to a PostgreSQL DB for the cached data):

Also, a funny holiday reminder that the NSA is spying on all of us!

ACLU NSA Vid [funny]

whois_limit

limiter.py

#!/usr/bin/python

import ast
import getpass
import hashlib
import os
import random
import re
import socket
import string
import sys
import time

def rstr(size):
	outp = ""
	for x in range(0, size):
		outp += random.choice(string.digits + string.ascii_uppercase + string.ascii_lowercase + "~!@#$%^&*-_=+?")
	return outp

fobj = open(sys.argv[1], "r")
conf = ast.literal_eval(fobj.read().strip())
fobj.close()

servport = conf["limiter"]["port"]
password = conf["limiter"]["pass"]
numtimes = conf["limiter"]["conn"]
timeouts = conf["limiter"]["time"]

prepad = rstr(8); pospad = rstr(8); cntrlist = []
addrlist = {}

sockobjc = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sockobjc.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sockobjc.bind(("", servport))
sockobjc.listen(1)

while (1):
	(sockconn, sockaddr) = sockobjc.accept()
	print("conn open:", sockaddr)
	try:
		sockconn.settimeout(1)
		datalist = sockconn.recv(1024).strip().split(" ")
		try:
			sendflag = 0
			scounter = datalist[0].strip()
			inetaddr = datalist[1].strip()
			authhash = datalist.pop()
			sharedsec = (prepad + " " + password + " " + pospad)
			temphash = hashlib.sha256(sharedsec + " " + " ".join(datalist) + " " + sharedsec).hexdigest()
			if (temphash != authhash):
				sockconn.send("0" + " " + prepad + " " + pospad)
				sendflag = 1
			else:
				if (len(cntrlist) >= 65536):
					prepad = rstr(8); pospad = rstr(8); cntrlist = []
				if (scounter in cntrlist):
					sockconn.send("1" + " " + scounter)
					sendflag = 1
				else:
					cntrlist.append(scounter)
					if (not inetaddr in addrlist.keys()):
						addrlist[inetaddr] = [0, 0]
					prestime = time.time()
					if ((prestime - addrlist[inetaddr][0]) >= timeouts):
						addrlist[inetaddr][0] = prestime
						addrlist[inetaddr][1] = 0
					print("conn info:", sockaddr, scounter, datalist, addrlist[inetaddr])
					if (addrlist[inetaddr][1] < numtimes):
						addrlist[inetaddr][1] += 1
						sockconn.send("2" + " " + "ok")
						sendflag = 1
			if (sendflag != 1):
				sockconn.send("2" + " " + "no")
		except:
			pass
	except:
		pass
	try:
		print("conn closed:", sockaddr)
		sockconn.shutdown(socket.SHUT_RDWR)
		sockconn.close()
	except:
		pass

whoiss.py

#!/usr/bin/python

import ast
import getpass
import hashlib
import os
import psycopg2
import random
import re
import socket
import string
import sys
import time

def sstr(inpt):
	outp = ""
	yesl = (string.digits + string.ascii_uppercase + string.ascii_lowercase + "-_.")
	for chrl in inpt:
		if (chrl in yesl):
			outp += chrl
	return outp

def rnum(size):
	random.seed(time.time())
	outp = ""
	for x in range(0, size):
		outp += random.choice(string.digits)
	return outp

def lims(connaddr):
	global limhost, limport
	global limpass, limpre, limpos
	x = 0
	limresp = ["-1"]
	try:
		while ((x < 8) and (limresp[0] != "2")):
			limnumb = rnum(8)
			limobjc = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
			limobjc.connect((limhost, limport))
			limdata = (limnumb + " " + connaddr)
			limsec = (limpre + " " + limpass + " " + limpos)
			limhash = hashlib.sha256(limsec + " " + limdata + " " + limsec).hexdigest()
			limobjc.sendall(limdata + " " + limhash)
			limresp = limobjc.recv(1024).strip().split(" ")
			limobjc.close()
			if (len(limresp) < 1):
				limresp = ["-1"]
			if (limresp[0] == "0"):
				limpre = limresp[1]
				limpos = limresp[2]
			elif (limresp[0] == "1"):
				pass
			print("recv limit:", limdata, limresp)
			x += 1
	except:
		pass
	return limresp

'''{
"db":{"host":"127.0.0.1", "user":"whois", "pass":"Siohw1!", "name":"dbname", "table":"whois_cache", "col":"text"},
"limiter":{"host":"127.0.0.1", "port":3434, "pass":"Limiter1!", "conn":1, "time":10},
"whois":{"port":4343},
}'''
fobj = open(sys.argv[1], "r")
conf = ast.literal_eval(fobj.read().strip())
fobj.close()

servport = conf["whois"]["port"]
childlist = []

limhost = conf["limiter"]["host"]
limport = conf["limiter"]["port"]
limpass = conf["limiter"]["pass"]
limpre = ""; limpos = ""

sqlshost = conf["db"]["host"]
sqlsuser = conf["db"]["user"]
sqlspass = conf["db"]["pass"]
sqlsdb = conf["db"]["name"]
sqlstbl = conf["db"]["table"]
sqlscol = conf["db"]["col"]

sockobjc = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sockobjc.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sockobjc.bind(("", servport))
sockobjc.listen(1)

while (1):
	for x in range(0, len(childlist)):
		try:
			os.waitpid(childlist[x], os.WNOHANG)
		except:
			childlist[x] = -1
	while (-1 in childlist):
		childlist.remove(-1)
	lims("127.0.0.1")
	(sockconn, sockaddr) = sockobjc.accept()
	print("conn open:", sockaddr)
	try:
		childpid = os.fork()
	except:
		childpid = -1
	if (childpid == 0):
		resplim = lims(sockaddr[0])
		try:
			sqldom = sockconn.recv(1024).strip()
			sqldom = sstr(sqldom.upper())
			connresp = ""
			print("conn data:", sockaddr, sqldom)
			if ((resplim[0] == "2") and (resplim[1] == "ok")):
				try:
					conn = psycopg2.connect("host='%s' dbname='%s' user='%s' password='%s'" % (sqlshost, sqlsdb, sqlsuser, sqlspass))
					curs = conn.cursor()
					curs.execute("SELECT %s FROM %s WHERE name = '%s';" % (sqlscol, sqlstbl, sqldom))
					rows = curs.fetchall()
					conn.close()
					leng = 0
					for rowo in rows:
						connresp = ("%s\n\n\n" % (rowo[0].strip()))
						leng += 1
						break
					if (leng < 1):
						connresp = ("NOT FOUND\n")
				except:
					connresp = ("SERVER ERROR (1)\n")
			else:
				connresp = ("LIMIT REACHED\n")
			sockconn.send(connresp)
		except:
			pass
		try:
			print("conn closed:", sockaddr)
			sockconn.shutdown(socket.SHUT_RDWR)
			sockconn.close()
		except:
			pass
		sys.exit(0)
	else:
		try:
			sockconn.close()
		except:
			pass
		childlist.append(childpid)

Limiter Notes:

  • The shared secret is padded with 2 random strings:
    • shared-secret = (pre-pad + common-password + post-pad)
    • These 2 strings are re-generated after 2^16 unique nonces are used
  • The message data is prefixed with a unique nonce string:
    • message-data = (uniq-nonce + message-body)
  • The limiter server uses sha256 hashing to authenticate data:
    • auth-message = sha256(shared-secret + message-data + shared-secret)
    • Can switch to a basic HMAC call if greater security is needed
  • The limiter server is a single process which communicates with any connecting clients
    • Can switch to a forked-child setup if faster connections are needed

Whois Notes:

  • The whois server uses forked-child processes to communicate with multiple clients at the same time
    • Each client process will make its own connection to the database server

A Simple Puppet Master/Node/Agent Starter Guide

If you’re looking for a simple, quick starter guide to setting up a basic Puppet master/agent between VM’s then you should take a look at this blog I came across from a Google search. I’m putting this here as a bookmark to myself:

http://www.6tech.org/2013/01/how-to-install-puppet-open-source-on-centos-6-3/

Edit:

Pushing an example shell script to some agents (puppetnode):

[master ~]# cat /etc/puppet/manifests/site.pp
node "puppetnode"
{
	file { "/usr/local/bin/repoconf.sh" :
		mode => 0755,
		owner => root,
		group => root,
		source => "puppet:///modules/bin/repoconf.sh"
	}
	exec { "/usr/local/bin/repoconf.sh" :
		require => File["/usr/local/bin/repoconf.sh"]
	}
	package { "nc" :
		ensure => latest,
		require => Exec["/usr/local/bin/repoconf.sh"]
	}
}
[master ~]# cat /etc/puppet/modules/bin/files/repoconf.sh
#!/bin/bash
echo `date` >> /tmp/custom.puppet.sh.log
[puppetnode ~]# puppet agent -t
Info: Retrieving plugin
Info: Caching catalog for puppetnode
Info: Applying configuration version '1386822999'
Notice: /Stage[main]/Main/Node[puppetnode]/File[/usr/local/bin/repoconf.sh]/ensure: defined content as '{md5}dfd896a6b7b57885fac7bac43f2bd263'
Notice: /Stage[main]/Main/Node[puppetnode]/Exec[/usr/local/bin/repoconf.sh]/returns: executed successfully
Notice: /Stage[main]/Main/Node[puppetnode]/Package[nc]/ensure: created
Notice: Finished catalog run in 6.84 seconds

Converting CSV Data To Wiki Tables Via Python

#!/usr/bin/python
import sys
x = 0; l = 1
print('{| border="1" class="wikitable"')
for line in sys.stdin.readlines():
	type = "|"
	if (x == 0):
		type = "!"
	if (x != 0):
		print('|-')
	if ("," in line):
		l = 0
		for coli in line.split(","):
			print(type + ' style="white-space:nowrap;" | ' + coli.strip())
			l += 1
	else:
		print('| colspan="'+str(l)+'" align="middle" | ' + line)
	x += 1
print('|}')

POC – An Encrypted File Upload/Download Site In PHP

There is no site currently running this script but I have posted the code on github just in case anyone would like to play with it or run it. [GIT Repo]

Sfts0

Sfts2

<?php
	# sudo su -
	# mkdir -p /var/www/uploads/$sub
	# for d in /var /var/www /var/www/uploads ; do chown root:root $d ; chmod 755 $d ; done
	# chown root:apache /var/www/uploads/$sub
	# chmod 770 /var/www/uploads/$sub
	
	function safe_valu($vkeyname)
	{
		if (isset($_GET[$vkeyname])) { return $_GET[$vkeyname]; }
		if (isset($_POST[$vkeyname])) { return $_POST[$vkeyname]; }
		return "";
	}
	
	function rand_numb()
	{
		$o = "";
		for ($x = 0; $x < 6; $x += 1) { $o .= rand(0, 9); }
		return $o;
	}
	
	function remo_file($pathname)
	{
		if (!is_file($pathname)) { return 0; }
		$fmodtime = filectime($pathname);
		$lastfmod = intval((time() - $fmodtime) / (60 * 60));
		if ($lastfmod >= 48) { unlink($pathname); return 1; }
		return 0;
	}
	
	date_default_timezone_set("America/Toronto");
	srand(microtime() * 1000000);
	$WEB_EOL = "<br/>";
	$writedir = "/var/www/uploads/jon";
	
	$scptmode = safe_valu("mode");
	$pinncode = preg_replace("/[^0-9]/i", "", safe_valu("pinc"));
	$password = safe_valu("pass");
	$aeskhash = hash("SHA256", $password, true);
	
	if ($scptmode == "e")
	{
		$aesinitv = openssl_random_pseudo_bytes(16);
		if (($_FILES["file"]["error"] < 1) && ($_FILES["file"]["size"] < 4096000))
		{
			while (1)
			{
				$pinncode = rand_numb();
				$filename = ($writedir."/".$pinncode);
				if (!file_exists($filename)) { break; }
				if (remo_file($filename) == 1) { break; }
			}
			$fsrcobjc = fopen($_FILES["file"]["tmp_name"], "rb");
			$fdstobjc = fopen($filename, "wb");
			if (($fsrcobjc !== false) && ($fdstobjc !== false))
			{
				fwrite($fdstobjc, "".$_FILES["file"]["name"].""); # filename as string (unknown length)
				fwrite($fdstobjc, "\1"); # non-printable separator (1 byte)
				fwrite($fdstobjc, "".$_FILES["file"]["size"].""); # filesize in bytes (unknown length)
				fwrite($fdstobjc, "\1"); # non-printable separator (1 byte)
				$emessage = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $aeskhash, "magicstring", MCRYPT_MODE_CBC, $aesinitv);
				fwrite($fdstobjc, $emessage); # encrypted magic string (16 bytes)
				fwrite($fdstobjc, $aesinitv); # initialization vector (16 bytes)
				while (!feof($fsrcobjc))
				{
					$fsrcdata = fread($fsrcobjc, 16);
					$emessage = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $aeskhash, $fsrcdata, MCRYPT_MODE_CBC, $aesinitv);
					fwrite($fdstobjc, $emessage);
					$aesinitv = $emessage;
				}
				fclose($fdstobjc);
				fclose($fsrcobjc);
				chmod($filename, 0770);
			}
		}
	}
	
	if ($scptmode == "d")
	{
		$filelist = scandir($writedir);
		foreach ($filelist as $fileitem)
		{
			$itemname = ($writedir."/".$fileitem);
			if (remo_file($itemname) == 1) { continue; }
			if ($fileitem != $pinncode) { continue; }
			$fsrcobjc = fopen($itemname, "rb");
			if ($fsrcobjc !== false)
			{
				$filename = ""; $filechar = "";
				while ($filechar != "\1") { $filename .= $filechar; $filechar = fread($fsrcobjc, 1); }
				$filesize = ""; $filechar = "";
				while ($filechar != "\1") { $filesize .= $filechar; $filechar = fread($fsrcobjc, 1); }
				$filesize = intval($filesize);
				$magicode = fread($fsrcobjc, 16);
				$aesinitv = fread($fsrcobjc, 16);
				$dmessage = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $aeskhash, $magicode, MCRYPT_MODE_CBC, $aesinitv);
				if (rtrim($dmessage) == "magicstring")
				{
					header('Content-Type: application/octet-stream');
					header('Content-Disposition: attachment; filename="'.$filename.'"');
					header('Content-Length: '.$filesize);
					$tempinit = $aesinitv;
					while ($filesize > 0)
					{
						$aesinitv = $tempinit;
						$fsrcdata = fread($fsrcobjc, 16);
						$tempinit = $fsrcdata;
						$dmessage = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $aeskhash, $fsrcdata, MCRYPT_MODE_CBC, $aesinitv);
						$templeng = 16; if ($filesize < 16) { $templeng = $filesize; }
						print(substr($dmessage, 0, $templeng));
						$filesize -= 16;
					}
					fclose($fsrcobjc);
					exit(0);
				}
				fclose($fsrcobjc);
			}
		}
	}
?>

<html>
	<head>
		<title>Secure File Transfer Site</title>
		<style>
			body
			{
				background: #EEEEEE;
			}
			
			a
			{
				color: #000000;
				border-bottom: 1px dotted;
				text-decoration: none;
			}
			
			.minwide
			{
				width: 480px;
			}
			
			.blue
			{
				background: linear-gradient(#2E88C4, #075698) repeat scroll 0 0 rgba(0, 0, 0, 0);
			}
			
			.green
			{
				background: linear-gradient(#B8DB29, #5A8F00) repeat scroll 0 0 rgba(0, 0, 0, 0);
			}
			
			.red
			{
				background: linear-gradient(#F04349, #C81E2B) repeat scroll 0 0 rgba(0, 0, 0, 0);
			}
			
			.bubble
			{
				border-radius: 10px;
				color: #FFFFFF;
				margin: 15px;
				padding: 15px;
			}
			
			.info
			{
				background: linear-gradient(#F9D835, #F3961C) repeat scroll 0 0 rgba(0, 0, 0, 0);
				border-radius: 10px;
				color: #000000;
				margin: 15px;
				padding: 15px;
			}
		</style>
	</head>
	
	<body>
		<center>
			<form method="post" action="index.php" enctype="multipart/form-data">
				<input type="hidden" name="mode" value="e" />
				<table class="minwide bubble green">
					<tr>
						<td colspan="3">
							<center><b>Upload A File</b></center>
						</td>
					</tr>
					<tr>
						<td colspan="3">
							&nbsp;
						</td>
					</tr>
					<tr>
						<td align="right" style="width:1%;">
							<label for="file">Filename:</label>
						</td>
						<td align="left">
							<input type="file" name="file" />
						</td>
						<td align="left" style="width:1%;">
							&nbsp;
						</td>
					</tr>
					<tr>
						<td align="right" style="width:1%;">
							<label for="pass">Password:</label>
						</td>
						<td align="left">
							<input type="text" name="pass" style="width:100%;" />
						</td>
						<td align="left" style="width:1%;">
							<input type="submit" name="submit" value="Upload" />
						</td>
					</tr>
				</table>
			</form>
			
			<table class="minwide info">
				<tr>
					<td>
						<center>
						&nbsp;
						<?php
							if ($pinncode != "") { print("<a href='?pinc=".$pinncode."'>"."Your PIN code is: ".$pinncode."</a>".PHP_EOL); }
							else { print("No PIN code detected".PHP_EOL); }
						?>
						&nbsp;
						</center>
					</td>
				</tr>
			</table>
			
			<form method="post" action="index.php">
				<input type="hidden" name="mode" value="d" />
				<table class="minwide bubble blue">
					<tr>
						<td colspan="3">
							<center><b>Download A File</b></center>
						</td>
					</tr>
					<tr>
						<td colspan="3">
							&nbsp;
						</td>
					</tr>
					<tr>
						<td align="right" style="width:1%;">
							<label for="pinc">Pincode:</label>
						</td>
						<td align="left">
							<input type="text" name="pinc" size="8" value="<?php print($pinncode); ?>" />
						</td>
						<td align="left" style="width:1%;">
							&nbsp;
						</td>
					</tr>
					<tr>
						<td align="right" style="width:1%;">
							<label for="pass">Password:</label>
						</td>
						<td align="left">
							<input type="password" name="pass" style="width:100%;" />
						</td>
						<td align="left" style="width:1%;">
							<input type="submit" name="submit" value="Download" />
						</td>
					</tr>
				</table>
			</form>
			
			<table class="bubble red">
				<tr>
					<td>
						<center><b>How does this thing work?</b></center> <br /> <br />
						* You first upload a file along with a password string <br />
						&nbsp; * You then copy the PIN code link above and send that to another person <br />
						&nbsp; * You also tell them the shared, secret password over a different medium <br />
						* Any PIN code which points to a file that was created over 48 hours ago will be deleted <br />
						* The server generates a random 128 bit Initialization Vector & a unique 6 digit PIN code <br />
						&nbsp; * [iv = rand-bytes(16)] <br />
						* The server calculates a secret 256 bit key using a hashing algorithm & your password <br />
						&nbsp; * [passhash = SHA-256(password)] <br />
						* The server encrypts your file data using a symmetric block cipher <br />
						&nbsp; * [encdata = AES-256-CBC(filedata, passhash, iv)] <br />
						* The server encrypts a magic string so that the password can be validated before decryption <br />
						&nbsp; * [encmagic = AES-256-CBC("magicstr", passhash, iv)] <br />
						* The server writes out a final file named by the PIN code with the following data: <br />
						&nbsp; * [filepin = (filename + \1 + filesize + \1 + encmagic + iv + encdata)] <br />
						* There is a 4 MB file size upload limit
					</td>
				</tr>
			</table>
		</center>
	</body>
</html>

Proof Of Concept Script – Allowing Incoming Server Connections Through An Outbound Client Connection Only (All Through An External Public Server)

#!/usr/bin/python

import os
import random
import select
import socket
import string
import sys
import time

def rndstr(size):
	o = ""
	for x in range(0, size):
		o += random.choice(string.digits + string.ascii_uppercase + string.ascii_lowercase)
	return o

def tryclose(sockobjc):
	try:
		sockobjc.close()
	except:
		pass

def childrwe(socklist):
	buffsize = 1024
	bufflist = ["", ""]
	erroflag = 0; dataflag = 1
	while (erroflag == 0):
		if (dataflag == 0):
			for x in range(0, 2):
				if (bufflist[x]):
					y = ((x + 1) % 2)
					#print("send:",y,"data:",bufflist[x])
					try:
						socklist[y].send(bufflist[x])
						bufflist[x] = ""
					except:
						erroflag = 1
		dataflag = 0
		(readlist, writlist, errolist) = select.select(socklist, [], [], 0.01)
		for x in range(0, 2):
			if (socklist[x] in readlist):
				try:
					databuff = socklist[x].recv(buffsize)
				except:
					databuff = ""
					erroflag = 1
				if (not databuff):
					erroflag = 1
				else:
					bufflist[x] += databuff
					dataflag = 1
	tryclose(socklist[0]); tryclose(socklist[1])
	sys.exit(0)

def main():
	print("%s public [public_port] [private_port] [private_password]" % (sys.argv[0]))
	print("%s private [public_host] [private_port] [private_password] [local_port]" % (sys.argv[0]))
	print("")
	
	buffsize = 1024
	
	if (sys.argv[1] == "public"):
		clieport = int(sys.argv[2])
		servport = int(sys.argv[3])
		password = sys.argv[4]
		
		clieobjc = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
		clieobjc.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
		clieobjc.bind(("0.0.0.0", clieport))
		clieobjc.listen(1)
		clielist = []
		
		servobjc = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
		servobjc.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
		servobjc.bind(("0.0.0.0", servport))
		servobjc.listen(1)
		servlist = []
		
		childlst = []
		while (1):
			templist = [clieobjc, servobjc]
			for clieitem in clielist:
				if (clieitem[0]):
					templist.append(clieitem[0])
			for servitem in servlist:
				if (servitem[0]):
					templist.append(servitem[0])
			
			(readlist, writlist, errolist) = select.select(templist, [], [])
			
			if (clieobjc in readlist):
				(connobjc, addrobjc) = clieobjc.accept()
				uniqstri = rndstr(16)
				print(int(time.time()),"clie:","connection opened:",addrobjc,"id:",uniqstri)
				clielist.append([connobjc, None, "", addrobjc, uniqstri])
				sentflag = 0
				delelist = []
				for servitem in servlist:
					if (servitem[1] == "control"):
						print(int(time.time()),"serv:","sending notice:",servitem[2],"data:",uniqstri)
						try:
							servitem[0].send(uniqstri)
							sentflag = 1
						except:
							delelist.append(servitem)
					if (sentflag == 1):
						break
				for deleitem in delelist:
					print(int(time.time()),"serv:","connection closed:",deleitem[2])
					tryclose(deleitem[0])
					servlist.remove(deleitem)
			
			elif (servobjc in readlist):
				(connobjc, addrobjc) = servobjc.accept()
				print(int(time.time()),"serv:","connection opened:",addrobjc)
				servlist.append([connobjc, "", addrobjc])
			
			else:
				delelist = []
				for servitem in servlist:
					if (servitem[0] in readlist):
						try:
							databuff = servitem[0].recv(buffsize)
						except:
							delelist.append(servitem)
						if (not databuff):
							delelist.append(servitem)
						else:
							print(int(time.time()),"serv:","recv from:",servitem[2])
							#print(int(time.time()),"serv:","recv from:",servitem[2],"data:",databuff)
							if (databuff.strip() == password):
								print(int(time.time()),"serv:","verified auth:",servitem[2])
								servitem[1] = "control"
							else:
								for clieitem in clielist:
									if (databuff.strip() == clieitem[4]):
										print(int(time.time()),"serv:","est. middle:",clieitem[3],"*----",clieitem[4],"----*",servitem[2])
										clieitem[1] = servitem[0]
				for deleitem in delelist:
					print(int(time.time()),"serv:","connection closed:",deleitem[2])
					tryclose(deleitem[0])
					servlist.remove(deleitem)
				
				delelist = []
				for clieitem in clielist:
					if (clieitem[0] in readlist):
						try:
							databuff = clieitem[0].recv(buffsize)
						except:
							delelist.append(clieitem)
						if (not databuff):
							delelist.append(clieitem)
						else:
							print(int(time.time()),"clie:","recv from:",clieitem[3],"id:",clieitem[4])
							#print(int(time.time()),"clie:","recv from:",clieitem[3],"id:",clieitem[4],"data:",databuff)
							clieitem[2] += databuff
				for deleitem in delelist:
					print(int(time.time()),"clie:","connection closed:",deleitem[3],"id:",deleitem[4])
					tryclose(deleitem[0])
					clielist.remove(deleitem)
			
			delelist = []
			for childpid in childlst:
				try:
					os.waitpid(childpid, os.WNOHANG)
				except:
					delelist.append(childpid)
			for deleitem in delelist:
				print(int(time.time()),"fork:","child exit:",deleitem)
				childlst.remove(deleitem)
			
			for clieitem in clielist:
				if (clieitem[1]):
					childpid = os.fork()
					if (childpid == 0):
						for sockitem in clielist:
							if (sockitem[0] != clieitem[0]):
								tryclose(sockitem[0]); tryclose(sockitem[1])
						for sockitem in servlist:
							if (sockitem[0] != clieitem[1]):
								tryclose(sockitem[0])
						if (clieitem[2]):
							try:
								clieitem[1].send(clieitem[2])
							except:
								pass
						childrwe([clieitem[0], clieitem[1]])
						sys.exit(0)
					else:
						print(int(time.time()),"fork:","child start:",childpid)
						delelist = []
						for sockitem in clielist:
							if (sockitem[0] == clieitem[0]):
								delelist.append(sockitem)
						for deleitem in delelist:
							tryclose(deleitem[0]); tryclose(deleitem[1])
							clielist.remove(deleitem)
						delelist = []
						for sockitem in servlist:
							if (sockitem[0] == clieitem[1]):
								delelist.append(sockitem)
						for deleitem in delelist:
							tryclose(deleitem[0])
							servlist.remove(deleitem)
						childlst.append(childpid)
	
	if (sys.argv[1] == "private"):
		servport = int(sys.argv[3])
		password = sys.argv[4]
		loclport = int(sys.argv[5])
		
		servobjc = None
		childlst = []
		while (1):
			forkitem = None
			if (servobjc == None):
				try:
					servaddr = socket.gethostbyaddr(sys.argv[2])
					servobjc = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
					servobjc.connect((servaddr[2][0], servport))
					servobjc.send(password)
				except:
					servobjc = None
			if (servobjc == None):
				time.sleep(1)
				continue
			
			(readlist, writlist, errolist) = select.select([servobjc], [], [])
			
			if (servobjc in readlist):
				try:
					databuff = servobjc.recv(buffsize)
					clieaddr = socket.gethostbyaddr(sys.argv[2])
					clieobjc = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
					clieobjc.connect((clieaddr[2][0], servport))
					clieobjc.send(databuff)
					middobjc = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
					middobjc.connect(("127.0.0.1", loclport))
					forkitem = [clieobjc, middobjc, databuff]
				except:
					servobjc = None
			
			delelist = []
			for childpid in childlst:
				try:
					os.waitpid(childpid, os.WNOHANG)
				except:
					delelist.append(childpid)
			for deleitem in delelist:
				childlst.remove(deleitem)
			
			if (forkitem):
				childpid = os.fork()
				if (childpid == 0):
					childrwe([forkitem[0], forkitem[1]])
					sys.exit(0)
				else:
					tryclose(forkitem[0]); tryclose(forkitem[1])
					childlst.append(childpid)

if (__name__ == "__main__"):
	main()

[user1@public-server ~]$ ./fwbust.py public 61337 51337 abcxyz

[user2@private-server ~]$ ./fwbust.py private public.server.com 51337 abcxyz 22

[user3@local ~]$ ssh -p 61337 [email protected]
[user2@private-server ~]$ hostname …

Figured it out yet? 🙂

Auto Login To Cisco WiFi Curl Command

#!/bin/bash
read -p "P: " -s p
printf "$p" | openssl sha1
echo
while true
do
	echo "Attempting login..."
	curl -sL "https://wlc.company.com/login.html" -d "buttonClicked=4" -d "err_flag=0" -d "err_msg=" -d "info_flag=0" -d "info_msg=" -d "redirect_url=" -d "username=$USER" -d "password=$p" > /tmp/wifi.log 2>&1
	sleep 60
done

A Simple Server/Router Firewall

This simple firewall achieves the following:

  • Drops all layer-2 ARP traffic from being forwarded between bridged clients (WiFi)
    • Security: Prevents ARP cache poisoning attacks between clients only
    • Note: This breaks the ability for clients to learn about each others addresses to talk to each other
    • Trick: Clients could still talk to each other by setting static ARP entries to the MAC of the router with each others IP addresses
  • Router loops through the DHCP lease table and sets a static ARP entry for each IP / MAC combo found for every client
    • Security: Prevents ARP cache poisoning attacks coming from a client into the router
    • Note: This does not prevent attackers with Rogue DHCP servers from answering other clients first
  • Drops all layer-3 UDP-DHCP traffic from being broadcasted between clients (WiFi)
    • Security: Prevents rogue DHCP server traffic from being sent between clients
  • General firewalling rules
    • Allows specific inbound traffic only: lo/dhcp/ssh/related/established – drops all else
    • Allow a Destination-NAT port forwarding to a given server IP/Port
    • Allow a Source-NAT for clients of the router to get out
    • Note: Does not prevent DHCP starvation DoS attacks
  • Routing rules to direct traffic to the main VLANs
    • 192.168.0.0/18 is used for the local DHCP VLSM
    • 192.168.96.0/19 -> 192.168.64.2/24 (Part of the 192.168.64.0/18 VLSM)
    • 192.168.160.0/19 -> 192.168.128.2/24 (Part of the 192.168.128.0/18 VLSM)
    • 192.168.192.0/18 is a free VLSM block

 

LAN="br-lan"
WAN="eth0.2"
SRV="192.168.161.2:22"
ROU="192.168.96.0/19:192.168.64.2 192.168.160.0/19:192.168.128.2"


C=`/usr/sbin/ebtables -L FORWARD | grep -i '.p ARP.*.j DROP'`
if [ "$C" == "" ] ; then
	echo "Setting ebtables"
	
	/usr/sbin/ebtables -F
	
	for INTF in -i -o ; do
		/usr/sbin/ebtables -A FORWARD "$INTF" "$LAN" -p ARP -j DROP
		
		for PORT in 67 68 ; do
			for TYPE in sport dport ; do
				/usr/sbin/ebtables -A FORWARD "$INTF" "$LAN" -p ip --ip-protocol udp --ip-"$TYPE" "$PORT" -j DROP
			done
		done
	done
fi


while read E ; do
	M=`echo "$E" | awk '{ print $2 }'`
	I=`echo "$E" | awk '{ print $3 }'`
	/usr/sbin/ip neighbor change "$I" lladdr "$M" dev "$LAN" nud permanent
done < /tmp/dhcp.leases


C=`/usr/sbin/iptables -nvL | grep -i '^chain' | tail -n +4`
if [ "$C" != "" ] ; then
	echo "Setting iptables"
	
	/usr/sbin/iptables -F ; /usr/sbin/iptables -X
	/usr/sbin/iptables -t nat -F ; /usr/sbin/iptables -t nat -X
	/usr/sbin/iptables -t mangle -F ; /usr/sbin/iptables -t mangle -X
	/usr/sbin/iptables -t raw -F ; /usr/sbin/iptables -t raw -X
	
	/usr/sbin/iptables -P INPUT ACCEPT
	/usr/sbin/iptables -A INPUT -i lo -j ACCEPT
	/usr/sbin/iptables -A INPUT -p udp --dport 67 -j ACCEPT
	/usr/sbin/iptables -A INPUT -p tcp --dport 22 -j ACCEPT
	/usr/sbin/iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
	/usr/sbin/iptables -A INPUT -j DROP
	
	/usr/sbin/iptables -P FORWARD ACCEPT
	/usr/sbin/iptables -P OUTPUT ACCEPT
	
	if [ "$WAN" != "" ] ; then
		if [ "$SRV" != "" ] ; then
			/usr/sbin/iptables -t nat -A PREROUTING -i "$WAN" -p tcp --dport 443 -j DNAT --to "$SRV"
		fi
		/usr/sbin/iptables -t nat -A POSTROUTING -o "$WAN" -j MASQUERADE
	fi
fi

for ROUTE in $ROU ; do
	SRC=`echo "$ROUTE" | awk -F':' '{ print $1 }'`
	DST=`echo "$ROUTE" | awk -F':' '{ print $2 }'`
	C=`/usr/sbin/ip route | grep -i "$SRC"`
	if [ "$C" == "" ] ; then
		echo "Adding route [$SRC] -> [$DST]"
		
		/usr/sbin/ip route add "$SRC" via "$DST"
	fi
done

Just some LDAP commands with auth

ldapsearch -xZW -h ldap-master -D "uid=$USER,ou=users,dc=company,dc=com" -LLL 'uid=testuser'
ldapmodify -xZW -h ldap-master -D "uid=$USER,ou=users,dc=company,dc=com" -f /tmp/mod.ldiff
ls... | while read l ; do echo "[$l]" ; c=`echo "$l" | grep -i '^userpassword:'` ; if [ "$c" != "" ] ; then d=`echo "$l" | awk '{ print $2 }' | base64 -d` ; echo "    $d" ; fi ; done

My Net Loss Proof SSH Tunnel Commands

/etc/rc.local

sysctl net.ipv4.conf.all.forwarding=1
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
while true ; do ifconfig tun0 inet 10.0.0.1 netmask 255.255.255.0 pointopoint 10.0.0.2 mtu 1500 up ; sleep 5 ; done &

[common]

S="1.2.3.4"

client

screen -S rssh
sudo ssh -w0:0 "root@$S" 'while true ; do echo `date`-$RANDOM ; sleep 5 ; done'

os x/bsd

screen -S rtun
sudo su -
ifconfig tun0 inet 10.0.0.2 netmask 255.255.255.0 pointopoint 10.0.0.1 mtu 1500 up
R=`netstat -nr | grep -i 'default[ ]*[1-9]' | awk '{ print $2 }'`
route add -host "$S" "$R"
route delete default "$R"
route add default 10.0.0.1
while true ; do c=`ifconfig tun0 2> /dev/null` ; if [ "$c" == "" ] ; then route add default "$R" ; break ; fi ; sleep 5 ; done