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문제의 소스코드를 볼 수 있다.
문제 설명
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보다 작아야 한다.
문제 풀이
main 함수 부분을 확인하니 getpath가 보이는 것을 알 수 있다 getpath함수를 한번 살펴보겠다.
getpath 함수부분을 확인해보면 getpath+49부분에서 ebp-0xc를 가져오는데 이 부분이 ret의 값이다.
그래서 pattern create 한다음 offset을 확인해보면 ret의 위치는 buffer에서 80바이트 떨어져있음을 알 수 있다.
offset 위치를 확인하였고 바로 공격코드를 작성해 보도록 하겠다.
먼저 buf에 0x90인 nop를 채워주어 아무것도 실행되지 않고 다음으로 넘어가도록하여 쉘코드를 실행하도록 하였고 payload는 ret위치까지 80바이트 채워주고 ret값에 적당히 nop위치로 잡아서 주소값을 채우고 buf를 뒤에 넣었다.
하지만 공격에 실패를 하고 bzzzt 0xffffd120이라고 출력을 하고 exit되었다. 왜 공격에 실패를 하였을까? bzzzt뒤에 우리가 넣은 ret의 주소를 출력하는데 0xffffd120으로 0xbf000000과 and 연산을 했을 때 0xbf000000이 나오므로 if문에서 참이되어 종료가 된것이다. 따라서 이 문제를 해결하기 위해서는 stack에 쉘코드를 심어놓고 ret에서 호출을 하면 안된다.
이 문제를 풀기 위해서는 RTL라는 기법을 사용하여 풀어야한다.
ret의 offset을 알고있기 때문에 system함수의 위치와 /bin/sh의 위치를 확인하였다.
바로 poc코드를 작성 해보도록 하겠다.
ret앞까지 A를 80개 채웠고 ret에 system함수의 위치를 넣었다. 그 다음 4바이트는 system함수가 실행되고 난 후 ret값이 들어가지만 우리는 쉘만 실행하면 되기 때문에 아무값으로 채웠고 그다음 /bin/sh의 위치를 넣어서 쉘을 실행하도록 코드를 작성하였다.
작성한 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 |