diff options
| author | jvoisin | 2017-11-29 11:36:57 +0100 |
|---|---|---|
| committer | GitHub | 2017-11-29 11:36:57 +0100 |
| commit | 10437787b0e8ede80976de4a1c22775fc1282f36 (patch) | |
| tree | 1ab911ab000989b98449475eda655a797e278049 /src/sp_execute.c | |
| parent | 8df77884f38e7a7334b56aafe2f441567f175af8 (diff) | |
Implement eval hooking
It's not possible to hook the `eval` builtin like other functions.
Diffstat (limited to 'src/sp_execute.c')
| -rw-r--r-- | src/sp_execute.c | 79 |
1 files changed, 52 insertions, 27 deletions
diff --git a/src/sp_execute.c b/src/sp_execute.c index 45a4ae6..086d769 100644 --- a/src/sp_execute.c +++ b/src/sp_execute.c | |||
| @@ -28,49 +28,55 @@ ZEND_COLD static inline void terminate_if_writable(const char *filename) { | |||
| 28 | } | 28 | } |
| 29 | } | 29 | } |
| 30 | 30 | ||
| 31 | static void construct_include_handler(const char * const filename) { | 31 | static void is_builtin_matching(const char * const filename, char* function_name, |
| 32 | if (SNUFFLEUPAGUS_G(config).config_disabled_constructs->construct_include) { | 32 | char *param_name, sp_node_t *config) { |
| 33 | const sp_node_t* config = SNUFFLEUPAGUS_G(config).config_disabled_constructs->construct_include; | 33 | if (!config || !config->data) { |
| 34 | if (!config || !config->data) { | 34 | return; |
| 35 | return; | 35 | } |
| 36 | } | 36 | |
| 37 | if (true == should_disable(EG(current_execute_data), function_name, filename, param_name)) { | ||
| 38 | sp_terminate(); | ||
| 39 | } | ||
| 40 | } | ||
| 41 | |||
| 42 | char *get_eval_filename(const char *filename) { | ||
| 43 | size_t i = strlen(filename) - 1; | ||
| 44 | int count = 0; | ||
| 45 | char *clean_filename = estrdup(filename); | ||
| 37 | 46 | ||
| 38 | while (config) { | 47 | //ghetto as fuck |
| 39 | sp_disabled_function *config_node = (sp_disabled_function*)(config->data); | 48 | //get the filename in which eval() is called from "foo.php(1) : eval()'d code" |
| 40 | if (true == sp_match_value(filename, config_node->value, config_node->value_r)) { | 49 | while (i) { |
| 41 | if (true == config_node->allow) { | 50 | if (clean_filename[i] == '(') { |
| 42 | return; | 51 | if (count == 1) { |
| 43 | } | 52 | clean_filename[i] = 0; |
| 44 | sp_log_disable("include", "inclusion path", filename, config_node); | 53 | break; |
| 45 | if (false == config_node->simulation) { | ||
| 46 | sp_terminate(); | ||
| 47 | } | ||
| 48 | } | 54 | } |
| 49 | config = config->next; | 55 | count++; |
| 50 | } | 56 | } |
| 57 | i--; | ||
| 51 | } | 58 | } |
| 59 | return clean_filename; | ||
| 52 | } | 60 | } |
| 53 | 61 | ||
| 54 | static void sp_execute_ex(zend_execute_data *execute_data) { | 62 | static void sp_execute_ex(zend_execute_data *execute_data) { |
| 55 | if (NULL == execute_data->func->common.function_name) { | 63 | if (true == should_disable(execute_data, NULL, NULL, NULL)) { |
| 56 | goto execute; | ||
| 57 | } | ||
| 58 | |||
| 59 | if (true == should_disable(execute_data)) { | ||
| 60 | sp_terminate(); | 64 | sp_terminate(); |
| 61 | } | 65 | } |
| 62 | 66 | ||
| 63 | if (execute_data->func->op_array.type == ZEND_EVAL_CODE) { | 67 | if (execute_data->func->op_array.type == ZEND_EVAL_CODE) { |
| 64 | sp_log_debug("Currently in an eval\n"); | 68 | sp_node_t* config = SNUFFLEUPAGUS_G(config).config_disabled_constructs->construct_eval; |
| 69 | char *filename = get_eval_filename((char *)zend_get_executed_filename()); | ||
| 70 | is_builtin_matching(filename, "eval", NULL, config); | ||
| 71 | efree(filename); | ||
| 65 | } | 72 | } |
| 66 | 73 | ||
| 67 | if (NULL != execute_data->func->op_array.filename) { | 74 | if (NULL != execute_data->func->op_array.filename) { |
| 68 | if (true == SNUFFLEUPAGUS_G(config).config_readonly_exec->enable) { | 75 | if (true == SNUFFLEUPAGUS_G(config).config_readonly_exec->enable) { |
| 69 | terminate_if_writable(ZSTR_VAL(execute_data->func->op_array.filename)); | 76 | terminate_if_writable(ZSTR_VAL(execute_data->func->op_array.filename)); |
| 70 | } | 77 | } |
| 71 | } | 78 | } |
| 72 | 79 | ||
| 73 | execute: | ||
| 74 | orig_execute_ex(execute_data); | 80 | orig_execute_ex(execute_data); |
| 75 | } | 81 | } |
| 76 | 82 | ||
| @@ -86,7 +92,26 @@ static int sp_stream_open(const char *filename, zend_file_handle *handle) { | |||
| 86 | if (true == SNUFFLEUPAGUS_G(config).config_readonly_exec->enable) { | 92 | if (true == SNUFFLEUPAGUS_G(config).config_readonly_exec->enable) { |
| 87 | terminate_if_writable(filename); | 93 | terminate_if_writable(filename); |
| 88 | } | 94 | } |
| 89 | construct_include_handler(filename); | 95 | sp_node_t* config = SNUFFLEUPAGUS_G(config).config_disabled_constructs->construct_include; |
| 96 | switch (data->opline->extended_value) { | ||
| 97 | case ZEND_INCLUDE: | ||
| 98 | is_builtin_matching(filename, "include", "inclusion path", config); | ||
| 99 | break; | ||
| 100 | case ZEND_REQUIRE: | ||
| 101 | is_builtin_matching(filename, "require", "inclusion path", config); | ||
| 102 | break; | ||
| 103 | case ZEND_REQUIRE_ONCE: | ||
| 104 | is_builtin_matching(filename, "require_once", "inclusion path", config); | ||
| 105 | break; | ||
| 106 | case ZEND_INCLUDE_ONCE: | ||
| 107 | is_builtin_matching(filename, "include_once", "inclusion path", config); | ||
| 108 | break; | ||
| 109 | case ZEND_EVAL: | ||
| 110 | is_builtin_matching(filename, "eval", NULL, config); | ||
| 111 | break; | ||
| 112 | default: | ||
| 113 | break; | ||
| 114 | } | ||
| 90 | } | 115 | } |
| 91 | 116 | ||
| 92 | end: | 117 | end: |
