Re: [SC-L] By default, the Verifier is disabled on .Net and Java

2006-05-13 Thread Gary McGraw
Shall we ask ed felten to did out the old type confusion toolkit?

gem

 -Original Message-
From:   Stephen de Vries [mailto:[EMAIL PROTECTED]
Sent:   Sat May 13 15:12:48 2006
To: Dinis Cruz
Cc: Secure Coding Mailing List
Subject:Re: [SC-L] By default, the Verifier is disabled on .Net and Java


On 12 May 2006, at 14:58, Dinis Cruz wrote:

> Michael Silk wrote:
>> You can't disable the security manager even with the verifier off.  
>> But
>> you could extend some final or private class that the security  
>> manager
>> gives access to.
> This is not correct. With the verifier disabled there are multiple  
> ways you can jump out of the Security Manager Sandbox.
>
> Here is a quote from 1997's Java Security (Gary McGraw and Eduard  
> W. Feltern) book, page 75, Chapter Three 'Serious Holes in the  
> Security Model"

I'm a bit sceptical of this, I know Sun's track record on fixing JVM  
vulnerabilities hasn't always been great, but 9 years seems a bit  
excessive!  Unfortunately the book doesn't provide any more details  
on the vulnerabilities so we're left guessing whether these still  
affect modern JVMs.  Even with verification turned off with the - 
noverify option, I think it would be difficult to break out of a  
defined security manager.

>
> "... The Type Confusion Tool Kit The Princeton team, as a  
> feasibility demonstration, created a tool kit that allows any type  
> confusion attack to be turned into a disarming of Java's security.  
> In other words, the tool kit servers as a way of turning a small  
> security breach into a complete system penetration. The type  
> confusion tool kit has not been released to the public, and is  
> considered to dangerous to describe in any detail here..."
>
> A variation of this quote can also at the bottom of this page:  
> Section 7 -- You're Not My Type
>
> Another quote from Section 7 -- You're Not My Type
> "...As mentioned in Chapter 2, every aspect of Java security  
> depends critically on the type-safety of the language. This means  
> that if Java is going to be secure, it has to make sure that all  
> pointers are properly tagged; that is, the tag must match the  
> actual type of object that is being pointed to.
>
> In a type-confusion attack, a malicious applet creates two pointers  
> to the same object-with incompatible type tags. When this happens,  
> the Java system is in trouble. The applet can write into that  
> memory address through one pointer, and read it through another  
> pointer. The result is that the applet can bypass the typing rules  
> of Java, completely undermining its security"
>
> The example that we have been playing around here (the direct  
> access to a private member) is probably not the best one to use to  
> test the verifier, since there are multiple ways that this type of  
> illegal access can be 'accidentally' detected by the VM (in Java  
> there are some cases where the class loading process detects this,  
> and in .Net the JIT will catch it)
>
> I think that it will be better to use the examples shown in the  
> brilliant LSD paper http://lsd-pl.net/papers.html#java

The paper mentions avenues of attack through vulnerabilities in  
Netscape 4.x's JVM and IE (Mirosoft's JVM).  These are  
vulnerabilities in specific implementations of the JVM rather than  
inherent flaws in the JVM spec.  Any type confusion attacks that are  
possible because of the lack of default verification (via -verify) in  
the JRE would affect the security of the users' own local code so  
it's unlikely that this will prove to be a practical attack vector,  
IMHO.

