样例代码
<?php
eval('$a="hello";');
echo $a;
assert('printf("xxx2");');
preg_replace("/test/e","phpinfo();","just test");
$new_func = create_function('$v','return system($v);');
$new_func("whoami");
call_user_func('system','whoami');
echo exec("echo exec");
echo shell_exec("echo shell_exec");
echo `echo back_quote`;
system('echo system');
passthru('echo passthru');
$array = array("whoami","ls");
$a_array = array("whoami");
array_map("system",$array);
call_user_func_array("system",$a_array);
popen("whoami >> ./test.txt","r");
?>
eval
2 0 E > INCLUDE_OR_EVAL '%24a%3D%22hello%22%3B', EVAL
assert
3 INIT_FCALL 'assert'
4 SEND_VAL 'printf%28%22xxx2%22%29%3B'
5 DO_ICALL
preg_replace
7 7 INIT_FCALL 'preg_replace'
8 SEND_VAL '%2Ftest%2Fe'
9 SEND_VAL 'phpinfo%28%29%3B'
10 SEND_VAL 'just+test'
11 DO_ICALL
create_function
9 12 INIT_FCALL 'create_function'
13 SEND_VAL '%24v'
14 SEND_VAL 'return+system%28%24v%29%3B'
15 DO_ICALL $7
16 ASSIGN !1, $7
10 17 INIT_DYNAMIC_CALL !1
18 SEND_VAL_EX 'whoami'
call_user_func(system)
12 21 INIT_FCALL 'system'
22 SEND_USER 'whoami'
23 DO_FCALL 0
exec
14 24 INIT_FCALL 'exec'
25 SEND_VAL 'echo+exec'
26 DO_ICALL $11
shell_exec
16 29 INIT_FCALL 'shell_exec'
30 SEND_VAL 'echo+shell_exec'
31 DO_ICALL $12
反引号
18 33 INIT_FCALL 'shell_exec'
34 SEND_VAL 'echo+back_quote'
35 DO_ICALL $13
system
20 37 INIT_FCALL 'system'
38 SEND_VAL 'echo+system'
39 DO_ICALL
passthru
22 40 INIT_FCALL 'passthru'
41 SEND_VAL 'echo+passthru'
42 DO_ICALL
array_map
24 43 ASSIGN !2, <array>
25 44 ASSIGN !3, <array>
26 45 INIT_FCALL 'array_map'
46 SEND_VAL 'system'
47 SEND_VAR !2
48 DO_ICALL
call_user_func_array(system)
27 49 INIT_FCALL 'system'
50 SEND_ARRAY !3
51 DO_FCALL 0
popen
29 52 INIT_FCALL 'popen'
53 SEND_VAL 'whoami+%3E%3E+.%2Ftest.txt'
54 SEND_VAL 'r'
55 DO_ICALL \
小结
综上,
- eval不是函数,关注INCLUDE_OR_EVAL
- call_user_func和call_user_func_array也不是函数,只是使用
SEND_USER
和SEND_ARRAY
来传参,即INIT_FCALL->SEND_USER/SEND_ARRAY->DO_ICALL
- 反引号等价于shell_exec
- create_fucntion在调用创建的匿名函数时,用到了
INIT_DYNAMIC_CALL和SEND_VAL_EX
- 基本调用流程:INIT_FCALL(相应函数名)->SEND_VAL(根据需要的参数个数传参)->DO_ICALL(执行函数)