FRIDA 사용법

이 글은 제가 카카오톡 봇 커뮤니티에 작성했던 글을 그대로 복사한 것입니다.

개요

안녕하세요. 그동안 카페 눈팅만 하다가 드디어 글을 쓰게 된 윤입니다.

카페 에디터가 스마트 에디터 3.0으로 바뀐 이후로 처음 쓰는 글이군요.

먼저, 해당 글을 쓰게 된 배경부터 알아봅시다. 몇 분이 제 블로그를 보셨을진 모르겠지만, 저는 타 플랫폼에서 봇 시스템을 구축했습니다. WEB 버전이 존재했기 때문에 쉬웠습니다. 그러다가 하게 된 것이 모든 API의 호출이 가능한 모듈을 만들기 시작했고, 결국엔 APP 버전에서만 지원하는 동작들을 구현하기 위해 후킹을 다짐했습니다.

분명 HTTPS 통신을 하는데, 일반적인 HTTPS 스니핑 도구는 패킷을 잡지 못 하더라고요. 왜 그런진 모르겠습니다.

어떻게든 비밀스러운 이 부분을 알고 싶었기 때문에 직접 소스를 보진 못 하겠고, 훔쳐보는 방식으로라도 주고받는 파라미터들을 보기 위해서,

오늘 알아볼 것은 Frida(프리다) 입니다.

image

변태처럼 앱이 어떻게 서버로 데이터를 넣어버리는지에 대한 관음을 아주 다양한 방법으로 할 수 있게 해주는 도구죠.

아. 참고로 저는 할 수 있는게 없습니다.

APK는 보통 자바, 또는 코틀린으로 짜죠. 그래서 디컴파일을 하면 자바 코드를 볼 수 있는 게 여럿 있습니다. 물론, 전 자바로 Hello World 찍는 것 조차 힘들어합니다. 안드로이드 구조 하나도 모릅니다.

Frida 라는 툴도 지금 처음 써봅니다. 해야지 해야지 고민하면서 문서만 몇 번 본게 답니다.

프리다는 파이썬으로 만들어졌나 봅니다. pip 를 통한 설치를 지원합니다. 물론, 파이썬도 못 합니다.

다행이도, 인젝션 언어중에 자바스크립트를 지원합니다. JS는 조금 할 줄 압니다.

제 개발환경은 다음과 같습니다. VMWare 에 리눅스를 설치한 상황이죠.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
DISTRIB_ID=LinuxMint
DISTRIB_RELEASE=19.2
DISTRIB_CODENAME=tina
DISTRIB_DESCRIPTION="Linux Mint 19.2 Tina"
NAME="Linux Mint"
VERSION="19.2 (Tina)"
ID=linuxmint
ID_LIKE=ubuntu
PRETTY_NAME="Linux Mint 19.2"
VERSION_ID="19.2"
HOME_URL="https://www.linuxmint.com/"
SUPPORT_URL="https://forums.ubuntu.com/"
BUG_REPORT_URL="http://linuxmint-troubleshooting-guide.readthedocs.io/en/latest/"
PRIVACY_POLICY_URL="https://www.linuxmint.com/"
VERSION_CODENAME=tina
UBUNTU_CODENAME=bionic

그리고 안드로이드 스튜디오, AVD, ADB 를 설치한 상황입니다. 물론 스튜디오는 사용하지 않고 AVD, ADB 만 사용합니다.


💬 ADB 에 프리다 서버 설치하기

https://github.com/frida/frida/releases/

이곳에서 frida-server-{ver}-android-{platform} 압축파일을 다운받습니다.

글 작성 당시에는 frida-server-12.11.3-android-x86를 다운받았습니다.

압축을 풀고, 나온 파일을 실행중인 안드로이드 애뮬레이터의 임시 폴더로 넣을겁니다.

넣기 전에, 애뮬레이터 쉘의 권한부터 얻습니다.

1
$ adb root

한 줄이 끝입니다. 아무런 동작도 필요없이 권한을 얻었습니다.

1
2
3
$ adb push frida-server-12.11.3-android-x86 /data/local/tmp
$ adb shell
$ cd /data/local/tmp

