ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [시스템해킹 #5] RET SLED, FEBP
    EVI$ION/SYSTEM HACKING 2019. 6. 24. 22:45

    [RET SLED]

    • ret: 어셈블리어 명령어. POP EIP, JMP EIP
    • RET: 리턴 어드레스

    어셈블리어 명령어인 ret과 리턴 어드레스를 의미하는 RET은 철자가 같아 혼동의 여지가 있다. 이 둘의 구분을 위해 어셈블리어 명령어인 ret을 '가젯'이라 부르고, ret의 주소를 '가젯 주소'라 한다. (하지만 보통 가젯과 가젯 주소는 어셈블리어 ret의 주소로 혼용되곤 한다.) 가젯은 코드 영역에 위치하기 때문에 컴파일 시에 결정되고 고정적이다. 

     

    RET SLED의 목적은 ret(어셈블리어) 명령을 한번 더 실행시킴으로써 shellcode를 실행시키는 것이다. 

    리턴 어드레스(RET)에 ret 가젯을 삽입함으로써 리턴 어드레스를 뒤로 지연시키기 때문에 SLED라고 하며, 삽입된 ret 가젯을 통해 shellcode 주소로 점프하여 shellcode를 실행시킨다. (shellcode의 위치는 어디든 상관 없다.)

     

    RET SLED의 흐름은 ROP(Return Oriented Programming)에 사용되는 pop-pop-ret 가젯 흐름과 상당히 비슷하다.

     

     

    RET SLED 페이로드

    버퍼 + &ret (가젯 주소) + &shellcode (shellcode 주소) + shellcode

     

    RET SLED 예제

    아래 소스코드를 보면, 리턴 어드레스 부분에 들어가는 주소가 0xbf~(스택 영역)로 시작해도 안되고, 0x40~ (공유 라이브러리 영역)으로 시작해도 안되는 것을 알 수 있다. 따라서 RET SLED를 이용하여 리턴 어드레스 부분에 코드 영역(0x08~)의 주소를 삽입해야 한다.

     

    가젯 주소 = 0x804851e = \x1e\x85\x0x\x08

     

    리턴 어드레스 자리에 코드 영역의 주소인 ret 가젯 주소를 넣는다. 그리고 그 뒤에 shellcode 주소를 넣어야 하는데, shellcode 주소를 알아내기 위해서 아래와 같이 덤프한다. 적당히 NOP이 있는 곳을 shellcode 시작 주소로 본다.

     

    shellcode 주소 = 0xbffffa05

     

    알아낸 shellcode 주소를 ret 가젯 주소 뒤에 삽입하면 된다.

     

    [FEBP (Fake EBP)]

    리턴 어드레스인 RET에 스택 주소나 라이브러리 주소를 덮어씌울 수 없을 때 사용하는 기법이다. EBP를 조작하여 leave-ret 가젯을 한번 더 실행시키는 기법으로, 이 기법을 사용하기 위해서는 함수 에필로그에 대한 이해가 필요하다.

     

    <LEAVE>

    MOV ESP, EBP

    POP EBP

     

    <RET>

    POP EIP

    JMP EIP

     

     

    먼저 함수 프롤로그가 수행된 직후의 스택을 보면 아래와 같다. 함수가 막 호출되어 ebp와 esp가 같아진 상태이다.

    함수 프롤로그 수행 직후

    위 상태에서 함수가 계속 수행이 되고, 수행이 끝나면 leave 명령어가 수행될 것이다. leave 명령어의 POP EBP가 수행되면 스택 상태는 아래처럼 된다. 

    leave - pop ebp 수행 직후

    이 상태에서 ret 명령어의 POP EIP를 수행하면 ESP가 RET+4의 위치로 이동한다.

     

    위와 같은 상태에서 leave-ret 과정을 다시 수행한다. leave 수행 과정은 아래와 같다.

    leave - mov esp, ebp 수행 후
    leave - pop ebp 수행 후

    leave 명령어 수행 후 ret을 실행하면 EIP의 코드 영역이 실행될 것이다.

     

    여기까지의 설명을 참고하여 FEBP가 어떻게 수행되는지 알아보자.

    함수가 호출되어 함수 프롤로그가 수행된 후, 버퍼의 맨 처음 4바이트에 shellcode의 주소를 넣고, 바로 뒤에 shellcode를 넣은 다음, SFP는 &buf-4, RET에는 leave-ret 가젯으로 덮어씌운다. 이 상태에서 leave 명령어를 수행하면 ebp는 &buf-4를 가리키고, esp는 RET을 가리키게 된다. 그 다음 ret 명령어를 수행하면 esp는 RET+4를 가리키고 eip는 다시 RET을 가리키게 되므로, eip에 의해 RET에 있는 leave-ret 과정을 한번 더 수행하게 된다. 

    다시 한번 leave 명령어가 수행되면 esp가 &shellcode를 가리키게 되고, 이 상태에서 ret 명령어가 수행되면 eip에 의해 shellcode가 실행되게 된다.

    FEBP 실행 과정

     

    FEBP 페이로드

    버퍼 시작 주소(=shellcode 주소) + (버퍼 시작 주소 - 4) + (leave/ret 가젯 주소)

                                                            SFP                         RET

     

    꼭 위와 같은 형태일 필요는 없으나, 반드시 버퍼 맨 처음에 shellcode의 주소가 들어가야 하고, SFP에 (버퍼 시작 주소 - 4)가 들어가야 한다.

     

     

    참고문헌

    https://d4m0n.tistory.com/88

Designed by Tistory.