반응형

최근 우리 회사의 모바일 보안 솔루션 팀에서 흥미로운 업무 지원 요청을 받았다.

 

한 고객사의 게임에서 모드앱(해킹앱)이 발생했으며, 이를 분석해 달라는 요청이 왔다.

 

특히, 해당 모드앱은 LDPlayer, GameGuardian, Magisk, Hide the Magisk Manager APP 등

 

다양한 기능프레임 워크들을 사용하였다.

 

당연히 위의 환경으로 설정하게 되면 단말기 또는 Emulator는 루팅된 환경이 된다.

 

게임 앱 같은 경우 서비스 정책상 Emulator차단하게 되면 큰 단점으로 이어질 수 있기 때문에

 

대부분 허용해 준다.

 

하지만 여기서 가장 큰 문제점은 우리 회사에서 제공하는 보안 솔루션에서

 

최신 Magisk 27.0 버전을 탐지하지 못하고 있었다.

 

따라서 최신 Magisk 27.0 버전을 탐지할 수 있는 방법Magisk의 기능 중 하나인 DenyList

 

루팅 탐지를 우회하는 각종 모듈들을 탐지할 수 있는 방법에 대한 좋은 주제로 분석을 진행하게 되었다.

 

Magisk는 전 세계적으로 사용하고 있는 루팅 툴이다.

 

그러면 그만큼 패치가 자주 일어나고, 우회 - 탐지 - 우회 - 탐지가 반복적으로 발생한다.

 

따라서 Root causeMagisk 자체를 탐지하면 해결될 것 같았다.

 

이런 생각으로 분석을 진행하였다.

 

자세한 로직과 원리는 공개하지 못하지만,

 

최신 Magisk 27.0, Magisk, Hide Magisk Manager, DenyList, 루팅 탐지를 우회하는 각종 모듈 등을 

 

적용하여도 탐지할 수 있는 방법을 발견하게 되었다.

 

결과는 다음과 같다.

 

기본 Magisk 탐지인 com.topjohnwu.magisk를 탐지하는 경우이다.

 

이는 대부분의 모바일 보안 솔루션에서 탐지를 한다.

 

해당 방법은 우리 회사에서 만든 보안 솔루션에서도 탐지를 한다.

 

 

 

 

하지만 문제는 다음과 같이 Hide the Magisk Manager APP의 기능으로 Magisk 패키지명

 

랜덤으로 숨겨 버린 후, DenyList에 해당 앱을 추가하면 모바일 보안 솔루션에서 탐지를 하지 못하였다.

 

 

그 이유로는 첫 번째 같은 경우는 com.topjohnwu.magisk이라는 정해진 패키지명으로 설치가 되기 때문에

 

패턴으로 쉽게 탐지가 가능하지만,

 

위의 두 번째 같은 경우에는 Random Package Name설치가 되어 패턴으로는 알 수 없기 때문이다.

 

하지만 분석 끝에 탐지할 수 있는 방법을 발견하였고

 

아래와 같이 Random Package Name으로 설치된 Magisk를 탐지할 수 있었다.

 

 

 

끝으로 보안 업무를 주로 할 때 오펜시브(공격적) 경향이 강했다. (사실 오펜시브가 더 재밌었다.)

 

보안 취약점을 찾고 이를 악용해 시스템을 테스트하는 것이 주된 역할이었다.

 

하지만 이번 업무는 이전과는 달리 디펜시브(방어적) 측면에서 생각해야 하는 업무였다.

 

주 업무가 아닌 업무 지원 역할로이었기 때문에 처음에는 사실 힘들었다.

 

하지만, 지금 생각해 보면 새로운 경험을 쌓는 좋은 기회였던 것 같다.

 

거의 3주 동안 퇴근 후 주말 밤낮없이 분석을 진행했던 것 같다.

 

다른 접근 방식을 배울 수 있었고, 보안의 다양한 측면을 이해하는 데 큰 도움이 되었다.

 

앞으로도 이러한 경험을 바탕으로 조금 더 성장할 수 있을 것 같다.

 

탐지 로직은 더 추가할 예정이다.

반응형

'모바일 해킹 > AoS' 카테고리의 다른 글

[Mobile-CTF] KGB Messenger  (1) 2022.06.01
[UnCrackable AoS] Level 3  (0) 2022.03.24
[UnCrackable AoS] Level 2  (0) 2022.03.23
[UnCrackable AoS] Level 1  (0) 2022.03.23
[Android] NDK란??  (0) 2022.03.09

반응형

Level 3 앱을 설치한 후 실행해보자.

 

 

 

이번에는 Level 1~2와는 다르게 문구가 다르게 보인다.

 

빠르게 디컴파일 툴로 해당 문구를 출력해주는 부분을 보자.

 

그림 부분에서는 잘렸지만 이번에도 루팅 체크를 하는 것 같다.

 

다시 if문 조건절에 있는걸 보면 총 5개메소드 루팅체크하는 로직이 존재한다.

 

모두 OR로 되어있기 때문에 하나 하나 분석해봐야 한다.

 

 

먼저 Level 1~2에서 한 것처럼 RootDetection.checkRoot1()을 먼저 살펴보자.

 

아래의 그림은 checkRoot1() 메소드이다.

 

 

해당 메소드를 보면 이름만 바뀐 것을 볼 수 있다.

 

즉, 로직은 Level 1~2와 같다는 말이다.

 

이 부분을 빠르게 후킹 해서 루팅 우회를 진행해보자.

 

 

Frida가 실행된 후 앱은 바로 꺼졌다.

 

