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 + "[email protected]#$%^&*-_=+?")
	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 small whois server and a nice holiday video

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
A Simple Puppet Master/Node/Agent Starter Guide

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('|}')
Converting CSV Data To Wiki Tables Via Python

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>
POC – An Encrypted File Upload/Download Site In PHP

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()

[[email protected] ~]$ ./fwbust.py public 61337 51337 abcxyz

[[email protected] ~]$ ./fwbust.py private public.server.com 51337 abcxyz 22

[[email protected] ~]$ ssh -p 61337 [email protected]
[[email protected] ~]$ hostname …

Figured it out yet? 🙂

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

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

A Simple Server/Router Firewall

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 "[email protected]$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
My Net Loss Proof SSH Tunnel Commands

Thought This Was Cool (+OpenSSH Config)

Daily NSA Edit: http://www.theguardian.com/world/2013/sep/05/nsa-how-to-remain-secure-surveillance

and another one! http://prism-break.org

To choose a specific set of ciphers, hashes, and key exchanges for your OpenSSH server:

rm -fv *ec*key*

sshd_config

# Strongest
HostKey        /usr/local/etc/ssh_host_rsa_key
KexAlgorithms  diffie-hellman-group-exchange-sha256
Ciphers        aes256-cbc,aes256-ctr
MACs           hmac-sha2-512,hmac-sha2-256

# Tunneling
TCPKeepAlive     yes
PermitRootLogin  yes
PermitTunnel     point-to-point
Thought This Was Cool (+OpenSSH Config)

A Quick SSH Based VPN Tunnel With Default Gateway Override

sudo su

screen -S server
ssh -o Tunnel=point-to-point -w 0:0 [email protected]
ifconfig tun0 10.0.0.2 pointopoint 10.0.0.1
h=$(dig +search +short "$(cat ~/client.txt)" | grep -i '^[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*$' | head -n 1 | sed -e 's/[0-9]*$/0/g')
g=$(netstat -nr | grep -i '^0.0.0.0.*0.0.0.0' | awk '{ print $2 }')
route add -net "$h" netmask 255.255.255.0 gw "$g"
for s in $(cat ~/servers.txt) ; do echo "[$s]" ; i=$(dig +search +short "$s") ; route add -host "$i" gw 10.0.0.1 ; done
#route add -net 128.0.0.0 netmask 128.0.0.0 gw 10.0.0.1
#route add -net 0.0.0.0 netmask 128.0.0.0 gw 10.0.0.1

screen -S client
echo 1 > /proc/sys/net/ipv4/ip_forward
iptables -F ; iptables -X ; iptables -t nat -F ; iptables -t nat -X
iptables -t nat -A POSTROUTING -o em1 -j MASQUERADE
while true ; do ifconfig tun0 10.0.0.1 pointopoint 10.0.0.2 ; sleep 3 ; done

You should change the following references above: infraopslab and em1

while true ; do ping -c 1 google.ca ; if [ $? -ne 0 ] ; then reboot ; fi ; sleep 3 ; done
netstat -nr | grep -Eiv '^(kernel|destination|0.0.0.0.*0.0.0.0|.*0.0.0.0)' | while read l ; do d=`echo "$l" | awk '{ print $1 }'` ; g=`echo "$l" | awk '{ print $2 }'` ; n=`echo "$l" | awk '{ print $3 }'` ; echo "$d $g $n" ; for t in net host ; do route del "-$t" "$d" netmask "$n" gw "$g" > /dev/null 2>&1 ; done ; done
A Quick SSH Based VPN Tunnel With Default Gateway Override

Bash Login Script To Auto Add Your SSH Agent/Key

~/.bashrc

FOLDIR=~/.tmp/sshagent
mkdir -p $FOLDIR/shell > /dev/null 2>&1
. $FOLDIR/shell/cmds.$(hostname -s) > /dev/null 2>&1
sshcheck=$(ssh-add -l 2>&1 | grep -i '^[0-9][0-9][0-9][0-9 ]')
if [ "$sshcheck" == "" ]
then
	mkdir -p $FOLDIR/sock > /dev/null 2>&1
	rm -frv $FOLDIR/sock/agent.$(hostname -s) > /dev/null 2>&1
	killall -9 ssh-agent > /dev/null 2>&1
	ssh-agent -a $FOLDIR/sock/agent.$(hostname -s) > $FOLDIR/shell/cmds.$(hostname -s)
	. $FOLDIR/shell/cmds.$(hostname -s) > /dev/null 2>&1
	ssh-add
fi

Description of the script above (nfs friendly):
* Attempt to run the last ssh-agent export commands and check for valid keys with the ssh-add command
* If nothing exists then kill any current ssh-agent processes and save a new set of ssh-agent export commands
* Run the current set of ssh-agent export commands and add the default ssh key with ssh-add

Bash Login Script To Auto Add Your SSH Agent/Key

Scripting JS Against PHPLDAPAdmin

Just a lame script to find any attributes for a given objectClass which are not used by any other objectClasses:

var a="";
var l=document.getElementsByTagName("tr");
for (var i in l)
{
	try { var m=l[i].getElementsByTagName("a"); }
	catch(e) { var m=[]; }
	if (m.length == 1)
	{
		try { var z=l[i].innerHTML.match(/^.*Used.*by.*objectClasses.*User.*Authorization.*$/); }
		catch(e) { var z=0; }
		if (z)
		{
			var p=l[i].parentNode.getElementsByTagName("tr")[0].getElementsByTagName("a");
			a += ("\""+p[0].innerHTML+"\", ");
		}
	}
}
console.log(a);
Scripting JS Against PHPLDAPAdmin