前言

最近几天再看php代码,发现自己看代码的能力太弱了,于是找了laravel框架来审计,学习一下反序列化.

环境准备

1
2
3
>>composer create-project laravel/laravel laravel --prefer-dist "5.6.29"
>>cd ./laravel
>>./artisan key:generate

漏洞分析

漏洞简介

Laravel framework 5.5.40及之前版本和5.6.x版本至5.6.29版本中存在安全漏洞。远程攻击者可借助应用程序的密钥利用该漏洞执行代码。

In Laravel Framework through 5.5.40 and 5.6.x through 5.6.29, remote code execution might occur as a result of an unserialize call on a potentially untrusted X-XSRF-TOKEN value.

decrypt分析

漏洞存在于App\Http\Middleware\EncryptCookies这个类中,我们来跟进一下这个类。

laravel1

可以看到,这个类继承自Illuminate\Cookie\Middleware\EncryptCookies,跟进这个父类看下

laravel2

可以看到初始化变量$encrypterIlluminate\Contracts\Encryption\Encrypter的对象,这里的handle函数用来处理我们的请求,跟进这个函数,可以看到会先调用decrypt函数,跟进这个函数

laravel3

看到会先对$request中的cookies进行遍历,获取每个cookie,然后调用decryptCookie函数对cookie解密,跟进这个函数

laravel4

它会先判断是不是数组,如果是数组会在进行遍历一遍获取值,最终还是要调$this->encrypter->decrypt($cookie)这个方法进行解密,在开始的时候,$encrypter成了Illuminate\Contracts\Encryption\Encrypter的对象,那么这里就要调用该类的decrypt函数,跟进一下

laravel5

可以看到函数首先会调用getJsonPayload函数,对cookie解码,获取每个参数的值,然后调用openssl_decrypt函数解密,注意漏洞点就在这,这里$payload[value]我们可控,那么只要知道key我们就可以伪造cookie,解密后触发反序列化了。那么现在就是要找一条可以触发的链进行attack了。

Http header

同样的在App\Http\Middleware\VerifyCsrfToken类中,也存在密钥利用的点,该类会检验http请求头的参数

laravel11

我们可以看到该类初始化Illuminate\Contracts\Encryption\Encrypter的对象,实例相同的类,使用handle函数处理request请求,前三个方法不看,着重看第四个tokensMatch函数,看名字就知道会校验cookie是否合理,跟进这个函数

laravel12

可以看到这个函数会调用getTokenFromRequest获取token,然后会对头部的X-XSRF-TOKEN进行校验,接着就进入 Illuminate\Contracts\Encryption\Encrypter 中的decrypt函数中,下面的步骤就和上面一样了,这里不多讲。

pop链

这里用phpgcc里面的链,可以触发攻击,里面的前三条链都适用于这个版本,这里先分析下第一条链

触发点:Illuminate\Broadcasting\PendingBroadcast类中的__destruct函数中,这里看一下这个函数

laravel6

在这个方法中可以看到,让当前events属性去调用dispatch函数,很自然我们可以想到拿他去触发__call方法,那么全局找下能用的__call,这里用的是Faker\Gererator类中的,看下这个函数

laravel7

函数里面再去调用format函数,跟进这个函数

laravel8

看到有个call_user_func_array,那么很可能可以RCE,跟进一下getFormatter函数,看他干什么的

laravel9

可以看到,函数可以返回对应$formatter名的值,那么我们如果控制$formatters这个变量就可以返回我们想要的值,造成RCE

这里放一下整个链的过程

laravel-56x

attack

laravel10

结尾

这一部分代码看下来,还是有很多收获的,对代码的认识又多了一点,学到了很多.