따라서 뒤의 IntegrityCheck.isDebuggable(this.getApplicationContext()

 

MainActivity.tampered != 0도 추가적으로 우회를 해보았다.

 

하지만 똑같이 우회가 되지 않았다.

 

그래서 앱이 문제인지 아니면 문제에서 의도한 것인지 파악하기 위해 로그를 분석해보았다.

 

 

위의 그림은 앱이 실행될 때 발생되는 로그를 캡처한 것이다.

 

처음 시작하자마자 Tampering detected! Terminating...라는 문구가 나온다.

 

뭔가 탐지됐다는 말이다.

 

따라서 코드단에서 분석을 진행할 때 놓친 부분이 있나 싶어서 디컴파일 툴에서

 

"Tampering detected! Terminating..." 문구를

 

검색해보았다.

 

 

나오지 않았다.

 

이는 앱단(java)에서 처리하는 것이 아니다고 판단할 수 있다.

 

100%로는 아니다.

 

저 문자열이 동적으로 생성되거나 문자열이 난독화되어있으면

 

원하는 문자인 "Tampering detected! Terminating..."을 검색해도 나오지 않는다.

 

따라서 어딘가에서 루팅 혹은 디버거 탐지 등 어떤 것인지 모르는 탐지 로직이 실행되고 있으며

 

탐지 로직에 걸려 로그가 나왔다는 것만 알 수 있다.

 

따라서 우리가 Secret String을 맞춰 성공하는 alert가 있는 곳으로 가보자.

 

 

if문 앞의 this.check.check_code(v4)가 실행되면서 true을 return 해주면

 

우리는 성공한 메시지를 볼 수 있다.

 

this.check.check_code 메소드를 살펴보자.

 

살펴보면 check_code 메소드에서 this.bar을 호출하고 this.bar에서 return 된 값을 return 한다.

 

this.bar 함수는 위에 정의가 되어있으며 이 역시 native이다.

 

native를 분석하기 전에 컨셉을 잡아보자.

 

아직 루팅 우회가 되지 않았다.

 

앱단에서는 해당 로직을 찾을 수 있었지만 후킹 한 결과 앱이 종료가 되는 현상이 있었다.

 

또한 log에는 Tampering detected! Terminating...라는 문구가 나왔었다.

 

따라서 첫 번째로는 native에서 루팅 우회를 하는 로직을 찾아봐야 한다.

 

두 번째로는 Secret String과 관련된 key를 찾는 것이다.

 

먼저 루팅 우회를 먼저 해야 다음 과정을 진행할 수 있기 때문에 루팅 탐지 로직을 찾아보자.

 

먼저 해당 문구를 IDA에서 찾아보자.

 

 

찾아본 결과 sub_30D0에서 Tampering detected! Terminating... 문구가 사용되고 있다.

 

그렇다면 바로 sub_30D0 함수를 살펴보자.

 

 

살펴보면 우리가 원했던 문구인 Tampering detected! Terminating... 를 찾아볼 수 있다.

 

또한 log에서 볼 수 있었던 TAGUnCrackable3, 내용은 Tampering detected! Terminating...

 

log_print 하는 부분도 찾았다.

 

따라서 여기에서 탐지한다는 의미이다.

 

천천히 코드를 살펴보자.

 

v0 = fopen("/proc/self/maps", "r");

 

먼저 fopen 함수를 사용해서 /proc/self/maps를 읽어온다.

fopen 함수는 원형은 다음과 같고 하는 역할은 파일을 읽어 FILE 구조체 포인터 넘겨주는 함수이다.

 

따라서 v0에는 /proc/self/maps 파일의 포인터가 담겨있다.

 

/proc/self/maps는 무슨 역할을 하는 파일일까?

 

먼저 /proc 디렉터리는 리눅스 계열에서 사용되는 디렉터리이고 실행되는 프로세스 정보를 담고 있다.

 

여기서 의미하는 self는 자신의 pid를 의미한다.

 

maps은 현재 실행되고 있는 프로세스의 주소 맵 또는 프로세스의 메모리 주소 공간을 보여주는 파일이다.

 

종합해보면 현재 실행하고 있는 프로세스(Level 3 앱)의 메모리 주소 맵을 담고 있는

 

파일이라고 생각하면 된다.

 

실제 테스트 단말기에서 maps을 확인해보면 다음과 같은 정보를 볼 수 있다.

 

jackpotlteks:/ # cat /proc/27212/maps
.....
12c00000-13cc0000 rw-p 00000000 00:01 33530                              /dev/ashmem/dalvik-main space (region space)_4735_4735 (deleted)
13cc0000-13ec0000 rw-p 010c0000 00:01 33530                              /dev/ashmem/dalvik-main space (region space)_4735_4735 (deleted)
13ec0000-14140000 ---p 012c0000 00:01 33530                              /dev/ashmem/dalvik-main space (region space)_4735_4735 (deleted)
14140000-2ac00000 rw-p 01540000 00:01 33530                              /dev/ashmem/dalvik-main space (region space)_4735_4735 (deleted)
6f13f000-6f41a000 rw-p 00000000 103:11 228934                            /data/dalvik-cache/arm64/system@framework@boot.art
6f41a000-6f430000 r--p 002db000 103:11 228934                            /data/dalvik-cache/arm64/system@framework@boot.art
6f430000-6f565000 rw-p 00000000 103:11 228943                            /data/dalvik-cache/arm64/system@framework@boot-core-libart.art
6f565000-6f577000 r--p 00135000 103:11 228943                            /data/dalvik-cache/arm64/system@framework@boot-core-libart.art
6f577000-6f5b7000 rw-p 00000000 103:11 228949                            /data/dalvik-cache/arm64/system@framework@boot-conscrypt.art
6f5b7000-6f5ba000 r--p 00040000 103:11 228949                            /data/dalvik-cache/arm64/system@framework@boot-conscrypt.art
......

 

그다음 sub_30D0 함수의 코드를 분석해보자.

 

  v0 = fopen("/proc/self/maps", "r"); // v0에 /proc/self/maps 파일 포인터 저장
  
  if ( v0 )
  {
   	......
  }
  else
  {
LABEL_7:
    v1 = "Error opening /proc/self/maps! Terminating...";
  }

 

만약 if문에서 v0null이면 즉, 파일을 열었을 때 열지 못했다면

 

LABEL 7:로 가면서 "Error opening /proc/self/maps! Terminating..."라는 문구와 종료가 된다.

 

하지만 v0에 파일 포인터가 잘 넘어왔으면 if문 내부로 들어가게 된다.

 

 ...
 
 if ( v0 ) 
  {
    do
    {
      while ( !fgets(&v3, 512LL, v0) ) // /proc/self/maps 512 길이만큼 가져와 v3에 담는다.
      {
        fclose(v0);
        usleep(500LL);
        v0 = fopen("/proc/self/maps", "r");
        if ( !v0 )
          goto LABEL_7;
      }
    }
    while ( !strstr(&v3, "frida") && !strstr(&v3, "xposed") );  
    v1 = "Tampering detected! Terminating...";
  }
  
  ...

 

if문 내부로 들어와서 처음 실행되는 곳이 바로 do while문이다.

 

while문 안에는 fgets라는 함수가 존재한다.

 

fgets 함수의 원형은 다음과 같다.

 

 

쉽게 설명해서 파일 스트림(stream)에서 해당 길이(num)만큼 문자열을 받는다(str).

 

정리하면 /proc/self/maps의 파일 정보를 길이만큼 읽어와서 str에 넣어주는 함수이다.

 

여기까지 정리하면 코드는 다음과 같다.

 

  v0 = fopen("/proc/self/maps", "r"); // v0에 /proc/self/maps 파일 포인터 저장
  
  if ( v0 ) 
  {
    do
    {
      while ( !fgets(&v3, 512LL, v0) ) // /proc/self/maps 512 길이만큼 가져와 v3에 담는다.
      {
        fclose(v0);
        usleep(500LL);
        v0 = fopen("/proc/self/maps", "r");
        if ( !v0 )
          goto LABEL_7;
      }
    }
    while ( !strstr(&v3, "frida") && !strstr(&v3, "xposed") ); 
    v1 = "Tampering detected! Terminating...";
  }
  else
  {
LABEL_7:
    v1 = "Error opening /proc/self/maps! Terminating...";
  }

 

이제 if문안의 2번째 while을 보자.

 

strstr 함수가 2개가 있고 첫 번째 인자에는 v3

 

즉, 위의 fgets 함수에서 /proc/self/maps의 파일 정보를 v3에 담았기 때문에 

 

strstr 함수로 파일 정보을 한 줄 한 줄 읽어 오면서 중 fridaxposed가 들어가 있는지 확인하는 것이다.

 

 

그렇다면 /proc/self/maps에 fridaxposed가 있는지 확인해보자.

 

.........
7d7844e000-7d7844f000 ---p 00000000 00:00 0
7d7844f000-7d78553000 rw-p 00000000 00:00 0
7d78553000-7d78bdc000 r--p 00000000 103:11 972986                        /data/local/tmp/re.frida.server/frida-agent-64.so
7d78bdc000-7d78bdd000 ---p 00000000 00:00 0
7d78bdd000-7d799da000 r-xp 00689000 103:11 972986                        /data/local/tmp/re.frida.server/frida-agent-64.so
7d799da000-7d79a74000 r--p 01485000 103:11 972986                        /data/local/tmp/re.frida.server/frida-agent-64.so
7d79a74000-7d79a8a000 rw-p 0151e000 103:11 972986                        /data/local/tmp/re.frida.server/frida-agent-64.so
7d79a8a000-7d79af5000 rw-p 00000000 00:00 0                              [anon:.bss]
7d79b23000-7d79b24000 ---p 00000000 00:00 0                              [anon:thread stack guard]
......

 

이렇게 maps 파일에 /data/local/tmp/re.frida.server/frida-agent-64.so 가 존재한다.

 

따라서 Tampering detected! Terminating... 문구가 log에 남은 것이다.

 

이제 후킹 포인트를 잡았다.

 

바로 strstr 함수이다.

 

첫 번째 인자를 바꾸거나 두 번째 인자인 frida를 다른 문자열로 바꾸면 되는 것이다.

 

밑의 그림은 strstr 함수를 후킹 하여 첫 번째 인자를 출력해보았다.

 

정상적으로 후킹이 되고 frida가 출력된 것으로 보아 frida가 포함된 문자열을 다른 문자열로 바꿔보자.

 

후킹 한 결과 원래 봤던 로그도 없으며 정상적으로 앱이 실행된다.

 

이렇게 루팅 또는 디버깅 우회가 끝이 났다.

 

 

 

다시 돌아와서 이제 Level 3에서 원하는 Secret String을 찾아야 한다.

 

위의 bar 메소드native 메소드이면 Level 2에서처럼 so 파일을 분석해보아야 한다.

 

so 파일IDA로 열어보자.

 

 

Level 2에서 분석한 것과 마찬가지로 CodeCheck_bar 함수를 클릭해서 분석을 해보자.

 

그 이유는 Level 2에 설명되어있다.

 

 

retrun 하는 result 변수가 처음에는 0으로 설정되어있다.

 

이렇게 0으로 설정되어있으면 Secret String을 맞췄다는 문구를 볼 수가 없다.

 

따라서 result 값이 1이 되도록 만들어줘야 한다.

 

물론 Level 2에서도 bar 함수의 return 값을 1로 설정해주면 되지만 이는 출제의도가 아니다.

 

따라서 코드를 분석해서 Secret String을 알아내야 한다.

 

 

Level 2를 제대로 이해를 했다면 Level 2에서와 마찬가지로 해당 코드를 보고 생각나는 것이 있을 것이다.

 

총길이가 24인 것을 생각할 수 있다.

 

그다음은 while 문을 살펴보자.

 

while 문에서 == 연산이 보인다.

 

== 기준으로 왼쪽 값오른쪽 값이 같냐라는 것이다.

 

같지 않은 경우 while문이 끝이 나며 result는 그대로 0으로 return 되기 때문에 문제를 해결하지 못한다.

 

따라서 while문이 이 문제의 핵심이다.

 

먼저 왼쪽을 보자.

 

 

먼저 v7이 뭐고 v8이 먼지 알아야 한다.

 

v8은 코드에서 그냥 0이다.

 

v7을 알아야 하는데 v7은 IDA에서 다음과 같이 정의되어있다.

 

 

따라서 v5+1472 이가 어떤 함수인지 어떤 역할을 하는지 알아봐야 한다.

 

이를 frida를 활용해서 찍어보면 GetByteArrayElements라는 함수가 나온다.

 

GetByteArrayElements 함수의 정의는 다음과 같다.

 

GetByteArrayElements 함수는 java의 byte 배열을 JNI로 전달하는 함수이다.

 

즉 앱단에서 어떤 값을 so 파일로 전달하는 함수이다.

 

어떤 값을 전달할까??? 

 

GetByteArrayElements가 실행 후 return 값이 담긴 v7를 출력해보자.

 

 

이렇게 앱단에서 입력한 "test123456781264864984" 값이

 

GetByteArrayElements 함수가 실행된 후 v7에 저장이 된다.

 

따라서 while 문의 왼쪽은 사용자가 입력한 Secret String이라는 의미이다.

 

그렇다면 이제 ==을 기준으로 오른쪽의 값이 바로 문제에서 원하는 Secret String이라는 말이다.

 

따라서 우리는 알아야 할 것이 3가지이다.

 

&qword_15038 + v8, &v9, v8이다.

먼저 &qword_15038을 알아보자.

 

먼저 &연산은 주소 값을 가져오는 의미이다.

 

qword_15038에 어떠한 값이 저장되어있는데 그 메모리 주소값을 가져오는 의미이다.

 

그 후 v8을 더해준다.

 

처음에 v80이다.

 

 

하지만 바로 밑에서 ++연산을 통해 v8을 1씩 증가시켜주고 있다.

 

이는 어떠한 문자열이나 값이 배열에 저장되어있는데 index를 한 개씩 증가시킨다는 의미이다.

 

즉, 24자리인 문자열이면 한 문자씩 가져온다는 의미이다.

 

그렇다면 qword_15038에 어떤 값이 들어있는지 살펴보자.

 

 

qword_15038Java_sg_vantagepoint_uncrackable3_MainActivity_init 함수에서 사용되었다.

 

따라서 Java_sg_vantagepoint_uncrackable3_MainActivity_init 함수를 분석해보자.

 

 

Java_sg_vantagepoint_uncrackable3_MainActivity_init에서 strncpy 함수에서

 

qword_15038으로 어떤 값을 copy하는데 무슨 값을? v5에 저장되어있는어떤 값을

 

얼만큼? 24자리 만큼 copy 하는 것이 보인다.

 

이를 frida를 이용해서 strncpy 함수의 두 번째 인자인 v5을 출력해보자.

 

출력해보니 "pizzapizzapizzapizzapizz683"라는 문자열이 나왔다.

 

24자리qword_15038에 copy하니 최종적으로 qword_15038에는

 

"pizzapizzapizzapizzapizz"가 저장된다.

 

이는 어디서 나온 것일까?라고 생각을 해보자.

 

qword_15038Java_sg_vantagepoint_uncrackable3_MainActivity_init 함수에서 초기화되었다.

 

따라서 함수명에서 추측할 수 있듯이 다시 입단으로 돌아가 MainActivity에 선언되어있는

 

native init 메서드가 있는지 확인해보자.

 

 

이렇게 pizzapizzapizzapizzapizzinit 메소드의 인자로 넘겨주었다.

 

따라서 현재까지 다음과 같은 값을 도출할 수 있다.

 

v8은 앞에서도 설명했듯이 0~24까지 증가한다.

 

따라서 pizzapizzapizzapizzapizz라는 문자열에서

 

v8가 0일 때 p,

 

v8가 1일 때 i... v8이 24일 때 z

 

이렇게 한 문자씩 처리하겠다는 의미이다.

 

v80일 때를 보자면 문자 'p'xor연산을 한다.

 

^xor을 의미하는데 p&v9+v8 값을 xor 한다는 의미이다.

 

&v9+v8에서도 앞서 설명한 것처럼 한 문자씩 가져와서 p와 xor 하겠다는 것이다.

 

뒤에서 그림으로 설명되어있다.

 

그렇다면 v9에는 어떤 값이 들어있는지 확인해보자.

 

v9sub_10E0 함수에서 처리된다.

 

sub_10E0 함수에서 v9의 인자 값을 넘겨주고 sub_10E0 함수가 끝나면 v9에는

 

어떤 값이 저장되어있을 것이다.

 

sub_10E0 함수가 끝날 때 v9에는 어떤값이 들어있는지 확인해보자.

 

 

sub_10E0 함수가 끝날때 v9에는 이렇게 값이 들어가 있다.

 

여기까지 정리하자면 다음과 같이 도출할 수 있다.

이렇게 xor을 하는 코드를 작성해서 실행해보면 우리가 원하던 Secret String이 나온다.

 

이를 Level 3에 입력해보자.

 

 

 

정답이다.

 

이번 문제는 조금 설명이 많이길었다.

 

최대한 자세히 step by step으로 설명하려고 노력했다.

 

후킹 코드나 프리다 코드는 일부러 올리지 않았다.

 

적어도 후킹 코드나 프리다 코드는 직접 작성해보길 바란다.

 

검색하면 많이 나온다. 

반응형

'모바일 해킹 > AoS' 카테고리의 다른 글

Magisk 27.0 루팅 탐지 기법  (2) 2024.06.27
[Mobile-CTF] KGB Messenger  (1) 2022.06.01
[UnCrackable AoS] Level 2  (0) 2022.03.23
[UnCrackable AoS] Level 1  (0) 2022.03.23
[Android] NDK란??  (0) 2022.03.09
반응형

이번에는 Level 2를 풀어보자.

 

Level 2 앱을 다운로드하여 테스트 단말기에 설치한 후 실행한 모습이다.

 

 

역시나 루팅이 탐지되었다는 문구를 볼 수 있다.

 

이번 Level 2문제도 루팅을 우회해야만 진행할 수 있다.

 

따라서 static 분석을 하기위해  Level 2 apk 파일을 디컴파일 툴로 소스코드를 살펴 보자.

 

Level 2는 처음 시작하는 activitysg.vantagepoint.uncrackable2.MainActivity이다.

 

따라서 가장 먼저 sg.vantagepoint.uncrackable2.MainActivity인 부분을 살펴보자.

 

살펴본 결과 Level 1과 같이 b.a(), b.b(), b.c() 메소드에서 루팅 탐지를 하고 있는 것 같다는 느낌이 든다.

 

Level 1을 제대로 이해했으면 이런 느낌이 와야 한다. 

b.a() 메소드를 살펴보자.

 

 

Level 1과 똑같다.

 

하지만 이번에는 Level 1에서는 다른 방법으로 우회를 해보았다.

 

 

/sbin/su를 -> Level 2나 다른 문자열로 바꾼다면 해당 바이너리가 없기 때문에

 

return 값이 0이 될 것이다.

 

 

Level 1에서는 설명하지 않은

 

Build.TAGS.contains("test-keys")과 "/system/app/Superuser.apk ..."에 대해서는

 

조금만 검색하면 어떤 방식으로 루팅을 체크하는구나 감이 올 것이다.

 

검색하고 찾아보는 것도 실력을 키우는 것 중 하나이다.

 

따라서 Level 1에 대해서 100% 이해하고 넘어왔다면 루팅 우회는 금방 할 것이다.

 

같은 방법으로 우회해도 좋고 위의 방법대로 우회하든 정답은 없다.

 

그다음은 Level 1처럼 Secret String을 맞춰야 한다.

 

해당 메소드를 보자.

this.m.a(v4)이다.

 

v4는 우리가 입력한 string일 것이고 정확하게 비교하는 로직은 this.m.a에 있을 것이다.

 

this.m.a을 살펴보자.

 

this.m.a을 살펴보면 this.bar 메소드사용자가 입력한 String 값

 

byte형식으로 변환해서 bar 메소드로 넘겨준다.

 

bar 함수는 바로 밑에 정의가 되어있으며 내용은 아무것도 없다.

 

bar 메소드modifier을 살펴보면 native라는 것이 보인다.

 

nativejava에서 즉 앱단에서 처리하는 것이 아니라

 

c/c++을 이용해서 so 파일 안에서 처리하겠다는 의미이다.

 

자세한 내용은 여기(클릭)를 참조하자

 

따라서 이번 문제는 자바 앱단이 아닌 native 단 까지 분석을 진행해야 한다는 의미이다.

 

안드로이드에서 NDK를 사용하기 위해서는 so 파일을 load 시켜주는 과정이 꼭 필요하다.

 

 

load 시켜주는 과정이 위에서 빨간 박스 안에 System.loadLibrary("foo")이다.

 

libfoo.so 파일에서 this.bar라는 메소드가 정의되어 있으며

 

해당 메소드에서 이리저리 처리되고 반환 값만 자바단으로 retrun 해주는 형식이다.

 

사실문제의 의도와는 다르게 해당 this.bar 메소드를 후킹 해서 true로 반환해준다면

 

굳이 Secret String을 구하지 않고 밑의 그림처럼 해당 문제를 풀 수 있다.

 

 

하지만 이는 Level 2의 문제 출제 의도랑은 전혀 관련이 없다.

 

따라서 so 파일을 한번 분석을 해보자.

 

so 파일 대부분 lib 파일 안에 존재한다.

 

하지만 폴더가 4개나 있다.

 

이는 사용자가 어떤 OS bit를 가지고 있지 모르니 개발자가 모든 bit에서 실행할 수 있도록 한 것이다.

 

자신의 테스트 단말기의 bit는 다음과 같이 확인할 수 있다.

 

 

따라서 arm64-v8a 폴더로 가보면 libfoo.so 파일이 하나 있다.

 

이걸 분석을 해야 한다.

 

so 파일IDA로 분석을 진행한다.

 

IDA로 보면 Java_sg_vantagepoint_uncrackable2_MainActivity_init

 

Java_sg_vantagepoint_uncrackable2_CodeCheck_bar를 볼 수 있다.

 

이 둘 중 밑의 Java_sg_vantagepoint_uncrackable2_CodeCheck_bar 함수를 자세히 살펴봐야 한다.

 

그 이유는 Java_sg_vantagepoint_uncrackable2_CodeCheck_bar명에서 알 수 있듯이

 

bar가 들어가 있기 때문이다.

 

그렇다면 Java_sg_vantagepoint_uncrackable2_CodeCheck_bar 함수의 로직을 살펴보기 전에

 

컨셉을 잡아야 한다.

 

자세하게도 필요 없다.

 

크게 잡아도 된다.

 

나는 이번 문제를 풀 때 크게 2가지를 생각하고 분석에 들어갔다.

 

어떤 값을 return 하면  Secret String을 우회할 수 있을까?

 

또는 Java_sg_vantagepoint_uncrackable2_CodeCheck_bar에서 사용자가 입력한 Secret String 값과

 

Level 2에서 원하는 Secret String을 비교하는 로직이 있지 않을까?라는 큰 목표나 컨셉을 잡았고

 

이를 토대로 분석을 해보자.

 

 

코드를 보고 return result; 위주로 먼저 분석해보았다.

 

result는 처음에 0이라는 값을 가진다.

 

따라서 return이 0이면 우리가 원하는 Secret String을 찾았다는 메시지를 볼 수가 없다.

 

따라서 if문 안에 있는 result가 1이되게게끔 만들어주어야 한다.

 

물론 여기서 Java_sg_vantagepoint_uncrackable2_CodeCheck_bar 메소드의 return 값을

 

0이 아닌 1로 바꾸어도 문제는 풀 수 있다.

 

하지만 이는 출제자의 의도가 아니다.

 

따라서 if문 안에 있는 result에 (*(_QWORD *)v4 + 1368LL)라는 함수가

 

어떤 함수인지 어떤 역할을 하는지 알아봐야 한다.

 

이는 프리다로 후킹을 해서 확인해볼 수 있다.

 

 

확인해보니 ZN3art3JNI14GetArrayLengthEP7_JNIEnvP7_jarray라고 나온다.

 

여기서 유추해보자. ArrayLegnth이다.

 

(*(_QWORD *)v4 + 1368LL)함수는 뭔가 길이를 반환하는 함수인 거 같다. 

 

그리고 == 23이 붙어있는걸 보아하니

 

총길이가 23이 되어야 한다고 생각할 수 있다.

 

이 생각이 맞는지 검증하기 위해 strncmp의 함수를 살펴보자.

 

strncmp의 함수의 정의는 다음과 같다.

 

 

strncmp인자의 3번째 값으로 길이를 의미하는 23이 들어간 것으로 보아.

 

strncmp로 문제에서 원하는 String Secret 값과 내가 입력한 값이 23자리인지 확인한 다음

 

같다면 result1이 반환할 것이라고 예상할 수 있다.

 

따라서 strncmp를 후킹 하여 첫 번째 인자인 str1 인자를 찍어보면 내가 입력한 String

 

두 번째 인자 str2를 후킹 하면 문제에서 원하는 String이 들어가 있는 문자열이 나올 것이다.

 

이렇게 하면 Java_sg_vantagepoint_uncrackable2_CodeCheck_bar 함수를 분석하기 전에 생각했던

 

2가지의 컨셉을 만족할 수 있다.

 

후킹 코드를 작성해서 앱에서 12345678911234567892123을 입력한다.

 

후킹 코드가 제대로 동작하면

 

strncmp의 첫 번째 인자에 입력한 12345678911234567892123 값을 볼 수 있다.

 

그렇다면 문제에서 원하는 Secret String은 뭘까?

 

strncmp2번째 인자를 확인해보자.

 

이렇게 우리가 원하는 Secret String을 얻을 수 있다.

 

String을 문제에 넣어서 입력해보자.

 

 

이렇게 Level 2도 해결했다.

 

아마 많은 사람들의 풀이 방법을 보고 들어왔겠지만

 

대부분 루팅 우회를 할 때 exit를 후킹을 하는 방법이 많았다.

 

뭐 사실 틀린 말도 아니지만 실제 real world에서는

 

exit 함수로 하나로 루팅을 우회할 수 있는 경우는 거의 없다.

 

활용될 수는 있겠지만 절대 없다.

 

앱을 개발한 회사마다 또는 상황에 따라 보안 설루션들을 우회를 해야 하기 때문에

 

처음 연습할 때 습관을 잘 들이도록 하자.

반응형

'모바일 해킹 > AoS' 카테고리의 다른 글

[Mobile-CTF] KGB Messenger  (1) 2022.06.01
[UnCrackable AoS] Level 3  (0) 2022.03.24
[UnCrackable AoS] Level 1  (0) 2022.03.23
[Android] NDK란??  (0) 2022.03.09
[Android] Frida 설치  (0) 2022.01.23
반응형

시작하기 전에 사실 지금 나는 UnCrackable을 풀 이유는 없다.

 

대부분 UnCrackable은 모바일 취약점을 진단하는 입문자용으로 많이 쓰인다.

 

하지만 나도 처음에 모바일 취약점을 진단할 때를 생각해보면 조금 진입장벽이 높았다고 생각했다.

 

나처럼 처음에 어떻게 진단을 해야할까? 라는 사람에게 조금 도움이 되었으면 하는 바람이다.

 

또한 나중에 스스로 해결하고 생각할 수 있도록 풀이과정을 전부 다 포스팅하지 않을 것이다.

 

다만 해당 문제의 출제 원리를 자세히 설명할 것이다.

 

아래의 내용을 제대로 이해했다면 나머지도 금방 혼자서 해결할 수 있을 것이다.

 

그럼 시작!!!

 

UnCrackable에 대해서 짧게 설명하자면

 

OWASP에서 만든 모바일 테스트용 앱으로써, AoSiOS가 있다.

 

인터넷에 조금만 검색해보면 Level 1 apk 파일을 구할 수 있다.

 

Level 1의 apk 파일을 구했다면 테스트 단말기에 설치해준다.

 

 

앱을 단말기에 설치하면 다음과 같은 앱 아이콘이 보이며 실행하면 다음과 같은 문구가 뜬다.

 

 

Root detected!

 

모의해킹 직무를 하다 보면 모바일 진단을 하는 경우가 많다.

 

그리고 위와 같은 루팅이 탐지되었다는 문구를 수도 없이 많이 봤을 것이다.

 

따라서 이 앱을 실행하기 위해서는 Level 1에서 루팅 탐지 로직을 우회하여야 한다.

 

이것이 모바일 진단에서 가장 중요한 작업이다.

 

요즘 대부분 앱에서는 이러한 루팅 탐지디버깅 탐지 등 수많은 탐지 로직이 실행되고 있으며 

 

진단을 하기 위해서는 가장 첫 번째인 루팅 탐지를 우회하여야 한다.

 

(참고로 이 정도 난이도는 상용 앱에서는 거의 없다고 보면 된다.)

 

그럼 해당 문구가 어떻게 어떤 로직으로 인해 루팅이 탐지되었는지 살펴보자.

 

Level 1은 가장 처음 시작하는 부분이 sg.vantagepoint.uncrackable1.MainActivity이다.

 

그렇다면 sg.vantagepoint.uncrackable1.MainActivity을 살펴보기 위해

 

앱을 디컴파일해서 static 분석을 진행해보자.

 

 

앞에서 봤던 문구를 소스코드단에서 볼 수 있다.

 

먼저 onCreate 메소드를 보면 if문 안에

 

 if((c.a()) || (c.b()) || (c.c()))가 존재한다.

 

(c.a()) || (c.b()) || (c.c())) 이 3개의 메소드 중 하나만 true여도 this.a라는 메소드가 실행되어

 

