이 글은 제가 카카오톡 봇 커뮤니티에 작성했던 글을 그대로 복사한 것입니다.
개요
안녕하세요. 그동안 카페 눈팅만 하다가 드디어 글을 쓰게 된 윤입니다.
카페 에디터가 스마트 에디터 3.0으로 바뀐 이후로 처음 쓰는 글이군요.
먼저, 해당 글을 쓰게 된 배경부터 알아봅시다. 몇 분이 제 블로그를 보셨을진 모르겠지만, 저는 타 플랫폼에서 봇 시스템을 구축했습니다. WEB 버전이 존재했기 때문에 쉬웠습니다. 그러다가 하게 된 것이 모든 API의 호출이 가능한 모듈을 만들기 시작했고, 결국엔 APP 버전에서만 지원하는 동작들을 구현하기 위해 후킹을 다짐했습니다.
분명 HTTPS 통신을 하는데, 일반적인 HTTPS 스니핑 도구는 패킷을 잡지 못 하더라고요. 왜 그런진 모르겠습니다.
어떻게든 비밀스러운 이 부분을 알고 싶었기 때문에 직접 소스를 보진 못 하겠고, 훔쳐보는 방식으로라도 주고받는 파라미터들을 보기 위해서,
오늘 알아볼 것은 Frida(프리다) 입니다.
변태처럼 앱이 어떻게 서버로 데이터를 넣어버리는지에 대한 관음을 아주 다양한 방법으로 할 수 있게 해주는 도구죠.
아. 참고로 저는 할 수 있는게 없습니다.
APK는 보통 자바, 또는 코틀린으로 짜죠. 그래서 디컴파일을 하면 자바 코드를 볼 수 있는 게 여럿 있습니다. 물론, 전 자바로 Hello World 찍는 것 조차 힘들어합니다. 안드로이드 구조 하나도 모릅니다.
Frida 라는 툴도 지금 처음 써봅니다. 해야지 해야지 고민하면서 문서만 몇 번 본게 답니다.
프리다는 파이썬으로 만들어졌나 봅니다. pip 를 통한 설치를 지원합니다. 물론, 파이썬도 못 합니다.
다행이도, 인젝션 언어중에 자바스크립트를 지원합니다. JS는 조금 할 줄 압니다.
제 개발환경은 다음과 같습니다. VMWare 에 리눅스를 설치한 상황이죠.
1 | DISTRIB_ID=LinuxMint |
그리고 안드로이드 스튜디오, 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 | $ adb push frida-server-12.11.3-android-x86 /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 | // getLiveHook.js |
이후 다음 명령어를 이용하여 스크립트를 삽입하고, 해당 함수를 호출하게끔 앱을 동작시켰습니다.
1 | $ frida -U --no-pause -l getLiveHook.js -p 8300 |
원하는 출력은 나왔습니다. 그런데, 이후 에러가 발생하면서 앱 동작이 종료됩니다.
이러면 좀 더 정확한 동작을 확인할 수 없습니다.
제가 삽입한 스크립트 실행 후, 원래 동작까지 제대로 되었으면 좋겠습니다.
첨부한 문서를 보면 쉽게 답을 찾을 수 있었습니다.
1 | // getLiveHook.js |
그리고 동작을 확인합니다.
결과적으로, 문제없이 잘 동작하는 앱에서 후킹만 성공하는 것을 확인하였습니다.
또 보죠.