java - Searching for SessionID, SessionKey in a HTTPS Session -


i trying find solution getting sessionid , more important sessionkey. found solution based on java:

http://jsslkeylog.sourceforge.net

it using following class log rsa-sessionkey:

/**  * transformer transform <tt>rsaclientkeyexchange</tt> ,  * <tt>premastersecret</tt> classes log <tt>rsa</tt> values.  */ public class rsaclientkeyexchangetransformer extends abstracttransformer {  public rsaclientkeyexchangetransformer(string classname) {     super(classname, "<init>"); }  @override protected void visitendofmethod(methodvisitor mv, string desc) {     string premastertype = "ljavax/crypto/secretkey;";     if (classname.endswith("/premastersecret")) {         premastertype = "[b";     }     mv.visitvarinsn(aload, 0);     mv.visitfieldinsn(getfield, classname, "encrypted", "[b");     mv.visitvarinsn(aload, 0);     mv.visitfieldinsn(getfield, classname, "premaster", premastertype);     mv.visitmethodinsn(invokestatic, classname, "$logwriter$logrsa", "([b" + premastertype + ")v"); } } 

in android application using defaulthttpclient (org.apache.http.impl.client) establish https connection. connection trying find sessionkey. has idea if it´s possible read out key using android / java method? if not, know key- generation implemented?

i don't believe can done via public api. can session id there no public interface obtain key.

however, able use combination of reflection , native code access underlying openssl struct, contain both session id , master key. possible not @ safe hidden member , libraries not guaranteed remain same. in fact, looks struct layout has changed on openssl master branch parsing code below need updating if/when pulled android.

i used url.openconnection() instead of defaulthttpclient making https connection latter deprecated. here's class calls url.openconnection() , replaces default sslsocketfactory (nothing interesting here):