"Root detected!"라는 문구를 볼 수 있을 것이다.

 

그럼 (c.a()) || (c.b()) || (c.c()))라는 메소드를 모두 false로 만들어 줘야 한다.

 

c.a() 메소드를 살펴보자.

 

 

먼저 c.a 메소드이다.

 

java.lang.System.getenv 메소드는 현재 시스템의 환경변수 값을 얻어오는 메소드이다.

 

환경변수를 얻어온 값에서 :split 한 값을 for문을 loop 한다.

 

loop 하는 과정에서 File.exists() 메소드를 통해

루트 권한을 얻는 su 명령어(바이너리)가 존재하면 return 1을 하는 로직이다.

frida로 해당 System.getenv 메소드와 c.a()의 return 값을 찍어보자.

먼저 System.getenv 메소드의 return 값은 다음과 같다.

 

 

return 값을 :로 split 했기 때문에 String v0에는 다음과 같이 들어갈 것이다.

 

 

for문 로직을 살펴보자.

 

v0[0]에는 "/sbin"이라는 문자열이 들어가 있다.

 

그렇다면 for문에서 다음과 같이 실행될 것이다.

 

 

테스트용 단말기에 /sbin 디렉토리에 su라는 바이너리가 있는지 확인해보자.

이렇게 su라는 바이너리가 존재한다.

 

