web-dev-qa-db-fra.com

Pourquoi certains Java APIS Bypass Standard SecurityManager vérifie?

En Java, les contrôles normalement autorisés sont traités par le SecurityManager. Pour empêcher le code non approuvé d'invoquer un code privilégié et d'exploiter un bogue dans le code privilégié, SecurityManager vérifie toute la pile d'appels; Si l'un des appelants de la trace de la pile est non privilégié, la demande est refusée par défaut. Au moins, c'est comment le SecurityManager vérifie .

Cependant, quelques-uns spéciaux Java API suivent des règles différentes. Ils contournent les vérifications Standard SecurityManager et remplacent une vérification plus faible. En particulier, ils ne vérifient que l'appelant immédiat, et non la pile d'appels. Voir - ligne directrice 9-8 du Java Lignes directrices de codage sécurisées Pour plus de détails. Les API spéciales incluent, par exemple, Class.forName(), Class.getMethod(), et plus.)

Pourquoi? Pourquoi ces API spéciales contournent-elles les contrôles standard et remplacent une vérification plus faible? Et pourquoi est-ce sûr? En d'autres termes, pourquoi il suffit-il de vérifier que l'appelant immédiat? Cela n'a-t-il pas réintroduit tous les risques que les chèques Standard SecurityManager ont été conçus pour se défendre?

J'ai d'abord appris de cela lors de la lecture ne analyse de la récente Java EXPLOIT (CVE-2012-4681). Cette analyse déconstrait comment l'exploitation fonctionne. Parmi Autres choses, l'attaque consiste à tirer parti de la vérification plus faible faite par ces API spéciales. En particulier, le code malveillant Java Code réussit à faire référence à une classe de système de confiance (via un bogue séparé) , alors il est imbécile qui fait confiance à une classe de système à invoquer une de ces API spéciales. La vérification de l'autorisation résultante ne ressemble qu'à son appelant immédiat, voit que l'appelant immédiat est de confiance et permet l'opération - même si l'opération a été initiée à l'origine par code. Ainsi, les chèques plus faibles n'arrêtent pas l'attaque, mais aussi loin que je peux le voir, cette attaque aurait été empêchée d'utiliser les chèques Standard SecurityManager (puisque l'appelant de l'appelant est intrajusté). En d'autres termes, cette attaque récente a l'air d'attaque récente Comme un exemple de pourquoi la vérification plus faible est risquée.

Cependant, je sais que Java Designers sont des personnes intelligentes. Je soupçonne que le Java Les concepteurs doivent avoir considéré ces problèmes et avoir une bonne raison de contourner les contrôles standard et Remplacez les chèques plus faibles de ces API spéciales - ou, du moins, pensaient qu'ils avaient une bonne raison pour laquelle c'était en sécurité. Alors, peut-être que je manque quelque chose.

Quelqu'un peut-il nous éclairer à ce sujet? Est-ce que les Java concepteurs sont-ils vissés avec ces API spéciales ou étaient-il des raisons valables de substituer les contrôles les plus faibles?

Editer 9/1: Je ne demande pas comment fonctionne l'exploit; Je pense que je comprends comment fonctionne l'exploit. Je ne demande pas non plus pourquoi, dans cet exemple particulier, le code de confiance qui a invoqué ces API spéciales était la buggy. Plutôt, je demande pourquoi les APIS spéciales - comme Class.forName(), Class.getMethod(), et ainsi de suite - sont spécifiées et mises en œuvre pour utiliser la vérification de l'autorisation plus faible standard (regarder uniquement À l'appelant immédiat) au lieu de la vérification de l'autorisation Standard SecurityManager (regardez la pile d'appels entière). Cette décision de conception (d'utiliser des contrôles d'autorisation plus faibles pour ces API spéciales) a permis la vulnérabilité récente, il serait donc facile de critiquer la décision de conception. Cependant, j'imagine qu'il y aurait peut-être eu de bonnes raisons de faire des choses de cette façon et je me demande ce que celles-ci pourraient être.

16
D.W.

Sommaire

Certaines méthodes de confiance ont besoin de plus d'autorisations internes pour remplir leurs tâches. Mais si ces méthodes ont des bugs, ils peuvent permettre à un attaquant non approuvé d'exécuter des actions indésirables à un niveau de privilège accru.

Fond

Nous avons une situation très similaire au niveau du système d'exploitation. Sur UNIX, il existe des drapeaux SETUID/SETGID et la commande sudo. Ils permettent à un utilisateur non privilégié d'exécuter des tâches qui nécessitent un niveau de privilèges plus élevé en interne.

Par exemple, un utilisateur normal n'est pas autorisé à modifier /etc/shadow. Mais nous voulons que les utilisateurs puissent changer leur mot de passe. Par conséquent, la commande passwd est signalée comme signalétique de confiance (racine SETUID) et autorisée à modifier ce fichier. Bien sûr, il doit effectuer ses propres vérifications de sécurité.

La même situation s'applique au Java Sandbox. Par exemple, le code non privilégié n'est pas autorisé à appeler de manière dynamique des méthodes. Mais les parties du système doivent le faire en interne.

Tout comme la commande passwd permet aux utilisateurs normaux de modifier leur propre mot de passe uniquement, la fonction MethodFinder.findMethod() est censée autoriser uniquement le code de confiance d'appeler des méthodes arbitraires.

Jusqu'à présent, tout va bien.

Exploitation de chargement de classe

ClassFinder.findClass() est une méthode de confiance. Il charge des classes supplémentaires avec les privilèges du code d'appel. Tout comme passwd vous permet de changer votre propre mot de passe.

Mais en cas d'erreur, il a essayé de récupérer en chargeant la classe avec une autorisation complète. Si nous pensons à passwd, un bug similaire causerait passwd pour modifier le mot de passe de la racine au lieu de l'utilisateur actuel.

Les systèmes d'exploitation permettront passwd de modifier le mot de passe racine, comme Class.forName() Permet ClassFinder.findClass() Pour charger des classes dans le mauvais contexte de sécurité.

Exploitation d'invocation de la méthode

Celui-ci est un peu plus complexe. La méthode de confiance est Method.invoke() Ici.

Mais il y avait une deuxième méthode de confiance impliquée appelée MethodFinder.findMethod(). Pour rester avec l'analogie du système d'exploitation, pensez-y sous la forme d'un script shell qui fonctionne avec des privilèges root via sudo.

Cette méthode/programme ne valident pas ses paramètres, cela vient de les transmettre à passwd. Maintenant passwd est invoqué dans un contexte de confiance. Par conséquent, cela changera volontiers le mot de passe de quiconque.

3