Question 1:
In class we discussed the following rule for drawing call graphs for Java:
- When an interface method is invoked, we conservatively assume that it can resolve
to the named method in any class that implements the interface (*)
In this question, we will try to find security issues in libraries using library-only call
graphs. In the process, we will discover some limitations of the above rule in a library-
only setting.
The following code snippets illustrate a Trusted Method Chaining attack (CVE-2010-
0840). For the actual exploit code and further explanation of the vulnerability, please re-
fer to Michael Reif, Michael Eichberg, Ben Hermann, Johannes Lerch, and Mira Mezini.
"Call graph construction for Java libraries". In Proceedings of the 2016 24th ACM SIG-
SOFT International Symposium on Foundations of Software Engineering (FSE 2016).
Listing 1: Library Code
public class TrustedClass {
private Map. Entry entry;
public TrustedClass (Map. Entry entry) { this.entry= entry; }
public void run() { entry.getValue(); }
}
public class Expression {
public Object getValue() { ... }
}
public interface Map. Entry {
public Object getValue();
}
public class TrustedThread {
public void execute() { Map. Entry entry; ... entry.getValue();
}
Listing 2: Attacker's Code
public class Link extends Expression implements Map. Entry {
public Link (Object target, String methodName, Object[] arguments) {
super (target, methodName, arguments);
}
// inherits public Object Expression.getValue()
}
public class Exploit {
}
public Exploit() {
}
Link 1 new Link (System.class, "setSecurity Manager", null);
TrustedClass trustedObj
new TrustedClass(1);
Objects of type Expression represent reflective code that can be executed by calling
getValue() on those objects. The attack works by writing trustedObj into a data
structure used by a thread with elevated permissions. Then the trusted thread exe-
cutes TrustedThread.execute(). This in turn executes Expression.getValue() and
eventually System.setSecurityManager (null) without any attacker defined methods
showing up on the trusted thread's call stack. In the Java Security Model, when sensitive
methods (e.g. System.setSecurityManager) are called, the call stack is checked to see
if any of the methods originate in untrusted code. Since no attacker defined methods
are on the call stack, setSecurityManager (null) is executed.
a. (10 points) For library-only call graph construction, what are the entry points that
should be considered for call graph construction and why? (Hint: Answer this in
general, without referring to the specifics of Listing 1 and 2)
b. (10 points) Using only code from Listing 1, draw the library-only call graph that
would result from using CHA (augmented with the rule (*)).
c. (10 points) Using code from both Listing 1 and Listing 2, draw a call graph that
would result from using CHA. Assume that the constructors Link and Exploit are
the only entry points.
Are there paths from the entry points to Expression.getValue()?
d. (10 points) Using code from both Listing 1 and Listing 2, draw the call graph for
the TrustedThread.execute() method.
- Are there any differences in this call graph compared to the library-only version?
e. (10 points) Suggest improvements to CHA that will enable the discovery of this
scenario, independent of the application.