System hacking/프로토스타(Protostar)

Protostar Stack6[RTL]

Roronoa 2022. 9. 23. 21:40
반응형

Protostar Stack6

https://exploit.education/protostar/stack-six/

 

Stack Six :: Andrew Griffiths' Exploit Education

Stack Six Stack6 looks at what happens when you have restrictions on the return address. This level can be done in a couple of ways, such as finding the duplicate of the payload ( objdump -s will help with this), or ret2libc , or even return orientated pro

exploit.education

위 사이트에 접속을 하면 Stack Six문제의 소스코드를 볼 수 있다.

문제 설명

[그림 1] 문제 설명

Source Code

#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();
}

먼저 main화면에서 getpath()함수를 실행한다.

getpath()함수에서 fflush(stdout)이 있는데 fflush(out)을 사용하여 출력 버퍼를 비우고 버퍼의 저장된 내용을 출력하는 역할을 수행한다. 그리고 gets로 buffer에 문자열을 입력받고 있다.

__builtin_return_address(0) 이라는 함수가 있는데 구글링을 통해 살펴보니 현재 함수의 리턴주소를 불러오는 역할을 한다. 만약 __builtin_return_address(1)로 설정되어 있으면 자신을 호출 함수의 리턴주소를 불러 온다. 현재 함수의 리턴주소를 불러와 ret에 저장한 후 0xbf000000와 and 연산을 통해서 조건문을 검증한다. and 연산의 값이 0xbf000000으로 참이 되면 실행이 종료되므로 ret의 주소의 앞자리는 b보다작거나 두번째자리가 f보다 작아야 한다.

문제 풀이

[그림 1] main 함수

main 함수 부분을 확인하니 getpath가 보이는 것을 알 수 있다 getpath함수를 한번 살펴보겠다.

 

[그림 2] getpath 함수

getpath 함수부분을 확인해보면 getpath+49부분에서 ebp-0xc를 가져오는데 이 부분이 ret의 값이다.

그래서 pattern create 한다음 offset을 확인해보면 ret의 위치는 buffer에서 80바이트 떨어져있음을 알 수 있다.

 

[그림 3] offset 위치 확인

offset 위치를 확인하였고 바로 공격코드를 작성해 보도록 하겠다.

 

[그림 4] poc 코드 작성

먼저 buf에 0x90인 nop를 채워주어 아무것도 실행되지 않고 다음으로 넘어가도록하여 쉘코드를 실행하도록 하였고 payload는 ret위치까지 80바이트 채워주고 ret값에 적당히 nop위치로 잡아서 주소값을 채우고 buf를 뒤에 넣었다.

 

[그림 5] 공격 실패

하지만 공격에 실패를 하고 bzzzt 0xffffd120이라고 출력을 하고 exit되었다. 왜 공격에 실패를 하였을까? bzzzt뒤에 우리가 넣은 ret의 주소를 출력하는데 0xffffd120으로 0xbf000000과 and 연산을 했을 때 0xbf000000이 나오므로 if문에서 참이되어 종료가 된것이다. 따라서 이 문제를 해결하기 위해서는 stack에 쉘코드를 심어놓고 ret에서 호출을 하면 안된다.

이 문제를 풀기 위해서는 RTL라는 기법을 사용하여 풀어야한다.

 

[그림 6] system, /bin/sh 위치 확인

ret의 offset을 알고있기 때문에 system함수의 위치와 /bin/sh의 위치를 확인하였다.

바로 poc코드를 작성 해보도록 하겠다.

 

[그림 7] poc코드 작성

ret앞까지 A를 80개 채웠고 ret에 system함수의 위치를 넣었다. 그 다음 4바이트는 system함수가 실행되고 난 후 ret값이 들어가지만 우리는 쉘만 실행하면 되기 때문에 아무값으로 채웠고 그다음 /bin/sh의 위치를 넣어서 쉘을 실행하도록 코드를 작성하였다.

 

[그림 8] 익스플로잇 성공

 작성한 poc코드를 실행하여 익스플로잇에 성공하였다. ^^

반응형

'System hacking > 프로토스타(Protostar)' 카테고리의 다른 글

Protostar Stack7  (0) 2022.09.25
Protostar Stack5[RTL이용하여 문제 풀이]  (3) 2022.09.22
Protostar Stack5 문제  (1) 2022.09.21
Protostar Stack4 문제  (0) 2022.09.17
Protostar Stack3 문제  (0) 2022.09.16