가. Frida Python Binding 이란?
- 프로그래밍에서 "바인딩(binding)"은 특정 리소스나 기능을 서로 연결하거나 연동시키는 것을 의미한다.
- 즉, Frida Python Binding은 Python 코드로 Frida의 기능을 사용할 수 있도록 해주는 것을 뜻한다.
- Frida Script를 통해 후킹된 데이터를 Python으로 즉시 분석하는 등의 장점이 있다.
나. Binding 방법
※ 모바일 디바이스에서 프리다 서버가 동작하고 있어야 한다.
1. App 실행 후 Frida Script 실행 방법
- App이 실행중인 상태에서 스크립트를 실행하고 싶을때 사용하는 방법이다.
1-1. 코드 양식
import frida
import sys
# 패키지 이름
PACKAGE_NAME = "com.your.package.name"
# 삽입할 JavaScript 코드
jscode = """
Interceptor.attach(Module.findExportByName(null, 'target_function'), {
onEnter: function (args) {
console.log('Function called with argument: ' + args[0].toInt32());
}
});
"""
# 메시지 핸들러
def on_message(message, data):
if message['type'] == 'send':
print("[*] Message from script:", message['payload'])
elif message['type'] == 'error':
print("[!] Error in script:", message['stack'])
try:
# USB 장치에 연결
print("[*] Connecting to device...")
device = frida.get_usb_device(timeout=5)
# 실행 중인 프로세스 ID 가져오기
print(f"[*] Finding the process for package: {PACKAGE_NAME}")
processes = device.enumerate_processes()
pid = next((p.pid for p in processes if p.name == PACKAGE_NAME), None)
# 실행 중인 프로세스가 없다면 종료
if pid is None:
print(f"[!] Could not find a running process for package: {PACKAGE_NAME}")
sys.exit(1)
print(f"[*] Found process: {PACKAGE_NAME} (pid: {pid})")
# 프로세스에 세션 연결
print("[*] Attaching to the running process...")
session = device.attach(pid)
# JavaScript 코드 로드
print("[*] Creating and loading the script...")
script = session.create_script(jscode)
script.on('message', on_message) # 메시지 핸들러 설정
script.load()
# 후킹 스크립트 실행 유지, 엔터를 누를 시 종료
print("[*] Hook is running. Press Enter to exit.")
input()
except frida.ServerNotRunningError:
print("[!] Frida server is not running. Please start the Frida server on your device.")
except frida.TransportError:
print("[!] Unable to connect to the device. Check your USB connection and adb status.")
except Exception as e:
print(f"[!] Unexpected error: {e}")
1-2. 활용 예시
- 아래 예시는 OWASP UnCrackable L1 App의 Secret String을 찾기위한 코드이다.
- 'PACKAGE_NAME'은 frida-ps -Ua 명령어를 쳐서 찾는다.
- 위에서 찾은 프로세스 이름과 프리다 코드를 입력하여 실행한다.
import frida
import sys
# 패키지 이름
PACKAGE_NAME = "Uncrackable1"
# 삽입할 JavaScript 코드
jscode = """
setImmediate(function(){
Java.perform(function(){
var class_a = Java.use("sg.vantagepoint.a.a");
class_a.a.implementation = function (arg1, arg2){
var findCode = this.a(arg1, arg2);
var secret = "";
for (var i=0; i<findCode.length; i++){
secret = secret + String.fromCharCode(findCode[i]);
}
console.log("[+] SecretKey : " + secret);
return findCode;
}
})
})
"""
# 메시지 핸들러
def on_message(message, data):
if message['type'] == 'send':
print("[*] Message from script:", message['payload'])
elif message['type'] == 'error':
print("[!] Error in script:", message['stack'])
try:
# USB 장치에 연결
print("[*] Connecting to device...")
device = frida.get_usb_device(timeout=5)
# 실행 중인 프로세스 ID 가져오기
print(f"[*] Finding the process for package: {PACKAGE_NAME}")
processes = device.enumerate_processes()
pid = next((p.pid for p in processes if p.name == PACKAGE_NAME), None)
# 실행 중인 프로세스가 없다면 종료
if pid is None:
print(f"[!] Could not find a running process for package: {PACKAGE_NAME}")
sys.exit(1)
print(f"[*] Found process: {PACKAGE_NAME} (pid: {pid})")
# 프로세스에 세션 연결
print("[*] Attaching to the running process...")
session = device.attach(pid)
# JavaScript 코드 로드
print("[*] Creating and loading the script...")
script = session.create_script(jscode)
script.on('message', on_message) # 메시지 핸들러 설정
script.load()
# 후킹 스크립트 실행 유지, 엔터 입력시 종료
print("[*] Hook is running. Press Enter to exit.")
input()
except frida.ServerNotRunningError:
print("[!] Frida server is not running. Please start the Frida server on your device.")
except frida.TransportError:
print("[!] Unable to connect to the device. Check your USB connection and adb status.")
except Exception as e:
print(f"[!] Unexpected error: {e}")
- 아래와 같은 실행결과가 출력된다.
2. App 실행 전 Frida Script 실행 방법
- 보안 기능을 우회하여야 App을 실행할 수 있을때 사용하는 방법이다.
2-1. 코드 양식
import frida
import sys
import time
# 패키지 이름 설정
PACKAGE_NAME = "com.your.package.name"
# 삽입할 JavaScript 코드
jscode = """
javascript_code
"""
# 메시지 콜백 함수 정의
def on_message(message, data):
if message['type'] == 'send':
print("[*] Message from script:", message['payload'])
elif message['type'] == 'error':
print("[!] Error in script:", message['stack'])
try:
# USB 장치 연결
print("[*] Connecting to device...")
device = frida.get_usb_device(timeout=5)
# 프로세스 생성 및 일시 정지
print(f"[*] Spawning process for package: {PACKAGE_NAME}")
pid = device.spawn([PACKAGE_NAME])
# 프로세스에 세션 연결
print("[*] Attaching to the spawned process...")
session = device.attach(pid)
# JavaScript 코드 로드
print("[*] Creating and loading the script...")
script = session.create_script(jscode)
script.on('message', on_message) # 메시지 핸들러 설정
script.load()
# JavaScript 코드가 로드될때까지 대기
print("[*] Waiting for the script to load...")
time.sleep(1)
# 프로세스 실행 재개
print("[*] Resuming the process...")
device.resume(pid)
# 후킹 스크립트 실행 유지
print("[*] Hook is running. Press Enter to exit.")
input()
except frida.ServerNotRunningError:
print("[!] Frida server is not running. Please start the Frida server on your device.")
except frida.TransportError:
print("[!] Unable to connect to the device. Check your USB connection and adb status.")
except Exception as e:
print(f"[!] Unexpected error: {e}")
2-2. 활용 예시
- 아래는 OWASP UnCrackable L1 App의 Rooting 탐지 우회 기능을 수행하기 위한 코드이다.
import frida
import sys
import time
# 패키지 이름 설정
PACKAGE_NAME = "owasp.mstg.uncrackable1"
# 삽입할 JavaScript 코드
jscode = """
setImmediate(function(){
if (Java.available) {
Java.perform(function () {
try {
var c_class = Java.use("sg.vantagepoint.a.c");
c_class.a.implementation = function () {
console.log("[+] 루팅탐지 a 메소드 반환값 FALSE로 변조 완료");
return false;
}
c_class.b.implementation = function () {
console.log("[+] 루팅탐지 b 메소드 반환값 FALSE로 변조 완료");
return false;
};
c_class.c.implementation = function () {
console.log("[+] 루팅탐지 b 메소드 반환값 FALSE로 변조 완료");
return false;
};
var b_class = Java.use("sg.vantagepoint.a.b");
b_class.a.implementation = function (context) {
console.log("[+] 디버그 탐지 a 메소드 반환값 FALSE로 변조 완료");
return false;
};
}
catch (error) {
console.log("[-] 아래와 같은 오류가 발생함");
console.log(string(error.stack));
}
});
}
else {
console.log("[-] Java가 활성화되지 않음");
}
})
"""
# 메시지 콜백 함수 정의
def on_message(message, data):
if message['type'] == 'send':
print("[*] Message from script:", message['payload'])
elif message['type'] == 'error':
print("[!] Error in script:", message['stack'])
try:
# USB 장치 연결
print("[*] Connecting to device...")
device = frida.get_usb_device(timeout=5)
# 프로세스 생성 및 일시 정지
print(f"[*] Spawning process for package: {PACKAGE_NAME}")
pid = device.spawn([PACKAGE_NAME])
# 프로세스에 세션 연결
print("[*] Attaching to the spawned process...")
session = device.attach(pid)
# JavaScript 코드 로드
print("[*] Creating and loading the script...")
script = session.create_script(jscode)
script.on('message', on_message) # 메시지 핸들러 설정
script.load()
# JavaScript 코드가 로드될때까지 대기
print("[*] Waiting for the script to load...")
time.sleep(1)
# 프로세스 실행 재개
print("[*] Resuming the process...")
device.resume(pid)
# 후킹 스크립트 실행 유지
print("[*] Hook is running. Press Enter to exit.")
input()
except frida.ServerNotRunningError:
print("[!] Frida server is not running. Please start the Frida server on your device.")
except frida.TransportError:
print("[!] Unable to connect to the device. Check your USB connection and adb status.")
except Exception as e:
print(f"[!] Unexpected error: {e}")
- 실행 결과
'Mobile App 취약점 진단 · 모의해킹 > AOS App 취약점 진단 · 모의해킹' 카테고리의 다른 글
Android UnCrackable Level 3 문제풀이 (0) | 2025.01.01 |
---|---|
[AOS 취약점 진단] 05강 - 하드코딩된 중요정보 확인(실습 4) (0) | 2024.07.16 |
Android UnCrackable Level 2 문제풀이 (0) | 2024.03.02 |
Android UnCrackable Level 1 문제풀이 (0) | 2024.02.25 |
[AOS 취약점 진단] 16강 - 루팅 탐지 우회 취약점 점검 (0) | 2024.02.25 |