Frida主動調用爆破密碼


Frida主動調用爆破密碼

0x00 案例下載地址

asktaosec/AndroidApplicationSecurity

0x01 案例分析

1 APP功能分析

安裝運行目標APP,經分析,該APP啟動后展現的是一個登錄界面,用戶在輸入框中輸入PIN,再點擊VERIFY PIN進行驗證,並提示驗證結果:

2 需要達到的目的

在平時的APP滲透測試過程當中,如果遇到一個登錄入口,首先想到的可能是通過抓取登錄操作向服務器傳輸的數據包,通過對數據包中的密碼字段進行爆破。但在這個案例中,遺憾的是APP並未向服務器發起網絡請求,而是通過客戶端本身對用戶的輸入進行判斷並返回正確的結果。因此,接下來就是學習如何在這種情況通過frida對密碼進行暴力破解,得到正確的返回結果。

3 反編譯分析目標APP

3.1 使用jadx反編譯目標APP

3.2 搜索特定字符串

當在app中點擊按鈕的時候,app會彈出響應的驗證結果提示:“Unfortunately,not the right PIN 😦” ,在jadx反編譯代碼中搜索字符串,目的是盡可能定位到離關鍵位置近的地方,沒有結果。

換個工具,使用androidkiller反編譯apk,並搜索提示的字符串,如下:

復制字符串資源對應的name:dialog_failure 到jadx反編譯得到的源碼中進行檢索,結果如下:


3.3 靜態代碼分析

以下為通過提示字符傳定位到的一個函數:

public void verifyPasswordClick(View view) {
        if (!Verifier.verifyPassword(this, this.txPassword.getText().toString())) {
            Toast.makeText(this, R.string.dialog_failure, 1).show();
        } else {
            showSuccessDialog();
        }
    }

閱讀代碼可知,函數的內部是一個if...else的條件判斷語句,當if條件為真時,表示我們輸入的PIN錯誤,返回驗證失敗的提示。反之,則表示驗證成功。

因此,關鍵的驗證邏輯可以判斷出應該在Verifier.verifyPassword()方法中,跟蹤此方法,查看內部實現的代碼邏輯,如下:

package org.teamsik.ahe17.qualification;

import android.content.Context;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class Verifier {
    private Verifier() {
    }

    public static boolean verifyPassword(Context context, String input) {
        if (input.length() != 4) {
            return false;
        }
        byte[] v = encodePassword(input);
        byte[] p = "09042ec2c2c08c4cbece042681caf1d13984f24a".getBytes();
        if (v.length != p.length) {
            return false;
        }
        for (int i = 0; i < v.length; i++) {
            if (v[i] != p[i]) {
                return false;
            }
        }
        return true;
    }

    private static byte[] encodePassword(String input) {
        byte[] SALT = {95, 35, 83, 73, 75, 35, 95};
        try {
            StringBuilder sb = new StringBuilder();
            sb.append((char) SALT[0]);
            sb.append((char) SALT[1]);
            for (int i = 0; i < input.length(); i++) {
                sb.append((char) input.getBytes("iso-8859-1")[i]);
                sb.append((char) SALT[i + 2]);
            }
            sb.append((char) SALT[6]);
            byte[] bArr = new byte[0];
            return SHA1(sb.toString()).getBytes("iso-8859-1");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
            return null;
        }
    }

    private static String convertToHex(byte[] data) {
        StringBuffer buf = new StringBuffer();
        for (int i = 0; i < data.length; i++) {
            int halfbyte = (data[i] >>> 4) & 15;
            int two_halfs = 0;
            while (true) {
                if (halfbyte < 0 || halfbyte > 9) {
                    buf.append((char) ((halfbyte - 10) + 97));
                } else {
                    buf.append((char) (halfbyte + 48));
                }
                halfbyte = data[i] & 15;
                int two_halfs2 = two_halfs + 1;
                if (two_halfs >= 1) {
                    break;
                }
                two_halfs = two_halfs2;
            }
        }
        return buf.toString();
    }

    private static String SHA1(String text) {
        try {
            MessageDigest md = MessageDigest.getInstance("SHA-1");
            byte[] bArr = new byte[40];
            md.update(text.getBytes("iso-8859-1"), 0, text.length());
            return convertToHex(md.digest());
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e2) {
            e2.printStackTrace();
        }
        return null;
    }
}

通過分析,我們可以知道verifyPassword的實現功能如下:

  1. 判斷PIN碼的長度是否為4位,不等於4位則驗證失敗。
  2. 將用戶輸入的4位PIN碼經encodePassword()函數轉換后與“09042ec2c2c08c4cbece042681caf1d13984f24a”進行比對,如果相同,則表示輸入正確。

0x03 Frida主動調用實現密碼爆破

既然我們知道了verifyPassword()函數的實現功能,也不難得出,當我們如果輸入正確的PIN的話,經encodePassword()處理過后得到的結果也一定是和“09042ec2c2c08c4cbece042681caf1d13984f24a”相同的字符串,因此,接下來就直接通過frida 主動調用encodePassword()來暴力破解得到結果並與“09042ec2c2c08c4cbece042681caf1d13984f24a”進行比較。

1 實現代碼

frida -U org.teamsik.ahe17.qualification.easy -l brutefroce.js
function main(){
	console.log("Entering the Script!"); /*打印日志,用來確定是否進入main函數開始執行*/
	
	Java.perform(function x(){
        console.log("Inside java perform");
        var Verifier = Java.use("org.teamsik.ahe17.qualification.Verifier");
        var stringClass = Java.use("java.lang.String");
        var p = stringClass.$new("09042ec2c2c08c4cbece042681caf1d13984f24a");
        var pSign = p.getBytes();
        for (var i = 0; i < 10000; i++){
            var v = "";
            if (i < 10){
                v = "000" + stringClass.$new(String(i));
            }else if (i>=10&&i<100) {
                v = "00" + stringClass.$new(String(i));
            }else if (i>+100&&i<1000) {
                v = "0" + stringClass.$new(String(i));
            }else{
                v = stringClass.$new(String(i));
            }

            var vSign = Verifier.encodePassword(v);

            if (parseInt(stringClass.$new(pSign))== parseInt(stringClass.$new(vSign)) ) {
                console.log("yes: " + v)
                break
            }
            console.log("not :" + v)
        }

	})

}

setImmediate(main)

2 密碼爆破效果


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM