ν‹°μŠ€ν† λ¦¬ λ·°

κ°œμš”

Rootingμ΄λž€ μ•ˆλ“œλ‘œμ΄λ“œμ—μ„œ μ œν•œλ˜μ–΄ μžˆλŠ” ν•˜μœ„ μ‹œμŠ€ν…œμ— λŒ€ν•΄ μ•‘μ„ΈμŠ€ ν•  수 μžˆλ„λ‘ ν•˜λŠ” 것을 μ˜λ―Έν•˜λ©° 이λ₯Ό 톡해 μ‚¬μš©μž λ””λ°”μ΄μŠ€ λ‚΄λΆ€μ—μ„œ μ‚¬μš©ν•  수 μ—†λŠ” λ‹€μ–‘ν•œ μ‹œμŠ€ν…œ λͺ…령을 λ‚΄λ € μˆ˜μ • λ˜λŠ” μ‚­μ œκ°€ κ°€λŠ₯ν•˜λ©° 루트 κΆŒν•œμœΌλ‘œ 접근이 κ°€λŠ₯ν•œ 앱을 μ‚¬μš©ν•  μˆ˜λ„ 있게 λ©λ‹ˆλ‹€.

 

λ£¨νŒ…μ„ ν•˜κ²Œλ˜λ©΄ μžμ‹ μ˜ μ‹œμŠ€ν…œ νŒŒμΌμ— 접근이 κ°€λŠ₯ν•΄ 지기 λ•Œλ¬Έμ— μ™„λ²½ν•˜κ²Œ μ œμ–΄κ°€ κ°€λŠ₯ν•΄μ Έ λ³΄μ•ˆμƒ λ¬Έμ œκ°€ λ°œμƒν•  수 μžˆμ–΄ μ‹€μ œ 금육, 곡곡 κΈ°κ΄€μ—μ„œλŠ” λ£¨νŒ… 된 λ‹¨λ§μ—μ„œ μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ΄ μ‹€ν–‰λ˜μ§€ μ•Šλ„λ‘ μ œμ–΄ν•˜κ³  μžˆμŠ΅λ‹ˆλ‹€.

 

Rooting 탐지 방법

1. μ• ν”Œλ¦¬μΌ€μ΄μ…˜ μ‹€ν–‰ μ‹œ νŠΉμ • λͺ…λ Ήμ–΄ μ‹€ν–‰ 및 확인(SU λͺ…λ Ή 싀행확인)
2. λ£¨νŒ… 된 단말에 μ‘΄μž¬ν•˜λŠ” 파일 확인(/system/su, /system/app/Superuse.apk λ“±)
3. 주둜 μ‚¬μš©λ˜λŠ” λ£¨νŒ… κ΄€λ ¨ μ–΄ν”Œ 체크(Kingo Root, FramaRoot, One Click Root, TowelRoot λ“±)

 

λ£¨νŒ… 탐지λ₯Ό μš°νšŒν•  수 μžˆλŠ” 방법은 λͺ‡ 가지가 μ‘΄μž¬ν•˜μ§€λ§Œ μ˜€λŠ˜μ€ 그쀑 "objection"μ΄λΌλŠ” 도ꡬλ₯Ό 톡해 λ£¨νŒ… 탐지λ₯Ό μš°νšŒν•΄λ³΄λ„λ‘ ν•˜κ² μŠ΅λ‹ˆλ‹€.

 

Objection μ΄λž€

Frida 기반으둜 λ™μž‘ν•˜λŠ” Run-Time Exploration으둜 말 κ·ΈλŒ€λ‘œ λŸ°νƒ€μž„μ„ μ‘°μž‘ν•˜μ—¬ νŠΉμ • ν–‰μœ„λ₯Ό ν•  수 μžˆλ„λ‘ ν”„λ‘œμ„ΈμŠ€μ— μ£Όμž…λ˜μ–΄ 디버깅을 μˆ˜ν–‰ν•˜κ±°λ‚˜ λ™μ μœΌλ‘œ λΆ„μ„ν•˜λŠ”λ° 주둜 μ‚¬μš©λ˜λŠ” λ„κ΅¬μž…λ‹ˆλ‹€. κ³Όκ±°μ—λŠ” iOS 기반으둜만 λ™μž‘ν•˜λ„λ‘ λ˜μ–΄μžˆμ§€λ§Œ ν˜„μž¬λŠ” Android ν™˜κ²½μ—μ„œλ„ λ™μž‘ν•˜λ„λ‘ 릴리즈 λ˜μ—ˆμŠ΅λ‹ˆλ‹€.(iOS ν™˜κ²½μ΄ 더 μ•ˆμ •μ μ΄κ³  ν˜Έν™˜μ„±μ΄ λ†’μŒ)

<python3 ν™˜κ²½>
# pip install objection -> μ„€μΉ˜
# objection -> μ‹€ν–‰
Options:
  -N, --network            Connect using a network connection instead of USB.
                           [default: False]

  -h, --host TEXT          [default: 127.0.0.1]
  -p, --port INTEGER       [default: 27042]
  -ah, --api-host TEXT     [default: 127.0.0.1]
  -ap, --api-port INTEGER  [default: 8888]
  -g, --gadget TEXT        Name of the Frida Gadget/Process to connect to.
                           [default: Gadget]

  -S, --serial TEXT        A device serial to connect to.
  -d, --debug              Enable debug mode with verbose output. (Includes
                           agent source map in stack traces)

  --help                   Show this message and exit.

  Commands:
  api          Start the objection API server in headless mode.
  device-type  Get information about an attached device.
  explore      Start the objection exploration REPL.
  patchapk     Patch an APK with the frida-gadget.so.
  patchipa     Patch an IPA with the FridaGadget dylib.
  run          Run a single objection command.
  version      Prints the current version and exists.

 

nox_adb shell
cd /data/local/tmp/
/data/local/tmp # ./<ν”„λ¦¬λ‹€μ„œλ²„νŒŒμΌ> &

objection은 "frida" 기반으둜 λ™μž‘ν•˜κΈ° λ•Œλ¬Έμ— μžμ‹ μ˜ λ””λ°”μ΄μŠ€ λ‚΄λΆ€λ‘œ μ‰˜ 접근을 ν•˜μ—¬ 프리닀 μ„œλ²„λ₯Ό μ‹€ν–‰ν•˜λ„λ‘ ν•˜κ² μŠ΅λ‹ˆλ‹€.

*프리닀 μ„œλ²„ μ„€μΉ˜λ°©λ²•μ€ ν•˜λ‹¨ ν¬μŠ€νŒ… μ°Έκ³ 

guleum-zone.tistory.com/137

 

프리닀(Frida) ν™˜κ²½ ꡬ좕

κ°œμš” Fridaλž€ Oleκ°€ κ°œλ°œν•œ DBI(Dynamic Binary Instrumentation) ν”„λ ˆμž„μ›Œν¬μž…λ‹ˆλ‹€. 파이썬 κΈ°λ°˜μœΌλ‘œ λ§Œλ“€μ–΄μ§„ νˆ΄μ΄κΈ°μ— νŒŒμ΄μ¬ λΌμ΄λΈŒλŸ¬λ¦¬λ₯Ό μ£Όλ‘œ μ‚¬μš©ν•©λ‹ˆλ‹€. λ˜ν•œ μ—°κ²°λœ λ‹¨λ§μ— λŒ€ν•œ λΆ„석을 μˆ˜

guleum-zone.tistory.com

프리닀 μ„œλ²„λ₯Ό μ‹€ν–‰ν•΄μ£Όμ…¨μœΌλ‹ˆ "frida-ps -U" λͺ…λ Ήμ–΄λ₯Ό 톡해 ν”„λ‘œμ„ΈμŠ€ κ°„ 톡신이 κ°€λŠ₯ν•œμ§€ 확인해 μ£Όμ‹œλ©΄ λ©λ‹ˆλ‹€. λ£¨νŒ… 탐지λ₯Ό μš°νšŒν•  앱은 insecurebank둜 ν•˜κ² μŠ΅λ‹ˆλ‹€.

 

frida-ps -Ua -> μ•± νŒ¨ν‚€μ§€λͺ… 확인(com.android.insecurebankv2)
objection -g <νŒ¨ν‚€μ§€λͺ…> explore

프리닀 μ„œλ²„ 톡신이 κ°€λŠ₯ν•˜λ©΄ μ’€ 전에 μ„€μΉ˜ν•΄μ£Όμ…¨λ˜ objection을 톡해 insecurebank에 attach ν•΄μ£Όμ‹œλ©΄ λ©λ‹ˆλ‹€.

 

νƒˆμ˜₯을 μš°νšŒν•˜κΈ° μœ„ν•΄μ„  insecurebank의 μ†ŒμŠ€μ½”λ“œλ₯Ό 원볡 ν˜•νƒœλ‘œ 돌린 ν›„ 정적 뢄석을 μ§„ν–‰ν•˜μ—¬ 탐지 포인트λ₯Ό μ°Ύμ•„μ£Όμ…”μ•Ό λ©λ‹ˆλ‹€. μ €λŠ” insecurebank 앱을. apkν˜•νƒœλ‘œ μΆ”μΆœ -> jadxλ₯Ό μ‚¬μš©ν•˜μ—¬ 원볡 ν˜•νƒœ μ½”λ“œ ν™•μΈν•˜λ„λ‘ ν•˜κ² μŠ΅λ‹ˆλ‹€.

 

Text Search νƒ­μ—μ„œ rootλ₯Ό κ²€μƒ‰ν•˜μ—¬ rooting 탐지 κ΄€λ ¨ μ½”λ“œκ°€ μ–΄λŠ μœ„μΉ˜μ— μ‘΄μž¬ν•˜λŠ”μ§€ 확인해야 λ©λ‹ˆλ‹€.

 

