1. 문제확인





Mommy told me to make a passcode based login system.

My initial C code was compiled without any error!

Well, there was some compiler warning, but who cares about that?


문제를 대충 해석해보면, 

엄마가 패스워드 넣는 로그인시스템을 만들어보라고 말했어~

내 초기 C코드는 에러없이 컴파일이 되었지!

뭐 워닝이 쫌있긴했는데 누가신경쓰겠냐? 라고 하고 있습니다.


우선 주어진 접속정보로 서버에 접속해서 passcode.c를 봐야겠네여



2. 문제 코드 분석


아래는 문제로 주어진 passcode.c에여


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
#include <stdio.h>
#include <stdlib.h>
 
void login(){
    int passcode1;
    int passcode2;
 
    printf("enter passcode1 : ");
    scanf("%d", passcode1);
    fflush(stdin);
 
    // ha! mommy told me that 32bit is vulnerable to bruteforcing :)
    printf("enter passcode2 : ");
        scanf("%d", passcode2);
 
    printf("checking...\n");
    if(passcode1==338150 && passcode2==13371337){
                printf("Login OK!\n");
                system("/bin/cat flag");
        }
        else{
                printf("Login Failed!\n");
        exit(0);
        }
}
 
void welcome(){
    char name[100];
    printf("enter you name : ");
    scanf("%100s", name);
    printf("Welcome %s!\n", name);
}
 
int main(){
    printf("Toddler's Secure Login System 1.0 beta.\n");
 
    welcome();
    login();
 
    // something after login...
    printf("Now I can safely trust you that you have credential :)\n");
    return 0;    
}



2-1) main()

프로그램 실행에 필요한 인자는 특별히 없어보이네여?

