Nepenthes as honeyd subsystem

Foreword: It does not work

Running Nepenthes as honeyd subsystem does not work.
But as I think it should work, i use this place to doc why it does not work, so there is a well formatted guide howto get it not working, howto reproduce the problems i had.

Requirements

I used Nepenthes 0.1.4 and honeyd 1.1 beta release ( Niels stated the beta would imprve the subsystem handling in his honeyd forums ).

Nepenthes

look at the readme

honeyd

  • python (+ dev files)
  • libevent
  • libdnsres
  • libdnet
  • pcre

Installation

As there are no debian packages, I installed libdnsres to /opt/libdnsres, the problem was i had to change the honeyd Makefile myself to see the dnsres.h file and to link it against libdnsres, honeyd failed to create its needed irs, so i helped out with mkdir -p, but these are minor problems.

So i had

Nepenthes in /opt/nepenthes/
honeyd in /opt/honeyd
libdnsres in /opt/libdnsres

the rest of the depencies was taken from debian packagemanagement.

honeyd configuration

I took a provided sample configuration and added my ‘most wanted’.

cat /opt/honeyd/share/honeyd/config.ethernet

create default
set default default tcp action block
set default default udp action block
set default default icmp action block

create template
set template ethernet "3com"
set template personality "Linux 2.4.7 (X86)"
add template subsystem "/opt/honeyd/share/honeyd/nepenthes.sh" shared restart

bind 192.168.53.120 template

cat /opt/honeyd/share/honeyd/nepenthes.sh

#!/bin/sh

#pwd
cd /opt/nepenthes/
pwd
bin/nepenthes
pwd

nepenthes configuration

i did not change the config the first run.

First run

honeyd came up and started Nepenthes as subsystem, I could see honeyd hooking the sockets

[ spam net mgr ] bindTCPSocket 0 2103 0 30 808cb30
[ spam net handler ] <in virtual bool nepenthes::TCPSocket::bindPort()>
honeyd[16345]: Subsytem "/opt/honeyd/share/honeyd/nepenthes.sh" binds 192.168.53.120:2103
honeyd[16345]: Listen: 0.0.0.0:2103 -> fd 32
[ debug net handler ] Success binding Port 2103
[ debug net ] Socket TCP  (bind) 0.0.0.0:0 -> 0.0.0.0:2103
        Adding DialogueFactory MSMQ Dialogue Factory

but then

[ spam net mgr ] bindTCPSocket 0 2107 0 30 808cb30
[ spam net handler ] <in virtual bool nepenthes::TCPSocket::bindPort()>
nepenthes: newsock_fd: socketpair: Too many open files
[ crit net handler ] Error creating Socket -1 to listen on TCP Port 2107
No buffer space available
[ crit net handler ] ERROR Could not init Socket Permission denied
[ crit net mgr ] ERROR Binding :2107 failed

searching the web for

newsock_fd: socketpair: Too many open files

did not help much

Tweaking I

I simply changed Nepenthes to load much less vuln modules.

Second run

Nepenthes still failed, as he was unable to chown his own logfile.

[ crit mgr ] Could not chown logfile var/log/nepenthes.log 'Operation not permitted'

I changed nepenthes source to startup even if he was unable to chown his logfile and using pstree I saw

pstree -aup

  ├─gnome-terminal,2180,nepenthesdev
  │   ├─bash,4266
  │   │   └─su,22933,root
  │   │       └─bash,22939
  │   │           └─honeyd,16602,nobody -d -f /opt/honeyd/share/honeyd/config.ethernet -u 0 -g 0
  │   │               ├─nepenthes.sh,16607 /opt/honeyd/share/honeyd/nepenthes.sh
  │   │               │   └─nepenthes,16609
  │   │               └─rrdtool,16608 -

Obviously nepenthes runs as nobody, and so he is not allowed to chown() his logfiles. So chown nobody:nobody could have solved this problem too ...

Third run: downlod something

I made Nepenthes load the x2 module, as it offers a neat interface to start downloads so i could verify the honeyd ↔ nepenthes setup works.

Then i telnetted the Virtual Nepenthes (as it works on a ip which does not exists) on port 10002 with another box in my lan.

Telnet Side

telnet 192.168.53.120 10002
Trying 192.168.53.120...
Connected to 192.168.53.120.
Escape character is '^]'.
Welcome to dong Shell

honeyd Side

honeyd[16602]: Connection request: tcp (192.168.53.1:3790 - 192.168.53.120:10002)
honeyd[16602]: Scheduling connection establishment: (192.168.53.1:3790 - 192.168.53.120:10002) -> subsystem "/opt/honeyd/share/honeyd/nepenthes.sh"
honeyd[16602]: Connection established: (192.168.53.1:3790 - 192.168.53.120:10002) -> subsystem "/opt/honeyd/share/honeyd/nepenthes.sh"
[ debug net mgr ] Socket TCP  (bind) 0.0.0.0:0 -> 0.0.0.0:10002
        DialogueFactory x-2 Factory eXample Dialogue Factory could Accept a Connection
