Hook Android Java Encryption with Frida: Self‑Exfiltration Techniques Explained

This tutorial demonstrates how to use Frida to hook Java‑level encryption functions in Android apps, covering preparation utilities, self‑exfiltration of MD5, SHA1, MAC, DES/AES/RSA, and signature algorithms with detailed code snippets and visual examples.

Python Crawling & Data Mining
Python Crawling & Data Mining
Python Crawling & Data Mining
Hook Android Java Encryption with Frida: Self‑Exfiltration Techniques Explained

Preface

Hello, I am "Code Farmer Saturday". This tutorial is for learning and discussion only; using the techniques for illegal activities is prohibited.

Preparation

Define helper functions for printing stack traces and converting data to Base64, Hex, and UTF‑8 formats.

function showStacks() { /* print stack trace */ }
function toBase64(tag, data) { console.log(tag + " Base64: ", ByteString.of(data).base64()); }
function toHex(tag, data) { console.log(tag + " Hex: ", ByteString.of(data).hex()); }
function toUtf8(tag, data) { console.log(tag + " Utf8: ", ByteString.of(data).utf8()); }

What Is Self‑Exfiltration?

When an Android app invokes Java‑level encryption methods (e.g., MessageDigest for MD5), the data passes through those methods, making it possible to hook them and capture the plaintext and ciphertext.

Self‑exfil concept
Self‑exfil concept

MD5 and SHA1 Self‑Exfil

Both MD5 and SHA1 follow the same workflow; only the algorithm name differs, so a single hook can handle both.

MD5 flow
MD5 flow
SHA1 flow
SHA1 flow

Hook the update and digest methods to capture input data and resulting hash. update receives the data to be hashed. digest returns the hash result.

Code

var messageDigest = Java.use("java.security.MessageDigest");
messageDigest.update.overload('byte').implementation = function(data) {
    console.log("MessageDigest.update('byte') is called!");
    showStacks();
    return this.update(data);
};
messageDigest.update.overload('java.nio.ByteBuffer').implementation = function(data) {
    console.log("MessageDigest.update('java.nio.ByteBuffer') is called!");
    showStacks();
    return this.update(data);
};
messageDigest.update.overload('[B').implementation = function(data) {
    var algorithm = this.getAlgorithm();
    var tag = algorithm + " update data";
    toUtf8(tag, data);
    toHex(tag, data);
    toBase64(tag, data);
    showStacks();
    return this.update(data);
};
messageDigest.digest.overload().implementation = function() {
    console.log("MessageDigest.digest() is called!");
    var result = this.digest();
    var algorithm = this.getAlgorithm();
    var tag = algorithm + " digest result";
    toHex(tag, result);
    toBase64(tag, result);
    showStacks();
    return result;
};
/* Additional overloads for byte[], int, int omitted for brevity */

MAC Self‑Exfil

MAC encryption requires a key; the update method feeds data, and doFinal produces the MAC.

Hook init, update, and doFinal to capture key material and processed data.

MAC flow
MAC flow

Code

var mac = Java.use("javax.crypto.Mac");
mac.init.overload('java.security.Key', 'java.security.spec.AlgorithmParameterSpec').implementation = function(key, spec) {
    console.log("Mac.init(Key, AlgorithmParameterSpec) is called!");
    showStacks();
    return this.init(key, spec);
};
mac.update.overload('byte').implementation = function(data) {
    console.log("Mac.update('byte') is called!");
    showStacks();
    return this.update(data);
};
mac.doFinal.overload().implementation = function() {
    console.log("Mac.doFinal() is called!");
    var result = this.doFinal();
    var algorithm = this.getAlgorithm();
    var tag = algorithm + " doFinal result";
    toHex(tag, result);
    toBase64(tag, result);
    showStacks();
    return result;
};
/* Additional overloads omitted for brevity */

DES/DESede/AES/RSA Hooking

These algorithms are instantiated via Cipher. Hook the init, update, and doFinal methods to capture keys, IVs, and ciphertext.

Cipher flow
Cipher flow

Code

var cipher = Java.use("javax.crypto.Cipher");
cipher.init.overload('int', 'java.security.Key').implementation = function(mode, key) {
    console.log("Cipher.init(int, Key) is called!");
    var algorithm = this.getAlgorithm();
    var tag = algorithm + " init Key";
    var keyBytes = key.getEncoded();
    toUtf8(tag, keyBytes);
    toHex(tag, keyBytes);
    toBase64(tag, keyBytes);
    showStacks();
    return this.init(mode, key);
};
cipher.doFinal.overload('[B').implementation = function(data) {
    console.log("Cipher.doFinal('[B') is called!");
    var algorithm = this.getAlgorithm();
    var tag = algorithm + " doFinal data";
    toUtf8(tag, data);
    toHex(tag, data);
    toBase64(tag, data);
    var result = this.doFinal(data);
    var resTag = algorithm + " doFinal result";
    toHex(resTag, result);
    toBase64(resTag, result);
    showStacks();
    return result;
};
/* Additional overloads for ByteBuffer, int offsets, etc., omitted */

Signature Algorithm Hooking

Signature uses update to feed data and sign to produce the signature. Hook both to capture the data flow.

Code

var signature = Java.use("java.security.Signature");
signature.update.overload('byte').implementation = function(data) {
    console.log("Signature.update('byte') is called!");
    showStacks();
    return this.update(data);
};
signature.sign.overload().implementation = function() {
    console.log("Signature.sign() is called!");
    var result = this.sign();
    var algorithm = this.getAlgorithm();
    var tag = algorithm + " sign result";
    toHex(tag, result);
    toBase64(tag, result);
    showStacks();
    return result;
};
/* Overloads with byte[] parameters omitted for brevity */

Practical Result

When any Java‑level encryption method is used in the target APK, the above hooks will log input data, keys, IVs, and output ciphertext or MAC, making reverse‑engineering much easier.

Hook output example
Hook output example

Conclusion

Self‑exfiltration is a helpful auxiliary tool for security analysis; it simply logs data and stack traces to aid debugging. Use responsibly and remember that the technique is only a part of a broader analysis workflow.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

JavaAndroidsecurityEncryptionHookingFrida
Python Crawling & Data Mining
Written by

Python Crawling & Data Mining

Life's short, I code in Python. This channel shares Python web crawling, data mining, analysis, processing, visualization, automated testing, DevOps, big data, AI, cloud computing, machine learning tools, resources, news, technical articles, tutorial videos and learning materials. Join us!

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.