Tanto si somos una empresa o un centro dedicado a la seguridad informática, o si simplemente queremos investigar malware, sabemos de la importancia de las HoneyNets como fuente para la detección y obtención de nuevas muestras de malware. También, si queremos descubrir hacia dónde se están dirigiendo los ataques y anticiparse a cuando ocurra en nuestra red en producción, nos puede venir bien montar una honey.
En varios artículos se ha hablado de Dionaea y en esta ocasión voy a mostrar algunos scripts para mostrar los últimos binarios que no eran detectados por la mayoría de antivirus.
Para considerar que se trate de una muestra nueva, tomamos como referencia VirusTotal porque ofrece un servicio con múltiples motores de antivirus guardándonos el resultado en el momento de enviar nuestra muestra. Si la muestra no la detectan más de tres motores, diremos que es un especimen nuevo o una mutación desconocida y no detectada.
Teniendo en cuenta lo anterior, he preparado una consulta SQL que ejecutaremos en la base de datos sqlite3 que muestra aquellos binarios que fueron detectados como malware por menos de cuatro motores de antivirus:
select count(distinct(virustotal)) from ( SELECT vt.virustotal_timestamp as timestamp,vs.virustotal,count(vs.virustotal) as undetected,virustotal_md5_hash,virustotal_permalink FROM virustotalscans vs inner join virustotals vt on vs.virustotal = vt.virustotal and virustotalscan_result is null group by vs.virustotal) where undetected >38 and strftime('%m-%Y', datetime(timestamp, 'unixepoch', 'localtime')) == strftime('%m-%Y','now', '-1 month') ;
Una manera de saber si está aumentando la actividad es contar los ataques recibidos y ver cuántos contenían esas muestras que suponemos nuevas. Adjunto la consulta para realizar esto:
select count(distinct(virustotal)) from ( SELECT vt.virustotal_timestamp as timestamp,vs.virustotal,count(vs.virustotal) as undetected,virustotal_md5_hash,virustotal_permalink FROM virustotalscans vs inner join virustotals vt on vs.virustotal = vt.virustotal and virustotalscan_result is null group by vs.virustotal) where undetected >38 and strftime('%m-%Y', datetime(timestamp, 'unixepoch', 'localtime')) == strftime('%m-%Y','now', '-1 month') ;
Se han detectado XXXX muestras de las cuales XX son únicas.
Otra información que se puede extraer de Dionaea es el origen de los ataques para identificar aquellos países “calientes”: aquellos que más nos visitan. De esta forma podemos ser conscientes de quién está llamando a nuestra puerta. Con el siguiente script se calcula el número de atacantes que han “visitado” nuestro honeypot y el de países de origen. También adjunto el código para crear un mapa con los países que más atacan.
#!/usr/bin/python2.6 import sqlite3 import GeoIP import getopt import sys gi = GeoIP.new(GeoIP.GEOIP_MEMORY_CACHE) countries = '' attackers = '0' def executeQueryTemp(sql): conn_tmp = sqlite3.connect('/opt/dionaea/var/dionaea/logsql.sqlite') ct = conn_tmp.cursor() ct.execute(sql) row_tmp = ct.fetchone() attackers = str(row_tmp[0]) ct.close() return attackers def executeQuery(sql): conn = sqlite3.connect('/opt/dionaea/var/dionaea/logsql.sqlite') c = conn.cursor() c.execute(sql) f_html = open('geomap.html', 'w') f_html.write('<div><script src="http://www.google.com/jsapi" type="text/javascript"></script>') f_html.write("""<script type="text/javascript">google.load('visualization', '1', {packages: [\'geomap\']});</script>""") f_html.write("""<script type="text/javascript"> function drawVisualization() { // Create and populate the data table. var data = new google.visualization.DataTable(); data.addColumn('string', '', 'Country'); data.addColumn('number', 'Hosts'); """) country_list = {} for row in c: count = row[0] ip_addr = row[1] country = gi.country_code_by_addr(str(ip_addr)) if country in country_list: country_list[str(country)] = country_list[str(country)] + count else: country_list[str(country)] = count # print str(country_list) countries = str(len(country_list)) f_html.write('data.addRows(' + str(countries) + ');') num_item = 0 for cc, cc_count in country_list.iteritems(): f_html.write('data.setValue(' + str(num_item) + ', 0, \'' + str(cc) + '\');') f_html.write('data.setValue(' + str(num_item) + ', 1, ' + str(cc_count) + ');') num_item = num_item + 1 f_html.write(""" var geomap = new google.visualization.GeoMap(document.getElementById('geomap')); geomap.draw(data, null); } google.setOnLoadCallback(drawVisualization); </script> </div> <div id="geomap" style="height: 350px; width: 600px;"> </div> """) f_html.close() return countries def createSQL(): queryDesc = "List of attackers by country" querySQL = """ SELECT count(remote_host) as count, remote_host FROM connections WHERE strftime('%m-%Y', datetime(connection_timestamp, 'unixepoch', 'localtime')) == strftime('%m-%Y','now','-1 month') GROUP BY remote_host ORDER BY count DESC ; """ return querySQL def createSQLTMP(): queryTMP = """ SELECT count(remote_host) FROM connections WHERE strftime('%m-%Y', datetime(connection_timestamp, 'unixepoch', 'localtime')) == strftime('%m-%Y','now','-1 month') ; """ return queryTMP def main(): countries = '' attackers = '0' query_attack = createSQLTMP() attackers = str(executeQueryTemp(query_attack)) query_country = createSQL() countries = str(executeQuery(query_country)) print str(attackers) print str(countries) f_text = open('geomap.txt', 'w') texto = 'Se han detectado ' + str(attackers) + ' atacantes desde ' + str(countries) + ' paises\n' f_text.write(texto) f_text.close sys.exit() if __name__ == "__main__": main()
Y aquí una imagen de muestra del mapa que genera:
Por último, algunas URLs capturadas durante el pasado mes que nos pueden venir bien para añadir en listas negras del firewall o proxy, podría extraerse con la siguiente consulta:
SELECT count(*), download_url FROM downloads d INNER JOIN connections c ON d.connection == c.connection and strftime('%m-%Y', datetime(connection_timestamp, 'unixepoch', 'localtime')) == strftime('%m-%Y', 'now', '-1 month') GROUP BY download_url ORDER BY count(*) DESC LIMIT 10 ;
NOTA: Los scripts son un refrito de varias fuentes que han sido modificados o me he basado en ellos para modificarlos. Disculpad si no son muy limpios.
Espero que os sean de utilidad y podáis corregir o ampliar la información que se puede extraer de Dionaea y las comentéis para compartirlas entre todos.