Write-ups/pwnable.xyz

rwsr - pwnable.xyz

dolphinlmg 2020. 2. 15. 19:13

Prob Info


Prob Info
Checksec

Code


int __cdecl main(int argc, const char **argv, const char **envp)
{
  const char *v3; // rdi
  int v4; // eax
  char *s; // ST10_8

  setup();
  v3 = "Read Write Sleep Repeat.";
  puts("Read Write Sleep Repeat.");
  do
  {
    while ( 1 )
    {
      while ( 1 )
      {
        print_menu(v3);
        v4 = read_ulong();
        if ( v4 != 1 )
          break;
        printf("Addr: ", argv);
        v3 = (const char *)read_ulong();
        puts(v3);
      }
      if ( v4 != 2 )
        break;
      printf("Addr: ", argv);
      s = (char *)read_ulong();
      v3 = "Value: ";
      printf("Value: ");
      *(_QWORD *)s = read_ulong();
    }
  }
  while ( v4 );
  return 0;
}

제목의 뜻이 read write sleep repeat이였다. 원하는 주소에 값을 읽고, 쓸 수 있다. PIE가 걸려있지 않아 bss영역을 바로 건들어보았다.

 

bss에 stdin, stdout이 그대로 박혀있었다. 이를 통해 일단 libc leak을 할 수 있다. 그런데 Full RELRO이기 때문에 GOT를 덮을 수는 없다. 

 

여기까지 삽질하다가 exit함수의 free를 이용해 익스하는 방법을 찾아 진행했다. exit 함수 내부적으로 initial을 하나씩 free하는데, free_hook을 덮고 initial->idx을 0에서 1로 변경해주면 메인함수가 끝나고 exit을 실행하면서 free를 하게되어 free_hook으로 뛰게된다. 

 

이 방법 말고도 libc의 environ 변수를 읽어서 스택 주소를 릭하는 방법도 있다.