Protostar - Stack 7 (쉘 코드 + 버퍼 오버플로우 + RTL)

oolongeya

·

2021. 9. 12. 17:58

stack7.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
 
char *getpath()
{
  char buffer[64];
  unsigned int ret;
 
  printf("input path please: "); fflush(stdout);
 
  gets(buffer);
 
  ret = __builtin_return_address(0);
 
  if((ret & 0xb0000000== 0xb0000000) {
      printf("bzzzt (%p)\n", ret);
      _exit(1);
  }
 
  printf("got path %s\n", buffer);
  return strdup(buffer);
}
 
int main(int argc, char **argv)
{
  getpath();
}
cs

중간 조건문을 보면 ret의 값이 0xb를 포함하게되면 exit 하는 것을 확인할 수 있다.

이 부분에 걸리지 않고 지나가면 되는 것이다.

 

참고로 문제를 풀 때, 주어진 문제 파일로 풀 수 있고, 소스코드를 직접 작성한 뒤 컴파일해서 푸는 경우가 있는데, 이는 환경(x86, x64)이 다르므로 페이로드 코드도 달라진다. 이 점 유의하자.

 

gdb를 사용해서 getpath 함수 부분을 살펴보자.

참고로 이 문제는 직접 코드 작성한 후 x64환경에서 풀이하는 것을 권장한다.

 

필요한 것은

 

1. system()의 주소

2. /bin/sh의 주소

3. 스택의 첫번째 요소로 가기 위한 패딩 값

 

main에 b를 걸고 run, conti  해서 찾아보자

찾는 과정은 이전 문제와 동일하다.

 

 

rtl 기법을 위해 pop rdi; ret의 주소도 구하자

 

 

구한 정보들로 페이로드를 작성하면,

 

 

쉘을 얻을 수 있다

 

또다른 방법도 있다.

 

ret에 값을 확인해서 공격을 막는건데, 이런 ret에 jmp rsp 값을 넣게되면,

rsp가 shellcode를 가리킬 때 공격이 성공할 것이다. (rsp, esp는 스택포인터)

 

아래 글을 통해 칼리의 보안 기능을 끄는 것을 확인할 수 있다.

https://kkomii22.tistory.com/69?category=970038 

 

Protostar - Stack 5 (쉘 코드 + 버퍼 오버플로우 + attach)

Stack5.c 1 2 3 4 5 6 7 8 9 10 11 #include #include #include #include int main(int argc, char **argv) {   char buffer[64];   gets(buffer); } cs 단계가 올라갈 수록 코드의 길이가 짧아진다. 함..

kkomii22.tistory.com

buf = 쉘코드 를 복사해서 페이로드에 작성한다.

 

 

또한 gdb 에서 jmpcall rsp 명령어를 통해

 

jmp rsp 의 주소를 얻을 수 있다.

 

따라서 최종 페이로드는

 

'A' * offset + jmp_rsp + buf가 되는것이다.

 

반응형