[server] add AFL support for fuzzing SPA Rijndael decryption routine directly with --afl-pkt-file
This commit is contained in:
parent
53be8c4116
commit
285ec0ddcb
@ -362,16 +362,19 @@ EXTRA_DIST = \
|
|||||||
test/afl/fuzzing-wrappers/helpers/fwknopd-parse-conf.sh \
|
test/afl/fuzzing-wrappers/helpers/fwknopd-parse-conf.sh \
|
||||||
test/afl/fuzzing-wrappers/helpers/fwknopd-stdin-hangs.sh \
|
test/afl/fuzzing-wrappers/helpers/fwknopd-stdin-hangs.sh \
|
||||||
test/afl/fuzzing-wrappers/helpers/fwknopd-stdin-test.sh \
|
test/afl/fuzzing-wrappers/helpers/fwknopd-stdin-test.sh \
|
||||||
|
test/afl/fuzzing-wrappers/helpers/fwknopd-enc-pkt-file.sh \
|
||||||
test/afl/fuzzing-wrappers/server-access.sh \
|
test/afl/fuzzing-wrappers/server-access.sh \
|
||||||
test/afl/fuzzing-wrappers/server-conf.sh \
|
test/afl/fuzzing-wrappers/server-conf.sh \
|
||||||
test/afl/fuzzing-wrappers/server-digest-cache.sh \
|
test/afl/fuzzing-wrappers/server-digest-cache.sh \
|
||||||
test/afl/fuzzing-wrappers/spa-pkts.sh \
|
test/afl/fuzzing-wrappers/spa-pkts.sh \
|
||||||
|
test/afl/fuzzing-wrappers/server-enc-pkts.sh \
|
||||||
test/afl/test-cases/client-rc/fwknoprc \
|
test/afl/test-cases/client-rc/fwknoprc \
|
||||||
test/afl/test-cases/server-access/access.conf \
|
test/afl/test-cases/server-access/access.conf \
|
||||||
test/afl/test-cases/server-conf/fwknopd.conf \
|
test/afl/test-cases/server-conf/fwknopd.conf \
|
||||||
test/afl/test-cases/spa-pkts/spa.start \
|
test/afl/test-cases/spa-pkts/spa.start \
|
||||||
test/afl/test-cases/spa-pkts/spa2.start \
|
test/afl/test-cases/spa-pkts/spa2.start \
|
||||||
test/afl/test-cases/spa-pkts/spa3.start \
|
test/afl/test-cases/spa-pkts/spa3.start \
|
||||||
|
test/afl/test-cases/enc-pkts/spa.enc \
|
||||||
test/tests/build_security.pl \
|
test/tests/build_security.pl \
|
||||||
test/tests/preliminaries.pl \
|
test/tests/preliminaries.pl \
|
||||||
test/tests/code_structure.pl \
|
test/tests/code_structure.pl \
|
||||||
|
|||||||
@ -331,6 +331,11 @@ add_salted_str(fko_ctx_t ctx)
|
|||||||
{
|
{
|
||||||
char *tbuf;
|
char *tbuf;
|
||||||
|
|
||||||
|
#if AFL_FUZZING
|
||||||
|
ctx->added_salted_str = 1;
|
||||||
|
return(FKO_SUCCESS);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* We only add the base64 encoded salt to data that is already base64
|
/* We only add the base64 encoded salt to data that is already base64
|
||||||
* encoded
|
* encoded
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -356,6 +356,10 @@ DLL_API int fko_set_raw_spa_digest(fko_ctx_t ctx);
|
|||||||
DLL_API int fko_set_spa_encryption_type(fko_ctx_t ctx, const short encrypt_type);
|
DLL_API int fko_set_spa_encryption_type(fko_ctx_t ctx, const short encrypt_type);
|
||||||
DLL_API int fko_set_spa_encryption_mode(fko_ctx_t ctx, const int encrypt_mode);
|
DLL_API int fko_set_spa_encryption_mode(fko_ctx_t ctx, const int encrypt_mode);
|
||||||
DLL_API int fko_set_spa_data(fko_ctx_t ctx, const char * const enc_msg);
|
DLL_API int fko_set_spa_data(fko_ctx_t ctx, const char * const enc_msg);
|
||||||
|
#if AFL_FUZZING
|
||||||
|
DLL_API int fko_afl_set_spa_data(fko_ctx_t ctx, const char * const enc_msg,
|
||||||
|
const int enc_msg_len);
|
||||||
|
#endif
|
||||||
DLL_API int fko_set_spa_hmac_type(fko_ctx_t ctx, const short hmac_type);
|
DLL_API int fko_set_spa_hmac_type(fko_ctx_t ctx, const short hmac_type);
|
||||||
|
|
||||||
/* Data processing and misc utility functions
|
/* Data processing and misc utility functions
|
||||||
|
|||||||
@ -164,7 +164,7 @@ _rijndael_decrypt(fko_ctx_t ctx,
|
|||||||
{
|
{
|
||||||
unsigned char *ndx;
|
unsigned char *ndx;
|
||||||
unsigned char *cipher;
|
unsigned char *cipher;
|
||||||
int cipher_len, pt_len, i, err = 0, res = FKO_SUCCESS;
|
int cipher_len=0, pt_len, i, err = 0, res = FKO_SUCCESS;
|
||||||
int zero_free_rv = FKO_SUCCESS;
|
int zero_free_rv = FKO_SUCCESS;
|
||||||
|
|
||||||
if(key_len < 0 || key_len > RIJNDAEL_MAX_KEYSIZE)
|
if(key_len < 0 || key_len > RIJNDAEL_MAX_KEYSIZE)
|
||||||
@ -187,6 +187,10 @@ _rijndael_decrypt(fko_ctx_t ctx,
|
|||||||
if(cipher == NULL)
|
if(cipher == NULL)
|
||||||
return(FKO_ERROR_MEMORY_ALLOCATION);
|
return(FKO_ERROR_MEMORY_ALLOCATION);
|
||||||
|
|
||||||
|
#if AFL_FUZZING
|
||||||
|
cipher_len = ctx->encrypted_msg_len;
|
||||||
|
memcpy(cipher, ctx->encrypted_msg, ctx->encrypted_msg_len);
|
||||||
|
#else
|
||||||
if((cipher_len = b64_decode(ctx->encrypted_msg, cipher)) < 0)
|
if((cipher_len = b64_decode(ctx->encrypted_msg, cipher)) < 0)
|
||||||
{
|
{
|
||||||
if(zero_free((char *)cipher, ctx->encrypted_msg_len) == FKO_SUCCESS)
|
if(zero_free((char *)cipher, ctx->encrypted_msg_len) == FKO_SUCCESS)
|
||||||
@ -194,6 +198,7 @@ _rijndael_decrypt(fko_ctx_t ctx,
|
|||||||
else
|
else
|
||||||
return(FKO_ERROR_ZERO_OUT_DATA);
|
return(FKO_ERROR_ZERO_OUT_DATA);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Since we're using AES, make sure the incoming data is a multiple of
|
/* Since we're using AES, make sure the incoming data is a multiple of
|
||||||
* the blocksize
|
* the blocksize
|
||||||
|
|||||||
@ -597,4 +597,39 @@ fko_set_spa_data(fko_ctx_t ctx, const char * const enc_msg)
|
|||||||
return(FKO_SUCCESS);
|
return(FKO_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if AFL_FUZZING
|
||||||
|
/* provide a way to set the encrypted data directly without base64 encoding.
|
||||||
|
* This allows direct AFL fuzzing against decryption routines.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
fko_afl_set_spa_data(fko_ctx_t ctx, const char * const enc_msg, const int enc_msg_len)
|
||||||
|
{
|
||||||
|
/* Must be initialized
|
||||||
|
*/
|
||||||
|
if(!CTX_INITIALIZED(ctx))
|
||||||
|
return FKO_ERROR_CTX_NOT_INITIALIZED;
|
||||||
|
|
||||||
|
if(enc_msg == NULL)
|
||||||
|
return(FKO_ERROR_INVALID_DATA_FUNCS_SET_MSGLEN_VALIDFAIL);
|
||||||
|
|
||||||
|
if(! is_valid_encoded_msg_len(enc_msg_len))
|
||||||
|
return(FKO_ERROR_INVALID_DATA_FUNCS_SET_MSGLEN_VALIDFAIL);
|
||||||
|
|
||||||
|
if(ctx->encrypted_msg != NULL)
|
||||||
|
free(ctx->encrypted_msg);
|
||||||
|
|
||||||
|
/* Copy the raw encrypted data into the context
|
||||||
|
*/
|
||||||
|
ctx->encrypted_msg = calloc(1, enc_msg_len);
|
||||||
|
if(ctx->encrypted_msg == NULL)
|
||||||
|
return(FKO_ERROR_MEMORY_ALLOCATION);
|
||||||
|
|
||||||
|
memcpy(ctx->encrypted_msg, enc_msg, enc_msg_len);
|
||||||
|
|
||||||
|
ctx->encrypted_msg_len = enc_msg_len;
|
||||||
|
|
||||||
|
return(FKO_SUCCESS);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/***EOF***/
|
/***EOF***/
|
||||||
|
|||||||
@ -127,6 +127,9 @@ static char *config_map[NUMBER_OF_CONFIG_ENTRIES] = {
|
|||||||
"GPG_EXE",
|
"GPG_EXE",
|
||||||
"FIREWALL_EXE",
|
"FIREWALL_EXE",
|
||||||
"VERBOSE",
|
"VERBOSE",
|
||||||
|
#if AFL_FUZZING
|
||||||
|
"AFL_PKT_FILE",
|
||||||
|
#endif
|
||||||
"FAULT_INJECTION_TAG"
|
"FAULT_INJECTION_TAG"
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -137,6 +140,7 @@ enum {
|
|||||||
FW_LIST = 0x200,
|
FW_LIST = 0x200,
|
||||||
FW_LIST_ALL,
|
FW_LIST_ALL,
|
||||||
FW_FLUSH,
|
FW_FLUSH,
|
||||||
|
AFL_PKT_FILE,
|
||||||
GPG_HOME_DIR,
|
GPG_HOME_DIR,
|
||||||
GPG_EXE_PATH,
|
GPG_EXE_PATH,
|
||||||
FIREWD_DISABLE_CHECK_SUPPORT,
|
FIREWD_DISABLE_CHECK_SUPPORT,
|
||||||
@ -161,6 +165,7 @@ static struct option cmd_opts[] =
|
|||||||
{
|
{
|
||||||
{"access-file", 1, NULL, 'a'},
|
{"access-file", 1, NULL, 'a'},
|
||||||
{"afl-fuzzing", 0, NULL, 'A'},
|
{"afl-fuzzing", 0, NULL, 'A'},
|
||||||
|
{"afl-pkt-file", 1, NULL, AFL_PKT_FILE },
|
||||||
{"config-file", 1, NULL, 'c'},
|
{"config-file", 1, NULL, 'c'},
|
||||||
{"packet-limit", 1, NULL, 'C'},
|
{"packet-limit", 1, NULL, 'C'},
|
||||||
{"digest-file", 1, NULL, 'd'},
|
{"digest-file", 1, NULL, 'd'},
|
||||||
|
|||||||
@ -1036,6 +1036,15 @@ config_init(fko_srv_options_t *opts, int argc, char **argv)
|
|||||||
#else
|
#else
|
||||||
log_msg(LOG_ERR, "[*] fwknopd not compiled with AFL fuzzing support");
|
log_msg(LOG_ERR, "[*] fwknopd not compiled with AFL fuzzing support");
|
||||||
clean_exit(opts, NO_FW_CLEANUP, EXIT_FAILURE);
|
clean_exit(opts, NO_FW_CLEANUP, EXIT_FAILURE);
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
case AFL_PKT_FILE:
|
||||||
|
#if AFL_FUZZING
|
||||||
|
opts->afl_fuzzing = 1;
|
||||||
|
set_config_entry(opts, CONF_AFL_PKT_FILE, optarg);
|
||||||
|
#else
|
||||||
|
log_msg(LOG_ERR, "[*] fwknopd not compiled with AFL fuzzing support");
|
||||||
|
clean_exit(opts, NO_FW_CLEANUP, EXIT_FAILURE);
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
case 'a':
|
case 'a':
|
||||||
|
|||||||
@ -59,6 +59,7 @@ static void init_digest_cache(fko_srv_options_t *opts);
|
|||||||
static void set_locale(fko_srv_options_t *opts);
|
static void set_locale(fko_srv_options_t *opts);
|
||||||
static pid_t get_running_pid(const fko_srv_options_t *opts);
|
static pid_t get_running_pid(const fko_srv_options_t *opts);
|
||||||
#if AFL_FUZZING
|
#if AFL_FUZZING
|
||||||
|
static void afl_enc_pkt_from_file(fko_srv_options_t *opts);
|
||||||
static void afl_pkt_from_stdin(fko_srv_options_t *opts);
|
static void afl_pkt_from_stdin(fko_srv_options_t *opts);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -187,7 +188,16 @@ main(int argc, char **argv)
|
|||||||
#if AFL_FUZZING
|
#if AFL_FUZZING
|
||||||
/* SPA data from STDIN. */
|
/* SPA data from STDIN. */
|
||||||
if(opts.afl_fuzzing)
|
if(opts.afl_fuzzing)
|
||||||
|
{
|
||||||
|
if(opts.config[CONF_AFL_PKT_FILE] != 0x0)
|
||||||
|
{
|
||||||
|
afl_enc_pkt_from_file(&opts);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
afl_pkt_from_stdin(&opts);
|
afl_pkt_from_stdin(&opts);
|
||||||
|
}
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Prepare the firewall - i.e. flush any old rules and (for iptables)
|
/* Prepare the firewall - i.e. flush any old rules and (for iptables)
|
||||||
@ -290,6 +300,61 @@ static void set_locale(fko_srv_options_t *opts)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if AFL_FUZZING
|
#if AFL_FUZZING
|
||||||
|
static void afl_enc_pkt_from_file(fko_srv_options_t *opts)
|
||||||
|
{
|
||||||
|
FILE *fp = NULL;
|
||||||
|
fko_ctx_t decrypt_ctx = NULL;
|
||||||
|
unsigned char enc_spa_pkt[AFL_MAX_PKT_SIZE] = {0}, rc;
|
||||||
|
int res = 0, es = EXIT_SUCCESS, enc_msg_len;
|
||||||
|
char dump_buf[AFL_DUMP_CTX_SIZE];
|
||||||
|
|
||||||
|
fp = fopen(opts->config[CONF_AFL_PKT_FILE], "rb");
|
||||||
|
if(fp != NULL)
|
||||||
|
{
|
||||||
|
enc_msg_len = 0;
|
||||||
|
while(fread(&rc, 1, 1, fp))
|
||||||
|
{
|
||||||
|
enc_spa_pkt[enc_msg_len] = rc;
|
||||||
|
enc_msg_len++;
|
||||||
|
if(enc_msg_len == AFL_MAX_PKT_SIZE-1)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
fclose(fp);
|
||||||
|
|
||||||
|
fko_new(&decrypt_ctx);
|
||||||
|
|
||||||
|
res = fko_afl_set_spa_data(decrypt_ctx, (const char *)enc_spa_pkt,
|
||||||
|
enc_msg_len);
|
||||||
|
if(res == FKO_SUCCESS)
|
||||||
|
res = fko_decrypt_spa_data(decrypt_ctx, "fwknoptest",
|
||||||
|
strlen("fwknoptest"));
|
||||||
|
if(res == FKO_SUCCESS)
|
||||||
|
res = dump_ctx_to_buffer(decrypt_ctx, dump_buf, sizeof(dump_buf));
|
||||||
|
if(res == FKO_SUCCESS)
|
||||||
|
log_msg(LOG_INFO, "%s", dump_buf);
|
||||||
|
else
|
||||||
|
log_msg(LOG_ERR, "Error (%d): %s", res, fko_errstr(res));
|
||||||
|
|
||||||
|
fko_destroy(decrypt_ctx);
|
||||||
|
|
||||||
|
if(res == FKO_SUCCESS)
|
||||||
|
{
|
||||||
|
log_msg(LOG_INFO, "SPA packet decode: %s", fko_errstr(res));
|
||||||
|
es = EXIT_SUCCESS;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
log_msg(LOG_ERR, "Could not decode SPA packet: %s", fko_errstr(res));
|
||||||
|
es = EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
log_msg(LOG_ERR, "Could not acquire SPA packet from file: %s.",
|
||||||
|
opts->config[CONF_AFL_PKT_FILE]);
|
||||||
|
|
||||||
|
clean_exit(opts, NO_FW_CLEANUP, es);
|
||||||
|
}
|
||||||
|
|
||||||
static void afl_pkt_from_stdin(fko_srv_options_t *opts)
|
static void afl_pkt_from_stdin(fko_srv_options_t *opts)
|
||||||
{
|
{
|
||||||
FILE *fp = NULL;
|
FILE *fp = NULL;
|
||||||
|
|||||||
@ -305,6 +305,9 @@ enum {
|
|||||||
CONF_GPG_EXE,
|
CONF_GPG_EXE,
|
||||||
CONF_FIREWALL_EXE,
|
CONF_FIREWALL_EXE,
|
||||||
CONF_VERBOSE,
|
CONF_VERBOSE,
|
||||||
|
#if AFL_FUZZING
|
||||||
|
CONF_AFL_PKT_FILE,
|
||||||
|
#endif
|
||||||
CONF_FAULT_INJECTION_TAG,
|
CONF_FAULT_INJECTION_TAG,
|
||||||
|
|
||||||
NUMBER_OF_CONFIG_ENTRIES /* Marks the end and number of entries */
|
NUMBER_OF_CONFIG_ENTRIES /* Marks the end and number of entries */
|
||||||
|
|||||||
@ -677,10 +677,16 @@ add_replay_dbm_cache(fko_srv_options_t *opts, char *digest)
|
|||||||
void
|
void
|
||||||
free_replay_list(fko_srv_options_t *opts)
|
free_replay_list(fko_srv_options_t *opts)
|
||||||
{
|
{
|
||||||
|
struct digest_cache_list *digest_list_ptr = NULL, *digest_tmp = NULL;
|
||||||
|
|
||||||
#ifdef NO_DIGEST_CACHE
|
#ifdef NO_DIGEST_CACHE
|
||||||
return;
|
return;
|
||||||
#endif
|
#endif
|
||||||
struct digest_cache_list *digest_list_ptr = NULL, *digest_tmp = NULL;
|
|
||||||
|
#if AFL_FUZZING
|
||||||
|
if(opts->afl_fuzzing)
|
||||||
|
return;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (opts->digest_cache == NULL)
|
if (opts->digest_cache == NULL)
|
||||||
return;
|
return;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user