따라서 c.a()는 return 1이 되면서 루팅이 탐지되는 것이다.

 

 

이처럼 c.a()와 c.b(), c.c()를 우회해주면 루팅 우회는 끝이 난다.

 

밑의 사진은 c.a()와 c.b(), c.c()를 후킹 하여 루팅 체크 로직을 우회한 모습이다.

 

 

이제 문제에서 원하는 Secret String을 찾아야 한다.

 

사실 위의 루팅 우회Secret String을 우회하는 방법은 한 가지가 있는 것이 아니라

 

여러 가지가 있다.

 

Level 1 문제에서 후킹 포인트가 너무 많다.

 

하지만 Level 1에서 만든 문제의 출제 의도에 맞게 풀어보는 것을 추천한다.

 

다시 돌아와서 핵심은 빨간 박스다.

 

a.a(v4)라는 값이 true이면 된다는 의미이다.

 

a.a 메소드를 살펴보자.

 

마찬가지로 핵심은 빨간색 박스이다.

 

사진이 조금 잘리긴 했지만 우리가 Enter the Secret String에 입력하는 값이 arg5에 저장된다.

 

 

그 후 입력했던 arg5값과 아래의 sg.vantagepoint.a.a.a 메소드에서 return 된 값이 같다면

 

그 값이 Secret key가 된다.

