전공쪽/pwnable.tw

[pwnable.tw] starbound

OSOR2 2020. 12. 31. 15:53

starbound 문제의 writeup 이다. 보호기법은 다음 사진과 같다. 

이 문제는 매우 크고 방대하기 때문에 자세한 분석은 하지 않았다. 세세한 기능은 파악하지 않고 취약점만 찾았다. 


취약점

int __cdecl main(int argc, const char **argv, const char **envp)
{
  int v3; // eax
  char nptr; // [esp+10h] [ebp-104h]

  init();
  while ( 1 )
  {
    alarm(0x3Cu);
    dword_805817C();
    if ( !readn(&nptr, 0x100u) )
      break;
    v3 = strtol(&nptr, 0, 10);
    if ( !v3 )
      break;
    ((void (*)(void))dword_8058154[v3])();
  }
  do_bye();
  return 0;
}

취약점은 main함수에서 발생한다. 이 프로그램은 메뉴선택시 특정한 배열에 함수들을 포인터로 관리하고 있다가 호출하는 방식인데, main에서 oob에러가 나기 때문에 전역변수 부분을 컨트롤 할 수 있다면 내가 원하는 주소로 호출이 가능하다. 

 

그래서 이 전역변수 부분을 이용하기 가장 쉬운 부분은 set_name 부분이다. 

ssize_t cmd_set_name()
{
  ssize_t result; // eax

  __printf_chk(1, "Enter your name: ");
  result = readn(&unk_80580D0, 0x64u);
  *(_BYTE *)(result + 0x80580CF) = 0;
  return result;
}

여기서 0x80580d0에 값을 세팅해줄 수 있는데 나는 여기서 0x80499a6으로 세팅했다. 

여기서 readn하는 부분인데, 0x80499a6에서는 size는 설정안하고 src만 설정한다. 그런데 이상태에서 read를 하면 size가 스택에 있는 값으로 들어가서 bof 취약점을 이용할 수 있다. 

libc파일을 주지 않았고, 쉘도 잘 안따져서 바이너리 안에 존재하는 open , read, puts 함수를 이용해 /home/starbound/flag파일을 출력해주었다.