Laravel Framework RCE Vulnerability
Research is free — Hunters explains how the bug works, the root-cause code pattern, how the fix addresses it, and how to test whether a target is affected, in chat. Investigate & write exploit is a paid run — the engine reads the advisory and fix commits, then builds and validates a working proof-of-concept exploit with reproduction steps.
Affected versions
Details
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. This involves the decrypt method in `Illuminate/Encryption/Encrypter.php` and PendingBroadcast in `gadgetchains/Laravel/RCE/3/chain.php` in phpggc. The attacker must know the application key, which normally would never occur, but could happen if the attacker previously had privileged access or successfully accomplished a previous attack.
The fix
dont serialize csrf cookie / header
src/Illuminate/Cookie/Middleware/EncryptCookies.php+17 −5
@@ -25,6 +25,15 @@ class EncryptCookies*/protected $except = [];+/**+* The cookies that should not be serialized.+*+* @var array+*/+protected $serialization = [+'XSRF-TOKEN' => false,+];+/*** Create a new CookieGuard instance.*@@ -73,7 +82,7 @@ protected function decrypt(Request $request)}try {-$request->cookies->set($key, $this->decryptCookie($cookie));+$request->cookies->set($key, $this->decryptCookie($key, $cookie));} catch (DecryptException $e) {$request->cookies->set($key, null);}@@ -85,14 +94,15 @@ protected function decrypt(Request $request)/*** Decrypt the given cookie and return the value.*+* @param string $name* @param string|array $cookie* @return string|array*/-protected function decryptCookie($cookie)+protected function decryptCookie($name, $cookie){return is_array($cookie)? $this->decryptArray($cookie)-: $this->encrypter->decrypt($cookie);+: $this->encrypter->decrypt($cookie, $this->serialization[$name] ?? true);}/**@@ -107,7 +117,7 @@ protected function decryptArray(array $cookie)foreach ($cookie as $key => $value) {if (is_string($value)) {-$decrypted[$key] = $this->encrypter->decrypt($value);+$decrypted[$key] = $this->encrypter->decrypt($value, $this->serialization[$key] ?? true);}}@@ -127,8 +137,10 @@ protected function encrypt(Response $response)continue;}+$serialize = $this->serialization[$cookie->getName()] ?? true;+$response->headers->setCookie($this->duplicate(-$cookie, $this->encrypter->encrypt($cookie->getValue())+$cookie, $this->encrypter->encrypt($cookie->getValue(), $serialize)));}
src/Illuminate/Foundation/Http/Middleware/VerifyCsrfToken.php+1 −1
@@ -138,7 +138,7 @@ protected function getTokenFromRequest($request)$token = $request->input('_token') ?: $request->header('X-CSRF-TOKEN');if (! $token && $header = $request->header('X-XSRF-TOKEN')) {-$token = $this->encrypter->decrypt($header);+$token = $this->encrypter->decrypt($header, false);}return $token;
References
- ADVISORYhttps://nvd.nist.gov/vuln/detail/CVE-2018-15133
- WEBhttps://github.com/laravel/framework/commit/d84cf988ed5d4661a4bf1fdcb08f5073835083a0
- WEBhttps://github.com/kozmic/laravel-poc-CVE-2018-15133
- PACKAGEhttps://github.com/laravel/framework
- WEBhttps://laravel.com/docs/5.6/upgrade#upgrade-5.6.30
- WEBhttp://packetstormsecurity.com/files/153641/PHP-Laravel-Framework-Token-Unserialize-Remote-Command-Execution.html