따라서 sg.vantagepoint.a.a.a에서 return 되는 값을 알아내고 입력한다면

 

Level 1을 clear 할 수 있다.

 

sg.vantagepoint.a.a.a 메소드를 살펴보자.

 

sg.vantagepoint.a.a.a 메소드를 보면 AES/ECB/PKCS7Padding라는 문구가 보인다.

 

이것은 AES 암호의 한 종류이다.

 

AES 암호와 관련이 있다는 말이다.

 

그렇다면 AES 암호를 하기 위해서는 key가 있어야 한다. (대칭키 암호이기 때문)

 

또한 암호화 과정이면 평문이 있어야 하고

 

복호화 과정이면 암호화된 암호문이 있어야 할 것이다.

 

이것은 v2.init(2, v0)을 보면 알 수 있다.

 

init에 첫 번째 인자가 1이면 암호화 과정이고

 

2이면 복호화 과정이다.

 

init의 두 번째 인자는 key이다.

 

keyv0의 변수가 들어가 있으며

 

v0SecretKeySpec v0 = new SecretKeySpec(arg2, "AES/ECB/PKCS7Padding")을 나타낸다.

 

v0 SecretKeySpec(arg2, "AES/ECB/PKCS7Padding")리턴 값으로 arg2값이 필요하다.

 

