From 5da3a92492bf169e62367d954cfa7432bee51fed Mon Sep 17 00:00:00 2001 From: jvoisin Date: Mon, 9 Jul 2018 07:37:58 +0000 Subject: Trying to fix sloppy comparison (#186) * Trying to fix sloppy comparison https://github.com/nbs-system/snuffleupagus/issues/10 by modifying php's opcode --- src/config.m4 | 2 +- src/php_snuffleupagus.h | 1 + src/snuffleupagus.c | 5 ++++ src/sp_config.c | 1 + src/sp_config.h | 4 ++++ src/sp_config_keywords.c | 5 ++++ src/sp_config_keywords.h | 1 + src/sp_execute.c | 1 + src/sp_sloppy.c | 39 ++++++++++++++++++++++++++++++++ src/sp_sloppy.h | 8 +++++++ src/tests/config/sloppy_comparison.ini | 1 + src/tests/sloppy_comparison.phpt | 30 ++++++++++++++++++++++++ src/tests/sloppy_comparison_disable.phpt | 14 ++++++++++++ 13 files changed, 111 insertions(+), 1 deletion(-) create mode 100644 src/sp_sloppy.c create mode 100644 src/sp_sloppy.h create mode 100644 src/tests/config/sloppy_comparison.ini create mode 100644 src/tests/sloppy_comparison.phpt create mode 100644 src/tests/sloppy_comparison_disable.phpt (limited to 'src') diff --git a/src/config.m4 b/src/config.m4 index a4fea4d..0165f87 100644 --- a/src/config.m4 +++ b/src/config.m4 @@ -6,7 +6,7 @@ sources="$sources sp_unserialize.c sp_utils.c sp_disable_xxe.c sp_list.c" sources="$sources sp_disabled_functions.c sp_execute.c sp_upload_validation.c" sources="$sources sp_cookie_encryption.c sp_network_utils.c tweetnacl.c" sources="$sources sp_config_keywords.c sp_var_parser.c sp_var_value.c sp_tree.c" -sources="$sources sp_pcre_compat.c sp_crypt.c sp_session.c" +sources="$sources sp_pcre_compat.c sp_crypt.c sp_session.c sp_sloppy.c" PHP_ARG_ENABLE(snuffleupagus, whether to enable snuffleupagus support, [ --enable-snuffleupagus Enable snuffleupagus support]) diff --git a/src/php_snuffleupagus.h b/src/php_snuffleupagus.h index f80ae66..008a480 100644 --- a/src/php_snuffleupagus.h +++ b/src/php_snuffleupagus.h @@ -43,6 +43,7 @@ #include "sp_utils.h" #include "sp_crypt.h" #include "sp_session.h" +#include "sp_sloppy.h" extern zend_module_entry snuffleupagus_module_entry; diff --git a/src/snuffleupagus.c b/src/snuffleupagus.c index c3fc686..08b2083 100644 --- a/src/snuffleupagus.c +++ b/src/snuffleupagus.c @@ -72,6 +72,7 @@ PHP_GINIT_FUNCTION(snuffleupagus) { SP_INIT(snuffleupagus_globals->config.config_unserialize); SP_INIT(snuffleupagus_globals->config.config_random); + SP_INIT(snuffleupagus_globals->config.config_sloppy); SP_INIT(snuffleupagus_globals->config.config_readonly_exec); SP_INIT(snuffleupagus_globals->config.config_global_strict); SP_INIT(snuffleupagus_globals->config.config_auto_cookie_secure); @@ -212,6 +213,10 @@ static PHP_INI_MH(OnUpdateConfiguration) { SNUFFLEUPAGUS_G(is_config_valid) = true; + if ((SNUFFLEUPAGUS_G(config).config_sloppy->enable)) { + hook_sloppy(); + } + if (SNUFFLEUPAGUS_G(config).config_random->enable) { hook_rand(); } diff --git a/src/sp_config.c b/src/sp_config.c index a89174a..eb5b324 100644 --- a/src/sp_config.c +++ b/src/sp_config.c @@ -22,6 +22,7 @@ sp_config_tokens const sp_func[] = { {.func = parse_eval_blacklist, .token = SP_TOKEN_EVAL_BLACKLIST}, {.func = parse_eval_whitelist, .token = SP_TOKEN_EVAL_WHITELIST}, {.func = parse_session, .token = SP_TOKEN_SESSION_ENCRYPTION}, + {.func = parse_sloppy_comparison, .token = SP_TOKEN_SLOPPY_COMPARISON}, {NULL, NULL}}; /* Top level keyword parsing */ diff --git a/src/sp_config.h b/src/sp_config.h index b44960f..979feda 100644 --- a/src/sp_config.h +++ b/src/sp_config.h @@ -53,6 +53,8 @@ typedef struct { bool enable; } sp_config_global_strict; typedef struct { bool enable; } sp_config_random; +typedef struct { bool enable; } sp_config_sloppy; + typedef struct { bool enable; } sp_config_auto_cookie_secure; typedef struct { bool enable; } sp_config_disable_xxe; @@ -151,6 +153,7 @@ typedef struct { typedef struct { sp_config_random *config_random; + sp_config_sloppy *config_sloppy; sp_config_unserialize *config_unserialize; sp_config_disabled_functions *config_disabled_functions; sp_config_disabled_functions *config_disabled_functions_ret; @@ -192,6 +195,7 @@ typedef struct { #define SP_TOKEN_DISABLE_XXE ".disable_xxe" #define SP_TOKEN_EVAL_BLACKLIST ".eval_blacklist" #define SP_TOKEN_EVAL_WHITELIST ".eval_whitelist" +#define SP_TOKEN_SLOPPY_COMPARISON ".sloppy_comparison" // common tokens #define SP_TOKEN_ENABLE ".enable(" diff --git a/src/sp_config_keywords.c b/src/sp_config_keywords.c index cc1f0f9..2a570cd 100644 --- a/src/sp_config_keywords.c +++ b/src/sp_config_keywords.c @@ -105,6 +105,11 @@ int parse_random(char *line) { NULL); } +int parse_sloppy_comparison(char *line) { + return parse_enable(line, &(SNUFFLEUPAGUS_G(config).config_sloppy->enable), + NULL); +} + int parse_disable_xxe(char *line) { return parse_enable( line, &(SNUFFLEUPAGUS_G(config).config_disable_xxe->enable), NULL); diff --git a/src/sp_config_keywords.h b/src/sp_config_keywords.h index f1f414a..36c66a5 100644 --- a/src/sp_config_keywords.h +++ b/src/sp_config_keywords.h @@ -15,5 +15,6 @@ int parse_upload_validation(char *line); int parse_eval_blacklist(char *line); int parse_eval_whitelist(char *line); int parse_session(char *line); +int parse_sloppy_comparison(char *line); #endif // __SP_CONFIG_KEYWORDS_H diff --git a/src/sp_execute.c b/src/sp_execute.c index ef71227..fb956ca 100644 --- a/src/sp_execute.c +++ b/src/sp_execute.c @@ -1,4 +1,5 @@ #include "php_snuffleupagus.h" +#include "zend_vm.h" #include #include diff --git a/src/sp_sloppy.c b/src/sp_sloppy.c new file mode 100644 index 0000000..05d2505 --- /dev/null +++ b/src/sp_sloppy.c @@ -0,0 +1,39 @@ +#include "sp_sloppy.h" + +ZEND_API zend_op_array* (*zend_compile_file_default)(zend_file_handle* file_handle, int type) = NULL; +ZEND_API zend_op_array* (*zend_compile_string_default)(zval* source_string, char* filename) = NULL; + +static void modify_opcode(zend_op_array* opline) { + if (NULL != opline) { + zend_op* orig_opline = opline->opcodes; + for (; NULL != orig_opline->handler; orig_opline++) { + if (orig_opline->opcode == ZEND_IS_EQUAL) { + orig_opline->opcode = ZEND_IS_IDENTICAL; + zend_vm_set_opcode_handler(orig_opline); + } else if (orig_opline->opcode == ZEND_IS_NOT_EQUAL) { + orig_opline->opcode = ZEND_IS_NOT_IDENTICAL; + zend_vm_set_opcode_handler(orig_opline); + } + } + } +} + +ZEND_API zend_op_array* sp_compile_string(zval* source_string, char* filename) { + zend_op_array* opline = zend_compile_string_default(source_string, filename); + modify_opcode(opline); + return opline; +} + +ZEND_API zend_op_array* sp_compile_file(zend_file_handle* file_handle, int type) { + zend_op_array* opline = zend_compile_file_default(file_handle, type); + modify_opcode(opline); + return opline; +} + +void hook_sloppy() { + zend_compile_file_default = zend_compile_file; + zend_compile_file = sp_compile_file; + + zend_compile_string_default = zend_compile_string; + zend_compile_string = sp_compile_string; +} diff --git a/src/sp_sloppy.h b/src/sp_sloppy.h new file mode 100644 index 0000000..c01b77c --- /dev/null +++ b/src/sp_sloppy.h @@ -0,0 +1,8 @@ +#ifndef SP_SLOPPY_H +#define SP_SLOPPY_H +#include "php_snuffleupagus.h" +#include "zend_vm.h" + +void hook_sloppy(); + +#endif diff --git a/src/tests/config/sloppy_comparison.ini b/src/tests/config/sloppy_comparison.ini new file mode 100644 index 0000000..ab2d32a --- /dev/null +++ b/src/tests/config/sloppy_comparison.ini @@ -0,0 +1 @@ +sp.sloppy_comparison.enable(); diff --git a/src/tests/sloppy_comparison.phpt b/src/tests/sloppy_comparison.phpt new file mode 100644 index 0000000..da28e3d --- /dev/null +++ b/src/tests/sloppy_comparison.phpt @@ -0,0 +1,30 @@ +--TEST-- +Sloppy comparison +--SKIPIF-- + +--INI-- +sp.configuration_file={PWD}/config/sloppy_comparison.ini +--FILE-- + +--EXPECT-- +lol diff --git a/src/tests/sloppy_comparison_disable.phpt b/src/tests/sloppy_comparison_disable.phpt new file mode 100644 index 0000000..f22804b --- /dev/null +++ b/src/tests/sloppy_comparison_disable.phpt @@ -0,0 +1,14 @@ +--TEST-- +Sloppy comparison +--SKIPIF-- + +--INI-- +--FILE-- + +--EXPECT-- +OK -- cgit v1.3