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

【pwnable.kr】lotto

lotto - 2 pt [writeup] 

Mommy! I made a lotto program for my homework.
do you want to play?


ssh [email protected] -p2222 (pw:guest)

scp -P 2222 -p [email protected]:/home/lotto/* ./下載程式。

IDA pseudocode

unsigned __int64 play()
{
  signed int i; // [rsp+Ch] [rbp-24h]
  signed int j; // [rsp+Ch] [rbp-24h]
  int v3; // [rsp+10h] [rbp-20h]
  signed int k; // [rsp+14h] [rbp-1Ch]
  int fd; // [rsp+1Ch] [rbp-14h]
  char buf[8]; // [rsp+20h] [rbp-10h]
  unsigned __int64 v7; // [rsp+28h] [rbp-8h]

  v7 = __readfsqword(0x28u);
  printf("Submit your 6 lotto bytes : ");
  fflush(stdout);
  read(0, submit, 6uLL);                        // user input
  puts("Lotto Start!");
  fd = open("/dev/urandom", 0);
  if ( fd == -1 )
  {
    puts("error. tell admin");
    exit(-1);
  }
  if ( (unsigned int)read(fd, buf, 6uLL) != 6 )
  {
    puts("error2. tell admin");
    exit(-1);
  }
  for ( i = 0; i <= 5; ++i )
    buf[i] = (unsigned __int8)buf[i] % 45u + 1; // 1-45
  close(fd);
  v3 = 0;
  for ( j = 0; j <= 5; ++j )
  {
    for ( k = 0; k <= 5; ++k )
    {
      if ( buf[j] == submit[k] )
        ++v3;
    }
  }
  if ( v3 == 6 )
    system("/bin/cat flag");
  else
    puts("bad luck...");
  return __readfsqword(0x28u) ^ v7;
}

主要的函式就是一個play,從STDIN read 6byte到submit陣列(位於bss段),從/dev/urandom讀6byte到buf陣列(位於stack)中,buf中每個字元%45+1,範圍(1-45)。然後判斷一下buf和submit,相等就拿flag。

漏洞發生在判斷相等的時候,判斷了6*6 36次。因此,只要submit中有一位和buf陣列中的一位相等,v3就等於6。概率大約是6/45(未排除多個數字重複的情況)。手工輸入一個ascii(1-45)的字元6次即可。我輸入的是空格(0x20)。

flag

- Select Menu -
1. Play Lotto
2. Help
3. Exit
1
Submit your 6 lotto bytes :
Lotto Start!
bad luck...
- Select Menu -
1. Play Lotto
2. Help
3. Exit
1
Submit your 6 lotto bytes :
Lotto Start!
sorry mom... I FORGOT to check duplicate numbers... :(