arg2값은 앞의 메소드에서 본 byte값을 의미한다.

 

이렇게 key 셋팅과 AES 셋팅이 끝나면 dofinal 메소드로 복호화를 진행한다.

 

dofinal에는 arg3값이 인자로 들어가 있는데

 

arg3은 앞의 메소드에서 Base64 decode 한 값이 들어간다.

 

이것이 바로 암호문이며 이것을 복호화를 한다면 문제에서 원하는

 

즉 Level 1의 출제의도인 Secret key를 얻을 수 있는 것이다.

 

 

위의 과정을 코드를 작성해도 좋고 후킹을 해도 좋고 방법은 여러 가지이다.

 

밑의 사진은 위의 과정을 코드로 작성하여 Secret key를 구한 모습이다.

 

 

 

반응형

'모바일 해킹 > AoS' 카테고리의 다른 글

[UnCrackable AoS] Level 3  (0) 2022.03.24
[UnCrackable AoS] Level 2  (0) 2022.03.23
[Android] NDK란??  (0) 2022.03.09
[Android] Frida 설치  (0) 2022.01.23
Byte Code & Binary Code  (2) 2021.11.09
반응형

NDK란???

 

 

Native Development Kit의 약자로 안드로이드에서 C/C++ 코드를 사용해야 할 때가 있다.

 

안드로이드에서 C나 C++를 사용하기 위해서는 JNI(Jave Native Interface)로 사용 및 개발할 수 있다.

 

즉, NDK는 안드로이드 환경에서 JNI를 사용하기 위해 구성된 키트라고 생각하면 된다.

 

요즘은 C언어를 사용하여 개발하는 일이 많지는 않지만

 

C언어로 만들어진 프로그램과 라이브러리는 여전히 서비스를 제공하는 데 있어서

 

중요한 위치를 차지하고 있다.

 

특히 안드로이드는 리눅스 기반이며 이는 대부분 C로 제작되어있다.

 

C로 제작되어 있기 때문에 C로 작성된 라이브러리를 사용하는 것이 당연한 말이다.

 

또한 가장 큰 장점은 안드로이드의 앱을 개발할 때 Java로 만든 애플리케이션에서

 

일정 부분을 C/C++로 미리 작성된 라이브리를 재 사용이 가능해 개발 시간이 단축되는 장점이 있다.

 

주로 안드로이드에서 가장 많이 사용되는 파일이 libc.so 파일이다.

 

여기서 .so 파일은 shared object 또는 shared library라고 불린다.

 

shared object 또는 shared library는 실행 파일과는 분리되어 있지만

 

Linker라는 것으로 인해 실행 시 실행파일과 함께 메모리에 적재되어

 

프로그램이 정상적으로 실행될 수 있게 해 준다.

 

즉, .so 파일을 쉽게 정의하자면

 

이미 특정한 기능이나 함수들이 미리 정의 및 구현되어 있는 파일을 의미한다.

 

 

쉽게 설명하자면 위의 간단한 C 코드를 보자.

 

그냥 printf 함수로 "Hello World"를 출력하는 C 코드이다.

 

저기서 printf 함수는 위의 코드에서 작성한 적도 없으며 보이지도 않는다.

 

이는 "stdio.h" 헤더 파일에 printf가 미리 정의가 되어 stdio.h 헤더를 선언해주고 그냥 사용한 것이다.

 

이는 안드로이드 앱에서도 마찬가지이다.

반응형

'모바일 해킹 > AoS' 카테고리의 다른 글

[UnCrackable AoS] Level 2  (0) 2022.03.23
[UnCrackable AoS] Level 1  (0) 2022.03.23
[Android] Frida 설치  (0) 2022.01.23
Byte Code & Binary Code  (2) 2021.11.09
Android Penetration Testing - Rooting (Galaxy S6)  (5) 2021.08.27
반응형

안드로이드 애플리케이션에 대해 취약점 분석 및 모의해킹을 진행 시 Frida는 필수이다.

 

먼저 AndroidFrida를 설치하고 실행 하기 위해서는 PC에서 후킹 스크립트를 작성해야한다.

 

따라서 PC와 모바일 둘 다 Frida를 실행 할 수 있는 환경을 만들어주어야 한다.

 

PC 환경은 이전 포스팅을 보고 환경을 만들어 주자. (클릭)

 

먼저 진단용 단말기는 루팅이 진행되어야한다.

 

루팅과 관련된 내용은 따로 정리할지는 모르겠지만 검색만 하면 다른 포스팅이 많이 있다.

 

참고하자.

 

루팅된 폰에 다음과 같은 명령어를 입력하고 단말기가 32bit인지 64bit인지 확인한다.

 

getprop ro.product.cpu.abi

 

 

arm64-v8a는 64bit이기 때문에 frida 홈페이지에 가서 다운로드 받고 단말기에 넣어주기만 하면 끝이다.

 

Frida 공식 홈페이지는 다음과 같다. (클릭)

 

 

PC에 설치한 frida 버전과 똑같은 버전을 다운로드 받아 준다.

 

다운로드 받은 후 단말기에 해당 frida-server 파일을 넣어주고 실행 할 수 있는 퍼미션을 준다.

 

 

반응형

'모바일 해킹 > AoS' 카테고리의 다른 글

[UnCrackable AoS] Level 1  (0) 2022.03.23
[Android] NDK란??  (0) 2022.03.09
Byte Code & Binary Code  (2) 2021.11.09
Android Penetration Testing - Rooting (Galaxy S6)  (5) 2021.08.27
Android Penetration Testing - Setup  (2) 2021.01.11
반응형

 

갑자기 논문을 읽다가 평소와는 다르게 bytecode라는 단어를 보고

 

평소 같았으면 그냥 아 bytecode 하고 넘어갔지만

 

오늘 갑자기 bytecode??, binary code랑 뭐가 다른거지? 하고 어느 순간에 두개의 개념이 헷갈렸다.

 

따라서 이번에는 바이트 코드(Byte Code)바이너리 코드(Binary Code)를 짧게 정리해보고자 한다.

 

모든 언어를 예를 들거나 할때 등장하는 언어가 있다.

 

바로 C언어이다.

 

C언어는 컴파일러에 의해 소스파일(e.g., main.c, test.c)

 

오브젝트 파일(main.obj, test.obj)로 만들어진다. 

 

오브젝트 파일로 변환될때 0과 1로 이루어진 이진 코드

 

바이너리 파일로 변환된다.

 

0과 1로 이루어진 파일이기 때문에 컴퓨터는 해당 파일을 이해는 할 수 있다.

 

다만 실행은 못한다.

 

컴퓨터가 실행을 하기 위해서는 기계어(명령어 집합)가 되어야한다.

 

또한 C언어는 환경에 종속적이다.

 

이러한 문제점을 해결하고자 나온 언어가 자바(Java)이다.

 

자바는 컴파일러에 의해 소스파일(e.g., main.java)오브젝트 파일(e.g., main.class)로 변환되며

 

바이너리 코드가 아닌 바로 바이트 코드로 변환된다.

 

또한 환경에 독립적이며 바로 실행 할수 있다.

 

둘다 똑같이 컴파일러에 의해 소스파일컴파일 되었고

 

컴파일 된 파일 오브젝트 파일되었는데

 

C언어에서는 바이너리 코드, Java에서는 왜 바이트 코드일까?

 