[ spam net handler ] <in virtual nepenthes::Socket* nepenthes::TCPSocket::acceptConnection()>
[ spam net handler ] Socket TCP  (accept) 192.168.53.1:3790 -> 192.168.53.1:10002

Here is the first bug:
Even though honeyd knows who wants to connect whom, Nepenthes does not know,

honeyd[16602]: Connection established: (192.168.53.1:3790 - 192.168.53.120:10002) -> subsystem 

in comparision too:

[ spam net handler ] Socket TCP  (accept) 192.168.53.1:3790 -> 192.168.53.1:10002

Nepenthes thinks the address he was connected on is 192.168.53.1, thats pretty wrong, it should be 192.168.53.120.

So i started a download to see what will happen:

Telnet Side

download http://nepenthes.sourceforge.net/

honeyd Side

[ crit module ] Downloading file from "http://130.57.169.34/"
[ spam mgr event ] <in virtual uint32_t nepenthes::EventManager::handleEvent(nepenthes::Event*)>
[ spam down mgr ] Checking Host 130.57.169.34 for locality
[ spam down mgr ] Host 130.57.169.34 is valid ip
[ info down mgr ] Handler http download handler will download http://130.57.169.34/
[ spam down handler ] <in virtual bool nepenthes::HTTPDownloadHandler::download(nepenthes::Download*)>
[ info down handler ] Resolving host http://130.57.169.34/ ...
[ debug spam fixme ] addDNS: Adding DNS 130.57.169.34 for ()
[ debug spam fixme ] DNS is ip 130.57.169.34
[ info down handler ] url 130.57.169.34 resolved
[ spam net mgr ] <in virtual nepenthes::Socket* nepenthes::SocketManager::connectTCPHost(uint32_t, uint32_t, uint16_t, time_t)>
[ debug net handler ] Connecting 192.168.53.1 -> 130.57.169.34:80
honeyd[17585]: Subsytem "/opt/honeyd/share/honeyd/nepenthes.sh" binds 192.168.53.1 to port 44294
honeyd[17585]: Subsystem /opt/honeyd/share/honeyd/nepenthes.sh on 192.168.53.120 attempts illegal bind 192.168.53.1:44294
[ crit net handler ] Could not Bind Socket for connectHost 0
Address already in use
[ crit net handler ] ERROR Could not connect host Permission denied

So ...

honeyd[17585]: Subsytem "/opt/honeyd/share/honeyd/nepenthes.sh" binds 192.168.53.1 to port 44294
honeyd[17585]: Subsystem /opt/honeyd/share/honeyd/nepenthes.sh on 192.168.53.120 attempts illegal bind 192.168.53.1:44294

the problem we face here is a direct result of honeyd’s mistake in setting the right local address on accepted connections.
Nepenthes will use the ip an attacker connected to download something to connect to the attacker, if honeyd tells nepenthes wrong information which ip was attacked, nepenthes has no way to handle this.

Further Tweaks

So, I needed a way to make nepenthes use the 192.168.53.120 ip address as base address for outgoing connections *always*. I set

        bind_address                "192.168.53.120";

in nepenthes.conf and changed

Socket *SocketManager::connectTCPHost(uint32_t localhost, uint32_t remotehost, uint16_t port,time_t connecttimeout)
{
	logPF();
	if ( /* localhost == INADDR_ANY && */  m_BindAddress != INADDR_ANY )
	{
		logDebug("Changed local Bind address from 0.0.0.0 to %s \n",inet_ntoa(*(in_addr *)&m_BindAddress));
		localhost = m_BindAddress;
	}
 
	TCPSocket *sock = new TCPSocket(getNepenthes(),localhost,remotehost,port,connecttimeout);
	sock->Init();
	m_Sockets.push_back(sock);
	return sock;
}

this would use the 192.168.53.120 ip address always when we connect a remote host.

Fith run

Restarting the fresh compiled Nepenthes and starting the same download again gives us

[ debug net handler ] Connecting 192.168.53.120 -> 130.57.169.34:80
honeyd[17940]: Subsytem "/opt/honeyd/share/honeyd/nepenthes.sh" binds 192.168.53.120 to port 8864
honeyd[17940]: Subsytem "/opt/honeyd/share/honeyd/nepenthes.sh" binds 192.168.53.120:8864
[ crit net handler ] ERROR Could not connect host Connection timed out

The “Connection timed out” comes right away, there is no time the connection waits.

But dont ask me why, I was able to download the wiki with this setup after restarting Nepenthes.

