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

2006-05-03 Thread Jeff Williams








Two important clarifications for Java
(based on my experiments):



1) The verifier IS enabled for the classes
that come with the Java platform, such as those in rt.jar. So, for
example, if you create a class that tries to set System.security (the private variable
that points to the SecurityManager instance), you get a verification exception.
(If this was possible, it would allow a complete bypass of the Java sandbox).



2) The verifier also seems to be enabled
for classes running inside Tomcat. Im not sure about other J2EE
containers.



So I dont think its fair to
say that most Java code is running without verification.



But Denis is right. There is a real
problem with verification, as demonstrated in the message below. This is
a clear violation of the Java VM Spec, yet my messages to the team at Sun
developing the new verifier have been ignored. And its a real
issue, given the number of applications that rely on libraries they didnt
compile. I dont think a real explanation of how the Sun verifier actually
works is too much to ask, given the risk.





--Jeff















From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED]
On Behalf Of Dinis Cruz
Sent: Tuesday, May 02, 2006 7:48
PM
To: 'Secure Coding Mailing List'
Cc:
'[EMAIL PROTECTED]'
Subject: [SC-L] By default, the
Verifier is disabled on .Net and Java 





Here is a more detailed
explanation of why (in my previous post) I said: 99% of .Net and Java code that is currently deployed is executed
on an environment where the VM verifier is disabled, .

--

In .Net the verifier (the CLR function that checks for type safety) is only
enabled on partial trust .Net environments.

For example, in Full Trust .Net you can successfully assign Type A to Type B
(also called a Type Confusion attack) which clearly breaks type safety.

I have done some research on this topic, and on my spare time I was able to
find several examples of these situations:


 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)
 C# readonly modifier is not enforced by the CLR
 (when in Full Trust (http://owasp.net/blogs/dinis_cruz/archive/2005/12/26/390.aspx)
 Also related: 



 
  JIT prevents short
  overflow (and PeVerify doesn't catch it) (http://owasp.net/blogs/dinis_cruz/archive/2006/01/10/422.aspx)
   
  and ANSI/UNICODE
  bug in System.Net.HttpListenerRequest (http://www.owasp.net//blogs/dinis_cruz/archive/2005/12/17/349.aspx)
 


Here is Microsoft's 'on the record' comment about this
lack of verification (and enforcement of type safety) on Full Trust code (note:
I received these comments via the MSRC):

...
Some people have argued that Microsoft should always enforce type safety
at runtime (i.e. run the verifier) even if code is Fully Trusted.
We've chosen not to do this for a number of reasons (e.g. historical,
perf, etc). There are at least two important things to consider about
this scenario:

1) Even if we tried to enforce type safety using the verifier for Fully
Trusted code, it wouldn't prevent Fully Trusted from accomplishing the
same thing in 100 other different ways. In other words, your example
accessed an object as if it were a different incompatible type - The
verifier could have caught this particular technique that allowed him to
violate type safety. However, he could have accomplished the same
result using private reflection, direct memory access with unsafe code,
or indirectly doing stuff like using PInvoke/native code to disable
verification by modifying the CLR's verification code either on disk or
in memory. There would be a marginal benefit to insuring people wrote
cleaner more type safe code by enforcing verification
at runtime for
Full Trust, but you wouldn't get any additional security benefits
because you can perform unverifiable actions in dozens of ways the
verifier won't prevent if you are Fully Trusted.

2) As mentioned at the end of #1 above, one argument is that it's good
for programmers (even fully trusted ones) to follow type safety rules,
and doing runtime verification would keep people writing cleaner code.
However, we don't need to do the verification at runtime in order
to
encourage good type safety hygiene. Instead, we can rely on our
languages to do this for us. For example, C# and VB by default ensure
that you produce verifiable code. If you've written your code in a
language like C#, you're not going to run into cases where you've
accidentally created 

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

2006-05-03 Thread David Eisner
Wall, Kevin wrote:
  same intuition about the verifier, but have just tested  
 this and it is not the case.  It seems that the -noverify is the  
 default setting! If you want to verify classes loaded from the local  
 filesystem, then you need to explicitly add -verify to the cmd line.
 


Is this (still) true?  The -verify and -noverify flag are no longer
documented [1], although they are still accepted.

I did a little experiment (with my default 1.5 VM).  I compiled a
HelloWorld program, then changed a few byes in the class file with a hex
editor.

-8--
$ java -cp . HelloWorld
Exception in thread main java.lang.ClassFormatError: Interface name
has bad constant pool index 13056 in class file HelloWorld
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:620)
at
java.security.SecureClassLoader.defineClass(SecureClassLoader.java:124)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:260)
at java.net.URLClassLoader.access$100(URLClassLoader.java:56)
at java.net.URLClassLoader$1.run(URLClassLoader.java:195)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:268)
at java.lang.ClassLoader.loadClass(ClassLoader.java:251)
at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:319)

