Und3r__Score__

_Frida Hooking Script 04_ 무결성 검증 우회 본문

취약점진단/Mobile (Android, iOS)

_Frida Hooking Script 04_ 무결성 검증 우회

_underscore_ 2024. 2. 21. 11:24

(in Android)

classes.dex 파일을 이용하여 무결성 검증을 수행하는 진단 대상 애플리케이션이 있어 우회하기 위해 제작한 후킹 스크립트입니다. 애플리케이션에서 java.util.zip.ZipEntry를 이용하여 classes.dex 파일들을 확인하고, 해당 파일들의 hash digest 값을 비교하여 무결성을 검증하고 있었습니다.

 

java.security.MessageDigest digest()를 후킹하여 classes.dex 파일들의 hash digest 값들을 확인하고, 문자열 비교에 사용되는strcmp 함수 return 값을 변조하여 검증 로직을 우회하는 스크립트입니다.

import frida
import time
import sys
    
def main():
	
    jscode = """
		/* classes.dex files digest */
		/* 원본 classes.dex digest
		classes.dex : bce6c0faac948d78fcfbfe69f5e2qwer
		classes2.dex : 381c62b1c16dea3659cb3143ac2dqwer
		classes3.dex : dc520119264a046bf35be2b7b2baqwer
		classes4.dex : c0512da813e66a65df3a9a5c8f2bqwer
		*/
		/* 변조 classes.dex digest
		classes.dex : dda8da7d10a2b292b6f00a617a8ca192
		*/
		
		var md5 = Java.use("java.security.MessageDigest");
		md5.digest.overload().implementation = function(){
			var ret = this.digest();
			
			var buffer = Java.array('byte',ret);
			var resultStr = "0x";
			for(var i = 0; i < 16; ++i){
				 var nn = buffer[i];
				 if (nn < 0)
				 {
					 //nn = 0xFFFFFFFF + nn + 1;
					 nn = (nn)>>>0;
					 nn = nn.toString(16).toUpperCase().substr(-2,2);
				 }
				 else if (nn < 16){
					nn = '0' + nn.toString(16).toUpperCase();
				 }
				 else{
					nn = nn.toString(16).toUpperCase();
				 }
				 resultStr+= nn;
			}
			
			console.log("[classes.dex digest] Digest : " + resultStr);
			
			return ret;
		}
		
		var flagDexHash = Boolean(0);
			
		//strcmp
		Interceptor.attach(Module.findExportByName(null, "strcmp"), {
			onEnter: function (args) {
				var str1 = Memory.readUtf8String(args[0]);
				var str2 = Memory.readUtf8String(args[1]);
				
				if(str2 == "dda8da7d10a2b292b6f00a617a8ca192"){
					console.log("[strcmp][+](" + str1 + "," + str2 + ")");
					flagDexHash = Boolean(1);
				}				
			},
			onLeave: function(retval) {
				
				if(this.flagDexHash){
					retval.replace(0);
					console.log("[strcmp][-] Compare dex hash");
					flagDexHash = Boolean(0);
				}
				
				return retval;
			}
			
		});
    """ 

    device = frida.get_device_manager().enumerate_devices()[-1]
    pid = device.spawn([pkgNm])
    session = device.attach(pid)
    script = session.create_script(jscode)
	time.sleep(3)
	script.load()
	print("[*] Start Script")
	sys.stdin.read()

if __name__ == "__main__":
    main()