ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [02-11 공부정리(Chaining RTL 정리)]
    공부정리 2018. 2. 11. 01:10

    오늘은 protostar Stack6~7번을 풀었다.

    6번은 RTL을 7번은 Chaining RTL을 이용해서 풀었다.

    7번같은 경우는 ASLR이 걸려있는 상황이라면 ROP를 이용해야 하는 문제였다.

    내일은 ASLR이 걸려있는 상태라고 가정하고 ROP로 문제를 풀어볼 생각이다.


    자 그럼 오늘 공부한 부분들을 정리하도록 하겠다.




    [Chaining RTL]

    RTL공격을 할때 System( )뒤에 dummy값으로 "AAAA"를 준 적이 있다.

    RTL 정리할 때도 말했지만 dummy값 부분은 의미없는 부분이 아니다.

    system( )가 끝나고 복귀할 주소가 저장되어 있는 공간이다.

    하지만, 우리는 /bin/sh을 따내면 그 뒤 상황은 어디로 복귀하던 상관이 없기에 "AAAA"라는 dummy값을 준 것이다.


    Chaining RTL은 저 부분에 dummy값 대신 실제 함수주소를 넣어 연속적으로 RTL공격을 하는 공격기법이다.

    여기서 가젯이라는 개념을 알아야 Chaining RTL공격을 할 수있다.


    [Gadget이 왜 필요한가?]

    우리가 연속적으로 함수를 호출한다고 해서 무작정 dummy값부분에 다음 함수주소를 넣으면 안된다.

    왜 그런지 스택을 보면서 얘기해보자

    buf[64] 

    SFP 

    System( ) 

    puts( ) 

    /bin/sh 

    이렇게 puts( )를 넣어버리면 puts( )에 인자값을 넘길수 없다.


    스택진행 상황을 보면

    1. System("/bin/sh")가 끝나면 RET에 있는 주소로 복귀한다.


    2. RET은 puts( )니까 puts( )을 호출한다.


    3. 인자값을 받아온다...( ? )


    4. puts( )가 끝나면 RET에 있는 주소로 복귀한다....( ? )

    3번과 4번을 진행할 때를 보면 어디서 인자값을 받아오며 어디로 복귀할 것인가?

    3번은 /bin/sh다음 스택에 있는 dummy값이 들어갈 것이며, 4번은 /bin/sh문자열 주소로 복귀할 것이다.

    맞다. 저런식으로 스택에 넣으면 우리가 원하는 방향으로 진행할 수가 없다.

    따라서, 우리는 Gadget을 이용해서 스택을 /bin/sh다음으로 이동시켜줘야 하는 것이다.


    [Gadget에 대해서..]

    Gadget은 어셈블리에서 POP과 RET으로 구성된 것을 말한다.

    항상 RET으로 끝나야하며, POP이 몇개 있느냐에 따라 [PR gadget], [PPR gadget] 이라고 부른다.


    [Stack7 Gadget]

    objdump로 gadget을 추출하며, 이름을 주자면 위에서부터 pppr/pr/ppppr/ppr gadget이라고 부를 수 있다.





    [Chaining RTL 실습]

    우리는 System( )가 끝난 뒤에 puts( )를 호출하고 싶다.

    System( )의 인자값은 1개이기 때문에 PR gadget이 있으면 된다.


    스택을 그려 이해를 돕자면

     buf[64]

    SFP 

    System( ) 

    PR gadget 

    /bin/sh 

    puts( ) 

    AAAA

     D 


    1. System("/bin/sh")가 종료되고 RET에 있는 PR gadget주소로 복귀한다.


    2. POP을 진행한다. (/bin/sh가 POP되고 ESP는 puts( )주소를 가리킨다.)


    3. RET을 진행한다. (puts( )함수로 복귀한다.)


    4. puts("D")가 실행되고 종료된다.


    5. RET에 있는 [0x41414141]은 존재하지 않기에 프로그램은 종료된다.

    이런식으로 진행된다.

    물론, puts( ) RET에 다른 함수를 넣어서 추가로 연속적인 동작을 이어나갈 수 있다.


    직접 실습을 통해 우리가 예상한 결과가 맞는지 확인해보자


    [puts( ) "D"]

    puts( )의 인자값으로 넘겨줄 D는 [0x080480e8]에 있는 D를 사용했다.


    [Shell 종료 후 "D" 출력]

    빨간 박스부분을 보면 exit로 Shell을 종료한 후, puts("D")가 실행되어 D가 출력되는 모습을 확인할 수 있다.


    이상으로 Chaining RTL의 정리를 마치도록 한다.




    [PLT & GOT]

    Stack7문제를 ROP로 풀려고 공부하다가 이해가 덜 돼서 ROP공격은 못했지만

    공부하면서 알게된 내용들을 간략하게나마 정리하겠다.


    #함수가 CALL될 때

    - 함수가 불러지기전에 PLT에서 GOT로 JMP한 후

    [dl_runtime_resolve] -> [dl_fixup_] -> [dl_lookup_symbol_x] 순으로 진행되면서

    함수의 실제이름이 들어있는 주소와 SYMTAB / libc 주소를 얻어 실제 함수를 구하는 과정이 진행된다.

    위와 같은 복잡한 과정은 함수를 처음 호출 했을 때만 저렇고, 그 이후는 GOT에서 바로 저장되어 있던 함수주소를 넘겨준다.


    "GOT에서 바로 저장되어 있던 함수주소를 넘겨준다."


    이 부분을 잘 생각해보자

    만약 우리가 printf("/bin/sh")라는 함수를 실행하려한다면 PLT는 GOT에게 실제 printf( )주소를 받아올 것이다.

    이때 GOT에 printf( )주소가 아닌 System( )의 주소를 넣어 놓는다면?

    System("/bin/sh")가 실행될 것이다.

    이러한 기법을 [GOT Overwrite]라고 한다.


    Stack7으로 GOT Overwrite를 실습해보도록 하자


    [Stack7 getpath( )]

    strdup( )는 인자값 변수안에 문자열을 그대로 출력해주는 함수이다.

    Strdup( ) : IBM Knowledge Center

    Stack7에서는 strdup(buf)로 선언되어 있으며, buf에 /bin/sh를 입력해줄 것이다.

    그 후, strdup( )의 GOT를 System( )로 덮어쓰면 System("/bin/sh")이 실행되는 것이다.


    [strdup( ) GOT]

    strdup( )의 PLT를 따라가보면 [0x8049760]로 JMP한다.

    저 곳에는 Global_Offset_Table 바로 strdup( )의 GOT가 있는 곳이다.

    따라서, JMP하는 주소를 System( )의 주소로 바꾸면 될 것이다.


    [GOT Overwrite]

    set명령어로 System( )의 주소인 [0xb7ecffb0]으로 바꿔준 후, 계속 진행했더니

    보는 바와같이 System("/bin/sh")이 실행되서 쉘이 획득된 모습을 볼 수 있다.


    이는 당연히 Local환경이기 때문에 gdb로 가능한 것이다.

    실제 Remote환경에서는 gdb로 불가능할 뿐더러, ASLR이 걸려있다면 GOT의 주소가 계속 변할 것이다.

    그렇게 되면 Memory leak을 먼저 진행한 후, offset을 계산해서 공격해야 할 것이다.

    이를 ROP라고 하며, 위에 정리한 RTL, Chaining RTL, GOT Overwrite 개념을 먼저 알아야 수월한 지식 습득이 가능하다.

    다음에는 ROP에 대해 공부하고 정리하는 글을 쓰도록 하겠다.

    '공부정리' 카테고리의 다른 글

    메모리 보호기법 - PIE  (1) 2019.01.12
    [02-14 공부정리(FSB 정리)]  (0) 2018.02.15
    [02-10 공부정리]  (0) 2018.02.10
    [02-08 공부정리(RTL정리)]  (1) 2018.02.08
    [02-07 공부정리]  (2) 2018.02.07

    댓글

Designed by Tistory.