$ java -cp . -verify HelloWorld
Exception in thread main java.lang.ClassFormatError: Interface name
has bad constant pool index 13056 in class file HelloWorld
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:620)
at
java.security.SecureClassLoader.defineClass(SecureClassLoader.java:124)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:260)
at java.net.URLClassLoader.access$100(URLClassLoader.java:56)
at java.net.URLClassLoader$1.run(URLClassLoader.java:195)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:268)
at java.lang.ClassLoader.loadClass(ClassLoader.java:251)
at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:319)

$ java -cp . -noverify HelloWorld
#
# An unexpected error has been detected by HotSpot Virtual Machine:
#
#  EXCEPTION_ACCESS_VIOLATION (0xc005) at pc=0x6d7415fb, pid=3512,
tid=2260
#
# Java VM: Java HotSpot(TM) Client VM (1.5.0_06-b05 mixed mode)
# Problematic frame:
# V  [jvm.dll+0x615fb]
#
# An error report file with more information is saved as hs_err_pid3512.log
#
# If you would like to submit a bug report, please visit:
#   http://java.sun.com/webapps/bugreport/crash.jsp
#

-8--

-David

[1] http://java.sun.com/j2se/1.4.2/docs/tooldocs/windows/java.html


___
Secure Coding mailing list (SC-L)
SC-L@securecoding.org
List information, subscriptions, etc - http://krvw.com/mailman/listinfo/sc-l
List charter available at - http://www.securecoding.org/list/charter.php


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

2006-05-03 Thread Wall, Kevin
David Eisner wrote...

 Wall, Kevin wrote:

The correct attribution for bring this up (and the one whom you are
quoting) is Dinis Cruz.

   same intuition about the verifier, but have just tested
  this and it is not the case.  It seems that the -noverify is the
  default setting! If you want to verify classes loaded from the
local  
  filesystem, then you need to explicitly add -verify to the cmd
line.
 
 Is this (still) true?  The -verify and -noverify flag are no longer
 documented [1], although they are still accepted.
 
 I did a little experiment (with my default 1.5 VM).  I compiled a
 HelloWorld program, then changed a few byes in the class file with a
 hex editor.

Perhaps no longer true (at least one could hope), but I can't take
credit
for the part you quoted above. That was Dinis.

Also, from the results of your test, it seems to indicate that SOME TYPE
of verification is taking place, but if all you did was change a few
ARBITRARY bytes in the .class file, I don't think that proves the
byte code verifier is being being run in it's entirety. IIRC, the
discussion was around the issue of 'type safety'. It's hard to see how
a HelloWorld program would show that.

It's entirely possibly that the (new 1.5) default just does some
surface level of byte code verification (e.g., verify that everything
is legal op codes / byte code) before HotSpot starts crunching
on it and that this works differently if either the '-verify' or
'-noverify' flags are used. E.g., suppose that '-verify' flag, does
some deeper-level analysis, such as checks to ensure type safety, etc,
whereas the '-noverify' doesn't even validate the byte codes are
legal op codes or that the .class file has a legal format. This might
even make sense because checking for valid file format and valid
Java op codes ought to be fairly cheap checks compared to the
deeper analysis required for things like type safety.

You didn't discuss details of what bits you tweaked, so I'm not
quite yet ready to jump up and down for joy and conclude that Sun has
now seen the light and has made the 1.5 JVM default to run the byte
code through the *complete* byte code verifier. I think more tests
are either necessary or someone at Sun who can speak in some official
capacity steps up and gives a definitive word one way or another on
this.

-kevin
---
Kevin W. Wall   Qwest Information Technology, Inc.
[EMAIL PROTECTED]   Phone: 614.215.4788
Linux *is* user-friendly.  It's just choosy about its friends.
- Robert Slade, http://sun.soci.niu.edu/~rslade/bkl3h4h4.rvw


This communication is the property of Qwest and may contain confidential or
privileged information. Unauthorized use of this communication is strictly 
prohibited and may be unlawful.  If you have received this communication 
in error, please immediately notify the sender by reply e-mail and destroy 
all copies of the communication and any attachments.

