Frida Tutorial 3

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 ์ฝ˜์†”์— ์ถœ๋ ฅํ•˜๋„๋ก ํ•˜์„ธ์š”:

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 ์ฝ˜์†”์— ํ”Œ๋ž˜๊ทธ๋ฅผ ์ถœ๋ ฅํ•˜๊ฒŒ ํ•˜์„ธ์š”:

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 ์Šคํ…์„ ์ƒ์„ฑํ•˜๋„๋ก ํ•˜๊ณ , ๊ทธ ํ›„์— ์ˆ˜์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:

# 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๋ฅผ ๋ž˜ํ•‘ํ•ฉ๋‹ˆ๋‹ค):

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๋ฅผ ๋ณด๊ณ ํ•˜๋„๋ก ๊ฐ•์ œํ•ฉ๋‹ˆ๋‹ค.
  • invoke๋Š” Verify๋ฅผ ๋ˆ„๋ฅด์ง€ ์•Š๊ณ  ๋ฉ”์„œ๋“œ๋ฅผ ์ง์ ‘ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค๋‹ˆ๋‹ค.

NOTE: Android 14 (API 34)์—์„œ๋Š” seccomp-bpf ์ œํ•œ์œผ๋กœ ์ธํ•ด attach๊ฐ€ ์ฐจ๋‹จ๋˜๋ฏ€๋กœ Objection/Frida๋ฅผ spawn ๋ชจ๋“œ(-f)๋กœ ์‹คํ–‰ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.


ํ˜„๋Œ€ Android ๋…ธํŠธ (2023 - 2025)

  • libsu 5.x์™€ Zygisk๋Š” su๋ฅผ ๊ฝค ์ž˜ ์ˆจ๊ธฐ์ง€๋งŒ, 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 ์ง€์›ํ•˜๊ธฐ