[ crit module ] Downloading file from "http://nepenthes.sourceforge.net"
[ spam mgr event ] <in virtual uint32_t nepenthes::EventManager::handleEvent(nepenthes::Event*)>
[ spam down mgr ] Checking Host nepenthes.sourceforge.net for locality
[ info down mgr ] Handler http download handler will download http://nepenthes.sourceforge.net
[ spam down handler ] <in virtual bool nepenthes::HTTPDownloadHandler::download(nepenthes::Download*)>
[ info down handler ] Resolving host http://nepenthes.sourceforge.net ...
[ debug spam fixme ] addDNS: Adding DNS nepenthes.sourceforge.net for ()
[ debug spam fixme ] <in virtual bool nepenthes::DNSResolverADNS::resolveDNS(nepenthes::DNSQuery*)>

honeyd[18006]: Connect: udp 192.168.53.120:0 -> 192.168.53.1:53
honeyd[18006]: Connect: allocated port 24376
honeyd[18006]: Connection established: subsystem "/opt/honeyd/share/honeyd/nepenthes.sh" -> (192.168.53.120:24376 - 192.168.53.1:53)


[ spam net handler ] <in virtual bool nepenthes::TCPSocket::doRespond(char*, uint32_t)>
[ spam net handler ] <in virtual int32_t nepenthes::TCPSocket::doWrite(char*, uint32_t)>
[ debug spam fixme ] <in virtual uint32_t nepenthes::DNSResolverADNS::handleEvent(nepenthes::Event*)>
[ debug spam fixme ] 1 DNS Resolves in Queue
[ debug net handler ] giving data to X2Dialogue
[ debug net handler ] sended 24 from 24 bytes
[ spam net handler ] done sending 24 bytes
[ debug spam fixme ] <in virtual uint32_t nepenthes::DNSResolverADNS::handleEvent(nepenthes::Event*)>
[ debug spam fixme ] 1 DNS Resolves in Queue
[ debug spam fixme ] <in virtual uint32_t nepenthes::DNSResolverADNS::handleEvent(nepenthes::Event*)>
[ debug spam fixme ] 1 DNS Resolves in Queue
[ debug fixme ] resolved dns nepenthes.sourceforge.net (0 left)
[ debug spam fixme ]  1 resolves
[ debug spam fixme ] result '0 66.35.250.209
[ info down handler ] url nepenthes.sourceforge.net resolved

[ spam net mgr ] <in virtual nepenthes::Socket* nepenthes::SocketManager::connectTCPHost(uint32_t, uint32_t, uint16_t, time_t)>
[ debug net mgr ] Changed local Bind address from 0.0.0.0 to 192.168.53.120
[ debug net handler ] Connecting 192.168.53.120 -> 66.35.250.209:80

honeyd[18006]: Subsytem "/opt/honeyd/share/honeyd/nepenthes.sh" binds 192.168.53.120 to port 36403
honeyd[18006]: Subsytem "/opt/honeyd/share/honeyd/nepenthes.sh" binds 192.168.53.120:36403
honeyd[18006]: Connect: tcp 192.168.53.120:36403 -> 66.35.250.209:80
honeyd[18006]: Connect: allocated port 36403
honeyd[18006]: Connection established: subsystem "/opt/honeyd/share/honeyd/nepenthes.sh" -> (192.168.53.120:36403 - 66.35.250.209:80)


