ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Buffer Overflow-2
    Security/System 2018.01.29 00:05

    [소스코드 1]

    - Buffer Overflow공격을 진행하기 전에 우선 아래의 소스코드를 분석해본다.

    - Callee인 Func함수에서의 스택 구조는 아래와 같다.

     0012FB68

     BUF[4] 공간

     =>

     Test

     0012FB6C

     EBP

     =>

      sta

     0012FB70

     RET

     =>

     ck B

     0012FB74

     

     

     uffe

     0012FB78

     

     

     r Ov

     0012FB7C

     

     

     er F

     0012FB80

        low

     0012FB84

       0000

     0012FB88

       0000
     ...   ...

    - memcpy함수를 실행하면 EBP는 물론 RET까지 attack배열의 문자열로 덮어 버린다. 즉, memcpy함수는 Buffer Overflow에 취약한 함수임을 알 수 있다.


    [소스코드 2]

    - 그렇다면 RET값을 임의의 값으로 변경할 수 있지 않을까? 라는 의문이 든다. AAAA라는 값으로 RET값을 변경시켜 보자.

     0012FB68

     BUF[4] 공간

     =>

     Test

     0012FB6C

     EBP

     =>

      sta

     0012FB70

     RET

     =>

     ck B

     0012FB74

     

     

     uffe

     0012FB78

     

     

     r Ov

     0012FB7C

     

     

     er F

     0012FB80

        low

     0012FB84

       0000

     0012FB88

       0000
     ...  

     ...

    - 위의 표를 살펴보면 RET값에  "ck b"문자열이 들어가져 있는 것을 볼 수 있는데, 이것을 "AAAA"로 바꾸면 RET값을 "AAAA"로 바꿀 수 있을 것이다. 즉, attack문자열에서 8번 인덱스에 AAAA를 복사하면 원하는 대로 들어갈 것이다.

    - 소스코드를 수정하고 확인해보면 스택구조는 아래와 같다.

     0012FB68

     BUF[4] 공간

     =>

     Test

     0012FB6C

     EBP

     =>

      sta

     0012FB70

     RET

     =>

     AAAA

     0012FB74

     

     

     uffe

     0012FB78

     

     

     r Ov

     0012FB7C

     

     

     er F

     0012FB80

        low

     0012FB84

       0000

     0012FB88

       0000
     ...  

     ...


    [소스코드 3]

    - RET도 내가 원하는 임의의 값으로 변경해봤다. 그러면 RET에 내가 작성한 코드의 시작 주소를 넣어 실행시킬 수 있도록 하려면 어떻게 해야 할까? 일단 "BBBBCCCCDDDD"가 내가 작성한 쉘코드라고 가정하고 스택에 삽입한다.

    - 스택 공간은 아래와 같이 구성되어 있을 것이다.

     0012FB68

     BUF[4] 공간

     =>

     Test

     0012FB6C

     EBP

     =>

      sta

     0012FB70

     RET

     =>

     AAAA

     0012FB74

     

     

     BBBB

     0012FB78

     

     

     CCCC

     0012FB7C

     

     

     DDDD

     0012FB80

        low

     0012FB84

       0000

     0012FB88

       0000
     ...  

     ...



    [소스코드 4]

     - "BBBBCCCCDDDD"라는 쉘코드가 스택에 삽입 되었으니 이번에는 쉘코드를 실행시키기 위해서 RET값을 쉘코드의 주소로 바꿔줘야 한다.

    쉘코드의 주소는 표에서 나타나있듯이 0012FB74이다. 따라서 RET에 0012FB74를 넣어주면 되는데 리틀 엔디안 방식이기 때문에 역순으로 넣어주면 된다.

    [소스코드 5]

    - [소스코드 4]에서 쉘코드의 주소를 직접 넣어주었다. 하지만 다른 코드에서도 주소가 같을 것이라는 보장이 없다. 어디서나 RET에 쉘코드의 주소를 삽입하도록 할 수는 없을까? 

    RET할때 ESP값으로 JMP한다면 어떤 코드에서든지 쉘 코드를 실행시킬 수 있을 것이다. 즉, RET값을 JMP ESP가 실행되도록 바꿔줘야한다.


    - 그렇다면 JMP ESP를 쓰고 있는 주소를 확인해보자. 일단 현재의 프로그램에서는 JMP ESP를 쓰고 있지 않으므로 모듈에서도 확인해주기 위해 alt+e키를 눌러준다. 그러면 아래와 같이 창이 뜨는데 

    여기서 찾아볼 모듈의 이름은 선택한 후 엔터를 눌러 들어간 후 JMP ESP가 있는지 찾아본다.


    - 그러면 ntdll모듈에서 아래와 같이 JMP ESP주소를 확인할 수 있을 것이다.


    - 알아낸 JMP ESP주소를 RET값에다가 넣어준다. 그러면 JMP ESP명령어가 있는 곳으로 RET할 것이고 JMP ESP 명령어가 실행되어 쉘코드가 있는 곳으로 JMP할 것이다.


    [소스코드 6]

    - 아래는 stdcall방식이지만 [소스코드 5]와 같은 결과가 나온다. 쉘코드가 들어가는 위치를 바꾸어 주었다.



    - 이제 쉘코드가 실행되도록 RET를 변조해봤으니 쉘코드를 직접 작성해본다.

      아래와 같이 새로운 프로젝트를 만든다.



    - 프로젝트를 만든 후 FileView를 클릭한다. 작업은 shellcode.cpp에서 할 것이다.



    [소스코드 7]

    - 아래와 같은 코드를 작성하고 실행해본다.


    - 그러면 아래와 같이 cmd창이 뜬다.


    - 해당 코드의 실행파일을 ollydbg로 연다.

     아래와 같이 main함수의 패턴을 찾아서 main함수로 따라들어간다.


    - 블록 지정한 부분을 복사한다.


    - 아까 작성한 소스코드를 주석처리하고 아래와 같이 복사한 어셈블리어를 붙여넣고 밑줄친 부분처럼 적당히 수정해준다. (참고로 EBP-8이 아닌 EBP-C라면 C앞에 0x를 붙여 16진수인 것을 표현해야 한다. 다른 것도 마찬가지이다.)


    - 그리고 다시 실행해보면 아까와 같이 cmd창이 뜬다.

     

    - 다시 이 코드의 실행파일을 ollydbg로 열어준다.

      아까와 마찬가지로 main함수로 들어가서 아래의 블록지정한 부분을 복사하는데 복사할 때는 마우스 오른쪽버튼 Binary-Binary copy로 복사한다.


    - 복사한 값을 메모장에 붙여넣으면 아래와 같이 넣고 공백 부분을 \x로 채워준다.


    - [소스코드 5]의 "BBBBCCCCDDDD"을 지우고 만든 쉘코드를 넣어준다.


    [소스코드 8]

    - [소스코드 7]에서 작성한 코드를 실행해보면 cmd창은 정상적으로 뜨지만 main함수가 정상적으로 종료되지 않아서 아래와 같은 창이 뜬다.


    - 이 창을 뜨지 않도록 하려면 [소스코드 5]에 ExitProcess(0);을 추가해준다. 

    - 이번에도 [소스코드 7 ]과 같은 방식으로 쉘코드를 만들면 된다.






    'Security > System' 카테고리의 다른 글

    Buffer Overflow-2  (0) 2018.01.29
    Buffer Overflow-1  (0) 2018.01.27
    RET값 변조  (0) 2018.01.27
    adminstrator, root 계정 패스워드 초기화 방법  (0) 2018.01.13
    리눅스 취약점  (0) 2018.01.08
    패스워드 크래킹  (0) 2018.01.07

    댓글 0

~ ^ . ^ ~