파일을 /data/local/tmp 폴더에 넣습니다. 그리고 쉘에 접속해, 해당 폴더로 이동합니다.

1
$ chmod 777 ./frida-server-12.11.3-android-x86

파일에 실행권한을 줍니다.

1
$ ./frida-server-12.11.3-android-x86 &

서버를 백그라운드로 실행시킵니다.

제 AVD 에는 플레이스토어가 안 보였으니 직접 APK 를 가져와서 위와 같은 방식으로 파일을 넣고 설치했습니다.


📪 프리다 CLI 명령어 설치하기

우리는 특정 앱만 후킹을 할겁니다. 그렇기 때문에 여러개 살아있는 프로세스 중 하나만 가져와서 후킹을 해야 하는 것이죠. 처음부터 끝까지 패키지를 사용해 프로그래밍 하는 방법도 있지만, 굳이 편하게 갈 수 있는 길을 돌아갈 필요는 없죠.

1
$ pip install frida-tools

PIP 로 한 번에 설치할 수 있습니다.

설치했으면 명령어를 사용해서, 후킹할 프로세스 패키지 이름을 가져올 것입니다.

1
$ frida-ps -Ua

실제 배포된 앱이기 때문에, 어차피 추후 나오겠지만 일단 가렸습니다.

🌏 특정 함수가 호출되는 것을 후킹하기

이제 frida-trace 명령어를 사용할 것입니다.

모바일을 위해 코드가 아니라 사진으로 올림

1
$ frida-trace -U -i '*search*' -p 8300

위 명령어로 search 함수가 동작이 호출되는 때를 확인할 수 있습니다.

후킹될 때 결과 출력

근데 암호화가 되어있는 것인지, 이래서는 아무것도 확인할 수가 없습니다.


🚀 특정 함수에 본인 코드 삽입하기

일단, 어떤 함수가 호출될 때 내 코드를 삽입하면 좋을지 알아봅시다.

아까 뽑아두었던 APK 파일을 가지고 언패킹을 해봅시다.

https://github.com/skylot/jadx/releases/

저는 GUI 버전을 가지고, APK 파일을 선택하는 것만으로도 언패킹이 되었습니다.

WEB 으로 API 구조를 대충 알고 있기에, 쉽게 접근할 수 있는 API 호출 함수를 찾아 수정할 계획입니다.

방송 정보를 가져오는 API 를 호출하는 함수입니다.

그리고 또 알아야 할건 해당 클래스 경로입니다.

열린 소스 파일에 적혀있습니다.

이곳에 적힌 설명을 따라, 저 getLive 함수에 제가 원하는 동작을 하도록 해보았습니다.

1
2
3
4
5
6
7
// getLiveHook.js
Java.perform(function() {
var RxClass = Java.use("클래스 이름");
RxClass.getLive.implementation = function(id) {
console.log('[id] ----------', id);
}
});

이후 다음 명령어를 이용하여 스크립트를 삽입하고, 해당 함수를 호출하게끔 앱을 동작시켰습니다.

1
$ frida -U --no-pause -l getLiveHook.js -p 8300

원하는 출력은 나왔습니다. 그런데, 이후 에러가 발생하면서 앱 동작이 종료됩니다.

이러면 좀 더 정확한 동작을 확인할 수 없습니다.

제가 삽입한 스크립트 실행 후, 원래 동작까지 제대로 되었으면 좋겠습니다.

첨부한 문서를 보면 쉽게 답을 찾을 수 있었습니다.

1
2
3
4
5
6
7
8
// getLiveHook.js
Java.perform(function() {
var RxClass = Java.use("클래스 이름");
RxClass.getLive.implementation = function(id) {
console.log('[id] ----------', id);
return this.getLive(id); // <-- 해당 코드 추가
}
});

그리고 동작을 확인합니다.

결과적으로, 문제없이 잘 동작하는 앱에서 후킹만 성공하는 것을 확인하였습니다.

또 보죠.

작성자: raravel
주소: https://raravel.dev/20210623-1925/
저작권 고지: 이 블로그의 모든 기사는 별도로 명시하지 않는 한 CC BY-NC-SA 4.0 에 따라 라이선스가 부여됩니다.