[Stack] RET sled에 대하여

두비니

·

2020. 8. 8. 02:39

 

 

오늘은 RET Sled에 대해서 알아볼 것입니다.

RET Sled는 Return Address영역에 RET 명령어의 주소를 연속적으로 삽입해서 esp를 조작하는 기법입니다.

일단 RET의 구조를 한번 봅시다.

 


Internal of "ret"


pop eip
jmp eip

 

 

 

 

이해를 돕기 위해 그림도 가져왔습니다. 상황 자체는 함수의 에필로그 중 leave까지 진행한 상황이라고 가정합시다. 그러면 SFP 안의 값이 ebp안으로 들어가있겠죠? 그런 뒤 esp는 RET를 가리키고 있을 거고요. 그런 뒤에 ret가 실행되면서 RET(return address)안에 있는 값이 eip에 pop되고, 그 값으로 jmp(이동)하게 됩니다. 이 그림의 경우에는 ret를 통해서 0xaabbccdd라는 주소에 접근하게 되겠죠?

 

지금 제가 쭉 얘기한 과정이 뭔지 모르겠다면 함수의 에필로그를 정리하고 옵시다.

https://dokhakdubini.tistory.com/227?category=809542

 

[stack] 함수의 에필로그(epilogue)

함수의 에필로그(epilogue)에 대하여 오늘은 함수의 에필로그라는걸 배울 것입니다. 보통 함수의 프롤로그와 에필로그를 묶어서 설명하는데, 모든 함수의 처음(프롤로그)과 끝(에필로그)에 공통��

dokhakdubini.tistory.com

 

 

지금까지 다양한 기법들을 써왔지만 공통적인 부분은 결론적으로 RET에 우리가 원하는 주소값을 써서, 그 값에 접근했다는 점입니다. 그러나 이제 RET Sled를 쓰는 경우는 RET에 우리가 원하는 주소값을 쓰지 못하는 경우입니다.

예시코드 한번 불러와보겠습니다.

 

 

    1  /*
     2          The Lord of the BOF : The Fellowship of the BOF
     3          - assassin
     4          - no stack, no RTL
     5  */

     6  #include <stdio.h>
     7  #include <stdlib.h>

     8  main(int argc, char *argv[])
     9  {
    10          char buffer[40];

    11          if(argc < 2){
    12                  printf("argv error\n");
    13                  exit(0);
    14          }

    15          if(argv[1][47] == '\xbf')
    16          {
    17                  printf("stack retbayed you!\n");	//오타났대요 풉키
    18                  exit(0);	
    19          }

    20          if(argv[1][47] == '\x40')
    21          {
    22                  printf("library retbayed you, too!!\n");
    23                  exit(0);
    24          }

    25          strcpy(buffer, argv[1]);
    26          printf("%s\n", buffer);

    27          // buffer+sfp hunter
    28          memset(buffer, 0, 44);
    29  }

 

해당 코드는 LOB giant >> assassin 의 문제 코드입니다.

보면 return address 부분에 스택영역 및 라이브러리 영역을 사용할 수 없기 때문에 스택영역이나 라이브러리 영역으로 리턴할 수 없습니다.

물론 다른 방법도 있겠지만, 만약 return address가 argv[1][43]~argv[1][47]이 아닌 다른 영역이면 어떻게 될까요?

 

위에서 예시를 들어놓은 부분을 조금 바꾸어보겠습니다.

 

 

0xaabbccdd였던 주소가 0x804851e로 바뀌었죠? 주소값 0x804851e가 들어갔다고 가정해봅시다. 우선 조건이였던 \xbf \x40으로 시작하지 않기때문에 제한조건에 걸리는건 없고, ret를 통해서 0x804851e명령이 실행되게 됩니다. 근데 0x804851e의 명령을 보면 ret를 한번 더 실행하게 되죠?

결국 위의 과정을 또 반복을 하지만, 이번에 다른 점은 esp가 ret가 이미 한 번 실행된 상태이기 때문에 return address의 밑을 가리키고 있다는 것이죠. 그럼 만약에 return address밑에 shellcode의 주소를 넣어놓았다면 한번 더 ret가 실행되면서 shellcode가 실행이 되겠죠?

 

지금 예시에서는 ret의 주소를 한번만 넣었지만, 만약 ret의 주소를 n번 삽입하여 반복하게 된다면 우리가 원하는 곳을 ret로 설정해 줄 수 있겠죠? 이런식으로 ret가 반복되서 실행되기 때문에 RET Sled라는 이름이 붙었습니다.

 

 

이 RET Sled를 사용한 문제는 역시나 예제로 사용한 LOB giant >> assassin이 있습니다. 

문제 풀어봅시다 @^0^==@

'SYSTEM HACKING > PWNABLE&REVERSING' 카테고리의 다른 글

함수의 got 구하기  (0) 2020.10.09
[Stack] Fake EBP에 대하여  (2) 2020.08.31
[Stack] Frame Pointer Overflow, FPO에 대하여  (0) 2020.07.30
[stack] 함수의 에필로그(epilogue)  (0) 2020.07.30
[ROP] gadget찾는법  (0) 2019.10.11