[ spam net handler ] <in virtual void nepenthes::TCPSocket::setStatus(socket_state)>
[ spam down handler dia ] <in virtual nepenthes::ConsumeLevel nepenthes::HTTPDialogue::connectionEstablished()>
[ spam net handler ] <in virtual bool nepenthes::TCPSocket::doRespond(char*, uint32_t)>
[ spam net handler ] <in virtual int32_t nepenthes::TCPSocket::doWrite(char*, uint32_t)>
[ spam down handler dia ] HTTP REQ
GET / HTTP/1.0
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)
Accept: */*
Host: nepenthes.sourceforge.net:80
Connection: close


[ debug net handler ] giving data to HTTPDialogue
[ debug net handler ] sended 150 from 150 bytes
[ spam net handler ] done sending 150 bytes
[ spam net handler ] <in virtual int32_t nepenthes::TCPSocket::doRecv()>
[ spam mgr event ] <in virtual uint32_t nepenthes::EventManager::handleEvent(nepenthes::Event*)>
[ spam net handler ] doRecv() 1024
...
...
...
[ spam net handler ] <in virtual int32_t nepenthes::TCPSocket::doRecv()>
[ spam mgr event ] <in virtual uint32_t nepenthes::EventManager::handleEvent(nepenthes::Event*)>
[ spam net handler ] doRecv() 0
[ spam down handler dia ] <in virtual nepenthes::ConsumeLevel nepenthes::HTTPDialogue::connectionShutdown(nepenthes::Message*)>
[ spam down handler dia ] FOUND HEADER (size 451)
[ spam down handler dia ] HTTP/1.1 200 OK
Date: Fri, 09 Dec 2005 12:57:43 GMT
Server: Apache/1.3.33 (Unix) PHP/4.3.10
X-Powered-By: PHP/4.3.10
Set-Cookie: DokuWiki=89e7003a2ffa495d8e53eddde737491e; path=/
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache
Set-Cookie: DokuWikiAUTH=deleted; expires=Thu, 09-Dec-04 12:57:42 GMT
Connection: close
Content-Type: text/html; charset=utf-8
[ spam mgr submit ] Download has flags 0
[ info mgr submit ] File 433ac3bb1381a836147072809e9f48ef has type HTML document text\012- exported SGML document text

A second download of the same url failed with an error resolving the dns.

[ crit module ] Downloading file from "http://nepenthes.sourceforge.net"
[ spam mgr event ] <in virtual uint32_t nepenthes::EventManager::handleEvent(nepenthes::Event*)>
[ spam down mgr ] Checking Host nepenthes.sourceforge.net for locality
[ info down mgr ] Handler http download handler will download http://nepenthes.sourceforge.net
[ spam down handler ] <in virtual bool nepenthes::HTTPDownloadHandler::download(nepenthes::Download*)>
[ info down handler ] Resolving host http://nepenthes.sourceforge.net ...
[ debug spam fixme ] addDNS: Adding DNS nepenthes.sourceforge.net for ()
[ debug spam fixme ] <in virtual bool nepenthes::DNSResolverADNS::resolveDNS(nepenthes::DNSQuery*)>

adns warning: sendto failed: Connection refused (NS=192.168.53.1)

[ spam net handler ] <in virtual bool nepenthes::TCPSocket::doRespond(char*, uint32_t)>
[ spam net handler ] <in virtual int32_t nepenthes::TCPSocket::doWrite(char*, uint32_t)>
[ debug spam fixme ] <in virtual uint32_t nepenthes::DNSResolverADNS::handleEvent(nepenthes::Event*)>
[ debug spam fixme ] 1 DNS Resolves in Queue
[ debug net handler ] giving data to X2Dialogue
[ debug net handler ] sended 24 from 24 bytes
[ spam net handler ] done sending 24 bytes
...
...
...
[ debug spam fixme ] 1 DNS Resolves in Queue
[ debug spam fixme ] <in virtual uint32_t nepenthes::DNSResolverADNS::handleEvent(nepenthes::Event*)>
...
...
...
adns warning: sendto failed: Transport endpoint is not connected (NS=192.168.53.1)
...
...
...
[ debug spam fixme ] 1 DNS Resolves in Queue
[ debug spam fixme ] <in virtual uint32_t nepenthes::DNSResolverADNS::handleEvent(nepenthes::Event*)>

[ debug fixme ] resolved dns nepenthes.sourceforge.net (0 left)
[ debug spam fixme ]  0 resolves
[ warn down handler ] url nepenthes.sourceforge.net unresolved

after restarting the setup it worked for another single shot.

Last run

I changed the nepenthes.sh script to

#!/bin/sh
nc -vvv -l -p 14711 -s 192.168.53.120

result is pretty short

honeyd[18271]: Subsytem "/opt/honeyd/share/honeyd/nepenthes.sh" binds 192.168.53.120:14711
nc: send_fd: sendmsg(-1): Bad file descriptor: Bad file descriptor
honeyd: receive_fd: recvmsg: expected received >0 got 0

Resume: It does not work

many ways to doesnotwork

Here is the list of problems i noticed when running Nepenthes as honeyd subsystem

  • Nepenthes file permissions trivial
  • 32 socketpairs are much too less
  • honeyd’s accept() passes wrong information to nepenthes.
  • connect() works more or less, definitly unreliable
  • resolving dns using adns failed after not using the socket for some time?
  • even netcat failed when asked to bind to its virtual address

but it works?

Niels stated

The current development version of Honeyd supports running mwcollect as subsystem. 
For testing purposes, I just bound mwcollect to 200 virtual IP addresses in a C-class network 
and am now waiting for the malware to come in.

Running mwcollect successfully as subsytem is another major milestone in getting subsystems to be more reliable. 
The next test is going to happen with apache and nmbd.

I'll keep you posted.

Niels.

in his honeyd forums

I’m not sure how he managed that.

 
howto/run_nepenthes_as_honeyd_subsystem.txt · Last modified: 2006/02/17 14:01
 
Recent changes RSS feed Creative Commons License Donate Powered by PHP Valid XHTML 1.0 Valid CSS Driven by DokuWiki