Valerio `sid` Costamagna bio photo

Valerio `sid` Costamagna

“It’s no use going back to yesterday, because I was a different person then.” ― Lewis Carroll, Alice in Wonderland

Email Twitter Github

ENVIRONMENT

1
2
3
4
5
6
$ echo $JAVA_HOME
/usr/lib/jvm/java-8-oracle
$ java -version
java version "1.8.0_77"
Java(TM) SE Runtime Environment (build 1.8.0_77-b03)
Java HotSpot(TM) 64-Bit Server VM (build 25.77-b03, mixed mode)
1
2
3
$ cat taint-sinks
java/io/PrintStream.println(Ljava/lang/String;)V
java/io/PrintStream.println(Ljava/lang/Object;)V
1
2
3
$ cat taint-sources
java/lang/Integer.toString(I)Ljava/lang/String;
java/io/ObjectInputStream.readObject()Ljava/io/Object;

INSTRUMENTING JRE

  1. using int tag:
1
java -jar Phosphor-0.0.2-SNAPSHOT.jar -forceUnboxAcmpEq -withEnumsByValue -taintSources taint-sources -taintSinks taint-sinks /usr/lib/jvm/java-8-oracle/jre/ jre-inst
  1. using obj tag (multiTaint):
1
java -jar Phosphor-0.0.2-SNAPSHOT.jar -forceUnboxAcmpEq -withEnumsByValue -taintSources taint-sources -taintSinks taint-sinks -multiTaint /usr/lib/jvm/java-8-oracle/jre/ jre-inst-obj
  1. using obj tag + implicit flow:
1
java -jar Phosphor-0.0.2-SNAPSHOT.jar -controlTrack -forceUnboxAcmpEq -withEnumsByValue -taintSources taint-sources -taintSinks taint-sinks -multiTaint /usr/lib/jvm/java-8-oracle/jre/ jre-inst-implicit

So far I did the following tests:

  1. JRE int-tag-instrumented on both test-app and jenkins
  2. JRE obj-tag-instrumented on both test-app and jenkins

INT TAG mode

First, I tested the JRE instrumented with int-tag tainting mode on both phosphortests.jar, test-app.jar and jenkins.

phosphortests results:

1
2
3
4
5
6
7
java -jar Phosphor-0.0.2-SNAPSHOT.jar -taintSources taint-sources -taintSinks taint-sinks phosphortests.jar phosphortests-inst-int

$ jre-inst/bin/java -Xbootclasspath/p:Phosphor-0.0.2-SNAPSHOT.jar -javaagent:Phosphor-0.0.2-SNAPSHOT.jar -cp phosphortests-inst-int/phosphortests.jar -ea phosphor.test.DroidBenchTest
testFieldSensitivity1
testFieldSensitivity2
testFieldSensitivity3
[...]

test-app results:

1
2
3
4
5
6
7
8
9
10
11
java -jar Phosphor-0.0.2-SNAPSHOT.jar -taintSources taint-sources -taintSinks taint-sinks test-app.jar testapp-inst-int

$ jre-inst/bin/java -Xbootclasspath/p:Phosphor-0.0.2-SNAPSHOT.jar -javaagent:Phosphor-0.0.2-SNAPSHOT.jar -cp testapp-inst-int/test-app.jar -ea com.test.Main
haha
plugin started
Phosphor plugin: Tainted Object ==> 123
12312
phosphor plugin: # of tainted objects 1
phosphor plugin: # of tainted objects 1
phosphor plugin: # of tainted objects 1
[...] 

(I see only 1 tainted object) I don’t know if it is a feature, but actually the plugin’s code starts an endless loop.

I also tested against jenkins. During the instrumentation step, i got several exceptions like the following one:

1
2
3
4
5
6
7
java.util.zip.ZipException: duplicate entry: javax/jmdns/impl/tasks/state/Renewer.class
	at java.util.zip.ZipOutputStream.putNextEntry(ZipOutputStream.java:232)
	at java.util.jar.JarOutputStream.putNextEntry(JarOutputStream.java:109)
	at edu.columbia.cs.psl.phosphor.Instrumenter.processJar(Instrumenter.java:631)
	at edu.columbia.cs.psl.phosphor.Instrumenter.processZip(Instrumenter.java:814)
	at edu.columbia.cs.psl.phosphor.Instrumenter._main(Instrumenter.java:512)
	at edu.columbia.cs.psl.phosphor.Instrumenter.main(Instrumenter.java:380)