public class myconnection implements runnable {    @override    public void run() {       try {          // create connection.          url url = new url("https://www.google.com");          httpsurlconnection urlconnection = (httpsurlconnection) url.openconnection();           // replace default sslsocketfactory our own.          mysslsocketfactory sslsocketfactory = new mysslsocketfactory();          urlconnection.setsslsocketfactory(sslsocketfactory);           // establish tls connection.          int statuscode = urlconnection.getresponsecode();          log.i("myconnection", string.format("status %d", statuscode));           // ssl details captured socket.          sslsocketfactory.getsessioninfo();        } catch (illegalaccessexception e) {          e.printstacktrace();       } catch (nosuchfieldexception e) {          e.printstacktrace();       } catch (ioexception e) {          e.printstacktrace();        }    } } 

here custom sslsocketfactory, of magic is. forward overridden methods real sslsocketfactory, caching sslsocket instance gets created. there 2 new (non-overridden) methods - native method shown further below , getsessioninfo() uses reflection on sslsocket native openssl ssl_session_st pointer , parses (and logs) fields of interest. note session id using supported sslsession.getid(); it's getting key requires being sneaky.

// use decorator pattern capture ssl socket default sslsocketfactory. class mysslsocketfactory extends sslsocketfactory {    // load ndk shared library.    static {       system.loadlibrary("my_native_helper");    }     // overridden methods forwarded real sslsocketfactory.    // addition sslsocket returned createsocket()    // cached.    sslsocketfactory realfactory_ = httpsurlconnection.getdefaultsslsocketfactory();    sslsocket s_;     // native method copies data native pointer bytebuffer.    native void readnative(long pointer, bytebuffer dst);     // use cached sslsocket access native openssl session data.    void getsessioninfo() throws nosuchfieldexception, illegalaccessexception {       // protected openssl ssl_session_st pointer. note       // not part of api , change across android versions.       // see https://android.googlesource.com/platform/external/conscrypt/+/lollipop-mr1-dev/src/main/java/org/conscrypt/opensslsessionimpl.java       sslsession session = s_.getsession();       field field = session.getclass().getdeclaredfield("sslsessionnativepointer");       field.setaccessible(true);       long sessionpointer = field.getlong(session);        // read many bytes need native pointer.       bytebuffer bytebuffer = bytebuffer.allocatedirect(104);       bytebuffer.order(byteorder.nativeorder());       readnative(sessionpointer, bytebuffer);        // parse openssl ssl_session_st. note layout of structure       // may change openssl versions , different compilers/platforms (e.g.       // 32-bit vs. 64-bit).       // see https://github.com/openssl/openssl/blob/openssl_1_0_0-stable/ssl/ssl.h#l451       intbuffer intbuffer = bytebuffer.asintbuffer();       log.i("myconnection", string.format("ssl version %04x", intbuffer.get(0)));        int master_key_length = intbuffer.get(4);       string master_key = "";       (int = 0; < master_key_length; ++i)          master_key += string.format("%02x", bytebuffer.get(20 + i));       log.i("myconnection", string.format("master key %s", master_key));        int session_id_length = intbuffer.get(17);       string session_id = "";       (int = 0; < session_id_length; ++i)          session_id += string.format("%02x", bytebuffer.get(72 + i));       log.i("myconnection", string.format("session id %s", session_id));    }     @override    public string[] getdefaultciphersuites() {       return realfactory_.getdefaultciphersuites();    }     @override    public string[] getsupportedciphersuites() {       return realfactory_.getsupportedciphersuites();    }     @override    public socket createsocket(socket s, string host, int port, boolean autoclose) throws ioexception {       s_ = (sslsocket)realfactory_.createsocket(s, host, port, autoclose);       return s_;    }     @override    public socket createsocket(string host, int port) throws ioexception {       s_ =  (sslsocket)realfactory_.createsocket(host, port);       return s_;    }     @override    public socket createsocket(string host, int port, inetaddress localhost, int localport) throws ioexception {       s_ = (sslsocket)realfactory_.createsocket(host, port, localhost, localport);       return s_;    }     @override    public socket createsocket(inetaddress host, int port) throws ioexception {       s_ =  (sslsocket)realfactory_.createsocket(host, port);       return s_;    }     @override    public socket createsocket(inetaddress address, int port, inetaddress localaddress, int localport) throws ioexception {       s_ = (sslsocket)realfactory_.createsocket(address, port, localaddress, localport);       return s_;    } } 

finally, here native c code enables reading memory bytebuffer native pointer. needs built using android ndk , loaded shown @ top of mysslsocketfactory.

#include <jni.h> #include <string.h>  jniexport void jnicall java_com_example_mysocketfactory_mysslsocketfactory_readnative(    jnienv *env, jobject o,    jlong pointer, jobject buffer) {    const char *p = (const char *)pointer;    memcpy(       (*env)->getdirectbufferaddress(env, buffer),       p,       (*env)->getdirectbuffercapacity(env, buffer)); } 

that's it. when myconnection.run() invoked on kitkat device, log shows:

i/myconnection﹕ status 200 i/myconnection﹕ ssl version 0301 i/myconnection﹕ master key 81ef39c5f8f7f796a34b307ff453511378fd081d14c37eb2e912fa829edf280e0fa7a499c370fdc156b8499758373d67 i/myconnection﹕ session id b9ee4ae0c7738909430d47e9b0d6d60420d34a17d08181f21996e55a463aa5cf 

i did make brief attempt defaulthttpclient abandoned when couldn't figure out how access default schemeregistry. think can done specifying clientconnectionmanager when constructing defaulthttpclient didn't feel pursuing deprecated path further. if want try use similar approach intercept sslsessionimpl instance handling connection. class has master_secret member native code not required, reflection (this code path not use openssl).


Comments

Popular posts from this blog

Java 3D LWJGL collision -

spring - SubProtocolWebSocketHandler - No handlers -

methods - python can't use function in submodule -