void profile(struct emu_config *conf, struct connection *con, void *data, unsigned int size, unsigned int offset) { struct emu *e = emu_new(); struct emu_env *env = emu_env_new(e); env->profile = emu_profile_new(); // struct emu_cpu *cpu = emu_cpu_get(e); struct emu_memory *mem = emu_memory_get(e); emu_cpu_reg32_set(emu_cpu_get(e), esp, 0x0012fe98); emu_memory_write_block(mem, CODE_OFFSET, data, size); emu_cpu_eip_set(emu_cpu_get(e), CODE_OFFSET + offset); run(e, env); bool needemu = false; struct emu_profile_function *function; for( function = emu_profile_functions_first(env->profile->functions); !emu_profile_functions_istail(function); function = emu_profile_functions_next(function) ) { if( strcmp("recv", function->fnname) == 0 ) { g_message("Can not profile %s, emulating instead", function->fnname); needemu = true; } } if( needemu == true ) { emulate(conf, con, data, size, offset); } else { GString *str = g_string_new(NULL); json_profile_debug(env->profile, str); //printf("%s", str->str); struct incident *i = incident_new("dionaea.module.emu.profile"); incident_value_string_set(i, "profile", str); incident_value_con_set(i, "con", con); connection_ref(con); GAsyncQueue *aq = g_async_queue_ref(g_dionaea->threads->cmds); g_async_queue_push(aq, async_cmd_new(async_incident_report, i)); g_async_queue_unref(aq); ev_async_send(g_dionaea->loop, &g_dionaea->threads->trigger); } emu_env_free(env); emu_free(e); }
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_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); } }
/* 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); } } } }