summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorkkadosh2018-03-02 13:31:56 +0000
committerjvoisin2018-03-02 14:31:56 +0100
commit17a09fafa2b569f0ce548220fd099cdf88e3a71e (patch)
tree7d07f6ba92635959fbae9b1ec9fa6470d3bf6576
parentbdd2cfc430d4b841c24a6c08e7934d667bdc6637 (diff)
Add .dump() for eval whitelist/blacklist + simulation mode for whitelist
-rw-r--r--src/sp_config.h2
-rw-r--r--src/sp_config_keywords.c6
-rw-r--r--src/sp_disabled_functions.c8
-rw-r--r--src/sp_execute.c26
-rw-r--r--src/tests/config/dump_eval_blacklist.ini1
-rw-r--r--src/tests/config/dump_eval_whitelist.ini1
-rw-r--r--src/tests/config/eval_whitelist_simulation.ini1
-rw-r--r--src/tests/dump_eval_blacklist.phpt39
-rw-r--r--src/tests/dump_eval_whitelist.phpt51
-rw-r--r--src/tests/dump_request.phpt3
-rw-r--r--src/tests/dump_request_too_big.phpt10
-rw-r--r--src/tests/dump_unserialize.phpt9
-rw-r--r--src/tests/eval_backlist_simulation.phpt4
-rw-r--r--src/tests/eval_whitelist_simulation.phpt28
14 files changed, 171 insertions, 18 deletions
diff --git a/src/sp_config.h b/src/sp_config.h
index 0ccd11e..e537ec2 100644
--- a/src/sp_config.h
+++ b/src/sp_config.h
@@ -119,6 +119,8 @@ typedef struct {
119 sp_list_node *blacklist; 119 sp_list_node *blacklist;
120 sp_list_node *whitelist; 120 sp_list_node *whitelist;
121 bool simulation; 121 bool simulation;
122 char *dump;
123 char *textual_representation;
122} sp_config_eval; 124} sp_config_eval;
123 125
124typedef struct { 126typedef struct {
diff --git a/src/sp_config_keywords.c b/src/sp_config_keywords.c
index a04c88f..9faaafb 100644
--- a/src/sp_config_keywords.c
+++ b/src/sp_config_keywords.c
@@ -153,11 +153,17 @@ int parse_global(char *line) {
153static int parse_eval_filter_conf(char *line, sp_list_node **list) { 153static int parse_eval_filter_conf(char *line, sp_list_node **list) {
154 char *token; 154 char *token;
155 char *rest; 155 char *rest;
156 sp_config_eval *eval = SNUFFLEUPAGUS_G(config).config_eval;
157
156 sp_config_functions sp_config_funcs[] = { 158 sp_config_functions sp_config_funcs[] = {
157 {parse_str, SP_TOKEN_EVAL_LIST, &rest}, 159 {parse_str, SP_TOKEN_EVAL_LIST, &rest},
158 {parse_empty, SP_TOKEN_SIMULATION, 160 {parse_empty, SP_TOKEN_SIMULATION,
159 &(SNUFFLEUPAGUS_G(config).config_eval->simulation)}, 161 &(SNUFFLEUPAGUS_G(config).config_eval->simulation)},
162 {parse_str, SP_TOKEN_DUMP, &(SNUFFLEUPAGUS_G(config).config_eval->dump)},
160 {0}}; 163 {0}};
164
165 eval->textual_representation = estrdup(line);
166
161 int ret = parse_keywords(sp_config_funcs, line); 167 int ret = parse_keywords(sp_config_funcs, line);
162 if (0 != ret) { 168 if (0 != ret) {
163 return ret; 169 return ret;
diff --git a/src/sp_disabled_functions.c b/src/sp_disabled_functions.c
index 4d94a97..5a39cdf 100644
--- a/src/sp_disabled_functions.c
+++ b/src/sp_disabled_functions.c
@@ -470,9 +470,15 @@ ZEND_FUNCTION(eval_blacklist_callback) {
470 if (SNUFFLEUPAGUS_G(in_eval) > 0) { 470 if (SNUFFLEUPAGUS_G(in_eval) > 0) {
471 char* filename = get_eval_filename(zend_get_executed_filename()); 471 char* filename = get_eval_filename(zend_get_executed_filename());
472 const int line_number = zend_get_executed_lineno(TSRMLS_C); 472 const int line_number = zend_get_executed_lineno(TSRMLS_C);
473 if (SNUFFLEUPAGUS_G(config).config_eval->dump) {
474 sp_log_request(
475 SNUFFLEUPAGUS_G(config).config_eval->dump,
476 SNUFFLEUPAGUS_G(config).config_eval->textual_representation,
477 SP_TOKEN_EVAL_BLACKLIST);
478 }
473 if (1 == SNUFFLEUPAGUS_G(config).config_eval->simulation) { 479 if (1 == SNUFFLEUPAGUS_G(config).config_eval->simulation) {
474 sp_log_msg("eval", SP_LOG_SIMULATION, 480 sp_log_msg("eval", SP_LOG_SIMULATION,
475 "A call to %s was tried in eval, in %s:%d, dropping it.", 481 "A call to %s was tried in eval, in %s:%d, logging it.",
476 current_function_name, filename, line_number); 482 current_function_name, filename, line_number);
477 } else { 483 } else {
478 sp_log_msg("eval", SP_LOG_DROP, 484 sp_log_msg("eval", SP_LOG_DROP,
diff --git a/src/sp_execute.c b/src/sp_execute.c
index 5cf139a..1517134 100644
--- a/src/sp_execute.c
+++ b/src/sp_execute.c
@@ -51,6 +51,8 @@ static void is_builtin_matching(const char *restrict const filename,
51 51
52static void ZEND_HOT 52static void ZEND_HOT
53is_in_eval_and_whitelisted(const zend_execute_data *execute_data) { 53is_in_eval_and_whitelisted(const zend_execute_data *execute_data) {
54 sp_config_eval *eval = SNUFFLEUPAGUS_G(config).config_eval;
55
54 if (EXPECTED(0 == SNUFFLEUPAGUS_G(in_eval))) { 56 if (EXPECTED(0 == SNUFFLEUPAGUS_G(in_eval))) {
55 return; 57 return;
56 } 58 }
@@ -71,11 +73,25 @@ is_in_eval_and_whitelisted(const zend_execute_data *execute_data) {
71 73
72 if (EXPECTED(NULL != current_function)) { 74 if (EXPECTED(NULL != current_function)) {
73 if (UNEXPECTED(false == check_is_in_eval_whitelist(current_function))) { 75 if (UNEXPECTED(false == check_is_in_eval_whitelist(current_function))) {
74 sp_log_msg( 76 if (eval->dump) {
75 "Eval_whitelist", SP_LOG_DROP, 77 sp_log_request(
76 "The function '%s' isn't in the eval whitelist, dropping its call.", 78 SNUFFLEUPAGUS_G(config).config_eval->dump,
77 current_function); 79 SNUFFLEUPAGUS_G(config).config_eval->textual_representation,
78 sp_terminate(); 80 SP_TOKEN_EVAL_WHITELIST);
81 }
82 if (eval->simulation) {
83 sp_log_msg(
84 "Eval_whitelist", SP_LOG_SIMULATION,
85 "The function '%s' isn't in the eval whitelist, logging its call.",
86 current_function);
87 return;
88 } else {
89 sp_log_msg(
90 "Eval_whitelist", SP_LOG_DROP,
91 "The function '%s' isn't in the eval whitelist, dropping its call.",
92 current_function);
93 sp_terminate();
94 }
79 } 95 }
80 } 96 }
81} 97}
diff --git a/src/tests/config/dump_eval_blacklist.ini b/src/tests/config/dump_eval_blacklist.ini
new file mode 100644
index 0000000..503143a
--- /dev/null
+++ b/src/tests/config/dump_eval_blacklist.ini
@@ -0,0 +1 @@
sp.eval_blacklist.list("strlen").dump("/tmp/dump_result/").simulation();
diff --git a/src/tests/config/dump_eval_whitelist.ini b/src/tests/config/dump_eval_whitelist.ini
new file mode 100644
index 0000000..2a6c909
--- /dev/null
+++ b/src/tests/config/dump_eval_whitelist.ini
@@ -0,0 +1 @@
sp.eval_whitelist.list("my_fun,cos").simulation().dump("/tmp/dump_result/");
diff --git a/src/tests/config/eval_whitelist_simulation.ini b/src/tests/config/eval_whitelist_simulation.ini
new file mode 100644
index 0000000..9d94db3
--- /dev/null
+++ b/src/tests/config/eval_whitelist_simulation.ini
@@ -0,0 +1 @@
sp.eval_whitelist.list("my_fun,cos").simulation();
diff --git a/src/tests/dump_eval_blacklist.phpt b/src/tests/dump_eval_blacklist.phpt
new file mode 100644
index 0000000..19da8cd
--- /dev/null
+++ b/src/tests/dump_eval_blacklist.phpt
@@ -0,0 +1,39 @@
1--TEST--
2Dump eval blacklist
3--SKIPIF--
4<?php
5if (!extension_loaded("snuffleupagus")) die "skip";
6?>
7--POST--
8post_a=data_post_a&post_b=data_post_b
9--GET--
10get_a=data_get_a&get_b=data_get_b
11--COOKIE--
12cookie_a=data_cookie_a&cookie_b=data_cookie_b
13--INI--
14sp.configuration_file={PWD}/config/dump_eval_blacklist.ini
15--FILE--
16<?php
17@mkdir("/tmp/dump_result/");
18foreach (glob("/tmp/dump_result/sp_dump.*") as $dump) {
19 @unlink($dump);
20}
21
22$a = strlen("1337 1337 1337");
23echo "Outside of eval: $a\n";
24eval('$a = strlen("1234");');
25echo "After eval: $a\n";
26$filename = glob('/tmp/dump_result/sp_dump.*')[0];
27$res = file($filename);
28if ($res[2] != "GET:get_a='data_get_a' get_b='data_get_b' \n") {
29 echo "1\n";
30} elseif ($res[3] != "POST:post_a='data_post_a' post_b='data_post_b' \n") {
31 echo "2\n";
32} elseif ($res[4] != "COOKIE:cookie_a='data_cookie_a&cookie_b=data_cookie_b' \n") {
33 echo "3\n";
34}
35?>
36--EXPECTF--
37Outside of eval: 14
38[snuffleupagus][0.0.0.0][eval][simulation] A call to strlen was tried in eval, in %a/dump_eval_blacklist.php:1, logging it.
39After eval: 4
diff --git a/src/tests/dump_eval_whitelist.phpt b/src/tests/dump_eval_whitelist.phpt
new file mode 100644
index 0000000..24ca1d1
--- /dev/null
+++ b/src/tests/dump_eval_whitelist.phpt
@@ -0,0 +1,51 @@
1--TEST--
2Dump eval whitelist
3--SKIPIF--
4<?php
5if (!extension_loaded("snuffleupagus")) die "skip";
6?>
7--POST--
8post_a=data_post_a&post_b=data_post_b
9--GET--
10get_a=data_get_a&get_b=data_get_b
11--COOKIE--
12cookie_a=data_cookie_a&cookie_b=data_cookie_b
13--INI--
14sp.configuration_file={PWD}/config/dump_eval_whitelist.ini
15--FILE--
16<?php
17@mkdir("/tmp/dump_result/");
18foreach (glob("/tmp/dump_result/sp_dump.*") as $dump) {
19 @unlink($dump);
20}
21
22function my_fun($p) {
23 return "my_fun: $p";
24}
25
26function my_other_fun($p) {
27 return "my_other_fun: $p";
28}
29
30$a = my_fun("1337 1337 1337");
31echo "Outside of eval: $a\n";
32eval('$a = my_fun("1234");');
33echo "After allowed eval: $a\n";
34eval('$a = my_other_fun("1234");');
35echo "After eval: $a\n";
36$filename = glob('/tmp/dump_result/sp_dump.*')[0];
37$res = file($filename);
38if ($res[2] != "GET:get_a='data_get_a' get_b='data_get_b' \n") {
39 echo "1\n";
40} elseif ($res[3] != "POST:post_a='data_post_a' post_b='data_post_b' \n") {
41 echo "2\n";
42} elseif ($res[4] != "COOKIE:cookie_a='data_cookie_a&cookie_b=data_cookie_b' \n") {
43 echo "3\n";
44}
45
46?>
47--EXPECTF--
48Outside of eval: my_fun: 1337 1337 1337
49After allowed eval: my_fun: 1234
50[snuffleupagus][0.0.0.0][Eval_whitelist][simulation] The function 'my_other_fun' isn't in the eval whitelist, logging its call.
51After eval: my_other_fun: 1234
diff --git a/src/tests/dump_request.phpt b/src/tests/dump_request.phpt
index 23cafdc..abff870 100644
--- a/src/tests/dump_request.phpt
+++ b/src/tests/dump_request.phpt
@@ -22,6 +22,9 @@ sp.configuration_file={PWD}/config/dump_request.ini
22--FILE-- 22--FILE--
23<?php 23<?php
24@mkdir("/tmp/dump_result/"); 24@mkdir("/tmp/dump_result/");
25foreach (glob("/tmp/dump_result/sp_dump.*") as $dump) {
26 @unlink($dump);
27}
25echo "1\n"; 28echo "1\n";
26system("echo 1337;"); 29system("echo 1337;");
27$filename = glob('/tmp/dump_result/sp_dump.*')[0]; 30$filename = glob('/tmp/dump_result/sp_dump.*')[0];
diff --git a/src/tests/dump_request_too_big.phpt b/src/tests/dump_request_too_big.phpt
index 795a5c2..d67ce6f 100644
--- a/src/tests/dump_request_too_big.phpt
+++ b/src/tests/dump_request_too_big.phpt
@@ -4,12 +4,7 @@ Dump request -- to big, so it's truncated.
4<?php 4<?php
5if (!extension_loaded("snuffleupagus")) { 5if (!extension_loaded("snuffleupagus")) {
6 print "skip"; 6 print "skip";
7}
8
9foreach (glob("/tmp/dump_result/sp_dump.*") as $dump) {
10 @unlink($dump);
11} 7}
12@rmdir("/tmp/dump_result/");
13?> 8?>
14--POST-- 9--POST--
15post_a=data_post_a&post_b=data_post_b&post_c=c 10post_a=data_post_a&post_b=data_post_b&post_c=c
@@ -25,6 +20,11 @@ END;
25sp.configuration_file={PWD}/config/dump_request.ini 20sp.configuration_file={PWD}/config/dump_request.ini
26--FILE-- 21--FILE--
27<?php 22<?php
23@mkdir("/tmp/dump_result/");
24foreach (glob("/tmp/dump_result/sp_dump.*") as $dump) {
25 @unlink($dump);
26}
27
28echo "1\n"; 28echo "1\n";
29system("echo 1337;"); 29system("echo 1337;");
30$filename = glob('/tmp/dump_result/*')[0]; 30$filename = glob('/tmp/dump_result/*')[0];
diff --git a/src/tests/dump_unserialize.phpt b/src/tests/dump_unserialize.phpt
index 9c3906d..dfa8501 100644
--- a/src/tests/dump_unserialize.phpt
+++ b/src/tests/dump_unserialize.phpt
@@ -5,11 +5,6 @@ Dump unserialize
5if (!extension_loaded("snuffleupagus")) { 5if (!extension_loaded("snuffleupagus")) {
6 print "skip"; 6 print "skip";
7} 7}
8
9foreach (glob("/tmp/dump_result/sp_dump.*") as $dump) {
10 @unlink($dump);
11}
12@rmdir("/tmp/dump_result/");
13?> 8?>
14--POST-- 9--POST--
15post_a=data_post_a&post_b=data_post_b 10post_a=data_post_a&post_b=data_post_b
@@ -22,6 +17,10 @@ sp.configuration_file={PWD}/config/dump_unserialize.ini
22--FILE-- 17--FILE--
23<?php 18<?php
24@mkdir("/tmp/dump_result/"); 19@mkdir("/tmp/dump_result/");
20foreach (glob("/tmp/dump_result/sp_dump.*") as $dump) {
21 @unlink($dump);
22}
23
25echo "1\n"; 24echo "1\n";
26var_dump(unserialize('s:1:"a";alyualskdufyhalkdjsfhalkjdhflaksjdfhlkasdhflkahdawkuerylksjdfhlkssjgdflaksjdhflkasjdf')); 25var_dump(unserialize('s:1:"a";alyualskdufyhalkdjsfhalkjdhflaksjdfhlkasdhflkahdawkuerylksjdfhlkssjgdflaksjdhflkasjdf'));
27$filename = glob('/tmp/dump_result/sp_dump.*')[0]; 26$filename = glob('/tmp/dump_result/sp_dump.*')[0];
diff --git a/src/tests/eval_backlist_simulation.phpt b/src/tests/eval_backlist_simulation.phpt
index ddeae60..bea5115 100644
--- a/src/tests/eval_backlist_simulation.phpt
+++ b/src/tests/eval_backlist_simulation.phpt
@@ -1,5 +1,5 @@
1--TEST-- 1--TEST--
2Eval blacklist 2Eval blacklist simulation
3--SKIPIF-- 3--SKIPIF--
4<?php if (!extension_loaded("snuffleupagus")) die "skip"; ?> 4<?php if (!extension_loaded("snuffleupagus")) die "skip"; ?>
5--INI-- 5--INI--
@@ -13,5 +13,5 @@ echo "After eval: $a\n";
13?> 13?>
14--EXPECTF-- 14--EXPECTF--
15Outside of eval: 14 15Outside of eval: 14
16[snuffleupagus][0.0.0.0][eval][simulation] A call to strlen was tried in eval, in %a/tests/eval_backlist_simulation.php:1, dropping it. 16[snuffleupagus][0.0.0.0][eval][simulation] A call to strlen was tried in eval, in %a/tests/eval_backlist_simulation.php:1, logging it.
17After eval: 4 17After eval: 4
diff --git a/src/tests/eval_whitelist_simulation.phpt b/src/tests/eval_whitelist_simulation.phpt
new file mode 100644
index 0000000..ff2f970
--- /dev/null
+++ b/src/tests/eval_whitelist_simulation.phpt
@@ -0,0 +1,28 @@
1--TEST--
2Eval whitelist simulation
3--SKIPIF--
4<?php if (!extension_loaded("snuffleupagus")) die "skip"; ?>
5--INI--
6sp.configuration_file={PWD}/config/eval_whitelist_simulation.ini
7--FILE--
8<?php
9function my_fun($p) {
10 return "my_fun: $p";
11}
12
13function my_other_fun($p) {
14 return "my_other_fun: $p";
15}
16
17$a = my_fun("1337 1337 1337");
18echo "Outside of eval: $a\n";
19eval('$a = my_fun("1234");');
20echo "After allowed eval: $a\n";
21eval('$a = my_other_fun("1234");');
22echo "After eval: $a\n";
23?>
24--EXPECTF--
25Outside of eval: my_fun: 1337 1337 1337
26After allowed eval: my_fun: 1234
27[snuffleupagus][0.0.0.0][Eval_whitelist][simulation] The function 'my_other_fun' isn't in the eval whitelist, logging its call.
28After eval: my_other_fun: 1234 \ No newline at end of file