가장 먼저, Toddler`s Secure Login System 1.0 beta. 라는 문자열을 출력한 후

welcome, login을 순차적으로 호출 하고

Now I can safely trust you that you have credential :) 출력해주면 프로그램이 끝나고있어여


2-2) welcome()

welcome함수에서는 이름을 입력받기위해 char 배열 100바이트짜리가 하나 선언이 되어 있어여

enter you name : 에 맞추어 이름을 입력하면,

Welcome [입력한 이름]! 을 출력해줍니다. 여기서 %100s로 100바이트만 받는 다는 점만 인지해두세여


2-3) login()

login 함수에서는 패스워드를 입력 받고 인증에 성공하면 플래그를 읽어주는 의도로 만들고 싶었던 것 같은 소스를 볼 수 있어여

꼼꼼하신 분이라면 바로 이상한 점을 아실 수 있겠져? scanf에서 입력을 받는 변수에 &가 빠져있어여 ㅠㅠ

그리고 리눅스에서는 제대로 동작 하지 않는 것으로 알고 있는뎅, passcode1을 입력 받은 다음 입력버퍼를 날려주는 fflush()를 호출하고 있어여


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
void login(){
    int passcode1;
    int passcode2;
 
    printf("enter passcode1 : ");
    scanf("%d"&passcode1);
    fflush(stdin);
 
    // ha! mommy told me that 32bit is vulnerable to bruteforcing :)
    printf("enter passcode2 : ");
        scanf("%d"&passcode2);
 
    printf("checking...\n");
    if(passcode1==338150 && passcode2==13371337){
                printf("Login OK!\n");
                system("/bin/cat flag");
    }
 
    else{
        printf("Login Failed!\n");
        exit(0);
    }
}



원래 의도를 예상해서 코드를 수정해보면 이처럼 바꿔볼 수 있겠져?
scanf에서 변수를 저장할 때는 이렇게 해당 변수의 주소값을 인자로 넣어줘야돼여 아마 문제에서 언급했던 워닝은 여기서 났겠네여
게다가 패스워드를 입력받아 저장 하려고했던 passcode1과 passcode2는 초기화 과정을 거치고 있지 않기 때문에 garbage값이 들어 있을꺼에여
결과적으론 이 가비지 값을 주소로 읽어서 거기다가 입력값을 쓰게 될 꺼에여


3. 디버깅


3-1) main()


2-1) 에서 살펴봤듯이 별내용은 없어 보이네여 printf를 실행하기 위한 put을 각각 호출 하고, welcome과 login을 순차적으로 호출하네여?


움..참고로 이번에 알게된 건데 문제서버에서 peda를 사용하고 싶으면 gdb를 실행한 후 source /usr/share/peda/peda.py를 쳐주면 peda가 실행되여ㅠ 넘나 편한 것..


3-2) welcome()

여기서부턴 자세히 봐야 할 부분이 있어여

맨처음 함수 인트로에 해당하는 스택프레임 부분이 +0과 +1라인에서 이루어지고 있어여

바로 다음 +3라인에서는 소스에서 살펴봤던 login함수 내 지역변수인 name[100]을 위한 공간확보를 하고 있네여

0x88만큼 스택을 확보했으니까 dummy까지 합쳐서 136바이트를 확보한 것을 알 수 있져?



실행을 해서 확인을 해보도록 하져



welcome+9에 브레이크 포인트를 건 멈춘 모습이에여

ebp는 0xffb771e8, esp는 0xffb77160으로 (0xffb771e8 - 0xffb77160)0x88만큼 스택 공간이 확보되어있는 것을 확인해 볼 수 있어여

여기까지의 스택 상황을 한번 그려본다면 아래처럼 되겠져?


welcome+48에서 scanf을 호출해서 입력을 받고 welcome+68에서 print를 해주는 부분을 분석해서 정확한 더미부분과 name변수의 공간을

확인해 봅시당!

welcome+68에서 브레이크를 걸고 진행을 해보면,

0xffde9198에 입력한 값(저는 JSBach를 입력했어여)이 위치하고 있는 것을 알 수 있어여, 이 정보를 가지고 스택을 다시 그려보져


확보 된 0x88(136)사이즈가 이처럼 사용되고 있다는 것 까지 알아냈습니다. welcome에서 볼 수 있는 사항은 여기 까지구 login을 보면서

이 내용을 어떻게 써먹을 지! 확인을 해보면 되겠습니당



3-3) login()

login함수도 역시 스택프레임을 구성하는 것으로 시작하고있어여 그리고 passcode1과 passcode2를 위한 공간을 확보하고있져?

0x28만큼 확보하고 있네여 login+6에 브레이크를 잡고 자세히 한번 살펴봅시당



ebp가 0xffde9208이고, esp가 0xffde91e0기때문에 0x28(40바이트)만큼 공간이 확보된 것을 알 수 있습니다.

위와 같이 스택을 똑같이 그려보면?

요렇게 그려 볼 수 있겠져? 근데 잘보면 ebp가 welcome함수랑 똑같아여

welcome함수 콜 후에 바로 login함수를 콜 했기 때문에, 당연한 것일 수 있지만 이게 실마리입니다.


우선 0x28공간이 어떻게 구분되어지는지 확인을 해봐야겠져!

passcode1을 입력을 받는 login+34부분에 브레이크 포인트를 걸고 한번 봅시당


scanf에서 사용하는 첫 번째 인자인 %d가 스택 최상단에 있고, 바로 아래 passcode1가 있겠네여?

이 passcod1의 값을 어떻게 가져왔는지 scanf 호출 전(login+24, +27)을 보면 알 수 있어여


mov edx, DWORD PTR[ebp-0x10]            // edx에 ebp-0x10의 주소에 있는 값을 대입

mov DWORD PTR [esp+0x4], edx            // esp+0x4의 주소에 edx값을 대입


즉, ebp-0x10 -> 0xffde9208 - 0x10 = 0xffde91f8에 있는 값을 가져다가 쓴다는 게 되는거져

아까 welcome에서 봤던 스택 모습을 한번 더 볼까여?


ebp는 welcome과 login이 동일하게 0xffde9208을 쓰고있습니다.

그래서 ebp-0x10 의 위치라면! ebp로부터 16바이트가 떨어진 곳의 값이 되겠네여, 그럼...

name입력에서 끝 4바이트가 된다는 것을 알 수 있습니다.


요기까지 상황을 정리해보겠습니당!


1. scanf에는 메모리에 쓰고싶은 곳의 포인터를 넘겨준다.

2. 그런데 개발자가 실수로 & 기호를 빼먹어서 변수에 있는 값을 포인터로 사용하게되었다.

3. 그 변수에 있는 값은 앞의 함수에서 입력한 값의 영향을 받는다.


이름을 입력할 때 마지막 네 바이트에 입력하고 싶은 메모리 번지를 넣고 그 다음 scanf에서 값을 쓰면

원하는 메모리번지에 값을 넣을 수 있다! 라는 결론 까지 올 수 있습니다.


한번 확인한 사항이 맞는지 테스트 값을 넣어서 확인을 해보겠습니다.


입력값은 A가 96개 B 4개를 넣었습니다. 우리가 확인 한 대로라면 scanf의 두 번째인자에는 0x42424242가 들어가 있어야되여...



확인한 대로 잘들어가있네여 ㅠㅠ 


그런데 이걸 가지고 어떻게 익스플로잇 할 수 있을까여??

소스 상에서는 passcode1과 passcode2의 값이 모두 일치해야 조건을 만족하고 플래그를 읽어주는데...

결과부터 말씀드리면 passcod1을 입력받은 후 fflush함수를 호출 할 때 GOT의 주소를 바꿔줌으로써 플래그를 읽어볼 수 있습니다.


PLT / GOT가 무엇인지 자세히 알고 싶으신 분은 아래 링크를 참조 하세여!


PLT와 GOT 자세히 알기1

https://bpsecblog.wordpress.com/2016/03/07/about_got_plt_1/


PLT와 GOT 자세히 알기2

https://bpsecblog.wordpress.com/2016/03/09/about_got_plt_2/


[참조] https://bpsecblog.wordpress.com/


문제 풀이에 필요한 정도로만 간략히 설명을 드리자면

동적 라이브러리를 사용할 때 프로그램 내에 임포트한 라이브러리의 함수가 없기 때문에 (여기서는 fflush함수가 되겠습니다.)

해당 함수의 주소를 얻어 올 수 있는 테이블들입니다.


라이브러리 함수를 호출하게 되면 먼저 plt로 간 후, got로 점프를 뛰고 got에서 라이브러리의 함수 주소를 얻어오는 구조가 되겠습니다.


우리는 이 부분에서 fflush함수 호출 할 때, plt에서 got로 점프를 뛰는 부분의 주소를 login+127의 주소(system("/bin/cat flag"))로 바꾸어

익스플로잇을 시도해볼 수 있습니다.


그럼 수정해야 될 주소를 확인해 봅시당!

0x08048593 <+47>: call   0x8048430 <fflush@plt>


여기가 최초 plt테이블로 뛰는 부분이에여, 저 안에 가면 got로 점프 뛰는부분이 있을거에여


첫 줄에 바로 점프뛰는 부분을 보면 0x804a004로 점프를 뛰고 그 주소를 보니깐! got로 뛰어가고있는 모습을 볼 수 있네욥

여기서 우리가 바꿀 주소가! 바로 0x804a004에요, 여기다가 login+127의 주소인 0x080485e3을 넣어 줄꺼랍니다.



4. 페이로드 작성

작성해야될 페이로드를 프로토 타입으로 한번 보면 요렇게 될꺼에여

NOP 96개 + got로 뛰는 주소 + login+127의 주소


결과부터 보면 


(python -c 'print "\x90"*96+"\x04\xa0\x04\x08"+"134514147"') | ./passcode 이렇게 되겠습니다.


이제 찬찬히 또 뜯어봅시당


프로그램에 입력을 넣어 주는 부분은 파이썬을 사용했어여

NOP에 해당하는 \x90이 96개 들어갔습니당, 그리고 리틀엔디언 방식으로 주소를 때려박아야하니깐 한바이트씩 역순으로!

0x804a004 -> \x04\xa0\x04\x08이 되는거고여


그리고 scanf에서 포맷이 %d 즉, 정수형으로 받고있기 때문에~

0x080485e3을 십진수로 변환해준 134514147을 넣어줬어여


근데 뭐 이상한거 없으신가여? 제가 초보자여서 그런지 여기서 헤맸어여 ㅠㅠ

name[100]에 100바이트가 넘는 문자열을 입력하면 오버플로우가 안나나? 하는 생각을 했더랬져


제가 혹시 위에서 얘기했던 %100s 기억나시나요? 저렇게 사이즈를 정해줌으로써 딱 100바이트만 입력받고 100바이트이상 넘치는 문자열은

다음 인풋으로 넘어가더라고여..ㅎ;;;


그래서 정리해보면~


처음 이름을 입력하는 곳에 NOP + 0x804a004까지 들어가고 그 다음 passcode1을 입력하려고했던 로직에

0x080485e3이 입력이 되서 플래그를 읽을 수 있었습니다~







'Study > Pwnable' 카테고리의 다른 글

[HITCON Training] lab4 / return to library  (0) 2017.11.29
[HITCON Training] lab2 / shellcraft  (0) 2017.11.28
NX(No eXcutable) / ROP  (1) 2017.09.29
pwnable.kr / input / pwntools  (0) 2017.08.01
PEDA / pwnable.kr bof문제  (0) 2017.07.12

1. PEDA ?

Python Exploit Development Assistance for GDB 의 약자로써, 일반 GDB보다 바이너리 Exploit을 편리하게 할 수 있도록 다양한 옵션과 기능이 추가되어 만들어진 툴입니다. CTF대회같은 경우 시간절약이 중요하기 때문에 많이들 사용하시는 거 같습니다. 

저도 사용해보니 일단 알록달록해지는 UI와 디버깅 진행 할때마다 눈에 잘들어오는 stack 및 레지스트리 값 변화 등 보통의 gdb에 비해

아주아주 편리했습니다.


PEDA를 설치해본 결과 설치방법은 아래 링크가 가장 잘 설명이 되어있는 것 같습니다. 

설치 관련 블로그 링크 : https://hexa-unist.github.io/2015/02/25/PEDA-Introduction-Installation/



2. PEDA 기본 기능

모든 기능과 옵션을 본 글에서 다루기에는 어려움이 있어서... 상세한 내용은 2012년 BlackHat 발표자료를 첨부하였으니 살펴보시면 됩니다.


BH_US_12_Le_Linux_Interactive_Exploit_Development_with_GDB_and_PEDA_Slides.pdf


2-1) pdisas

gdb에서 disas 혹은 disassemble 로 사용했던 디스어셈블 기능의 확장판이라고 보시면 됩니다.

pdisas로 디스어셈블을 하게 되면 알록달록하게 하이라이팅 되어 비교적 가독성이 뛰어난 어셈블코드를 볼 수 있습니다.


아래 캡쳐를 보시면 확연히 비교가 됩니다.


disas func로 디스어셈블



pdisas func로 디스어셈블


2-2) stack 및 레지스트리 값 변화 확인

위 기능은 특별한 옵션을 주거나 명령을 통해 확인하는 것이 아니라, 브레이크 포인트를 걸고 디버깅을 하는 과정에서 바로 기능이 적용됩니다.



브레이크포인트를 걸고 실행을 하여 해당 위치에서 멈춘 화면입니다.

맨 위에는 각 레지스트리의 값과 해당 메모리에 어떤 값이 위치하고 있는지 해석도 나오고 있으며, 바로 아래에는 현재 브레이크 포인트가 어디에 멈추어져있는지(EIP 값이 얼마인지)를 나타내는 부분이 있고, 맨 아래에는 stack의 값 또한 바로 보여주고 있습니다.


2-3) find 명령어

find 명령어를 사용하여 특정 스트링을 검색 할 수 있습니다.

현재 프로그램에서 입력하는 곳에 "aaa"문자열을 입력한 상태였고, find명려어로 aaa를 서치한 결과입니다.



aaa라는 문자열이 heap과 stack에서 어디에 위치하고 있는지 표시해주고 있습니다.


2-4) 쉘코드 생성하기

BOF공격을 하기 위해 쉘코드를 찾으려고 여러 블로그를 뒤져보곤했는데, PEDA에선 각종 쉘코드를 제너레이트 해주는 기능이 있었습니다.

먼저 shellcode generate라고 입력하면 생성할 수 있는 shellcode의 종류를 보여줍니다.

위 캡쳐 화면에서 볼 수 있듯이 현재로써는 x86 쉘코드 밖에 지원이 되지 않는 것 같습니다.


직접 제너레이트 한 결과는 아래와 같습니다.



따로 쉘코드를 작성하거나, 블로그를 뒤져 찾아보지 않아도 되니 급할 때는 유용하게 사용 할 수 있을 것 같네요.



3) PEDA를 이용한 pwnable.kr bof문제 풀어보기


3-1) 문제 확인




문제 화면입니다.


Nana told me that buffer overflow is one of the most common software vulnerability. 

Is that true?


나나가 나에게 버퍼오버플로우가 가장 일반적인 소프트웨어 취약점이라고 말했는데 이거 실화냐? 라고 묻고있네요.

그리고 Download 링크가 두개가 있습니다. 하나는 c소스 파일이고 다른 하나는 c소스파일을 컴파일하여 생성된 바이너리인 것 같습니다.

wget으로 다 다운받아줍니다.


그리고 pwnable.kr 9000으로 돌리라고 하네요.


3-2) c소스파일 분석




메인함수에는 별 로직이 없네요.

func라는 함수에 헥사 값 0xdeadbeef라는 값을 전달하고 종료하고 있습니다.

bof를 유도 하는 로직은 func에 있는 듯 합니다.


func함수를 살펴보면 리턴 값은 없고, int형의 key라는 파라미터를 받고 있습니다. 

이 key값에는 메인함수에서 하드코드로 박혀있는 0xdeadbeef값이 전달이 되겠네요.


func함수의 바로 첫 라인에서는 overflowme라고 대놓고 선언되어있는 지역변수 char배열 32byte짜리 변수가 보입니다.

그리곤 overflow me : 라는 문자열을 출력하고 입력받은 값을 overflowme에 넣어주고 있습니다.

단순 gets함수로 받고 있기 때문에, 또 앞부분에서 size검사 부분이 없기 때문에 bof를 시킬 수 있는 포인트가 되며 

주석으로도 smash me! 라고 외치고 있는 것을 볼 수 있습니다.


아래 부분에서는 key 값이 0xcafebabe를 가지고 있는지 검사한 후 값이 일치하면 쉘을 넘겨 주고 있습니다.

위의 소스코드를 분석한 내용을 토대로 보면, func함수가 호출 되었을 때 stack의 모습을 예상해 볼 수 있습니다.





3-3) PEDA를 이용한 분석




main함수를 디스어셈블한 화면입니다. 함수 콜 직전에 0x0000063라인을 보면 mov로 esp에 함수 인자값을 대입하고 있는데,

간단히 push를 실행한 것과 동일하다고 보시면 되겠습니다.

그럼 func함수 호출부분에 브레이크 포인터를 걸고 실행하여 위의 내용이 맞는지 호출 전 스택의 상황을 살펴보도록 하겠습니다.



우리가 예상 한 것처럼 스택의 최상단에 func함수의 인자로 넣어준 0xdeadbeef가 위치하는 것을 확인할 수 있습니다.





si 명령을 통해 func함수 호출 직 후의 화면입니다. 함수 call을 하면서 다음 실행 명령 주소를 stack에 push한 것을 볼 수 있습니다.




func함수를 디스어셈블 한 화면입니다. 스택프레임 구성을 위해 ebp를 푸쉬하고있고, 지역변수인 overflowme[32]를 스택에 올리기위해 esp를 0x48 만큼 빼주고 있습니다. 정확히 32byte가 아니고, 0x48만큼인 이유는 컴파일러마다 약간의 사이즈 차이가 있기 때문이라고 하네요.


여기까지 분석한 스택의 상황을 그림으로 살펴보면 아래 처럼 되겠습니다.


더미가 overflowme[32]변수의 위에 위치할 지, 아래에 위치할 지 혹은 위 아래 나뉘어서 위치하고 있을 지는 직접 메모리를 들여다 보지 않아서 모르나, 둘이 합쳐 72byte(0x48)임은 어셈코드에서 알 수 있었고, 이에 따라 러프하게 개념적으로 위처럼 그려볼 수 있습니다. 

따라서 덮어써야할 내용은 

최소 44바이트(32byte + 4byte + 4byte + 0xcafebabe(4byte)) 부터 84byte(72byte + 4byte + 4byte + oxcafebabe(4byte))가 됩니다.

정확히 몇 바이트인지는 더 분석을 해봐야하겠네요.


입력값은 aaaaaaaa을 넣은 후 func+40에서 브레이크 포인트를 잡은 후 확인을 해보도록 하겠습니다.



esp(0xffffd1d0)에는 우리가 입력한 aaaaaaaa를 저장하고 있는 스택 내 overflowme[32]변수의 주소(0xffffd1ec)를 가르키고 있는 것을 볼 수 있습니다.



2-3) 에서 알아봤던 find명령어를 이용하여 aaaaaaaa가 위치한 스택 내 주소를 찾고, 0xdeadbeef가 위치한 스택 내 주소를 찾았습니다.

0xdeadbeef가 헥사값이라서 검색이 안될줄 알았는데 검색이 되어서 놀랐네요;

여하튼! 나온 주소 값의 차이는 0xffffd220 - 0xffffd1ec = 0x34(52) 임을 확인했습니다. 이 결과를 가지고 스택을 다시 그려보면

overflowme변수 위 아래에 더미가 껴있는 아래와 같은 형태로 그릴 수 있겠습니다.



3-4) exploit

결과부터 말씀드리면 exploit에 성공한 코드는 아래와 같습니다.


(python -c 'print "A"*52+"\xbe\xba\xfe\xca"';cat)|nc pwnable.kr 9000



먼저, python -c 'print "A"*52+"\xbe\xba\xfe\xca" 이 부분은 우리가 위에서 계산한 52바이트를 A라는 문자로 덮어버린 후

조작해야 할 헥사값 0xcafebabe로 만드는 문자열을 만드는 파이썬 구문입니다.

\xbe\xba\xfe\xca 처럼 역 순으로 문자열을 만든 이유는 엔디언 방식이 다르기 때문이고, 괄호와 세미콜론 + cat의 의미는

바이너리 실행 후 입력 값을 받는 형태를 맞춰주기 위함 입니다.

마지막으로 파이프로 연결한 후 문제에서 제시한 서버와 포트에 nc를 이용하여 전달하였습니다.



3-5) 결과



쉘이 실행 되었고 플래그값을 읽을 수 있음을 확인하였습니다 :)

'Study > Pwnable' 카테고리의 다른 글

[HITCON Training] lab4 / return to library  (0) 2017.11.29
[HITCON Training] lab2 / shellcraft  (0) 2017.11.28
NX(No eXcutable) / ROP  (1) 2017.09.29
pwnable.kr / input / pwntools  (0) 2017.08.01
pwnable.kr passcode  (5) 2017.07.31

1. Cycript

Cycript는 iOS에서 실행되고 있는 애플리케이션을 동적으로 수정하고 분석을 할 수 있게 해주는 SDK이다.

문법은 기본적으로 Objective-C / JavaScript를 혼합하여 사용 가능하다.

 


2. Cycript Hooking


2-1) view계층 확인하기

ex) UIApp.keyWindow.recursiveDescription()


view의 계층을 출력하여준다. NSLog로 출력하여 큰 화면으로 보면 아래와 같이 이쁘게 보인다.



2-2) subviews()

ex) UIApp.keyWindow.subviews()[index]


window는 하나 이상의 view를 가지며, view 역시 하나 이상의 view의 집합이다. 각 하위 view들의 접근은 subviews()[index]의 형태로 접근 가능하고, 2-1에서 확인한 계층을 참조하여 각 요소들을 찾을 수 있다.



2-3) _viewDelegate()

ex) UIApp.keyWindow.subviews()[2].subviews()[0]._viewDelegate()


_viewDelegate를 이용하여 해당 view의 controller에 접근 가능하다.


2-4) replacing existing objective-C methods

ex) Game2ViewController.prototype['recognizeAnswer'] 

= function() { NSLog(@"[JSACH]HOOKED"); return 1;}


target ViewController를 찾아 prototype배열에 후킹할 method에 접근하여 위와 같이 재정의해줌으로써 replacing가능함



참고) Cycript에서 사용하는 API나 문법, Trick들이 정리되어있는 링크

 

 - iOS Tricks

     http://iphonedevwiki.net/index.php/Cycript_Tricks


 - Cycript공식 홈페이지

http://www.cycript.org/


참고로 이 글은 Cycript 0.9.594버전을 기준으로 작성을 하였다.



3. 결과


3-1) 메서드 재정의


1
Game2ViewController.prototype['recognizeAnswer'= function() { NSLog(@"[JSBACH]HOOKED"); NSLog(@"[JSBACH] return SUCCESSED"); return 1;}





3-2) 메서드 후킹 로그


3-3) 후킹 성공 결과




4. 후기

frida와 Logos 그리고 오늘 Cycript까지 정리하면서 처음에 계획했던 후킹 방법 세가지에 대해 모두 간단하게 겪어(?)보았다. 각 방법의 장단점이 어느 정도 감이 오는 것 같아서 매우 뿌듯하고 흡족스럽다!


개인적으로 생각하는 frida와 Logos, Cycript를 비교하면 이렇다고 생각한다.


 항목

Logos 

Frida 

Cycript 

설치의 편의성

 

 

상 

수정사항 반영의 편의성

 

 

상 

후킹 사항 유지력 

 

하 

중 

 참조 자료의 양

중 

상 


4-1) 설치의 편의성

후킹하기 위한 각 툴들의 환경설치에 대한 평가 항목으로 선정해보았고, 개인적으로 소요된 시간과 환경의 까탈스러움 등을 고려하여 평가해보았다.


Logos의 경우 Mac사용자라면 간편한 편일 수 있으나, 본인은 Kali Linux에 환경을 설치하면서 꽤나 애를 먹었던 기억이 나서 낮은 '하'로 선정하였다.


Frida는 비교적 편리하게 설치하였으나, 단말에 Server Binary를 올려야하는 점과 Cycript만큼 간단하지 않았던 것같아(ㅎㅎ) '중'으로 점수를 매겼다.


Cycript의 경우 Cycia에서 패키지 설치만으로 모든 설치가 정상적으로 완료 되어 '상'으로 책정하였다.



4-2) 수정사항 반영의 편의성

후킹 코드 작성 중 수정사항이 생긴경우 재 반영하는 방법의 편의성에 대한 평가 항목이다.


Logos는 .deb파일을 재설치하고 Spring Board가 재시동되어야 하는 불편함이 있어 '하'가 되었다.


Frida의 경우 script를 종료 시킨 후 수정, 재실행의 과정이 있어야 하고.. 아무래도 Cycript만큼 간단하지 않았던것 같아 '중'으로 하였다.


Cycript는 후킹 script만 재정의 해주면 되므로 가장 간단하다고 판단하여 '상'으로 하였다.


4-3) 후킹 사항 유지력(?)

항목이름이 이상한거 같긴한데.. 적절한 명칭이 떠오르지않아서ㅠ... 한번 후킹 코드를 넣었을 때, 얼마나 유지가 되는지(?)에 대한 항목이다.


Logos는 한번 .deb설치가 되면 삭제가 될때까지 유지가 된다. 즉, 개발한 패키지를 한번 설치를 하고난 후 특별한 조치를 취하지 않아도 후킹코드가 유지된다. 가장 유지력이 좋다고 생각하여 '상'으로 책정하였다.


Frida는 후킹 script가 종료되기 전까지 유지가 되고, Cycript는 후킹 Process가 종료되기 전까지 유지 되므로 각각 '하'와 '중'으로 하였다.


4-4) 참조 자료의 양

비교 항목 중 가장 주관적인 항목으로 본인이 검색해 본 경험에 따라 그냥 매겼다.

아무래도 요즘 많이 떠오르고있는 Frida가 자료가 가장 많아 '상', Cycript와 Logos는 비슷 한것 같지만

Cycript가 예전 자료가 너무 많이나와서 사실상 볼 만한 자료가 거의 없었다. 따라서 더 애를 많이 먹었던 것 같아 '하'로 책정하였다.





다음 목표는 Logos를 이용하여 tsprotector와 비슷한 JB우회 패키지를 만들어 보고자 한다. 

fopen과 같은 file관련 API들, System call등을 후킹하여야 할 것으로 예상된다~


'Study > iOS' 카테고리의 다른 글

iOS Hooking#2(Frida)  (0) 2017.04.19
iOS Hooking#1(Logos)  (1) 2017.04.18
2장 iOS 해킹 기초 (1)  (0) 2016.06.18
자주쓰는 데이터형 변환  (0) 2016.06.01
[iOS/GCC] __attribute__((constructor)) / __attribute__((desstructor))  (0) 2016.05.13

+ Recent posts