Bug fixes and and updates

The XposedBridgeApi.jar library has been updated to utilize new
functionality.  The commit for the WebView checks was not
implemented correctly, and resulted in exceptions when attempting
to hook any application.  The code was also missing functionality
to disable all validation for the Apache libraries.
This commit is contained in:
Jake Valletta
2014-12-15 14:04:44 -05:00
parent d31bc8d0bd
commit 7ae8dca069
5 changed files with 258 additions and 39 deletions

View File

@@ -1,11 +1,22 @@
package just.trust.me;
import javax.net.ssl.SSLSocketFactory;
import android.net.http.SslError;
import android.webkit.SslErrorHandler;
import android.webkit.WebView;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
import java.security.SecureRandom;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.KeyManager;
@@ -13,45 +24,111 @@ import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.conn.scheme.HostNameResolver;
import org.apache.http.conn.scheme.PlainSocketFactory;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.SingleClientConnManager;
import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
import org.apache.http.params.HttpParams;
import de.robv.android.xposed.IXposedHookLoadPackage;
import de.robv.android.xposed.XC_MethodHook;
import de.robv.android.xposed.XC_MethodReplacement;
import de.robv.android.xposed.XposedBridge;
import de.robv.android.xposed.callbacks.XC_LoadPackage.LoadPackageParam;
import static de.robv.android.xposed.XposedHelpers.callMethod;
import static de.robv.android.xposed.XposedHelpers.callStaticMethod;
import static de.robv.android.xposed.XposedHelpers.findAndHookConstructor;
import static de.robv.android.xposed.XposedHelpers.findAndHookMethod;
import static de.robv.android.xposed.XposedHelpers.getObjectField;
import static de.robv.android.xposed.XposedHelpers.newInstance;
import static de.robv.android.xposed.XposedHelpers.setObjectField;
public class Main implements IXposedHookLoadPackage {
public void handleLoadPackage(final LoadPackageParam lpparam) throws Throwable {
findAndHookMethod("javax.net.ssl.TrustManagerFactory", lpparam.classLoader, "getTrustManagers", new XC_MethodReplacement() {
/* Apache Hooks */
/* external/apache-http/src/org/apache/http/impl/client/DefaultHttpClient.java */
/* public DefaultHttpClient() */
findAndHookConstructor(DefaultHttpClient.class, new XC_MethodHook() {
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
setObjectField(param.thisObject, "defaultParams", null);
setObjectField(param.thisObject, "connManager", getSCCM());
}
});
/* external/apache-http/src/org/apache/http/impl/client/DefaultHttpClient.java */
/* public DefaultHttpClient(HttpParams params) */
findAndHookConstructor(DefaultHttpClient.class, HttpParams.class, new XC_MethodHook() {
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
setObjectField(param.thisObject, "defaultParams", (HttpParams)param.args[0]);
setObjectField(param.thisObject, "connManager", getSCCM());
}
});
/* external/apache-http/src/org/apache/http/impl/client/DefaultHttpClient.java */
/* public DefaultHttpClient(ClientConnectionManager conman, HttpParams params) */
findAndHookConstructor(DefaultHttpClient.class, ClientConnectionManager.class, HttpParams.class, new XC_MethodHook() {
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
HttpParams params = (HttpParams)param.args[1];
setObjectField(param.thisObject, "defaultParams", params);
setObjectField(param.thisObject, "connManager", getCCM(param.args[0], params));
}
});
/* external/apache-http/src/org/apache/http/conn/ssl/SSLSocketFactory.java */
/* public SSLSocketFactory( ... ) */
findAndHookConstructor(SSLSocketFactory.class, String.class, KeyStore.class, String.class, KeyStore.class,
SecureRandom.class, HostNameResolver.class, new XC_MethodHook() {
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
String algorithm = (String)param.args[0];
KeyStore keystore = (KeyStore)param.args[1];
String keystorePassword = (String)param.args[2];
SecureRandom random = (SecureRandom)param.args[4];
KeyManager[] keymanagers = null;
TrustManager[] trustmanagers = null;
if (keystore != null) {
keymanagers = (KeyManager[])callStaticMethod(SSLSocketFactory.class, "createKeyManagers", keystore, keystorePassword);
}
trustmanagers = new TrustManager[]{new ImSureItsLegitTrustManager()};
setObjectField(param.thisObject, "sslcontext", SSLContext.getInstance(algorithm));
callMethod(getObjectField(param.thisObject, "sslcontext"), "init", keymanagers, trustmanagers, random);
setObjectField(param.thisObject, "socketfactory",
callMethod(getObjectField(param.thisObject, "sslcontext"), "getSocketFactory"));
}
});
/* external/apache-http/src/org/apache/http/conn/ssl/SSLSocketFactory.java */
/* public static SSLSocketFactory getSocketFactory() */
findAndHookMethod("org.apache.http.conn.ssl.SSLSocketFactory", lpparam.classLoader, "getSocketFactory", new XC_MethodReplacement() {
@Override
protected Object replaceHookedMethod(MethodHookParam param) throws Throwable {
return new TrustManager[]{new ImSureItsLegitTrustManager()};
return (SSLSocketFactory)newInstance(SSLSocketFactory.class);
}
});
findAndHookMethod("javax.net.ssl.SSLContext", lpparam.classLoader, "init", KeyManager[].class, TrustManager[].class, SecureRandom.class, new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
param.args[0] = null;
param.args[1] = new TrustManager[]{new ImSureItsLegitTrustManager()};
param.args[2] = null;
}
});
findAndHookMethod("javax.net.ssl.HttpsURLConnection", lpparam.classLoader, "setSSLSocketFactory", SSLSocketFactory.class, new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
super.beforeHookedMethod(param);
SSLContext context = SSLContext.getInstance("TLS");
context.init(null, new TrustManager[]{new ImSureItsLegitTrustManager()}, null);
param.args[0] = context.getSocketFactory();
}
});
/* external/apache-http/src/org/apache/http/conn/ssl/SSLSocketFactory.java */
/* public boolean isSecure(Socket) */
findAndHookMethod("org.apache.http.conn.ssl.SSLSocketFactory", lpparam.classLoader, "isSecure", Socket.class, new XC_MethodReplacement() {
@Override
protected Object replaceHookedMethod(MethodHookParam param) throws Throwable {
@@ -59,32 +136,134 @@ public class Main implements IXposedHookLoadPackage {
}
});
findAndHookMethod("javax.net.ssl.HttpsURLConnection", lpparam.classLoader, "setHostnameVerifier", HostnameVerifier.class, new XC_MethodHook() {
/* JSSE Hooks */
/* libcore/luni/src/main/java/javax/net/ssl/TrustManagerFactory.java */
/* public final TrustManager[] getTrustManager() */
findAndHookMethod("javax.net.ssl.TrustManagerFactory", lpparam.classLoader, "getTrustManagers", new XC_MethodReplacement() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
param.args[0] = org.apache.http.conn.ssl.SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER;
protected Object replaceHookedMethod(MethodHookParam param) throws Throwable {
return new TrustManager[]{new ImSureItsLegitTrustManager()};
}
});
findAndHookMethod("javax.net.ssl.HttpsURLConnection", lpparam.classLoader, "setDefaultHostnameVerifier", HostnameVerifier.class, new XC_MethodHook() {
/* libcore/luni/src/main/java/javax/net/ssl/HttpsURLConnection.java */
/* public void setDefaultHostnameVerifier(HostnameVerifier) */
findAndHookMethod("javax.net.ssl.HttpsURLConnection", lpparam.classLoader, "setDefaultHostnameVerifier",
HostnameVerifier.class, new XC_MethodReplacement() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
param.args[0] = org.apache.http.conn.ssl.SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER;
protected Object replaceHookedMethod(MethodHookParam param) throws Throwable {
return null;
}
});
// Trick for WebViews
findAndHookMethod("android.webkit.WebViewClient", lpparam.classLoader, "onReceivedSslError", HostnameVerifier.class, new XC_MethodReplacement() {
/* libcore/luni/src/main/java/javax/net/ssl/HttpsURLConnection.java */
/* public void setSSLSocketFactory(SSLSocketFactory) */
findAndHookMethod("javax.net.ssl.HttpsURLConnection", lpparam.classLoader, "setSSLSocketFactory", SSLSocketFactory.class,
new XC_MethodReplacement() {
@Override
protected Object replaceHookedMethod(MethodHookParam param) throws Throwable {
return null;
}
});
/* libcore/luni/src/main/java/javax/net/ssl/HttpsURLConnection.java */
/* public void setHostnameVerifier(HostNameVerifier) */
findAndHookMethod("javax.net.ssl.HttpsURLConnection", lpparam.classLoader, "setHostnameVerifier", HostnameVerifier.class,
new XC_MethodReplacement() {
@Override
protected Object replaceHookedMethod(MethodHookParam param) throws Throwable {
return null;
}
});
/* WebView Hooks */
/* frameworks/base/core/java/android/webkit/WebViewClient.java */
/* public void onReceivedSslError(Webview, SslErrorHandler, SslError) */
findAndHookMethod("android.webkit.WebViewClient", lpparam.classLoader, "onReceivedSslError",
WebView.class, SslErrorHandler.class, SslError.class, new XC_MethodReplacement() {
@Override
protected Object replaceHookedMethod(MethodHookParam param) throws Throwable {
((android.webkit.SslErrorHandler)param.args[1]).proceed();
return null;
}
});
findAndHookMethod("android.webkit.WebViewClient", lpparam.classLoader, "onReceivedError", HostnameVerifier.class,new XC_MethodReplacement() {
/* frameworks/base/core/java/android/webkit/WebViewClient.java */
/* public voidonReceivedError(WebView, int, String, String) */
findAndHookMethod("android.webkit.WebViewClient", lpparam.classLoader, "onReceivedError",
WebView.class, Integer.class, String.class, String.class, new XC_MethodReplacement() {
@Override
protected Object replaceHookedMethod(MethodHookParam param) throws Throwable {
return null;
}
});
} // End Hooks
/* Helpers */
//Create a SingleClientConnManager that trusts everyone!
public ClientConnectionManager getSCCM() {
KeyStore trustStore;
try {
trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
trustStore.load(null, null);
SSLSocketFactory sf = new TrustAllSSLSocketFactory(trustStore);
sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
SchemeRegistry registry = new SchemeRegistry();
registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
registry.register(new Scheme("https", sf, 443));
ClientConnectionManager ccm = new SingleClientConnManager(null, registry);
return ccm;
} catch (Exception e) {
return null;
}
}
//This function creates a ThreadSafeClientConnManager that trusts everyone!
public ClientConnectionManager getTSCCM(HttpParams params) {
KeyStore trustStore;
try {
trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
trustStore.load(null, null);
SSLSocketFactory sf = new TrustAllSSLSocketFactory(trustStore);
sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
SchemeRegistry registry = new SchemeRegistry();
registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
registry.register(new Scheme("https", sf, 443));
ClientConnectionManager ccm = new ThreadSafeClientConnManager(params, registry);
return ccm;
} catch (Exception e) {
return null;
}
}
//This function determines what object we are dealing with.
public ClientConnectionManager getCCM(Object o, HttpParams params) {
String className = o.getClass().getSimpleName();
if (className.equals("SingleClientConnManager")) {
return getSCCM();
}
else if (className.equals("ThreadSafeClientConnManager")) {
return getTSCCM(params);
}
return null;
}
class ImSureItsLegitTrustManager implements X509TrustManager {
@@ -97,4 +276,40 @@ public class Main implements IXposedHookLoadPackage {
return new X509Certificate[0];
}
}
/* This class creates a SSLSocket that trusts everyone. */
public class TrustAllSSLSocketFactory extends SSLSocketFactory {
SSLContext sslContext = SSLContext.getInstance("TLS");
public TrustAllSSLSocketFactory(KeyStore truststore) throws
NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException {
super(truststore);
TrustManager tm = new X509TrustManager() {
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
}
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
}
public X509Certificate[] getAcceptedIssuers() {
return null;
}
};
sslContext.init(null, new TrustManager[] { tm }, null);
}
@Override
public Socket createSocket(Socket socket, String host, int port, boolean autoClose) throws IOException, UnknownHostException {
return sslContext.getSocketFactory().createSocket(socket, host, port, autoClose);
}
@Override
public Socket createSocket() throws IOException {
return sslContext.getSocketFactory().createSocket();
}
}
}