1. 程式人生 > >【pwnable.kr】 mistake

【pwnable.kr】 mistake

這關很有意思,題目本意是一道原始碼中運算子優先順序導致的問題,如果直接看binary的話,看反編譯程式碼就不會被運算子優先順序迷惑。

先看一下反編譯程式碼,main函式。程式判斷/home/mistake/password能否開啟,再沒有別的檔案開啟的情況下open一般返回的fd是3。之後從stdin read 10byte,再用scanf讀取10byte 進行xor運算,之後兩者比較,如果相等就輸出flag。

IDA pseudocode:

int __cdecl main(int argc, const char **argv, const char **envp)
{
  int result; // eax
  int v4; // eax
  char buf; // [rsp+20h] [rbp-30h]
  char s2; // [rsp+30h] [rbp-20h]
  unsigned __int64 v7; // [rsp+48h] [rbp-8h]

  v7 = __readfsqword(0x28u);
  if ( open("/home/mistake/password", 0) >= 0 )
  {
    puts("do not bruteforce...");
    v4 = time(0LL);
    sleep(v4 % 20);
    if ( (signed int)read(0, &buf, 0xAuLL) > 0 )
    {
      printf("input password : ");
      __isoc99_scanf("%10s", &s2);
      xor((__int64)&s2, 10);
      if ( !strncmp(&buf, &s2, 0xAuLL) )
      {
        puts("Password OK");
        system("/bin/cat flag\n");
      }
      else
      {
        puts("Wrong Password");
      }
      close(0);
      result = 0;
    }
    else
    {
      puts("read error");
      close(0);
      result = 0;
    }
  }
  else
  {
    printf("can't open password %d\n");
    result = 0;
  }
  return result;
}

那麼輸入1111111111,0000000000即可。

再看一下題目原始碼,發現了mistake。fd=open("/home/mistake/password",O_RDONLY,0400) < 0中,判斷的優先順序要比賦值的高,open返回值是3,那麼fd的值就為假,也就是0了。