___
Secure Coding mailing list (SC-L)
SC-L@securecoding.org
List information, subscriptions, etc - http://krvw.com/mailman/listinfo/sc-l
List charter available at - http://www.securecoding.org/list/charter.php


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

2006-05-03 Thread Dinis Cruz
Ok, I just did some further tests and I think I can say that Java 
(version 1.5.0_06) has similar verification issues to the ones I 
discovered on the .Net Framework (see links in my previous post).


Here is a full description of my test (which is a variation of the one 
done by Stephen de Vries in the original discussion about type safety).


-

Objective: Call a private method directly that belongs to a different 
class (something that should not be possible to do)


Test environment: Mac OS X10.4.6

java -version

   java version 1.5.0_06
   Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_06-112)
   Java HotSpot(TM) Client VM (build 1.5.0_06-64, mixed mode, sharing)


Step by Step description of test:


Start by creation the File: publicPrivate.java

**
class publicPrivate {
   public static void main(String[] args)
   {
   System.out.println(Hello World!); //Display the string.
   externalClass.publicMethod();
   externalClass.publicMethod();
   }

}

class externalClass
{
   public static void publicMethod()
   {
   System.out.println(Inside the Public Method);
   }

   private static void privateMethod()
   {
   System.out.println(Inside the Private Method);
   }
}
**

Compile this using javac publicPrivate.java and you get two class files: 
publicPrivate.class and externalClass.class


execute java publicPrivate and you will get

   Hello World!
   Inside the Public Method
   Inside the Public Method

Note that if I change on the publicPrivate.java file the lines

   externalClass.publicMethod();
   externalClass.publicMethod();

to

   externalClass.publicMethod();
   externalClass.privateMethod();

I will get the following compilation error:

   publicPrivate.java:7: privateMethod() has private access in 
externalClass

   externalClass.privateMethod();
^
   1 error