완벽한 정답은 아니지만 두개의 차이점은 바로 실행 할 수 있냐 없냐의 차이이다.

 

차이점을 알아보자.

바이너리 코드

  • 컴퓨터가 인식하고 이해할 수 있는 이진 숫자 체계의 0과 1로 구성된 코드를 의미한다.

기계어

  • 기계어는 CPU가 직접 해독하고 실행할 수 있는 비트 단위로 쓰인 컴퓨터 언어를 통틀어 일컫는다.
  • 기계어는 프로그램을 나타내는 가장 낮은 단계의 개념이다.
  • 기계어는 어셈블리어와 1 : 1로 쓰일 수 있다.

바이트 코드

  • 가상 머신에서 이해하고 실행 할 수 있는 0과 1로 구성된 코드이다.
  • 어떠한 환경에 종속적이지 않고 실행 될  수 있는 가상 머신용 기계어 코드이다.

 

나름 바이너리 코드바이트 코드의 차이를 간단하게 정리를 해보았다.

 

위의 논문에서도 바이너리 코드라고 하지 않고

 

바이트 코드라고 쓰여져있었던것이다. (안드로이드 관련 논문)

 

왜냐? 안드로이드에서 사용하는 애플리케이션(App)은 Java로 만들어졌기 때문이다.

 

 

 

 

반응형

'모바일 해킹 > AoS' 카테고리의 다른 글

[Android] NDK란??  (0) 2022.03.09
[Android] Frida 설치  (0) 2022.01.23
Android Penetration Testing - Rooting (Galaxy S6)  (5) 2021.08.27
Android Penetration Testing - Setup  (2) 2021.01.11
Android Penetration Testing - Introduction  (0) 2021.01.11
반응형

오늘은 Galaxy S6를 루팅 해볼 것이다.

 

루팅 하는 이유는 모의해킹 진단 시 필수로 갖추어야 할 환경이다.

 

무조건 테스트 단말기를 구입해서 진행하는 것이 좋다.

 

루팅에 대한 문제점은 다른 블로그가 많으니 이에 따른 불이익은 책임지지 않는다.

 

먼저 루팅을 위해서는 총 4가지 파일이 준비되어있어야 한다.

 

1. 해당 단말기의 통신사와 일치하는 펌웨어

2. TWRP

3. Magisk

4. Odin

 

이렇게 총 4가지가 필요하다.

 

위의 4가지 파일을 정리하자면 다음과 같다.

 

1. G920SKSS3ETJ1 (SKT)

2. twrp-3.3.1-0-zeroflteskt.img

3. Magisk-v23.0

4. Odin3-v3.13.1

 

이렇게 준비해주면 된다.

 

(만약 위의 환경과 맞을 시 댓글을 남겨주시면 공유해드리겠습니다.)

 

위의 파일 중 먼저 테스트 단말기에서 설정을 해주어야 한다.

 

밑에서 이제 설명할 것인데 그림들을 일부러 크게 캡처하였다.

 

하나하나 잘 읽어보도록 하자.

 

 

1. 단말기 설정

 

먼저 설정에 들어가서 제일 밑에 있는 디바이스 정보를 눌러준다.

 

 

그 후 소프트웨어 정보를 클릭해준다.

 

 

그리고 빌드번호를 7번 눌러주면 개발자 모드가 활성화된다.

 

 

뒤로 가기로 다시 설정으로 돌아오면 밑에 개발자 옵션이 새로 생긴 것을 볼 수 있다.

 

개발자 옵션을 클릭해서 들어가 보자.

 

 

개발자 옵션에 들어가면 밑으로 내려가다 보면 USB 디버깅 옵션이 나오는데 이것을 활성화시켜주자.

 

 

 

여기까지 하면 단말기 설정은 끝이다.

 

원래 OEM 해제를 해주어야 하지만 Galaxy S6에는 없다.

 

따라서 USB 디버깅만 활성화해주면 된다.

 

그런 다음 Galaxy S6의 경우는 전원을 꺼준

 

홈버튼이 있는데 홈버튼 + 음향(-) +전원 키를

 

몇 초 누르다 보면바로 다운로드 모드로 들어가 주어야 한다.

 

adb 명령어로는 다음과 같이 입력해도 된다.

 

 

위의 2개의 방법 중 편한 하나를 선택해서 다운로드 모드로 진입해주자.

 

다운로드 모드로 진입하면 다음과 같은 화면을 볼 수 있다.

 

 

 

2. 펌웨어 설치

 

이제 다운로드가 되었으면 펌웨어 설치를 해주어야 한다.

 

이 상태에서 PC와 단말기를 USB로 연결하여 odin을 실행시켜준다.

 

그 후 펌웨어를 하나씩 올려주어야 하는데 펌웨어는 총 4개의 파일로 구성되어있다.

 

 

AP, BL, CP, CSC로 구성되어 있는데 밑의 그림처럼 odin의 BL, AP, CP, CSC 항목

 

차례대로 하나씩 넣어주자.

 

펌웨어 파일을 넣어주기 전 Options에 들어가 "Auto Reboot"를 꼭 해제해주자.

 

 

 

위의 그림처럼 펌웨어 파일을 넣어준 후 Start 버튼을 눌러주자.

 

 

Start를 누르게 되면 이제 펌웨어가 단말기에 새롭게 설치가 된다.

 

이렇게 조금만 기다려주면 다음과 같은 화면을 볼 수 있다.

 

 

이렇게 되었으면 폰에서는 아직까지 다운로드 중...이라는 문구를 볼 수 있는데

 

진행이 안 된 것이 아니라폰을 강제적으로 꺼주어야 한다.

 

폰을 강제적으로 끄는 방법은 음향(-) + 전원 버튼이다.

 

약 7초간 누르면 폰이 강제적으로 꺼진 후 system 설치가 진행될 것이다.

 

그 후 No command라는 문구가 나올 수 있는데 그 이후에 

 

Android Recovey라는 화면이 나온다. (나올 수도 있고 안 나올 수도 있다.)

 

그러면 5번, 6번에 "Wipe data/factory reset", "Wipe cache partition"이라는 것을 전원 버튼으로 클릭하여

 

차례로 5번 Yes, 6번 Yes를 진행해준다.

 

그 후 1번째 "Reboot system now"를 클릭한 후 단말기가 다시 켜지기를 기다리자.

 

 

기다리면 위의 화면처럼 진행해주면 된다.

 

3. TWRP 설치

 

다음은 이제 TWRP를 설치를 해주어야 한다.

 

이는 Magisk라는 루팅 애플리케이션을 설치하기 위해서이다.

 

다시 1. 단말기 설정에 들어가서 꼭 USB 디버깅을 설정을 해주어야 한다.

 

그 후 다시 다운로드 모드로 들어간다.

 

다운로드 모드로 들어간 후 twrp를 받았던 파일을 odinAP부분에 넣어주자.

 

 

 

이렇게 넣어주고 Start를 눌러준 후 다시 폰을 강제 재부팅을 해주는데 여기서부터가 중요하다.

 

Galaxy S6에서 강제 재부팅을 한 후 화면이 꺼진 후

 

바로 홈 버튼 + 음향(+) + 전원 버튼을 누르고 있어야 한다. (중요!!!!!)

 

그러면 다음과 같은 twrp 리커버리지 화면을 볼 수 있다.

 

 

 

4. Magsik 설치

 

이제 리커버리지 화면에서 "Swipe to Allow Modifications"를 옆으로 스와이프 해주자.

 

 

그 후 "Wipe"를 클릭해주자.

 

 

위의 그림에서는 잘 보이지 않지만 "Format Data"를 클릭해주자.

 

 

그 후 "YES"를 입력해준다.

 

 

Yes를 누른 후 화면에서... done이라는 문구가 나오면 된다.

 