> or a variation of the ones I discovered in .Net:
>
> Possible Type Confusion issue in .Net 1.1 (only works in FullTrust)  
> (http://owasp.net/blogs/dinis_cruz/archive/2005/11/08/36.aspx)
> Another Full Trust CLR Verification issue: Exploiting Passing  
> Reference Types by Reference (http://owasp.net/blogs/dinis_cruz/ 
> archive/2005/12/28/393.aspx)
> Another Full Trust CLR Verification issue: Changing Private Field  
> using Proxy Struct (http://owasp.net/blogs/dinis_cruz/archive/ 
> 2005/12/28/394.aspx)
> Another Full Trust CLR Verification issue: changing the Method  
> Parameters order (http://owasp.net/blogs/dinis_cruz/archive/ 
> 2005/12/26/390.aspx)
> In fact, it would be great to have a 'verifier checker' tool. A set  
> of scripts that would test for verifier issues on Java execution  
> environments (this would make it very easy to detect who is using  
> the verifier and what type of verification is performed).
>
> After this explanation, Stephen, do you still disagree with my  
> original comments:
>
> "This is a very weird decision by the Java Architects, since what  
> is the point of creating and enforcing a airtight security policy  
> if you can jump strait out of it via a Type Confusion attack?

This is speculation.  We don't know if it's possible to break the  
security manager through a type confusion attack - the one ref

Re: [SC-L] By default, the Verifier is disabled on .Net and Java

2006-05-13 Thread Michael Silk

Stephen,

I think the reason you get the IllegalAccessError is because the VM
thinks you are loading from a remote url.

I don't think the user of a classloader per-se forces the
verification of the class. (I wrote a class loader like yours that
just loads a file with no package in the current dir and was able to
access the private method).

You can also note that your class isn't verified if -noverify is
passed (perhaps this is obvious :)

-- Michael



On 5/13/06, Stephen de Vries <[EMAIL PROTECTED]> wrote:


On 12 May 2006, at 09:10, Charles Miller wrote:
>
> It's not reflection: you're confusing IllegalAccessException and
> IllegalAccessError.
>
> For any non-Java nerd still listening in: there are two fundamental
> types of "Throwable" exception-conditions in Java: Exceptions and
> Errors[1]. Exceptions represent application-level conditions --
> things an application is likely to be able to recover from, like
> network timeouts, trying to read beyond the end of a file, and so
> on. Errors, on the other hand, represent VM-level problems that an
> application can't really do anything about, like running out of
> memory, not finding a required native library, or encountering
> corrupted class files.
>
> IllegalAccessException happens when reflective code attempts to
> access some field or method it's not supposed to. Because it's a
> result of reflection, it's considered an application-level problem
> and it's assumed your code can recover gracefully.
>
> Amusingly enough, you can get around most IllegalAccessExceptions
> in java just by calling {field|method}.setAccessible(true). So long
> as there's no explicit SecurityManager installed, as soon as you've
> done that you're free to modify the field or call method to your
> heart's content[2].
>
> IllegalAccess_Error_, on the other hand, happens when some non-
> reflective code issues a bytecode instruction that attempts to
> access a field or method it shouldn't be able to see. If you look
> at its class hierarchy, the meaning of the class is pretty clear:
> IllegalAccessError is a subclass of IncompatibleClassChangeError,
> which is a subclass of LinkageError. Because this is a problem at
> the bytecode/classloading level, and literally something that could
> happen on _any_ method-call or field-access, it's flagged as an error.
>
> The Error generally occurs when class A has been compiled against a
> version of class B where a method is public, but that method is
> private in the version of the same class it encounters at runtime.
> This sort of thing happens quite often in Java, you're frequently
> stuck in "jar file hell", in a twisty turny maze of library
> interdependencies, all with slightly different version numbers.
>
> More about the circumstances of IllegalAccessError here:
>
>http://java.sun.com/docs/books/vmspec/2nd-edition/html/
> ConstantPool.doc.html
>
> Dynamic classloading isn't really at fault here. There are all
> sorts of pits you can fall into when you start rolling your own
> classloader (the Java webapp I develop supports dynamic runtime-
> deployable plugins, and the classloading issues are a HUGE
> headache), but IllegalAccessError isn't one of them.
>
> Charles
>
>[1] Exceptions are further divided into checked exceptions and
> runtime exceptions, but that's beyond the scope of this email
>[2] See also: http://www.javaspecialists.co.za/archive/
> Issue014.html

Thanks for clearing this up Charles.
I've created another example that uses a class loader to load the
classes, and this time, it throws an IllegalAccessError just like
Tomcat does:

Loading class: /Users/stephen/data/dev/classloader/myclass/
somepackage/MyTest.class
Loading class: /Users/stephen/data/dev/classloader/myclass/java/lang/
Runnable.class
Loading class: /Users/stephen/data/dev/classloader/myclass/java/lang/
Object.class
Loading class: /Users/stephen/data/dev/classloader/myclass/
somepackage/MyData.class
Loading class: /Users/stephen/data/dev/classloader/myclass/java/lang/
System.class
Exception in thread "main" java.lang.IllegalAccessError: tried to
access method somepackage.MyData.getName()Ljava/lang/String; from
class somepackage.MyTest
 at somepackage.MyTest.run(MyTest.java:15)
 at classloader.Main.main(Main.java:26)
Java Result: 1

This error is thrown irrespective of the -verify flag.  So it looks
like using a classloader causes the VM to perform verification,
whether or not the "verifier" was enabled.  Michael Silk made a
similar statement earlier in this thread.  Would you agree?

PoC code below:

package classloader;

public class Main {

 public Main() {
 }

 public static void main(String[] args) {
 //Illegal Access Error
 try {
 CustomLoader cl = new CustomLoader(System.getProperty
("user.dir")+"/myclass/");
 Class myClass = cl.loadClass("somepackage.MyTest");
 Runnable r = (Runnable)myClass.newInstance();
 r.run();

 } catch (Excepti

Re: [SC-L] By default, the Verifier is disabled on .Net and Java

2006-05-13 Thread Stephen de Vries


On 12 May 2006, at 14:58, Dinis Cruz wrote:


Michael Silk wrote:
You can't disable the security manager even with the verifier off.  
But
you could extend some final or private class that the security  
manager

gives access to.
This is not correct. With the verifier disabled there are multiple  
ways you can jump out of the Security Manager Sandbox.


Here is a quote from 1997's Java Security (Gary McGraw and Eduard  
W. Feltern) book, page 75, Chapter Three 'Serious Holes in the  
Security Model"


I'm a bit sceptical of this, I know Sun's track record on fixing JVM  
vulnerabilities hasn't always been great, but 9 years seems a bit  
excessive!  Unfortunately the book doesn't provide any more details  
on the vulnerabilities so we're left guessing whether these still  
affect modern JVMs.  Even with verification turned off with the - 
noverify option, I think it would be difficult to break out of a  
defined security manager.




"... The Type Confusion Tool Kit The Princeton team, as a  
feasibility demonstration, created a tool kit that allows any type  
confusion attack to be turned into a disarming of Java's security.  
In other words, the tool kit servers as a way of turning a small  
security breach into a complete system penetration. The type  
confusion tool kit has not been released to the public, and is  
considered to dangerous to describe in any detail here..."


A variation of this quote can also at the bottom of this page:  
Section 7 -- You're Not My Type


Another quote from Section 7 -- You're Not My Type
"...As mentioned in Chapter 2, every aspect of Java security  
depends critically on the type-safety of the language. This means  
that if Java is going to be secure, it has to make sure that all  
pointers are properly tagged; that is, the tag must match the  
actual type of object that is being pointed to.


In a type-confusion attack, a malicious applet creates two pointers  
to the same object-with incompatible type tags. When this happens,  
the Java system is in trouble. The applet can write into that  
memory address through one pointer, and read it through another  
pointer. The result is that the applet can bypass the typing rules  
of Java, completely undermining its security"


The example that we have been playing around here (the direct  
access to a private member) is probably not the best one to use to  
test the verifier, since there are multiple ways that this type of  
illegal access can be 'accidentally' detected by the VM (in Java  
there are some cases where the class loading process detects this,  
and in .Net the JIT will catch it)


I think that it will be better to use the examples shown in the  
brilliant LSD paper http://lsd-pl.net/papers.html#java


The paper mentions avenues of attack through vulnerabilities in  
Netscape 4.x's JVM and IE (Mirosoft's JVM).  These are  
vulnerabilities in specific implementations of the JVM rather than  
inherent flaws in the JVM spec.  Any type confusion attacks that are  
possible because of the lack of default verification (via -verify) in  
the JRE would affect the security of the users' own local code so  
it's unlikely that this will prove to be a practical attack vector,  
IMHO.



or a variation of the ones I discovered in .Net:

Possible Type Confusion issue in .Net 1.1 (only works in FullTrust)  
(http://owasp.net/blogs/dinis_cruz/archive/2005/11/08/36.aspx)
Another Full Trust CLR Verification issue: Exploiting Passing  
Reference Types by Reference (http://owasp.net/blogs/dinis_cruz/ 
archive/2005/12/28/393.aspx)
Another Full Trust CLR Verification issue: Changing Private Field  
using Proxy Struct (http://owasp.net/blogs/dinis_cruz/archive/ 
2005/12/28/394.aspx)
Another Full Trust CLR Verification issue: changing the Method  
Parameters order (http://owasp.net/blogs/dinis_cruz/archive/ 
2005/12/26/390.aspx)
In fact, it would be great to have a 'verifier checker' tool. A set  
of scripts that would test for verifier issues on Java execution  
environments (this would make it very easy to detect who is using  
the verifier and what type of verification is performed).


After this explanation, Stephen, do you still disagree with my  
original comments:


"This is a very weird decision by the Java Architects, since what  
is the point of creating and enforcing a airtight security policy  
if you can jump strait out of it via a Type Confusion attack?


This is speculation.  We don't know if it's possible to break the  
security manager through a type confusion attack - the one reference  
we have is 9 years old and doesn't say much, the other targets  
specific implementation flaws older JVMs.  Java verification and  
security has many layers (as we've seen in trying to pinpoint exactly  
when it happens!), so I don't think it's accurate to equate a lack of  
local code verification with a complete breakdown of the security  
manager - unless someone demonstrates otherwise.


regards,
Stephen



Re: [SC-L] By default, the Verifier is disabled on .Net and Java

2006-05-13 Thread Stephen de Vries


On 12 May 2006, at 09:10, Charles Miller wrote:


It's not reflection: you're confusing IllegalAccessException and  
IllegalAccessError.


For any non-Java nerd still listening in: there are two fundamental  
types of "Throwable" exception-conditions in Java: Exceptions and  
Errors[1]. Exceptions represent application-level conditions --  
things an application is likely to be able to recover from, like  
network timeouts, trying to read beyond the end of a file, and so  
on. Errors, on the other hand, represent VM-level problems that an  
application can't really do anything about, like running out of  
memory, not finding a required native library, or encountering  
corrupted class files.


IllegalAccessException happens when reflective code attempts to  
access some field or method it's not supposed to. Because it's a  
result of reflection, it's considered an application-level problem  
and it's assumed your code can recover gracefully.


Amusingly enough, you can get around most IllegalAccessExceptions  
in java just by calling {field|method}.setAccessible(true). So long  
as there's no explicit SecurityManager installed, as soon as you've  
done that you're free to modify the field or call method to your  
heart's content[2].


IllegalAccess_Error_, on the other hand, happens when some non- 
reflective code issues a bytecode instruction that attempts to  
access a field or method it shouldn't be able to see. If you look  
at its class hierarchy, the meaning of the class is pretty clear:  
IllegalAccessError is a subclass of IncompatibleClassChangeError,  
which is a subclass of LinkageError. Because this is a problem at  
the bytecode/classloading level, and literally something that could  
happen on _any_ method-call or field-access, it's flagged as an error.


The Error generally occurs when class A has been compiled against a  
version of class B where a method is public, but that method is  
private in the version of the same class it encounters at runtime.  
This sort of thing happens quite often in Java, you're frequently  
stuck in "jar file hell", in a twisty turny maze of library  
interdependencies, all with slightly different version numbers.


More about the circumstances of IllegalAccessError here:

   http://java.sun.com/docs/books/vmspec/2nd-edition/html/ 
ConstantPool.doc.html


Dynamic classloading isn't really at fault here. There are all  
sorts of pits you can fall into when you start rolling your own  
classloader (the Java webapp I develop supports dynamic runtime- 
deployable plugins, and the classloading issues are a HUGE  
headache), but IllegalAccessError isn't one of them.


Charles

   [1] Exceptions are further divided into checked exceptions and  
runtime exceptions, but that's beyond the scope of this email
   [2] See also: http://www.javaspecialists.co.za/archive/ 
Issue014.html


Thanks for clearing this up Charles.
I've created another example that uses a class loader to load the  
classes, and this time, it throws an IllegalAccessError just like  
Tomcat does:


Loading class: /Users/stephen/data/dev/classloader/myclass/ 
somepackage/MyTest.class
Loading class: /Users/stephen/data/dev/classloader/myclass/java/lang/ 
Runnable.class
Loading class: /Users/stephen/data/dev/classloader/myclass/java/lang/ 
Object.class
Loading class: /Users/stephen/data/dev/classloader/myclass/ 
somepackage/MyData.class
Loading class: /Users/stephen/data/dev/classloader/myclass/java/lang/ 
System.class
Exception in thread "main" java.lang.IllegalAccessError: tried to  
access method somepackage.MyData.getName()Ljava/lang/String; from  
class somepackage.MyTest

at somepackage.MyTest.run(MyTest.java:15)
at classloader.Main.main(Main.java:26)
Java Result: 1

This error is thrown irrespective of the -verify flag.  So it looks  
like using a classloader causes the VM to perform verification,  
whether or not the "verifier" was enabled.  Michael Silk made a  
similar statement earlier in this thread.  Would you agree?


PoC code below:

package classloader;

public class Main {

public Main() {
}

public static void main(String[] args) {
//Illegal Access Error
try {
CustomLoader cl = new CustomLoader(System.getProperty 
("user.dir")+"/myclass/");

Class myClass = cl.loadClass("somepackage.MyTest");
Runnable r = (Runnable)myClass.newInstance();
r.run();

} catch (Exception e) {
e.printStackTrace();
}


}

}


package classloader;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

public class CustomLoader extends ClassLoader {
private String path = null;

public CustomLoader(String path) {
this.path = path;
}


private byte[] getBytes( String filename ) throws IOException {
File file = new File( filename );
long len = file.length();
byte raw[] = new byte[(int)len];
FileInputStream fi