Home [Hackthebox] Waiting
Post
Cancel

[Hackthebox] Waiting

거의 두 달 만에 모바일 분야에서 새로운 문제가 나와서 한 번 풀어보았습니다.

키워드: Mobile, Reversing

description

분석


일단 후킹을 걸게되면 앱이 crash가 나면서 꺼집니다. 스말리 코드 패치도 몇번 해보고 안돼서 이렇게 하는게 아니구나라는 판단을 내렸습니다. 따라서 코드를 좀 더 살펴보았죠.
앱 패키지 디렉토리 안에 Secret이라는 수상한 클래스가 존재했습니다. 그리고 라이브러리를 통해서 getdxXEPMNe라는 메서드를 선언합니다.
secret

그래서 바로 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 암호화 해주면 되겠죠?🙃
flag

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)부터 jarsingerapk서명을 하면 안되고 apksigner를 이용해줘야 한다고 합니다. 스말리코드 패치하고 jarsigner로 서명했는데 API 30인 에뮬에 설치하려고 하니 안돼서 찾아보니 이런 내용이 있었네요. 자세한 설명은 래퍼런스의 링크를 통해서 보시면 됩니다.

Reference


[Hackthebox] Encryption Bot

[CTF][hxp CTF 2022] valentine

Comments powered by Disqus.