ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • |Lord Of Bufferoverflow| #12 golem - darkknight
    Wargame Site/BOF 2019. 6. 17. 12:25

     

     

    문제를 천천히 분석해보면, 41 개 즉, 1Byte Overflow 를 활용해서 문제를 해결해야한다.

    1 Byte 의 역할은 SFP 의 첫 바이트를 의미한다.

    예상대로 다음과 같이 ebp 의 값에 41이 들어간 것을 확인할 수 있다.

     

    그리고 이 화면은 disas main 에서 problem_child 가 실행되고 난 직후의 모습이다.

    esp 를 증가 시킨 뒤, 바로 leave 가 있는 것을 볼 수 있는데, 이것은 우리에게 어떤 의미를 가질까

     

    leave 는 mov esp, ebp 즉, esp 의 값을 ebp 의 값으로 바꾸는 과정이다.

    ret 는 esp 의 값을 eip 로 설정하는 코드이다.

    그리고 ebp 는 우리가 조정해 줄 수 있는 상태이다.

     

    그렇다면!!

     

    SFP 를 통해서 EIP 까지 조정할 수 있는 상태가 된다.

    결국 SFP 를 변조해주고, esp + 4 과정이 발생한 뒤에, leave ret 의 과정이 있으므로

    SFP 를  Buffer 의 시작주소 -4 로 설정하고 첫 4 Byte 를 EIP 가 향해야하는 주소로 돌려주면 문제는 해결될 것이다.

    그럼 인자를 앞 뒤로 조작해주어야 할 것이다.

     


    삽질의 시작

     

    [ 우리가 넣어준 Shellcode 주소 ]  + [ Shellcode ] + [ NOP ](11) + .... + [ Buffer 시작 - 4 (마지막 1Byte) ] 로 설계해주면 된다.

    shellcode 는 25 byte 코드를 사용했다.

    하지만, Shellcode 의 위치는 /xff 라는 곳에 위치하기 때문에 사용할 수 없었다.

    아래의 코드에서처럼 EBP 에 아무런 변화가 없음을 알 수 있었다.

     

     

    위의 코드에서 /xff 부분을 /xf0 으로 바꿔주었을 뿐인데 SFP 부분이 잘 바뀐 것을 알 수 있었다.

     

    이 방법으로는 접근할 수 없을 것 같다. 하더라도 지금 수준보다는 복잡한 /xff 자체를 변형 시키는 방법으로 해결될 듯 하다.

     


     

    우리가 넣어준 값으로 돌려주는 기존의 방식이 먹히지 않는다. 그렇다면, 우리가 넣어주지 않는 영역으로 들어가야할 것 같다.

     

    여기서, RTL 이라는 개념이 나온다.

    기존의 방식은 execve('/bin/sh', ['/bin/sh',0], 0) 를 직접 Shellcode 로 변형하여 만들어 주었다면,

    이번에는 파일안에 있는 함수를 토대로 진행해보려고 한다.

     

    RTL(Return To Libc) 이 그 기법이다.

    EBP 의 역할을 이해하는 것이 RTL 을 이해하는 첫 번째 관문이다.

     

    EBP 를 기준으로 - 영역과 + 영역이 가지는 의미는 달라진다.

    BOF 준비운동 (3) Step 7 에 나오는 부분을 이해해보자.

     

    - 영역은 지역변수의 역할을 하고, + 영역은 인자를 담당하고 있다.

     

     

    따.라.서

    EIP 를 특정 함수에 이동을 시킬 수 있고, SFP 를 적절히 조절할 수 있다면 함수를 SFP 의 내용대로 동작시킬 수 있다.

     

    이번 실습에서 사용할 코드는 system("/bin/sh") 이다.

     

     


     

    RTL 실습

     

    1. 라이브러리 의존성을 확인한다.

     ldd [ filename ] 

    > ldd darkknight ( O ) , ldd ./darkknight ( O )

     

    이번 실습에서 사용할 라이브러리는 libc.so.6 이다. libc.so.6 은 (0x40018000) 에 위치해있다.

     

     

     

    2. 라이브러리 내의 특정 함수를 찾는다.

     nm -D [  Library Name  ] 

    > nm -D /lib/libc.so.6 을 통해 확인해보자.

    ' grep 을 이용해서 필요한 system 함수만 가져온다. ' 

    system 함수는 00040ae0 위치에 있는 것을 알 수 있다.

    여기서 중요한 점은 이것은 offset 값이라는 사실이다. 

     

     

     

     

    3. 이번엔 특정 문자열을 탐색해보자.

     strings -tx [  Library Name  ] 

    > strings -tx /lib/libc.so.6

    ' grep 을 이용해서 필요한 /bin/sh 을 가져온다. '

    이 또한 마찬가지로 offset 이 출력되는 것을 알 수 있다.

     

     

     

    4. 작전을 다시 짜보자.


    여기서 주의할점!

    우선 마지막 1Byte 를 파악한 뒤 실습하는 게 좋다.

    왜냐하면 ebp 의 위치가 틀릴 경우 전혀 다른 코드가 되어버리기 때문이다.

    buffer 의 시작이 0xbffffc74 인 것을 알 수 있다. 따라서 마지막 1 Byte 는 \x70 값을 주면 된다.


     

     

     

     

    그렇다면, 이 작전에서 수정해야하는 곳을 찾아보자.

    [ 우리가 넣어준 Shellcode 주소 ]  + [ Shellcode ] + [ NOP ](11) + .... + [ Buffer 시작 - 4 (마지막 1Byte) ] 

     

    우선, system 과 /bin/sh 의 주소를 구해보자.


    system 의 주소 : 0x40018000 ( /lib/libc.so.6 의 주소 ) + 0x00040ae0

    /bin/sh 의 주소 : 0x40018000 ( /lib/libc.so.6 의 주소 ) + 0x000e3ff9

    따라서, system 은 '0x40058ae0'  /bin/sh 는 '0x400fbff9' 에 위치하는 것을 알 수 있다.


    [ System 의 주소 ] + AAAA (EBP 역할) + [ /bin/sh 의 주소 ]  + ..... + [ Buffer 시작 - 4 (마지막 1Byte) ]

    "\xe0\x8a\x05\x40" + "AAAA" + "\xf9\xbf\x0f\x40" + "\x90" * 28 + "\x70" 이 형태로 작성하면 될 것 이다.

     

     

     

     

    위의 글을 천천히 읽어보면 다음과 같은 결실을 맺을 수 있을 것이다.

     

     

     

    댓글

Designed by Tistory.