Skip to content

Commit

Permalink
Resolving #178
Browse files Browse the repository at this point in the history
 - Added a boomerang query to find the points to information of the call site parameters. For each of the array parameters, its constants are found by traversing through the jimple method body.
 - Added a headless test for SSLParameters.
  • Loading branch information
sritejakv committed Nov 1, 2019
1 parent b18f4a7 commit d57e745
Show file tree
Hide file tree
Showing 5 changed files with 189 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ public SootMethod getMethod(){
return stmt().getMethod();
}

public CryptoScanner getCryptoScanner() {
return this.cryptoScanner;
}

public String getObjectId() {
if(objectId == null) {
MessageDigest md;
Expand Down
101 changes: 93 additions & 8 deletions CryptoAnalysis/src/main/java/crypto/constraints/ConstraintSolver.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,25 @@
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.stream.Collectors;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Multimap;
import com.google.common.collect.Sets;

import boomerang.BackwardQuery;
import boomerang.Boomerang;
import boomerang.ForwardQuery;
import boomerang.callgraph.ObservableICFG;
import boomerang.jimple.Statement;
import boomerang.jimple.Val;
import boomerang.results.BackwardBoomerangResults;
import crypto.analysis.AlternativeReqPredicate;
import crypto.analysis.AnalysisSeedWithSpecification;
import crypto.analysis.ClassSpecification;
Expand All @@ -27,6 +36,7 @@
import crypto.analysis.errors.ImpreciseValueExtractionError;
import crypto.analysis.errors.InstanceOfError;
import crypto.analysis.errors.NeverTypeOfError;
import crypto.boomerang.CogniCryptIntAndStringBoomerangOptions;
import crypto.extractparameter.CallSiteWithExtractedValue;
import crypto.extractparameter.CallSiteWithParamIndex;
import crypto.extractparameter.ExtractedValue;
Expand All @@ -42,9 +52,11 @@
import crypto.rules.CryptSLSplitter;
import crypto.rules.CryptSLValueConstraint;
import crypto.typestate.CryptSLMethodToSootMethod;
import soot.Body;
import soot.IntType;
import soot.SootMethod;
import soot.Type;
import soot.Unit;
import soot.Value;
import soot.jimple.AssignStmt;
import soot.jimple.Constant;
Expand All @@ -54,6 +66,8 @@
import soot.jimple.NewExpr;
import soot.jimple.Stmt;
import soot.jimple.StringConstant;
import soot.jimple.internal.JNewArrayExpr;
import wpds.impl.Weight.NoWeight;

public class ConstraintSolver {

Expand Down Expand Up @@ -168,9 +182,9 @@ public int evaluateRelConstraints() {

public EvaluableConstraint createConstraint(ISLConstraint con) {
if (con instanceof CryptSLComparisonConstraint) {
return new ComparisonConstraint((CryptSLComparisonConstraint) con);
return new ComparisonConstraint((CryptSLComparisonConstraint) con, ConstraintSolver.this.object.getCryptoScanner().icfg());
} else if (con instanceof CryptSLValueConstraint) {
return new ValueConstraint((CryptSLValueConstraint) con);
return new ValueConstraint((CryptSLValueConstraint) con, ConstraintSolver.this.object.getCryptoScanner().icfg());
} else if (con instanceof CryptSLPredicate) {
return new PredicateConstraint((CryptSLPredicate) con);
} else if (con instanceof CryptSLConstraint) {
Expand Down Expand Up @@ -358,8 +372,11 @@ private void handlePredefinedNames(CryptSLPredicate pred) {

public class ComparisonConstraint extends EvaluableConstraint {

public ComparisonConstraint(CryptSLComparisonConstraint c) {
ObservableICFG<Unit, SootMethod> icfg;

public ComparisonConstraint(CryptSLComparisonConstraint c, ObservableICFG<Unit, SootMethod> icfg) {
super(c);
this.icfg = icfg;
}

@Override
Expand Down Expand Up @@ -489,7 +506,7 @@ private Map<Integer, CallSiteWithExtractedValue> extractValueAsInt(String exp, I
catch (NumberFormatException ex) {
// 2. If not, it's a variable name.
// Get value of variable left from map
final Map<String, CallSiteWithExtractedValue> valueCollection = extractValueAsString(exp, cons);
final Map<String, CallSiteWithExtractedValue> valueCollection = extractValueAsString(exp, cons, icfg);
if (valueCollection.isEmpty()) {
return valuesInt;
}
Expand All @@ -515,8 +532,11 @@ else if(value.getKey().equals("false"))

public class ValueConstraint extends EvaluableConstraint {

public ValueConstraint(CryptSLValueConstraint c) {
private ObservableICFG<Unit, SootMethod> icfg;

public ValueConstraint(CryptSLValueConstraint c, ObservableICFG<Unit, SootMethod> icfg) {
super(c);
this.icfg = icfg;
}

@Override
Expand All @@ -540,7 +560,7 @@ public void evaluate() {

private List<Entry<String, CallSiteWithExtractedValue>> getValFromVar(CryptSLObject var, ISLConstraint cons) {
final String varName = var.getVarName();
final Map<String, CallSiteWithExtractedValue> valueCollection = extractValueAsString(varName, cons);
final Map<String, CallSiteWithExtractedValue> valueCollection = extractValueAsString(varName, cons, icfg);
List<Entry<String, CallSiteWithExtractedValue>> vals = new ArrayList<>();
if (valueCollection.isEmpty()) {
return vals;
Expand Down Expand Up @@ -590,14 +610,13 @@ public boolean hasErrors() {
return !errors.isEmpty();
}

protected Map<String, CallSiteWithExtractedValue> extractValueAsString(String varName, ISLConstraint cons) {
protected Map<String, CallSiteWithExtractedValue> extractValueAsString(String varName, ISLConstraint cons, ObservableICFG<Unit, SootMethod> dynICFG) {
Map<String, CallSiteWithExtractedValue> varVal = Maps.newHashMap();
for (CallSiteWithParamIndex wrappedCallSite : parsAndVals.keySet()) {
final Stmt callSite = wrappedCallSite.stmt().getUnit().get();

for (ExtractedValue wrappedAllocSite : parsAndVals.get(wrappedCallSite)) {
final Stmt allocSite = wrappedAllocSite.stmt().getUnit().get();

if (wrappedCallSite.getVarName().equals(varName)) {
InvokeExpr invoker = callSite.getInvokeExpr();
if (callSite.equals(allocSite)) {
Expand All @@ -617,13 +636,79 @@ protected Map<String, CallSiteWithExtractedValue> extractValueAsString(String va
} else {
varVal.put(retrieveConstantFromValue, new CallSiteWithExtractedValue(wrappedCallSite, wrappedAllocSite));
}
} else if (wrappedAllocSite.getValue() instanceof JNewArrayExpr) {
BackwardBoomerangResults<NoWeight> backwardQueryResults = getBoomerangResults(invoker.getArg(wrappedCallSite.getIndex()),
wrappedCallSite,
wrappedAllocSite,
dynICFG
);

varVal.putAll(extractSootArray(backwardQueryResults, wrappedAllocSite.stmt().getMethod().getActiveBody(),
wrappedCallSite,
wrappedAllocSite)
);
}
}
}
}
}
return varVal;
}


/***
* Function to fetch boomerang results for the received soot value.
* @param sootValue value for which boomerang has to be run
* @param callSite call site at which sootValue is involved
* @param allocSite allocation site at which sootValue is involved
* @param dynICFG ICFG on which boomerang is run
* @return boomerang results
*/
private BackwardBoomerangResults<NoWeight> getBoomerangResults(Value sootValue, CallSiteWithParamIndex callSite,
ExtractedValue allocSite, ObservableICFG<Unit, SootMethod> dynICFG){
Boomerang boomerang = new Boomerang(new CogniCryptIntAndStringBoomerangOptions()) {
@Override
public ObservableICFG<Unit, SootMethod> icfg() {
return dynICFG;
}
};
Val queryVal = new Val(sootValue, allocSite.stmt().getMethod());
Statement s = new Statement(callSite.stmt().getUnit().get(), callSite.stmt().getMethod());
BackwardQuery backQuery = new BackwardQuery(s, queryVal);
return boomerang.solve(backQuery);
}


/***
* Function that finds the values assigned to a soot array.
* @param backwardBoomerangResults results obtained from boomerang
* @param methodBody soot body of the method
* @param callSite call site at which sootValue is involved
* @param allocSite allocation site at which sootValue is involved
* @return extracted array values
*/
private Map<String, CallSiteWithExtractedValue> extractSootArray(BackwardBoomerangResults<NoWeight> backwardBoomerangResults, Body methodBody,
CallSiteWithParamIndex callSite, ExtractedValue allocSite){
Map<String, CallSiteWithExtractedValue> arrVal = Maps.newHashMap();
for (ForwardQuery v : backwardBoomerangResults.getAllocationSites().keySet()) {
soot.Value arrayLocal = ((AssignStmt) v.stmt().getUnit().get()).getLeftOp();
if (methodBody != null) {
Iterator<Unit> unitIterator = methodBody.getUnits().snapshotIterator();
while (unitIterator.hasNext()) {
final Unit unit = unitIterator.next();
if (unit instanceof AssignStmt) {
AssignStmt uStmt = (AssignStmt) (unit);
soot.Value leftValue = uStmt.getLeftOp();
soot.Value rightValue = uStmt.getRightOp();
if (leftValue.toString().contains(arrayLocal.toString()) && !rightValue.toString().contains("newarray")) {
arrVal.put(retrieveConstantFromValue(rightValue), new CallSiteWithExtractedValue(callSite, allocSite));
}
}
}
}
}
return arrVal;
}
}

public List<ISLConstraint> getRequiredPredicates() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,4 +115,24 @@ public void oracleExample() {
scanner.exec();
assertErrors();
}

@Test
public void sslExample() {
String mavenProjectPath = new File("../CryptoAnalysisTargets/SSLMisuseExample").getAbsolutePath();
MavenProject mavenProject = createAndCompile(mavenProjectPath);
HeadlessCryptoScanner scanner = createScanner(mavenProject);

setErrorsCount(new ErrorSpecification.Builder("<crypto.SSLExample: void MisuseOne()>")
.withTPs(ConstraintError.class, 1)
.build());
setErrorsCount(new ErrorSpecification.Builder("<crypto.SSLExample: void MisuseTwo()>")
.withTPs(ConstraintError.class, 1)
.build());
setErrorsCount(new ErrorSpecification.Builder("<crypto.SSLExample: void MisuseThree()>")
.withTPs(ConstraintError.class, 2)
.build());

scanner.exec();
assertErrors();
}
}
29 changes: 29 additions & 0 deletions CryptoAnalysisTargets/SSLMisuseExample/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>SSLMisuseExample</groupId>
<artifactId>SSLMisuseExample</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>

<name>SSLMisuseExample</name>
<url>http://maven.apache.org</url>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>

<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package crypto;
import java.security.NoSuchAlgorithmException;

import javax.crypto.BadPaddingException;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.net.ssl.SSLParameters;

public class SSLExample {

public void NoMisuse() throws NoSuchAlgorithmException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException {
String[] paramOne = {"TLSv1.1", "TLSv1.2"};
String[] paramTwo = {"TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384"};
SSLParameters params = new SSLParameters();
params.setCipherSuites(paramTwo);
params.setProtocols(paramOne);
}

public void MisuseOne() throws NoSuchAlgorithmException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException {
String[] paramOne = {"IPv4", "TLSv1.2"};
String[] paramTwo = {"TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384"};
SSLParameters params = new SSLParameters();
params.setCipherSuites(paramTwo);
params.setProtocols(paramOne);
}

public void MisuseTwo() throws NoSuchAlgorithmException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException {
String[] paramOne = {"TLSv1.1", "TLSv1.2"};
String[] paramTwo = {"TLS_ECDHE_ECDSA_WITH_AES_256_SHA_SHA384"};
SSLParameters params = new SSLParameters();
params.setCipherSuites(paramTwo);
params.setProtocols(paramOne);
}

public void MisuseThree() throws NoSuchAlgorithmException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException {
String[] paramOne = {"TLSv2.1", "TLSv1.2"};
String[] paramTwo = {"TL_ECDHE_ECDSA_WITH_AES_256_SHA_SHA384"};
SSLParameters params = new SSLParameters();
params.setCipherSuites(paramTwo);
params.setProtocols(paramOne);
}

}

0 comments on commit d57e745

Please sign in to comment.