From 94649dee9e8b8b6c6c28b79d565ae7b388e3d6d9 Mon Sep 17 00:00:00 2001 From: xXx-caillou-xXx Date: Fri, 13 Jul 2018 11:38:51 +0200 Subject: Allow rules matching on echo and print --- src/snuffleupagus.c | 7 +++++ src/sp_disabled_functions.c | 42 ++++++++++++++++++++++--- src/sp_disabled_functions.h | 3 ++ src/tests/config/disabled_function_echo.ini | 2 ++ src/tests/disabled_function_echo.phpt | 18 +++++++++++ src/tests/disabled_function_echo_2.phpt | 14 +++++++++ src/tests/disabled_function_echo_local_var.phpt | 20 ++++++++++++ 7 files changed, 101 insertions(+), 5 deletions(-) create mode 100644 src/tests/config/disabled_function_echo.ini create mode 100644 src/tests/disabled_function_echo.phpt create mode 100644 src/tests/disabled_function_echo_2.phpt create mode 100644 src/tests/disabled_function_echo_local_var.phpt (limited to 'src') diff --git a/src/snuffleupagus.c b/src/snuffleupagus.c index edca185..ad1d0a9 100644 --- a/src/snuffleupagus.c +++ b/src/snuffleupagus.c @@ -261,6 +261,13 @@ static PHP_INI_MH(OnUpdateConfiguration) { // This is needed to implement the global strict mode CG(compiler_options) |= ZEND_COMPILE_HANDLE_OP_ARRAY; } + if (zend_hash_str_find(SNUFFLEUPAGUS_G(config).config_disabled_functions_hooked, + "echo", strlen("echo")) || + zend_hash_str_find(SNUFFLEUPAGUS_G(config).config_disabled_functions_ret_hooked, + "echo", strlen("echo"))) { + zend_write_default = zend_write; + zend_write = hook_echo; + } SNUFFLEUPAGUS_G(config).hook_execute = SNUFFLEUPAGUS_G(config).config_disabled_functions_reg->disabled_functions || diff --git a/src/sp_disabled_functions.c b/src/sp_disabled_functions.c index 14783f6..f266951 100644 --- a/src/sp_disabled_functions.c +++ b/src/sp_disabled_functions.c @@ -236,13 +236,15 @@ static bool check_is_builtin_name( return (zend_string_equals_literal(config_node->function, "include") || zend_string_equals_literal(config_node->function, "include_once") || zend_string_equals_literal(config_node->function, "require") || - zend_string_equals_literal(config_node->function, "require_once")); + zend_string_equals_literal(config_node->function, "require_once") || + zend_string_equals_literal(config_node->function, "echo")); } if (config_node->r_function) { return (sp_is_regexp_matching(config_node->r_function, "include") || sp_is_regexp_matching(config_node->r_function, "include_once") || sp_is_regexp_matching(config_node->r_function, "require") || - sp_is_regexp_matching(config_node->r_function, "require_once")); + sp_is_regexp_matching(config_node->r_function, "require_once") || + sp_is_regexp_matching(config_node->r_function, "echo")); } return false; } @@ -383,7 +385,12 @@ bool should_disable(zend_execute_data* execute_data, } if (config_node->r_value || config_node->value) { - if (check_is_builtin_name(config_node)) { + if (check_is_builtin_name(config_node) && + !config_node->var && + !config_node->param && + !config_node->r_param && + !config_node->key && + !config_node->r_key) { if (false == is_param_matching(execute_data, config_node, builtin_param, &arg_name, builtin_param_name, &arg_value_str)) { @@ -566,8 +573,14 @@ static int hook_functions(HashTable* to_hook_ht, HashTable* hooked_ht) { if (!HOOK_FUNCTION(ZSTR_VAL(key), disabled_functions_hook, PHP_FN(check_disabled_function)) || check_is_builtin_name(((sp_list_node*)Z_PTR_P(value))->data)) { - zend_symtable_add_new(hooked_ht, key, value); - zend_hash_del(to_hook_ht, key); + if (zend_string_equals_literal(key, "echo") || + zend_string_equals_literal(key, "print")) { + zend_hash_str_add_new(hooked_ht, "echo", strlen("echo"), value); + zend_hash_del(to_hook_ht, key); + } else { + zend_symtable_add_new(hooked_ht, key, value); + zend_hash_del(to_hook_ht, key); + } } } ZEND_HASH_FOREACH_END(); @@ -648,3 +661,22 @@ int hook_disabled_functions(void) { } return ret; } + +zend_write_func_t zend_write_default = NULL; + +int hook_echo(const char* str, size_t str_length) { + zend_string* zs = zend_string_init(str, str_length, 0); + + bool ret = should_disable_ht( + EG(current_execute_data), "echo", zs, NULL, + SNUFFLEUPAGUS_G(config).config_disabled_functions_reg->disabled_functions, + SNUFFLEUPAGUS_G(config).config_disabled_functions_hooked); + + zend_string_release(zs); + + if (ret) { + sp_terminate(); + } + + return zend_write_default(str, str_length); +} diff --git a/src/sp_disabled_functions.h b/src/sp_disabled_functions.h index 4e795a1..83b1551 100644 --- a/src/sp_disabled_functions.h +++ b/src/sp_disabled_functions.h @@ -1,7 +1,10 @@ #ifndef __SP_DISABLE_FUNCTIONS_H #define __SP_DISABLE_FUNCTIONS_H +extern zend_write_func_t zend_write_default; + int hook_disabled_functions(); +int hook_echo(const char*, size_t); bool should_disable(zend_execute_data *, const char *, const zend_string *, const char *, const sp_list_node *, const zend_string *); bool should_disable_ht(zend_execute_data *, const char *, const zend_string *, diff --git a/src/tests/config/disabled_function_echo.ini b/src/tests/config/disabled_function_echo.ini new file mode 100644 index 0000000..39bc5e3 --- /dev/null +++ b/src/tests/config/disabled_function_echo.ini @@ -0,0 +1,2 @@ +sp.disable_function.function("echo").var("$abc").value("123").drop(); +sp.disable_function.function("echo").value("oops").drop(); diff --git a/src/tests/disabled_function_echo.phpt b/src/tests/disabled_function_echo.phpt new file mode 100644 index 0000000..a884e4a --- /dev/null +++ b/src/tests/disabled_function_echo.phpt @@ -0,0 +1,18 @@ +--TEST-- +Echo hooking +--SKIPIF-- + +--INI-- +sp.configuration_file={PWD}/config/disabled_function_echo.ini +--FILE-- + +--CLEAN-- +--EXPECTF-- +qwerty[snuffleupagus][0.0.0.0][disabled_function][drop] Aborted execution on call of the function 'echo' in %a/tests/disabled_function_echo.php:3. diff --git a/src/tests/disabled_function_echo_2.phpt b/src/tests/disabled_function_echo_2.phpt new file mode 100644 index 0000000..20dbee4 --- /dev/null +++ b/src/tests/disabled_function_echo_2.phpt @@ -0,0 +1,14 @@ +--TEST-- +Echo hooking +--SKIPIF-- + +--INI-- +sp.configuration_file={PWD}/config/disabled_function_echo.ini +--FILE-- + +--CLEAN-- +--EXPECTF-- +qwe1[snuffleupagus][0.0.0.0][disabled_function][drop] Aborted execution on call of the function 'echo' in %a/tests/disabled_function_echo_2.php:3. diff --git a/src/tests/disabled_function_echo_local_var.phpt b/src/tests/disabled_function_echo_local_var.phpt new file mode 100644 index 0000000..bfa3c8c --- /dev/null +++ b/src/tests/disabled_function_echo_local_var.phpt @@ -0,0 +1,20 @@ +--TEST-- +Echo hooking +--SKIPIF-- + +--INI-- +sp.configuration_file={PWD}/config/disabled_function_echo.ini +--FILE-- + +--CLEAN-- +--EXPECTF-- +3 +[snuffleupagus][0.0.0.0][disabled_function][drop] Aborted execution on call of the function 'echo' in %a/tests/disabled_function_echo_local_var.php:3. -- cgit v1.3