static bool nl_hup(struct lcfgx_tree_node *node) { g_debug("%s", __PRETTY_FUNCTION__); GHashTableIter iter; gpointer key, value; g_hash_table_iter_init(&iter, nl_runtime.link_addr_cache); while( g_hash_table_iter_next(&iter, &key, &value) ) { struct link_addr *nla = value; if( nla == NULL ) continue; g_debug("doing %s", nla->iface); if( nla->active ) { GHashTableIter addr_iter; gpointer addr_key, addr_value; g_hash_table_iter_init(&addr_iter, nla->addrs); while( g_hash_table_iter_next(&addr_iter, &addr_key, &addr_value) ) { struct incident *i; i = incident_new("dionaea.module.nl.addr.hup"); incident_value_string_set(i, "addr", g_string_new(addr_key)); incident_value_string_set(i, "iface", g_string_new(nla->iface)); incident_value_int_set(i, "scope", nla->ifindex); incident_report(i); incident_free(i); } } } return true; }
static void nl_ihandler_cb(struct incident *i, void *ctx) { g_debug("%s i %p ctx %p", __PRETTY_FUNCTION__, i, ctx); struct connection *con; incident_value_con_get(i, "con", &con); char *remote = con->remote.ip_string; char *local = con->local.ip_string; char *prefix = "::ffff:"; if( strncmp(local, prefix, strlen(prefix)) == 0) local += strlen(prefix); if( strncmp(remote, prefix, strlen(prefix)) == 0) remote += strlen(prefix); int ifindex; int err; { g_debug("local addr %s remote addr %s", local, remote); struct rtnl_addr *addr = rtnl_addr_alloc(); struct nl_addr *a; if ( ( err = nl_addr_parse(local, AF_UNSPEC, &a)) != 0 ) g_critical("could not parse addr %s (%s)", local, nl_geterror(err)); rtnl_addr_set_local(addr, a); nl_addr_put(a); struct rtnl_addr *res = NULL; nl_cache_foreach_filter(nl_runtime.addr_cache, OBJ_CAST(addr), cache_lookup_cb, &res); g_critical("LOCAL RTNL_ADDR %p", res); /* struct nl_dump_params params = { .dp_type = NL_DUMP_LINE, .dp_fd = stdout, }; nl_cache_dump_filter(nl_runtime.addr_cache, ¶ms, OBJ_CAST(addr)); */ ifindex = rtnl_addr_get_ifindex(res); } struct rtnl_neigh *res = NULL; { struct rtnl_neigh *neigh = rtnl_neigh_alloc(); rtnl_neigh_set_ifindex(neigh, ifindex); struct nl_addr *a; if ( ( err = nl_addr_parse(remote, AF_UNSPEC, &a)) != 0 ) g_critical("could not parse addr %s (%s)", remote, nl_geterror(err)); rtnl_neigh_set_dst(neigh, a); nl_addr_put(a); nl_cache_foreach_filter(nl_runtime.neigh_cache, OBJ_CAST(neigh), cache_lookup_cb, &res); } if( res ) { g_critical("GOT NEIGH %p", res); struct nl_addr *lladdr = rtnl_neigh_get_lladdr(res); char buf[123]; nl_addr2str(lladdr, buf, sizeof(buf)); g_critical("GOT NEIGH %s", buf); struct incident *i = incident_new("dionaea.module.nl.connection.info.mac"); incident_value_string_set(i, "mac", g_string_new(buf)); incident_value_con_set(i, "con", con); incident_report(i); incident_free(i); } }
void emulate_ctx_free(void *data) { struct emu_emulate_ctx *ctx = data; GHashTableIter iter; gpointer key, value; g_hash_table_iter_init (&iter, ctx->files); while( g_hash_table_iter_next (&iter, &key, &value) ) { g_debug("file key %p %i value %p \n", key, *(int *)key, value); struct tempfile *tf = value; if( tf->fh == NULL ) { /* file was closed by shellcode */ struct incident *i = incident_new("dionaea.download.complete"); incident_value_string_set(i, "path", g_string_new(tf->path)); if( ctx->ctxcon ) incident_value_con_set(i, "con", ctx->ctxcon); incident_value_string_set(i, "url", g_string_new("emulate://")); incident_report(i); incident_free(i); }else tempfile_close(tf); tempfile_unlink(tf); tempfile_free(tf); } g_hash_table_destroy(ctx->files); g_hash_table_iter_init (&iter, ctx->processes); while( g_hash_table_iter_next (&iter, &key, &value) ) { g_debug("process key %p %i value %p \n", key, *(int *)key, value); } g_hash_table_destroy(ctx->processes); g_hash_table_iter_init (&iter, ctx->sockets); while( g_hash_table_iter_next (&iter, &key, &value) ) { struct connection *con = value; g_debug("connection key %p %i value %p type %s state %s socket %i\n", key, *(int *)key, value, connection_type_to_string(con->type), connection_state_to_string(con->state), con->socket); if( con->socket != -1 ) {/* avoid callbacks from connection_close() */ close(con->socket); con->socket = -1; } g_free(key); con->protocol.ctx = NULL; con->events.free.repeat = .5; connection_free(con); } g_hash_table_destroy(ctx->sockets); if( ctx->time != NULL ) g_timer_destroy(ctx->time); emu_free(ctx->emu); emu_env_free(ctx->env); g_mutex_clear(&ctx->mutex); if( ctx->ctxcon != NULL ) connection_unref(ctx->ctxcon); g_free(ctx); }
static void nl_obj_input(struct nl_object *obj, void *arg) { struct _obj { NLHDR_COMMON }; struct _obj *o = (struct _obj *)obj; if( o->ce_msgtype == RTM_NEWLINK || o->ce_msgtype == RTM_DELLINK ) { struct rtnl_link *link = (struct rtnl_link *)obj; struct nl_addr *a = rtnl_link_get_addr(link); char buf[123]; nl_addr2str(a, buf, sizeof(buf)); int ifindex = rtnl_link_get_ifindex(link); bool active = rtnl_link_get_flags(link) & IFF_UP; char *iface = rtnl_link_get_name(link); if( o->ce_msgtype == RTM_NEWLINK ) { struct link_addr *nla = g_hash_table_lookup(nl_runtime.link_addr_cache, &ifindex); if( nla == NULL ) { g_critical("LINK NEW %s %i", iface, ifindex); struct link_addr *nla = link_addr_new(iface, ifindex, active); g_hash_table_insert(nl_runtime.link_addr_cache, &nla->ifindex, nla); }else { g_critical("LINK CHANGE %s %i", iface, ifindex); GHashTableIter iter; gpointer key, value; g_hash_table_iter_init(&iter, nla->addrs); if( active != nla->active ) { while( g_hash_table_iter_next(&iter, &key, &value) ) { struct incident *i; if( active ) { g_critical("LINK UP"); i = incident_new("dionaea.module.nl.addr.new"); }else { g_critical("LINK DOWN"); i = incident_new("dionaea.module.nl.addr.del"); } incident_value_string_set(i, "addr", g_string_new(key)); incident_value_string_set(i, "iface", g_string_new(nla->iface)); incident_value_int_set(i, "scope", nla->ifindex); incident_report(i); incident_free(i); } nla->active = active; } } }else if( o->ce_msgtype == RTM_DELLINK ) { g_critical("LINK DEL %s %i", iface, ifindex); struct link_addr *nla = g_hash_table_lookup(nl_runtime.link_addr_cache, &ifindex); g_hash_table_remove(nl_runtime.link_addr_cache, &ifindex); link_addr_free(nla); } }else if( o->ce_msgtype == RTM_NEWADDR || o->ce_msgtype == RTM_DELADDR ) { char buf[128]; struct rtnl_addr *addr = (struct rtnl_addr *)obj; struct nl_addr *a = rtnl_addr_get_local(addr); int ifindex = rtnl_addr_get_ifindex(addr); nl_addr2str(a, buf, 128); char *slash; if( (slash = strstr(buf, "/")) != NULL) *slash = '\0'; char *saddr = NULL; struct link_addr *nla = g_hash_table_lookup(nl_runtime.link_addr_cache, &ifindex); if( !nla ) return; if( o->ce_msgtype == RTM_NEWADDR ) { if( g_hash_table_lookup(nla->addrs, buf) == NULL ) { g_warning("NEW ADDR %s!", buf); saddr = g_strdup(buf); g_hash_table_insert(nla->addrs, saddr, saddr); if( nla->active ) { struct incident *i = incident_new("dionaea.module.nl.addr.new"); incident_value_string_set(i, "addr", g_string_new(saddr)); incident_value_string_set(i, "iface", g_string_new(nla->iface)); incident_value_int_set(i, "scope", nla->ifindex); incident_report(i); incident_free(i); } } }else if( o->ce_msgtype == RTM_DELADDR ) { if( ( saddr = g_hash_table_lookup(nla->addrs, buf) ) != NULL ) { g_warning("DEL ADDR! %s", buf); if( nla->active ) { struct incident *i = incident_new("dionaea.module.nl.addr.del"); incident_value_string_set(i, "addr", g_string_new(saddr)); incident_value_string_set(i, "iface", g_string_new(nla->iface)); incident_value_int_set(i, "scope", nla->ifindex); incident_report(i); incident_free(i); } g_hash_table_remove(nla->addrs, buf); g_free(saddr); } } } /* struct nl_dump_params dp = { .dp_type = NL_DUMP_STATS, .dp_fd = stdout, .dp_dump_msgtype = 1, }; nl_object_dump(obj, &dp); struct nl_dump_params params = { .dp_type = NL_DUMP_LINE, .dp_fd = stdout, .dp_prefix = 1, }; g_debug("addr cache"); nl_cache_dump(nl_runtime.addr_cache, ¶ms); g_debug("arp cache"); nl_cache_dump(nl_runtime.neigh_cache, ¶ms); g_debug("link cache"); nl_cache_dump(nl_runtime.link_cache, ¶ms); */ }
/* Check for completed transfers, and remove their easy handles */ static void check_run_count(void) { g_debug("%s queued %i active %i", __PRETTY_FUNCTION__, curl_runtime.queued, curl_runtime.active); if( curl_runtime.queued > curl_runtime.active ) { char *eff_url=NULL; CURLMsg *msg; int msgs_left; struct session *session=NULL; CURL*easy; g_debug("REMAINING: %d", curl_runtime.queued); easy=NULL; while( (msg = curl_multi_info_read(curl_runtime.multi, &msgs_left)) ) { if( msg->msg == CURLMSG_DONE ) { curl_runtime.queued--; easy=msg->easy_handle; curl_easy_getinfo(easy, CURLINFO_PRIVATE, (char **)&session ); curl_easy_getinfo(easy, CURLINFO_EFFECTIVE_URL, &eff_url); switch( session->type ) { case session_type_download: if( msg->data.result == CURLE_OK ) { g_info("DOWNLOAD DONE: %s => (%d) %s", eff_url, msg->data.result, session->error); tempfile_close(session->action.download.file); struct incident *i = incident_new("dionaea.download.complete"); incident_value_string_set(i, "path", g_string_new(session->action.download.file->path)); incident_value_string_set(i, "url", g_string_new(session->url)); if( session->action.download.ctxcon ) incident_value_con_set(i, "con", session->action.download.ctxcon); incident_report(i); incident_free(i); } else { g_warning("DOWNLOAD FAIL: %s => (%d) %s", eff_url, msg->data.result, session->error); tempfile_close(session->action.download.file); } break; case session_type_upload: if( msg->data.result == CURLE_OK ) { g_info("UPLOAD DONE: %s => (%d) %s", eff_url, msg->data.result, session->error); if( session->action.upload.callback == NULL ) break; tempfile_close(session->action.upload.file); // if we have a callback, call the callback struct incident *i = incident_new(session->action.upload.callback); incident_value_string_set(i, "path", g_string_new(session->action.upload.file->path)); if( session->action.upload.userdata != NULL ) incident_value_string_set(i, "_userdata", g_string_new(session->action.upload.userdata)); incident_report(i); incident_free(i); tempfile_unlink(session->action.upload.file); } else { g_warning("UPLOAD FAIL: %s => (%d) %s", eff_url, msg->data.result, session->error); if( session->action.upload.callback == NULL ) break; tempfile_close(session->action.upload.file); tempfile_unlink(session->action.upload.file); } break; } curl_multi_remove_handle(curl_runtime.multi, easy); curl_easy_cleanup(easy); session_free(session); } } } }