stack6

oogu ㅣ 2022. 9. 9. 13:32

 

#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>

void getpath()
{
  char buffer[64];
  unsigned int ret;

  printf("input path please: "); fflush(stdout);

  gets(buffer);

  ret = __builtin_return_address(0);

  if((ret & 0xbf000000) == 0xbf000000) {
      printf("bzzzt (%p)\n", ret);
      _exit(1);
  }

  printf("got path %s\n", buffer);
}

int main(int argc, char **argv)
{

  getpath();
}

__builtin_return_address(0) 함수는 현재 함수 동작이 끝나고 돌아가야할 곳, 다시 말하면 나를 호출한 곳의 다음 주소값을 변수 ret에 넣는다. 즉, 스택 프레임에서 ret 값을 가져온다.

그 후 변수 ret 값을 bf000000 와 and 연산을 하고 bf000000 와 같으면 종료시켜버린다.  즉, and 연산 후 bf000000 값이 나오면 안된다.

 

[그림 1-1]

 

main 함수는 맛이 없다.

[그림 1-2]
[그림 1-3]

[그림 1-2] 참조하면 [그림 1-3] 나온다.

따라서 payload  = "A" * 80 + shellcode 위치 + shellcode 해보자

shellcode 위치를 먼저 찾아보자

[그림 1-4]
[그림 1-5]

[그림 1-4] 값을 넣으면 [그림 1-5]가 되는데 ret(0xffffd07c) 값에 BBBB 가 들어간 걸 확인할 수 있다. 따라서 0xffffd07c 다음 주소에 shellcode를 넣고 0xffffd07c 값에 shellcode 위치(0xffffd080) 을 넣으면 된다.

따라서 변수 ret 값은 0xffffd080 이 되는데 0xbf000000 와 and 연산을 해보자

[그림 1-6]

and 연산의 결과가 bf000000이다. 따라서 if문에 들어가기 때문에 변수 ret 값은 0xffffd080 이 될 수 없다.

shellcode 를 넣고 이동할 수 없으니 RTL 방법을 사용해보자

[그림 1-7]

system 함수 주소값은 0xf7e1df10 이다.  0xf7e1df10 and 0xbf000000 해보자

[그림 1-8]

and 연산 결과값이 bf000000 이 아니므로 if 문을 넘어간다, 따라서 stack6 문제는 RTL 방법으로 풀면된다,

[그림 2-1]
[그림 2-2]

성공

'protostar' 카테고리의 다른 글

format0  (0) 2023.01.24
stack7  (0) 2022.09.11
stack5 - Return to libc(RTL)  (0) 2022.09.07
stack5 - 쉘 코드  (0) 2022.09.07
stack4  (0) 2022.09.07