Besides the above expections, the instrumented version of jenkins is successfully created. Then i ran jenkins, and the following box shows the plugin messages:

1
2
3
4
5
6
7
sid@artdroid:~/PSU/deserialization/phosphor-mod/Phosphor/target$ ./jre-inst/bin/java -Xbootclasspath/a:Phosphor-0.0.2-SNAPSHOT.jar  -javaagent:Phosphor-0.0.2-SNAPSHOT.jar -jar jenkins/jenkins.war
Running from: /home/sid/PSU/deserialization/phosphor-mod/Phosphor/target/jenkins/jenkins.war
webroot: $user.home/.jenkins
plugin started
Phosphor plugin: Tainted Object ==> 800
phosphor plugin: # of tainted objects 1
[...]

Then I ran the jenkins.py from JavaUnserializeExploits and the file in /tmp is successfully created. The following is the log printed by jenkins:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
INFO: Accepted connection #2 from /127.0.0.1:33640
Phosphor plugin: Tainted Object ==> 0
Phosphor plugin: Tainted Object ==> 0
Phosphor plugin: Tainted Object ==> -1
Phosphor plugin: Tainted Object ==> 0
Exception in thread "TCP slave agent connection handler #2 with /127.0.0.1:33640" java.lang.ClassCastException: java.lang.UNIXProcess cannot be cast to java.util.Set
	at com.sun.proxy.$Proxy37.entrySet(Unknown Source)
	at sun.reflect.annotation.AnnotationInvocationHandler.readObject(AnnotationInvocationHandler.java:452)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:1058)
	at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1900)
	at java.io.ObjectInputStream.readOrdinaryObject$$PHOSPHORTAGGED(ObjectInputStream.java:1801)
	at java.io.ObjectInputStream.readObject0$$PHOSPHORTAGGED(ObjectInputStream.java:1351)
	at java.io.ObjectInputStream.readObject(ObjectInputStream.java:371)
	at hudson.remoting.Capability.read(Capability.java:125)
	at hudson.remoting.ChannelBuilder.negotiate(ChannelBuilder.java:355)
	at hudson.remoting.ChannelBuilder.build(ChannelBuilder.java:282)
	at hudson.cli.CliProtocol$Handler.runCli(CliProtocol.java:77)
	at hudson.cli.CliProtocol$Handler.run(CliProtocol.java:64)
	at hudson.cli.CliProtocol.handle(CliProtocol.java:40)
	at hudson.TcpSlaveAgentListener$ConnectionHandler.run(TcpSlaveAgentListener.java:156)
phosphor plugin: # of tainted objects 50
[...]

However, accessing to Jenkins web-dashboard a lots of error messages are printed in the console, and also the dashboard is not fully accessible (stacktrace errors are printed in the web page)

USING MULTITAINT

I’m going to show the results of JRE instrumented with obj-tag tainting mode (multiTaint) enabled.

phosphortests:

1
2
3
4
5
6
7
8
9
10
$ jre-inst-obj/bin/java -Xbootclasspath/p:Phosphor-0.0.2-SNAPSHOT.jar -javaagent:Phosphor-0.0.2-SNAPSHOT.jar -cp phosphortests-inst-multi/phosphortests.jar -ea phosphor.test.DroidBenchTest
testFieldSensitivity1
java.lang.reflect.InvocationTargetException
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at phosphor.test.DroidBenchTest.main(DroidBenchTest.java:521)
Caused by: java.lang.NoSuchMethodError: edu.columbia.cs.psl.phosphor.runtime.Tainter.taintedCharArray$$PHOSPHORTAGGED([Ledu/columbia/cs/psl/phosphor/runtime/Taint;[CLedu/columbia/cs/psl/phosphor/runtime/Taint;ILedu/columbia/cs/psl/phosphor/struct/TaintedCharArrayWithObjTag;)Ledu/columbia/cs/psl/phosphor/struct/TaintedCharArrayWithObjTag;
[...]

.. but the infamous java.lang.NoSuchMethodError arise again …

Same story with test-app but with different exception:

1
java -jar Phosphor-0.0.2-SNAPSHOT.jar -multiTaint -taintSources taint-sources -taintSinks taint-sinks test-app.jar testapp-inst-multi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
$ jre-inst-obj/bin/java -Xbootclasspath/p:Phosphor-0.0.2-SNAPSHOT.jar -javaagent:Phosphor-0.0.2-SNAPSHOT.jar -cp testapp-inst-multi/test-app.jar -ea com.test.Main
haha
Exception in thread "main" java.lang.IllegalAccessError: Argument carries taints:  Taint [lbl=java/lang/Integer.toString(I)Ljava/lang/String;  deps = []]
	at edu.columbia.cs.psl.phosphor.runtime.TaintChecker.checkTaint(TaintChecker.java:76)
	at edu.columbia.cs.psl.phosphor.runtime.TaintChecker.checkTaint(TaintChecker.java:64)
	at java.io.PrintStream.write$$PHOSPHORTAGGED(PrintStream.java)
	at sun.nio.cs.StreamEncoder.writeBytes(StreamEncoder.java:221)
	at sun.nio.cs.StreamEncoder.implFlushBuffer(StreamEncoder.java:291)
	at sun.nio.cs.StreamEncoder.flushBuffer(StreamEncoder.java:104)
	at java.io.OutputStreamWriter.flushBuffer(OutputStreamWriter.java:185)
	at java.io.PrintStream.write(PrintStream.java:527)
	at java.io.PrintStream.print(PrintStream.java:669)
	at java.io.PrintStream.println(PrintStream.java:806)
	at com.test.Main.main(Main.java:7)

Even the Jenkins’ turn is not happy for me:

1
2
3
4
5
6
7
8
9
10
11
$ ./jre-inst-obj/bin/java -Xbootclasspath/a:Phosphor-0.0.2-SNAPSHOT.jar  -javaagent:Phosphor-0.0.2-SNAPSHOT.jar -jar jenkins-multi/jenkins.war
Running from: /home/sid/PSU/deserialization/phosphor-mod/Phosphor/target/jenkins-multi/jenkins.war
webroot: $user.home/.jenkins
Exception in thread "main" java.lang.IllegalAccessError: Argument carries taints:  Taint [lbl=java/io/InputStream.read([BII)I  deps = []]
	at edu.columbia.cs.psl.phosphor.runtime.TaintChecker.checkTaint(TaintChecker.java:76)
	at edu.columbia.cs.psl.phosphor.runtime.TaintChecker.checkTaint(TaintChecker.java:64)
	at java.io.FileOutputStream.write$$PHOSPHORTAGGED(FileOutputStream.java)
	at Main.copyStream(Main.java:379)
	at Main.extractFromJar(Main.java:404)
	at Main._main(Main.java:190)
	at Main.main(Main.java:98)

TODO

  • Actually, the jre-inst-obj (multiTaint mode) doesn’t work

  • while instrumenting JRE with “java/io/InputStream.read()I” as taint-source, I see the following messages:

1
2
3
4
Source: com/sun/javafx/runtime/async/AbstractRemoteResource$ProgressInputStream.read$$PHOSPHORTAGGED(Ledu/columbia/cs/psl/phosphor/struct/TaintedIntWithIntTag;)Ledu/columbia/cs/psl/phosphor/struct/TaintedIntWithIntTag; Label: 1
Processed: 5000/31516
Processed: 6000/31516
Source: com/sun/webkit/SimpleSharedBufferInputStream.read$$PHOSPHORTAGGED(Ledu/columbia/cs/psl/phosphor/struct/TaintedIntWithIntTag;)Ledu/columbia/cs/psl/phosphor/struct/TaintedIntWithIntTag; Label: 1

I get no messages while instrumenting the JRE with “java/io/ObjectInputStream.readObject()Ljava/io/Object;” as single taint-source. It looks strange.

(update: Ok, disass. rt.jar I see phosphor instrumentation code. So, even if no messages are printed out by phosphor, the instrument. code is properly added )

  • tainting on methods which are calling each other, may arise IllegalAccessError ? The execution halts when I taint both “println” and “write” :
+ jre-inst/bin/java -Xbootclasspath/p:Phosphor-0.0.2-SNAPSHOT.jar -javaagent:Phosphor-0.0.2-SNAPSHOT.jar -cp testapp-inst-int/test-app.jar -ea com.test.Main
haha
plugin started

Exception: java.lang.IllegalAccessError thrown from the UncaughtExceptionHandler in thread "main"

Exception: java.lang.IllegalAccessError thrown from the UncaughtExceptionHandler in thread "Thread-0"