Maison >Opération et maintenance >Sécurité >Apache Shiro 1.2.4 Exemple d'analyse de vulnérabilité de désérialisation

Apache Shiro 1.2.4 Exemple d'analyse de vulnérabilité de désérialisation

王林
王林avant
2023-05-16 19:40:241055parcourir

0x00 Apache Shiro

La vulnérabilité de ce composant a été exposée il y a longtemps, mais je l'ai rencontré à nouveau au travail récemment. J'ai récemment regardé des trucs de désérialisation Java, j'ai donc décidé de le retirer et de l'analyser. encore une fois, et je l'ai également rencontré pendant le processus. Quelques questions étranges.

La plupart des articles d'analyse sur Internet ajoutent manuellement la dépendance de commons-collections4-4.0 afin d'utiliser la charge utile CommonsCollections2 générée par ysoserial. Cependant, la situation que j'ai rencontrée est que l'utilisation de CommonsBeanutils1 peut directement réussir. pas répéter l’analyse de CommonsCollections2 en ligne.

Analyse de débogage 0x01

Environnement de débogage :

JDK 1.8.0_72

Tomcat 8.0.30

Nous clonons d'abord le code source de shiro et passons à la branche problématique.

git clone https://github.com/apache/shiro.git shiro-rootcd shiro-root
git checkout 1.2.0

Afin de faire fonctionner les exemples fournis avec Shiro, nous devons apporter quelques modifications au fichier samples/web/pom.xml. Nous devons changer la version jstl en 1.2 et supprimer le champ scope de servlet-api. . Mettez jstl-1.2.jar dans le répertoire WEB-INF/lib. Ensuite, vous devriez pouvoir exécuter et déboguer.

Nous définissons le point d'arrêt sur la méthode solvePrincipals dans org.apache.shiro.mgt.DefaultSecurityManager et envoyons une requête avec RememberMe Cookie, et elle devrait pouvoir se briser.

Apache Shiro 1.2.4反序列化漏洞实例分析

Nous continuons à suivre la méthode getRememberedIdentity :

Apache Shiro 1.2.4反序列化漏洞实例分析Continuons à suivre la méthode getRememberedSerializedIdentity :

Apache Shiro 1.2.4反序列化漏洞实例分析Dans cette méthode, le cookie que nous avons transmis est lu et décodé en base64 :

Apache Shiro 1.2.4反序列化漏洞实例分析Connect Ensuite, Shiro appellera convertBytesToPrincipals et passez le tableau d'octets décodés en base64 en tant que paramètre :

Apache Shiro 1.2.4反序列化漏洞实例分析

Vous pouvez également le deviner grâce au nom de la fonction. Deux opérations sont effectuées, à savoir le décryptage et la désérialisation. Commençons par la partie décryptage. un simple débogage, il a été constaté qu'il s'agissait d'un déchiffrement AES et qu'il y avait une clé prédéfinie Base64.decode("kPH+bIxk5D2deZiIxcaaaA==");. Dans l'exemple fourni avec Shiro, aucune autre méthode n'a été utilisée pour définir cela. clé secrète, donc la valeur par défaut est utilisée ici.

Le IV rencontré dans le décryptage AES est également obtenu à partir des premiers octets du cookie que nous avons transmis, nous pouvons donc facilement construire une valeur de cookie contenant n'importe quel contenu, et le texte brut déchiffré est un contenu sérialisé, la désérialisation est appelée pour la désérialisation.

Enfin, la méthode org.apache.shiro.io.DefaultSerializer#deserialize sera appelée pour la désérialisation :
Apache Shiro 1.2.4反序列化漏洞实例分析

L'ensemble du processus est très simple : lire le cookie -> décodage base64 -> décryptage -> Désérialisation

Notre charge utile est donc très simple à construire, je vais mettre le PoC complet sur mon GitHub.

0x02 Doutes et doutes résolus

Pendant le processus de débogage, j'ai rencontré quelques problèmes et la calculatrice n'est pas apparue avec succès. Enregistrons-le ici.

1. Pourquoi ne puis-je pas utiliser CommonsBeanutils1 pour créer un environnement local et toujours déclencher une exception ClassNotFound ?

Je déboguais ce problème depuis longtemps. Je pensais que c'était un problème avec la charge utile ou que le code de Shiro avait changé avec le temps, car le cas que j'ai rencontré à ce moment-là était que la charge utile avait été introduite dans l'âme, ce qui m'a fait très confus. Plus tard, nous avons découvert un problème clé. Dans l'exemple que nous avons cloné depuis github, la version dépendante de commons-beanutils est 1.8.3 et la version de la charge utile générée par ysoserial est 1.9.2, elle ne peut donc pas être exécutée avec succès dans le échantillon par défaut de. J'ai donc changé le numéro de version en 1.9.2 et c'est devenu un succès.

Donc, dans le cas que nous avons rencontré, la version réelle de l'environnement dépendant peut également être comme ça, nous pouvons donc directement réussir.

2. Si mes dépendances n'ont pas de packages de version haute tels que commons-beanutils et commons-collections, comment puis-je les utiliser ?

Une fois ce projet cloné, vous pouvez voir qu'il existe un package commons-collections :

Apache Shiro 1.2.4反序列化漏洞实例分析

Une exception sera levée lors de la tentative d'utilisation de CommonsCollections1 fournie par ysoserial, et elle ne peut pas réussir

Apache Shiro 1.2.4反序列化漏洞实例分析Lors du débogage, J'ai trouvé qu'il avait été lancé ici. Exception, la raison pour laquelle le tableau d'octets ne peut pas être désérialisé est très déroutante

Apache Shiro 1.2.4反序列化漏洞实例分析

J'ai vérifié la différence entre Class.forName() et ClassLoader.loadClass() en Java et j'ai découvert que forName() utilise toujours le ClassLoader() de l'appelant, tandis que loadClass() peut spécifier un ClassLoader différent. Alors, d'où vient ClasssLoader dans Shiro ? Il est obtenu via Thread.currentThread().getContextClassLoader();, qui est WebappClassLoader. Mais pourquoi cela indique-t-il que le tableau d'octets ne peut pas être chargé ? Après avoir cherché pendant un moment, j'ai vu la discussion ci-dessous sur le blog orange et j'ai appris la vérité sur tout cela :

Shiro resovleClass utilise ClassLoader.loadClass() au lieu de Class.forName(), ClassLoader.loadClass ne prend pas en charge le chargement de classes de type tableau.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer