[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <45A7E352.6060409@manico.net>
Date: Fri, 12 Jan 2007 09:36:50 -1000
From: Jim Manico <jim@...ico.net>
To: bugtraq@...urityfocus.com
Subject: Re: Corsaire Security Advisory: ChainKey Java Code Protection Bypass
issue
> The concept of encrypting Java class files to prevent de-compilation
is fundamentally flawed because the Java Virtual Machine (JVM) cannot
read encrypted class files.
The path of a .class file is: ByteCode verifier -> Class Loader ->
Security Manager -> Interpreter All 4 of these sub-components are part
of the JVM via the official specification.
I believe you conjecture is not true. You can implement your own
Classloader that accepts encrypted .class files if you are talking about
server-side Java. Client side Java that reads .class files from the
internet must go through the bytecode verifier first and that must be a
normal .class file. Now you are right in the fact that my the time
.class files hit the actual Interpreter, they must be decrypted already
but you simple cannot skip the ClassLoading step ever. .class files read
locally (like you would see in a server side J2EE app) go through the
ClassLoader first, and you can customize that to force encryption.
Now if you are talking about Java Applets, you are 100% right. But why
would anyone in their right mind use that solution with the nasty,
recent, continuous spate of vulnerabilities that break the sandbox? In
fact, I'm surprised some enterprises are not banning JVM's from the client.
But if you are talking J2EE I think your conjectures are wrong.
- Jim
>
> -- Corsaire Security Advisory --
>
> Title: ChainKey Java Code Protection Bypass issue
> Date: 06.11.06
> Application: Java Code Protection
> Environment: Java Virtual Machine
> Author: Stephen de Vries [stephen.de.vries@...saire.com]
> Audience: General distribution
> Reference: c061106-001
>
>
> -- Scope --
>
> The aim of this document is to clearly define an issue that exists with
> the ChainKey Java Code Protection product [1], that will allow an
> attacker to circumvent the encryption protection and de-compile any
> protected Java application.
>
>
> -- History --
>
> Discovered: 6.11.06 (Stephen de Vries)
> Vendor notified: 08.11.06 (responded 25.12.06)
> Document released: 12.01.07
>
>
> -- Overview --
>
> The ChainKey Java Code Protection product is described as "...a tool to
> protect your program codes written in Java, through multi-layer bytecode
> encryption, obfuscation and tamper proofing. The Protector can also be
> useful for enhancing your server-side security or for protecting
> important business logic from leaking." [1]. The tool functions by
> encrypting Java class files in order to prevent attackers from de-
> compiling the Java class files, and thus exposing the source code.
>
>
> -- Analysis --
>
> The concept of encrypting Java class files to prevent de-compilition is
> fundamentally flawed because the Java Virtual Machine (JVM) cannot read
> encrypted class files. It can only read files which comply with the
> well defined Java class file format [2]. Therefore, the encrypted class
> files have to be delivered to the JVM in the standard, unencrypted
> format. An attacker who wishes to de-compile the class file can simply
> modify the Java class loader to extract the unencrypted class files
> [4][5]. These class files can then be decompiled using well known and
> freely available decompilation tools such as Jode [3].
>
>
> -- Proof of Concept --
>
> The following code[4] was inserted in the defineClass(String name,
> byte[] b, int off, int len, ProtectionDomain protectionDomain) method of
> the java/lang/ClassLoader.java file which is included in the JDK source
> code:
>
> if (!name.startsWith("java")) {
> String baseDir = "/Users/stephen/dump";
> String dirName = baseDir + File.separatorChar +
> name.substring(0,name.lastIndexOf(".")).replace('.',
> File.separatorChar);
> File dir = new File(dirName);
> dir.mkdirs();
> File dump = new File(baseDir + File.separatorChar +
> name.replace('.', File.separatorChar) + ".class");
> FileOutputStream out = null;
> try {
> out = new FileOutputStream (dump);
> out.write (b, off, len);
> }
> catch (Exception e){
> e.printStackTrace ();
> }
> finally {
> if (out != null) {
> try {
> out.close ();
> }
> catch (Exception e) {
> }
> }
> }
> }
>
> This had the effect of writing the class file to a directory. The
> modified ClassLoader.class file was included in the JVM runtime.
> The "Game of life" encrypted sample application was then loaded using
> the new modified JVM. The raw class files were observed in the
> directory /Users/stephen/dump and these were loaded using Jode [3].
> Jode was successful in decompiling many of the important class files to
> the extent that functional process flow and constant values were
> exposed. Some local variable names remained in obfuscated form, but
> these did not detract from the overall ability to view the source code.
> As an example, the following code is the original source code of the
> GameOfLifeCanvas constructor as provided with the sample application:
>
> public GameOfLifeCanvas(GameOfLifeGrid gameOfLifeGrid, int cellSize) {
> this.gameOfLifeGrid = gameOfLifeGrid;
> this.cellSize = cellSize;
> gameOfLifeGrid.clear();
>
> addMouseListener(
> new MouseAdapter() {
> public void mouseReleased(MouseEvent e) {
> draw(e.getX(), e.getY());
> }
> public void mousePressed(MouseEvent e) {
> saveCellUnderMouse(e.getX(), e.getY());
> }
> });
>
> addMouseMotionListener(new MouseMotionAdapter() {
> public void mouseDragged(MouseEvent e) {
> draw(e.getX(), e.getY());
> }
> });
> }
>
> The same method as decompiled by Jode:
>
> public GameOfLifeCanvas(GameOfLifeGrid gameoflifegrid, int i) {
> gameOfLifeGrid = gameoflifegrid;
> cellSize = i;
> gameoflifegrid.clear();
> this.addMouseListener(new MouseAdapter() {
> public void mouseReleased(MouseEvent mouseevent) {
> draw(mouseevent.getX(), mouseevent.getY());
> }
>
> public void mousePressed(MouseEvent mouseevent) {
> saveCellUnderMouse(mouseevent.getX(), mouseevent.getY());
> }
> });
> this.addMouseMotionListener(new MouseMotionAdapter() {
> public void mouseDragged(MouseEvent mouseevent) {
> draw(mouseevent.getX(), mouseevent.getY());
> }
> });
> }
>
>
> -- Recommendations --
>
> Simple class file encryption using a pure Java solution is a
> fundamentally flawed approach to protecting the intellectual property of
> software creators, and as this advisory shows it cannot be relied on to
> provide any protection from reverse engineering methods. As a permanent
> solution to this issue consider re-architecting Java applications who's
> bytecode contains sensitive intellectual property so that the sensitive
> areas are executed in secured environments (such as on a server).
> Alternatively, consider strengthening the obfuscation mechanisms to
> delay decompilation of class files. However, it should be noted that
> obfuscation will not provide a permanent solution to the problem, but
> will only delay a persistent attacker in obtaining the source code.
>
>
> -- CVE --
>
> The Common Vulnerabilities and Exposures (CVE) project has assigned the
> name CVE-2007-0014 to this issue. This is a candidate for inclusion in
> the CVE list (http://cve.mitre.org), which standardises names for
> security problems.
>
>
> -- References --
>
> [1] http://www.chainkey.com/en/jcp/
> [2] http://java.sun.com/docs/books/vmspec/2nd-
> edition/html/ClassFile.doc.html
> [3] http://jode.sourceforge.net
> [4] Sergey Edunov's post: http://lists.owasp.org/pipermail/java-
> project/2006-October/000096.html
> [5] http://www.javaworld.com/javaworld/javaqa/2003-05/01-qa-0509-
> jcrypt.html
>
>
> -- Revision --
>
> a. Initial release.
> b. Released.
>
>
> -- Distribution --
>
> This security advisory may be freely distributed, provided that it
> remains unaltered and in its original form.
>
>
> -- Disclaimer --
>
> The information contained within this advisory is supplied "as-is" with
> no warranties or guarantees of fitness of use or otherwise. Corsaire
> accepts no responsibility for any damage caused by the use or misuse of
> this information.
>
>
> -- About Corsaire --
>
> Corsaire are a leading information security consultancy, founded in 1997
> in Guildford, Surrey, UK. Corsaire bring innovation, integrity and
> analytical rigour to every job, which means fast and dramatic security
> performance improvements. Our services centre on the delivery of
> information security planning, assessment, implementation, management
> and vulnerability research.
>
> A free guide to selecting a security assessment supplier is available at
> http://www.penetration-testing.com
>
>
> Copyright 2006-2007 Corsaire Limited. All rights reserved.
>
>
>
>
> ----------------------------------------------------------------------
> CONFIDENTIALITY: This e-mail and any files transmitted with it are
> confidential and intended solely for the use of the recipient(s) only.
> Any review, retransmission, dissemination or other use of, or taking
> any action in reliance upon this information by persons or entities
> other than the intended recipient(s) is prohibited. If you have
> received this e-mail in error please notify the sender immediately
> and destroy the material whether stored on a computer or otherwise.
> ----------------------------------------------------------------------
> DISCLAIMER: Any views or opinions presented within this e-mail are
> solely those of the author and do not necessarily represent those
> of Corsaire Limited, unless otherwise specifically stated.
> ----------------------------------------------------------------------
> Corsaire Limited, registered in England No. 3338312. Registered
> office: 3 Tannery House, Tannery Lane, Send, Surrey, GU23 7EF.
> Telephone: +44 (0)1483-226000
>
>
>
>
>
--
Best Regards,
Jim Manico
GIAC GSEC Professional, Sun Certified Java Programmer
jim@...ico.net
808.652.3805
Powered by blists - more mailing lists