PostLogin.root_status 파일의 λ‚΄μš© 쀑 "SU" κ΄€λ ¨ν•œ 탐지λ₯Ό μ§„ν–‰ν•˜μ—¬ μ‹€ν–‰λœ  단말 ν™˜κ²½μ΄ λ£¨νŒ… 단말인지 탐지λ₯Ό ν•˜κ³  μžˆμŠ΅λ‹ˆλ‹€. "doesSUexist"λ₯Ό ν΄λ¦­ν•˜μ—¬ μ—°κ΄€ λ‘œμ§μ„ μ°Ύμ•„λ³΄κ² μŠ΅λ‹ˆλ‹€.

 

λ°”λ‘œ ν•˜λ‹¨μ— Runtime.getRuntime(). execλ₯Ό 톡해 SUκ°€ μ‹€ν–‰λ˜λŠ”μ§€ μ•„λ‹Œμ§€ μ—¬λΆ€λ₯Ό νŒλ‹¨ν•˜κ³  있으며 νƒ€μž…μ€ Boolean λ°©μ‹μœΌλ‘œ True λ˜λŠ” Falseλ°˜ν™˜μ„ 톡해 ν˜λŸ¬κ°€κ³  μžˆλŠ” 것을 보싀 수 μžˆμŠ΅λ‹ˆλ‹€.

 

일반적으둜 λ£¨νŒ… 된 단말 λ‚΄λΆ€μ—λŠ” "su" λ°”μ΄λ„ˆλ¦¬ 파일이 μ‘΄μž¬ν•˜κΈ° λ•Œλ¬Έμ— 탐지에 걸리게 λ©λ‹ˆλ‹€.

 

# android hooking list class_methods <탐지 μ½”λ“œ 경둜>

첫 번째둜 objection을 μ‚¬μš©ν•˜μ—¬ λ£¨νŒ… 탐지 둜직이 μ‘΄μž¬ν•˜λŠ” νŒŒμΌμ— 훅을 κ±Έμ–΄ μ‘΄μž¬ν•˜λŠ” λ©”μ†Œλ“œλ¦¬μŠ€νŠΈλ₯Ό 좜λ ₯해보면 μœ„μ—μ„œ ν™•μΈν–ˆλ˜ "doesSUexist" λ©”μ„œλ“œκ°€ λ³΄μž…λ‹ˆλ‹€.

 

탐지 μ½”λ“œ κ²½λ‘œλŠ” μœ„μ²˜λŸΌ 파일λͺ…을 Copy ν•˜μ—¬ κ·ΈλŒ€λ‘œ λΆ™μ—¬ λ„£μ–΄ μ£Όμ‹œλ©΄ λ©λ‹ˆλ‹€.

 

# android hooking watch class_method <νŒ¨ν‚€μ§€λͺ….클래슀.λ©”μ†Œλ“œ> --dump-args

λ£¨νŒ… 된 단말이 μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ„ μ‹€ν–‰ν•  경우 "doesSUexist"의 λ°˜ν™˜ 값이 True 인지 False인지 μ—¬λΆ€λ₯Ό νŒλ‹¨ν•  수 μžˆλ‹€λ©΄ 이λ₯Ό μ‘°μž‘ν•˜μ—¬ λΉ„ λ£¨νŒ… 단말인 κ²ƒμ²˜λŸΌ ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

 

insecurebank의 앱을 λ‹€μ‹œ 재 μ‹œμž‘ν•˜μ—¬ λ°˜ν™˜ 값을 좔적해야 λ©λ‹ˆλ‹€.

 

앱을 μž¬μ‹€ν–‰ν•΄λ³Έ κ²°κ³Ό λ£¨νŒ… 된 단말일 경우 λ°˜ν™˜ 값이 TrueμΌκ±°λΌλŠ” 좔츑이 κ°€λŠ₯ν•©λ‹ˆλ‹€. 이제 이 λ°˜ν™˜ κ°’ 정보λ₯Ό μ΄μš©ν•΄ μ‘°μž‘ν•΄λ³΄κ² μŠ΅λ‹ˆλ‹€.

 

# android hooking set return_value <νŒ¨ν‚€μ§€λͺ….클래슀.λ©”μ†Œλ“œ> false

λ£¨νŒ… 단말 μΌμ‹œ false λ°˜ν™˜ 값을 좜λ ₯ν•˜λŠ” "deosSUexit" λ©”μ†Œλ“œμ— True κ°’μœΌλ‘œ λ¦¬ν„΄λ˜λ„λ‘ μ‘°μž‘μ„ ν•˜κ³  앱을 ν•œ 번 더 μž¬μ‹œμž‘ν•˜λ„λ‘ ν•˜κ² μŠ΅λ‹ˆλ‹€.

 

λ°˜ν™˜ 값을 λ¦¬ν„΄ν•˜μ—¬ μ„±κ³΅μ μœΌλ‘œ λΉ„ λ£¨νŒ… λ‹¨λ§λ‘œ μΈμ‹ν•˜κ²Œλ” μš°νšŒκ°€ κ°€λŠ₯해진 것을 λ³Ό 수 μžˆμŠ΅λ‹ˆλ‹€.

κ³΅μœ ν•˜κΈ° 링크
Comment