그 후 단만기를 USB로 PC에 연결하여 파일을 옮겨준다.

 

 

단말기를 PC에 연결하면 Internal Storage가 보이는데 거기에 위의 두 파일을 넣어준다.

 

(해당 파일도 필요시 댓글로 요청하면 공유해드리겠습니다.)

 

그 후 위의 Up A Level을 클릭 후 sdcard로 들어가 준다.

 

 

sdcard에 들어가면 아까 PC에서 단말기로 옮긴 2개의 파일이 보인다.

 

차례로 설치해주자.

 

 

 

똑같이 Magisk도 설치해준다.

 

 

 

 

이렇게 설치를 다 끝나면 위의 Reboot System을 눌러 다시 폰이 켜질 때까지 기다리자.

 

 

 

5. Magisk 실행

 

폰이 부팅되면 위의 Magisk라는 애플리케이션이 설치되어있다.

 

클릭하면 다음과 같은 문구를 볼 수 있고 확인을 눌러주자.

 

 

 

 

이렇게 설정한 후 설치를 클릭하여 Magisk를 설치해주자.

 

 

 

 

 

이제 Magisk 애플리케이션에 다시 들어가면 다음과 같은 문구를 볼 수 있는데 확인을 눌러주고

 

재부팅을 하면 Rooting이 성공한 것이다.

 

 

 

반응형

'모바일 해킹 > AoS' 카테고리의 다른 글

[Android] NDK란??  (0) 2022.03.09
[Android] Frida 설치  (0) 2022.01.23
Byte Code & Binary Code  (2) 2021.11.09
Android Penetration Testing - Setup  (2) 2021.01.11
Android Penetration Testing - Introduction  (0) 2021.01.11
반응형

먼저 안드로이드의 Pentesting를 배우기 위해서는 환경을 Setup 해줘야한다.

 

먼저 준비물이다.

 

3가지만 있으면 된다.

 

루팅된 테스트 폰과 PC와 테스트 폰과 PC가 연결 할 수 있는 선만 있으면된다.

 

다른것도 있지만 그건 설치만 하면된다.

 

우선 PC와 테스트용 모바일 폰이 연결이 되어야하며 PC에서 폰으로 명령어를 내리기 위해

 

ADB를 설치해주어야한다.

 

ADB란?

 

Android Debug Bridge의 약자로, Android를 위한 Debugging Tool이다.

 

주로 Debugging 용도로 사용되며 쉽게 설명하자면 PC에서 Android 기반의 Device와 연결하여

 

PC에서 보다 쉽게 Debugging 하기 위해 사용된다.

 

설치는 다음 주소에서 한다. (클릭)

 

 

Windows용을 다운받아 알집을 풀어주자.

 

압축을 풀면 platform-tools 폴더와 함께 다음과 같은 파일이 보일 것이다.

 

 

이제 cmd창에서 adb를 사용하기 위해 환경 변수를 설정해 줄것이다.

 

 

윈도우키를 누르고 "환경" 이라고 검색하면 시스템 환경 변수 편집이 있다.

 

 

여기서 환경 변수를 클릭한다.

 

 

클릭한 후 Path라는 것을 더블클릭하여 아까 설치한 platform-tools 폴더 경로를 입력해주자.

 

 

그 후 cmd 창을 열어 adb라고 입력 해보자.

 

이렇게 adb가 실행되면 PC와 테스트용 단말기가 연결이 가능하다.

 

pc와 테스트용 단말기를 연결하여 adb shell을 입력해보자.

 

이렇게 여러가지 명령어를 cmd 창을 통해 명령 할 수 있다.

 

일단 diva-beta.apk를 설치 해준다. (댓글로 요청시 보내드리겠습니다.)

 

설치 하면 zip 파일 형태인 diva-beta.apk가 보인다.

 

 

해당 경로에서 cmd 창을 열어 adb install diva-beta.apk를 입력해준다.

 

 

위의 명령어는 adb로 apk를 install 설치 한다는 의미이다.

 

이렇게하면 테스트용 단말기에 diva.apk가 설치된다.

 

그리고 pc에서 알집으로 diva-beta.apk를 풀어보자.

 

알집으로 푼 AndroidManifest.xml 파일을 에디터로 열어보자.

 

 

이렇게 알 수 없는 값으로 보인다.

 

그 이유는 APK가 컴파일 된 후 바로 알집을 풀었기 때문에 컴파일된 코드이다.

 

따라서 우리가 눈으로 읽을 수 없다.

 

AndroidManifest.xml 코드를 읽고 싶다면 Decomplie 과정을 진행해야한다.

 

Decomplie 과정을 진행하기 위해서는 apktool이나 JEBDecomplier tool을 사용한다.

 

apktool이란 대표적인 안드로이드 애플리케이션(Android Application) 대상의 리버스 엔지니어링 도구이다.

 

APK 파일을 분석하여 리소스를 뽑아낼 수 있고(디코딩), 코드를 수정하여 다시 재빌드(Rebuild)할 수도 있으며

 

실제로 XML, 이미지 파일, .dex 파일을 포함하여 안드로이드 앱의 주요 소스를 뽑기 위해 가장 많이 사용되고 있는 Tool 중 하나이다.

 

JEB 또한 apktool과 같은 리버스 엔지니어링 도구라고 생각하면 된다.

 

apktool은 여기서 다운로드 받을 수 있다. (클릭)

 

apktool로 Decomplie을 진행 할 때 다음과 같은 명령어를 입력한다.

 

java -jar apktool_버전 d diva-beta.apk

 

 

또한 JEB로 apk를 Decomplie할 때는 JEB에 Decomplie을 원하는 apk를 드래그하면 된다.

 

 

이제 AndroidManifest.xml가 Decomplie 되어 우리가 소스를 다시 분석할 수 있다.

 

 

위의 과정은 우리가 Source Code Level에서 분석할 때 주로 쓰이는 방법이다.

 

이제 App과 서버단에서 통신을 할 때 어떤 데이터를 주고 받는지 분석하기 위해

 

Android Traffic를 잡는 방법을 알아보자.

 

Android Traffic를 잡기 위해서는 Web-proxy를 사용한다.

 

Web-proxy로 대표적으로 burpfiddler가 있다.

 

burp에 대해서는 많은 포스팅이 되어 있으므로 이번에는 fiddler로 기준으로 설명하겠다.

 

fiddler를 설치하고 Tool-Options-HTTPS 탭에가서 밑에처럼 박스를 체크한다.

 

체크할 때 시스템에 인증서를 설치하는데 다 Yes를 눌러주자.

 

 

그 후 Connections 탭에가서 Allow remote computers to connect 박스를 체크를 해주자.

 

그 후 테스트용 폰으로 들어가서 PC의 ip 주소:8888를 입력한다.

 

 

그 후 fiddler 인증서를 테스트 단말기에 설치 해준다.

 

설치 한 후 테스트용 단말기에서 WiFi 항목에서 PC와 같은 네트워크 대역에 있는 WiFi을 클릭 한 후

 

고급탭에서 프록시를 자동에서 수동으로 변경한다.

 

변경 후 프록시 호스트 이름에 PC의 IP를 입력해주고 프록시 포트에는 8888로 입력 후 저장을 누른다.

 

 

 

 

그 후 fiddler에서 보면 테스트 단말기에서 전송되는 패킷을 볼 수 가 있다.

 

여기까지가 DIVA를 풀기 위한 전체적인 Setup 과정으로 보면 되겠다.

반응형

'모바일 해킹 > AoS' 카테고리의 다른 글

[Android] NDK란??  (0) 2022.03.09
[Android] Frida 설치  (0) 2022.01.23
Byte Code & Binary Code  (2) 2021.11.09
Android Penetration Testing - Rooting (Galaxy S6)  (5) 2021.08.27
Android Penetration Testing - Introduction  (0) 2021.01.11

+ Recent posts