This makes sense since this is the compiler detecting that we are trying 
to access a private member directly (note: this is also what happens in 
.Net's C# compiler). It also means that (like in my .Net examples) I 
will have to manipulate directly the bytecode of the class that I want 
to change


Using jEdit Oolong plug-in I disassembled  the  publicPrivate.class 
file, creating the file: publicPrivate.j


(this is a slightly edited version of the Oolong disassemble result 
since the original version didn't compile)

**
.class public publicPrivate
   .super java/lang/Object
  
   .method public init()V

   .limit stack 1
   .limit locals 1
   aload_0
   invokespecial java/lang/Object/init()V
   return
   .end method
  
   .method public static main([Ljava/lang/String;)V
   .limit stack 2   
   getstatic java/lang/System/out Ljava/io/PrintStream;

   ldc Hello World! - After Oolong disassemble
   invokevirtual java/io/PrintStream/println(Ljava/lang/String;)V
  
   invokestatic externalClass/publicMethod()V

   invokestatic externalClass/publicMethod()V
  
   return
  
   .end method

**
note the change:
   from:  ldc Hello World!
   to:  ldc Hello World! - After Oolong disassemble


I also had some problems with getting the jEdit Oolong plug-in to 
assemble the publicPrivate.j file, so I used jasmin instead:


java -jar jasmin-2.2/jasmin.jar  PublicPrivate.j

   Generated: publicPrivate.class

Executing java publicPrivate shows:

   Hello World!- After Oolong disassemble
   Inside the Public Method
   Inside the Public Method

Now, in jEdit, on the publicPrivate.j  file, I make the following change

from:
  
   invokestatic externalClass/publicMethod()V   
   invokestatic externalClass/publicMethod()V
  
to:
  
   invokestatic externalClass/publicMethod()V   
   invokestatic externalClass/privateMethod()V


Then save it and run jasmin again

java -jar jasmin-2.2/jasmin.jar  PublicPrivate.j

   Generated: publicPrivate.class

execute java publicPrivate and:

   Hello World!- After Oolong disassemble
   Inside the Public Method
   Inside the Private Method

Bingo! We successfully invoked the private method.

Now, just to confirm that this is against verification (and that the 
verifier is disabled by default)


java -noverify publicPrivate  (produces the same result)

   Hello World!- After Oolong disassemble
   Inside the Public Method
   Inside the Private Method

java -verify publicPrivate (throws an verification error)

   Hello World!- After Oolong disassemble
   Inside the Public Method
   Exception in thread main java.lang.IllegalAccessError: tried to 
access method externalClass.privateMethod()V from class publicPrivate

   at publicPrivate.main(PublicPrivate.j)



This should prove that the verifier is not enabled by default on java 
files loaded from the local computer.


What is interesting about this example is that we are not even doing a 
Type Confusion attack and trying to break type 

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

2006-05-03 Thread Michael Silk

Verifier in 1.5 is definately OFF by default:

to confirm this do the following:

1. Create this class:
==
public class Foo {
 public static int k = 23;

 static {
   System.out.println(initially k:  + k);
 }

 public static void m(){
   System.out.println(m() k:  + k);
 }
}
==

2. Compile it.

3. Create this class
==
public class Test {
 public static void main(String[] args){
   Foo.k = 34;
   Foo.m();
 }
}
==

4. Compile it.
5. Run it like so:
5a. java Test
5b. java -verify Test

6. Change Foo.java like so:
==
public class Foo {
 private static int k = 23;

 static {
   System.out.println(initially k:  + k);
 }

 public static void m(){
   System.out.println(m() k:  + k);
 }
}
==

(note k is now private).

7. recompile Foo.java (DO NOT recompile Test.java)
8. run Test.java like so:
8a. java Test
8b. java -verify Test


Note the differences ...

Tested with
===
java version 1.5.0_06
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_06-b05)
Java HotSpot(TM) Client VM (build 1.5.0_06-b05, mixed mode)
===


-- Michael


On 5/4/06, Wall, Kevin [EMAIL PROTECTED] wrote:

David Eisner wrote...

 Wall, Kevin wrote:

The correct attribution for bring this up (and the one whom you are
quoting) is Dinis Cruz.

   same intuition about the verifier, but have just tested
  this and it is not the case.  It seems that the -noverify is the
  default setting! If you want to verify classes loaded from the
local
  filesystem, then you need to explicitly add -verify to the cmd
line.

 Is this (still) true?  The -verify and -noverify flag are no longer
 documented [1], although they are still accepted.

 I did a little experiment (with my default 1.5 VM).  I compiled a
 HelloWorld program, then changed a few byes in the class file with a
 hex editor.

Perhaps no longer true (at least one could hope), but I can't take
credit
for the part you quoted above. That was Dinis.

Also, from the results of your test, it seems to indicate that SOME TYPE
of verification is taking place, but if all you did was change a few
ARBITRARY bytes in the .class file, I don't think that proves the
byte code verifier is being being run in it's entirety. IIRC, the
discussion was around the issue of 'type safety'. It's hard to see how
a HelloWorld program would show that.

It's entirely possibly that the (new 1.5) default just does some
surface level of byte code verification (e.g., verify that everything
is legal op codes / byte code) before HotSpot starts crunching
on it and that this works differently if either the '-verify' or
'-noverify' flags are used. E.g., suppose that '-verify' flag, does
some deeper-level analysis, such as checks to ensure type safety, etc,
whereas the '-noverify' doesn't even validate the byte codes are
legal op codes or that the .class file has a legal format. This might
even make sense because checking for valid file format and valid
Java op codes ought to be fairly cheap checks compared to the
deeper analysis required for things like type safety.

You didn't discuss details of what bits you tweaked, so I'm not
quite yet ready to jump up and down for joy and conclude that Sun has
now seen the light and has made the 1.5 JVM default to run the byte
code through the *complete* byte code verifier. I think more tests
are either necessary or someone at Sun who can speak in some official
capacity steps up and gives a definitive word one way or another on
this.

-kevin
---
Kevin W. Wall   Qwest Information Technology, Inc.
[EMAIL PROTECTED]Phone: 614.215.4788
Linux *is* user-friendly.  It's just choosy about its friends.
   - Robert Slade, http://sun.soci.niu.edu/~rslade/bkl3h4h4.rvw


This communication is the property of Qwest and may contain confidential or
privileged information. Unauthorized use of this communication is strictly
prohibited and may be unlawful.  If you have received this communication
in error, please immediately notify the sender by reply e-mail and destroy
all copies of the communication and any attachments.

___
Secure Coding mailing list (SC-L)
SC-L@securecoding.org
List information, subscriptions, etc - http://krvw.com/mailman/listinfo/sc-l
List charter available at - http://www.securecoding.org/list/charter.php



___
Secure Coding mailing list (SC-L)
SC-L@securecoding.org
List information, subscriptions, etc - http://krvw.com/mailman/listinfo/sc-l
List charter available at - http://www.securecoding.org/list/charter.php