Frida Tutorial 3

Reading time: 5 minutes

tip

AWS 해킹 배우기 및 연습하기:HackTricks Training AWS Red Team Expert (ARTE)
GCP 해킹 배우기 및 연습하기: HackTricks Training GCP Red Team Expert (GRTE) Azure 해킹 배우기 및 연습하기: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks 지원하기

이 포스트의 요약: https://joshspicer.com/android-frida-1
APK: https://github.com/OWASP/owasp-mstg/blob/master/Crackmes/Android/Level_01/UnCrackable-Level1.apk

Solution 1

https://joshspicer.com/android-frida-1을 기반으로

_exit()_ 함수를 후킹하고 decrypt function을 사용하여 verify를 누를 때 flag를 frida 콘솔에 출력하도록 하세요:

javascript
Java.perform(function () {
send("Starting hooks OWASP uncrackable1...")

function getString(data) {
var ret = ""
for (var i = 0; i < data.length; i++) {
ret += "#" + data[i].toString()
}
return ret
}

var aes_decrypt = Java.use("sg.vantagepoint.a.a")
aes_decrypt.a.overload("[B", "[B").implementation = function (var_0, var_1) {
send(
"sg.vantagepoint.a.a.a([B[B)[B   doFinal(enc)  // AES/ECB/PKCS7Padding"
)
send("Key       : " + getString(var_0))
send("Encrypted : " + getString(var_1))
var ret = this.a.overload("[B", "[B").call(this, var_0, var_1)
send("Decrypted : " + getString(ret))

var flag = ""
for (var i = 0; i < ret.length; i++) {
flag += String.fromCharCode(ret[i])
}
send("Decrypted flag: " + flag)
return ret //[B
}

var sysexit = Java.use("java.lang.System")
sysexit.exit.overload("int").implementation = function (var_0) {
send("java.lang.System.exit(I)V  // We avoid exiting the application  :)")
}

send("Hooks installed.")
})

Solution 2

Based in https://joshspicer.com/android-frida-1

루트 체크를 후킹하고 decrypt 함수를 수정하여 verify를 누를 때 frida 콘솔에 플래그를 출력하게 하세요:

javascript
Java.perform(function () {
send("Starting hooks OWASP uncrackable1...")

function getString(data) {
var ret = ""
for (var i = 0; i < data.length; i++) {
ret += "#" + data[i].toString()
}
return ret
}

var aes_decrypt = Java.use("sg.vantagepoint.a.a")
aes_decrypt.a.overload("[B", "[B").implementation = function (var_0, var_1) {
send(
"sg.vantagepoint.a.a.a([B[B)[B   doFinal(enc)  // AES/ECB/PKCS7Padding"
)
send("Key       : " + getString(var_0))
send("Encrypted : " + getString(var_1))
var ret = this.a.overload("[B", "[B").call(this, var_0, var_1)
send("Decrypted : " + getString(ret))

var flag = ""
for (var i = 0; i < ret.length; i++) {
flag += String.fromCharCode(ret[i])
}
send("Decrypted flag: " + flag)
return ret //[B
}

var rootcheck1 = Java.use("sg.vantagepoint.a.c")
rootcheck1.a.overload().implementation = function () {
send("sg.vantagepoint.a.c.a()Z   Root check 1 HIT!  su.exists()")
return false
}

var rootcheck2 = Java.use("sg.vantagepoint.a.c")
rootcheck2.b.overload().implementation = function () {
send("sg.vantagepoint.a.c.b()Z  Root check 2 HIT!  test-keys")
return false
}

var rootcheck3 = Java.use("sg.vantagepoint.a.c")
rootcheck3.c.overload().implementation = function () {
send("sg.vantagepoint.a.c.c()Z  Root check 3 HIT!  Root packages")
return false
}

var debugcheck = Java.use("sg.vantagepoint.a.b")
debugcheck.a.overload("android.content.Context").implementation = function (
var_0
) {
send("sg.vantagepoint.a.b.a(Landroid/content/Context;)Z  Debug check HIT! ")
return false
}

send("Hooks installed.")
})

Solution 3 – frida-trace (Frida ≥ 16)

손으로 훅을 작성하고 싶지 않다면 Frida가 Java 스텁을 생성하도록 하고, 그 후에 수정할 수 있습니다:

bash
# Spawn the application and automatically trace the Java method we care about
aadb shell "am force-stop owasp.mstg.uncrackable1"
frida-trace -U -f owasp.mstg.uncrackable1 \
-j 'sg.vantagepoint.a.a.a("[B","[B")[B' \
-j 'sg.vantagepoint.a.c!*' \
--output ./trace

# The first run will create ./trace/scripts/sg/vantagepoint/a/a/a__B_B_B.js
# Edit that file and add the logic that prints the decrypted flag or
# returns a constant for the root-checks, then:
frida -U -f owasp.mstg.uncrackable1 -l ./trace/_loader.js --no-pause

Frida 16+에서는 생성된 스텁이 이미 현대적인 ES6 템플릿 구문을 사용하며 내장된 QuickJS 런타임으로 컴파일됩니다 – 더 이상 frida-compile이 필요하지 않습니다.


Solution 4 – One-liner with Objection (2024)

Objection >1.12가 설치되어 있다면 단일 명령어로 플래그를 덤프할 수 있습니다 (Objection은 내부적으로 Frida를 래핑합니다):

bash
objection -g owasp.mstg.uncrackable1 explore \
--startup-command "android hooking watch class sg.vantagepoint.a.a method a \n  && android hooking set return_value false sg.vantagepoint.a.c * \n  && android hooking invoke sg.vantagepoint.a.a a '[B' '[B'"
  • watch class는 AES 루틴에서 반환된 평문을 출력합니다.
  • set return_value false는 모든 루트 / 디버거 검사가 false를 보고하도록 강제합니다.
  • invokeVerify를 누르지 않고 메서드를 직접 호출할 수 있게 해줍니다.

NOTE: Android 14 (API 34)에서는 seccomp-bpf 제한으로 인해 attach가 차단되므로 Objection/Frida를 spawn 모드(-f)로 실행해야 합니다.


현대 Android 노트 (2023 - 2025)

  • libsu 5.xZygisksu를 꽤 잘 숨기지만, Level 1의 Java 기반 검사는 /system/bin/su 파일이 존재하면 여전히 실패합니다. denylist를 활성화하거나 Frida로 java.io.File.exists()를 훅킹해야 합니다.
  • Frida 16.1은 Google의 Scudo 할당기로 인해 발생한 Android 12/13의 충돌을 수정했습니다. Abort message: 'missing SHADOW_OFFSET'가 표시되면 Frida를 업그레이드하거나 미리 빌드된 17.0 야간 버전을 사용하세요.
  • Play Integrity가 2023년에 SafetyNet을 대체했기 때문에 일부 최신 앱은 com.google.android.gms.tasks.Task API를 호출합니다. Level 1은 그렇지 않지만, 여기서 보여준 동일한 훅킹 전략이 작동합니다 – com.google.android.gms.safetynet.SafetyNetClient를 훅킹하고 위조된 EvaluationType을 반환하세요.

References

  • Frida 릴리스 발표 – "Frida 16.0 (2023-04-02): Android 12/13 안정성 수정 및 spawn API 개편"
  • Objection 1.12 – "Android 14를 위한 Spawn-only 모드" (BlackHat USA 2024 발표 슬라이드)

tip

AWS 해킹 배우기 및 연습하기:HackTricks Training AWS Red Team Expert (ARTE)
GCP 해킹 배우기 및 연습하기: HackTricks Training GCP Red Team Expert (GRTE) Azure 해킹 배우기 및 연습하기: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks 지원하기