stack7

oogu ㅣ 2022. 9. 11. 14:02

#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)
", ret);
      _exit(1);
  }

  printf("got path %s
", buffer);
  return strdup(buffer);
}

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

  getpath();

}

stack6 문제에서 if 문이 달라졌다.  

[그림 1-1]

[그림 1-1] 은 stack6번 exploit 이다. ret 값에 system_addr 값이 들어가는데 if문에서 0xb0000000 과 and 연산 결과가 0xb0000000 나오면 안된다.

[그림 1-2]

system_addr 과 and 연산에 결과가 0xb0000000 이다. 따라서 RTL 방법은 사용할 수 없다.

shellcode 를 넣고 shellcode 위치를 직접 가리킬 수 없고 시스템 주소도 넣을 수 없다, 따라서 stack7 문제는 ROP 로 해결해 보자.

[그림 1-3]

 

[그림 1-4]

[그림 1-3] 참조하면 [그림 1-4] 그릴 수 있다.

ROP 기법을 사용한다. 따라서 payload는 "A" * 80 + ret 명령어 주소 + system 함수 주소 + dummy + /bin/sh 이다.

[그림 1-5]

ret 명령어 주소는 [그림 1-5] 처럼 쉽게 구할 수 있다.

[그림 1-6]
[그림 1-7]

성공!

 

[그림 2-1]

rop 주소는 gdb 에서 프로그램 실행 후 ropgadget 명령어로 구할 수 있다. 

[그림 2-1] 확인하면 popret, pop2ret .. 확인할 수 있는데 말그대로 pop 명령어 수행 후 ret 수행한다는 뜻이다. 숫자는 pop 횟수이다. pop을 하는 이유는 스택에서 system 함수를 넣는 위치가 프로그램 실행되면서 다른 값으로 변조되면 엉뚱한 곳으로 eip가 실행되기 때문에 변조되는 부분은 pop으로 스택에서 빼기위함이다.

 

ROP 와 비슷한 jmpcall esp 방법으로 stack7 풀 수 있다.

[그림 2-2]

jmpcall esp libc 입력하면 jmp, call 명령어를 사용하는 주소가 뜬다. 따라서 payload를 "A" * 80 + jmp rsp 명령어 주소 + shellcode 입력하면 된다.

하지만 주소를 확인하면 0x7fff.. 이므로 if문에서 걸린다. 원래는 다른 주소도 떠야하는데 컴파일러 마다 차이가 있어 뜨지않아 결국 ROP로 풀어야한다. 째든 원리는 이해하자!

'protostar' 카테고리의 다른 글

format2  (0) 2023.01.24
format0  (0) 2023.01.24
stack6  (0) 2022.09.09
stack5 - Return to libc(RTL)  (0) 2022.09.07
stack5 - 쉘 코드  (0) 2022.09.07