거의 두 달 만에 모바일 분야에서 새로운 문제가 나와서 한 번 풀어보았습니다.
키워드: Mobile, Reversing
분석
일단 후킹을 걸게되면 앱이 crash
가 나면서 꺼집니다. 스말리 코드 패치도 몇번 해보고 안돼서 이렇게 하는게 아니구나라는 판단을 내렸습니다. 따라서 코드를 좀 더 살펴보았죠.
앱 패키지 디렉토리 안에 Secret
이라는 수상한 클래스가 존재했습니다. 그리고 라이브러리를 통해서 getdxXEPMNe
라는 메서드를 선언합니다.
그래서 바로 libsecret.so
파일을 열어보았습니다. getdxXEPMNe
의 동작 방식을 살펴보면 v4를 sha256
암호화하여 v10에 저장합니다. 그리고 byte_13B5
와 한 글자씩 XOR
합니다. 하지만 어떤 값을 sha256
암호화하는지 아직은 모르는 상태입니다. 따라서 다시 jadx로 돌아가서 getdxXEPMNe
를 사용하는 곳을 찾아보았습니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
__int64 __fastcall Java_com_example_waiting_Secrets_getdxXEPMNe(__int64 a1, __int64 a2, __int64 a3)
{
const char *v4; // x0
unsigned __int64 i; // x23
char v6; // w26
unsigned __int64 v7; // x0
_BYTE v9[52]; // [xsp+0h] [xbp-C0h] BYREF
char v10[68]; // [xsp+34h] [xbp-8Ch] BYREF
__int64 v11; // [xsp+78h] [xbp-48h]
v11 = *(_QWORD *)(_ReadStatusReg(ARM64_SYSREG(3, 3, 13, 0, 2)) + 40);
v4 = (const char *)(*(__int64 (__fastcall **)(__int64, __int64, _QWORD))(*(_QWORD *)a1 + 1352LL))(a1, a3, 0LL);
sha256(v4, v10);
for ( i = 0LL; i != 48; ++i )
{
v6 = byte_13B5[i];
v7 = __strlen_chk(v10, 0x41u);
v9[i] = v10[i - i / v7 * v7] ^ v6;
}
v9[48] = 0;
return (*(__int64 (__fastcall **)(__int64, _BYTE *))(*(_QWORD *)a1 + 1336LL))(a1, v9);
}
아래 사진처럼 SecretActivity
에서 사용하고 getPacakgeName
메서드를 통해서 패키지 이름을 넘겨주고 있습니다. 즉 앱의 패키지 이름을 sha256
암호화 해주면 되겠죠?🙃
Get Flag
1
2
3
4
5
6
7
8
9
10
11
12
13
from hashlib import sha256
info = lambda x : print(f"[+] {x}")
byte_13B5 =[0x71, 0x67, 0x23, 0x4A, 0x23, 0x8, 0x1, 0x1, 0x67, 0x5, 0x41, 0x41, 0x3, 0x5B, 0x51, 0x3A, 0x51, 0x5E, 0x17, 0x5C, 0x6A, 0x4D, 0x52, 0x9, 0x48, 0x57, 0x14, 0x5, 0x5A, 0x5F, 0x6A, 0x5, 0xC, 0x6, 0x5, 0xD, 0x50, 0x69, 0x5, 0x54, 0x55, 0x58, 0x51, 0x7, 0xE, 0x4B, 0x10, 0x18]
PACKAGE_NAME = 'com.example.waiting'
FLAG =''
if __name__ == '__main__':
sha256_encrypted = sha256(PACKAGE_NAME.encode()).hexdigest()
for i in range(len(byte_13B5)):
FLAG += chr(ord(sha256_encrypted[i])^byte_13B5[i])
info(f"Flag is {FLAG}")
잡설
문제를 풀면서 조금 의문이었던 점은 v10[i - i / v7 * v7]
요 부분이었는데, 파이썬
에서 i-i/v7*v7
를 계산하면 0만 출력됩니다. 하지만 c
에서는 올림을 하는지 0부터 v7-1을 출력하여 결국은 그냥 i
부터 순차적으로 도는 것이었습니다.ㅎㅎ
1
2
3
4
5
6
7
8
9
10
11
12
#include <stdio.h>
int main()
{
for(int i=0;i<48;i++){
printf("%d ",i-i/65*65);
}
return 0;
}
/* output */
/* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 */
그리고 Android 11(API 30)
부터 jarsinger
로 apk
서명을 하면 안되고 apksigner
를 이용해줘야 한다고 합니다. 스말리코드 패치하고 jarsigner
로 서명했는데 API 30
인 에뮬에 설치하려고 하니 안돼서 찾아보니 이런 내용이 있었네요. 자세한 설명은 래퍼런스의 링크를 통해서 보시면 됩니다.
Comments powered by Disqus.