💎一站式轻松地调用各大LLM模型接口,支持GPT4、智谱、星火、月之暗面及文生图 广告
### **常见php命令注入函数** eval(),,assert(), system(),preg_replace(), create_function, call_user_func, call_user_func_array,array_map(),反引号,ob_start(),exec(),shell_exec(),passthru(),escapeshellcmd(),popen(),proc_open(),pcntl_exec() [https://www.freebuf.com/column/166385.html](https://www.freebuf.com/column/166385.html) **PHP 执行系统命令可以使用以下几个函数** system、exec、passthru、·· 反引号、shell_exec、popen、proc_open、pcntl_exec **system:** 执行外部程序并显示输出 >[info]string system ( string $command [, int &$return_var ] ) ``` system ("/php7/php.exe test.php"); ``` **exec:** 执行一个外部命令 >[info]string exec ( string $command [, array &$output [, int &$return_var ]] ) ``` exec("/php7/php.exe test.php") ``` **passthru:** 执行外部程序并且显示原始输出 >[info]void passthru (string command, int &return_var) ``` passthru('echo $PATH'); ``` **shell_exec:**通过shell环境执行命令 ``` shell_exec('ls -lart') ``` >[info]string shell_exec (string command) `` 反引号:`反引号号里直接包含shell 命令` 会直接执行 ``` echo `ls -al`; $get="whoami"; echo `$get` ``` resource popen ( string $command , string $mode ) resource proc_open ( string $cmd , array $descriptorspec , array &$pipes [, string $cwd [, array $env [, array $other_options ]]] ) void pcntl_exec ( string $path [, array $args [, array $envs ]] ) 例子: ``` if( isset( $_POST[ 'Submit' ] ) ) { // Get input $target = $_REQUEST[ 'ip' ]; // Determine OS and execute the ping command. if( stristr( php_uname( 's' ), 'Windows NT' ) ) { // Windows $cmd = shell_exec( 'ping ' . $target ); } else { // *nix $cmd = shell_exec( 'ping -c 4 ' . $target ); } // Feedback for the end user echo "<pre>{$cmd}</pre>"; } 正常输入: input框输入 www.baidu.com或者输入ip 命令注入: input输入 0 | dir c:提交测试 常见的危险注入符号:%&|>等 ``` # **简单防御:** php.ini禁用这些函数 ``` disable_functions = passthru,exec,system,chroot,chgrp,chown,shell_exec,proc_get_status,proc_open,popen,ini_alter,ini_restore,dl,openlog,syslog,readlink,symlink,popepassthru,stream_socket_server ``` # **防御函数** 当用户提供的数据传入此函数,使用 escapeshellarg() 或 escapeshellcmd() 来确保用户欺骗 系统从而执行任意命令。 ## **escapeshellarg** ( string $arg ) 可以用到 php 的安全中,会过滤掉 arg 中存在的一些特殊字符。在输入的参数中如果包含中 文传递给 escapeshellarg,会被过滤掉。 php.5.6.10之前存在任意命令注入的漏洞,php.5.6.10被修复 ~~~ $dir = "."; system('ls '.escapeshellarg($dir)); escapeshellcmd('ls $dir'); ~~~ ## **escapeshellcmd** ( string $command ) escapeshellcmd()函数会转义命令中的所有 shell 元字符来完成工作。这些元字符包括:# & ; ` , | * ? ~ < > ^ ( ) [ ] { } $ \\ ``` 二者分工不同,前者为了防止用户利用shell的一些技巧(如分号、反引号等),执行其他命令;后者是为了防止用户的输入逃逸出“参数值”的位置,变成一个“参数选项”(命令构成:命令 参数选项 参数值) 渗透测试:[http://www.52bug.cn/hkjs/4879.html](http://www.52bug.cn/hkjs/4879.html) localhost/test.php?cmd=echo "aaaaaaa" >>1.txt 注释: 一、> 是定向输出到文件,如果文件不存在,就创建文件;如果文件存在,就将其清空;在我的一篇清空linux历史命令的文章中,就是这种方法,用echo > .bash_history,将文件内容清空(文件大小变成0字节)。 二、>> 这个是将输出内容追加到目标文件中。如果文件不存在,就创建文件;如果文件存在,则将新的内容追加到那个文件的末尾,该文件中的原有内容不受影响。 ``` 防御例子: ``` if( isset( $_POST[ 'Submit' ] ) ) { // 检查Anti-CSRF令牌 checkToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ], 'index.php' ); // 获取input信息 $target = $_REQUEST[ 'ip' ]; $target = stripslashes( $target ); // 把IP分成4个字节 $octet = explode( ".", $target ); //检查每八位字节是否为整数 if( ( is_numeric( $octet[0] ) ) && ( is_numeric( $octet[1] ) ) && ( is_numeric( $octet[2] ) ) && ( is_numeric( $octet[3] ) ) && ( sizeof( $octet ) == 4 ) ) { //如果所有的4个字节都是int,把IP放回去。 $target = $octet[0] . '.' . $octet[1] . '.' . $octet[2] . '.' . $octet[3]; // 确定操作系统并执行ping命令。 if( stristr( php_uname( 's' ), 'Windows NT' ) ) { // Windows $cmd = shell_exec( 'ping ' . $target ); } else { // *nix $cmd = shell_exec( 'ping -c 4 ' . $target ); } // 为最终用户提供结果 $html .= "<pre>{$cmd}</pre>"; } else { // 返回错误信息 $html .= '<pre>ERROR: You have entered an invalid IP.</pre>'; } } // 生成Anti-CSRF令牌 generateSessionToken(); ``` ``` // 检查Token function checkToken( $user_token, $session_token, $returnURL ) { //检查用户表单传过来的token是否等于当前的token 或者token不存在 if( $user_token !== $session_token || !isset( $session_token ) ) { if( !isset( $_SESSION[ 'dvwa' ] ) ) { $_SESSION[ 'dvwa' ] = array(); } $dvwaSession=$_SESSION[ 'dvwa' ]; if( !isset( $dvwaSession[ 'messages' ] ) ) { $dvwaSession[ 'messages' ] = array(); } $dvwaSession[ 'messages' ][] = 'CSRF token is incorrect'; session_commit(); header( "Location: {$returnURL}" ); exit; } } ``` ``` //生成token function generateSessionToken() { # Generate a brand new (CSRF) token if( isset( $_SESSION[ 'session_token' ] ) ) { unset( $_SESSION[ 'session_token' ] ); } $_SESSION[ 'session_token' ] = md5( uniqid() ); } ```