[Dreamhack] randzzz

chrmqgozj·2025년 2월 12일

DreamHack

목록 보기
25/39
  1. main
int __fastcall main(int argc, const char **argv, const char **envp)
{
  __int64 v4[3]; // [rsp+0h] [rbp-A0h]
  __int64 v5[3]; // [rsp+18h] [rbp-88h] BYREF
  __int64 v6[3]; // [rsp+30h] [rbp-70h]
  int v7; // [rsp+48h] [rbp-58h]
  char v8[68]; // [rsp+50h] [rbp-50h] BYREF
  unsigned int seconds; // [rsp+94h] [rbp-Ch] BYREF
  int j; // [rsp+98h] [rbp-8h]
  int i; // [rsp+9Ch] [rbp-4h]

  puts("----Start----");
  sleep(1u);
  puts("fall asleep from now on.");
  seconds = rand() + 1;
  sleep(seconds);
  rand();
  rand();
  printf("Can you guess the rand num?: ");
  __isoc99_scanf("%d", &seconds);
  if ( rand() % 10 == seconds )
  {
    v6[0] = 0x386C2C39364C396CLL;
    v6[1] = 0x30383338AC4C4C39LL;
    v6[2] = 0x353330354CCCCC34LL;
    v7 = -865323092;
    for ( i = 0; i <= 27; ++i )
      v8[i] = get_flag((unsigned int)*((char *)v6 + i), seconds);
  }
  if ( rand() % 10 == seconds )
  {
    v4[0] = 0x1B323838330B1335LL;
    v4[1] = 0xB332323361B2333LL;
    v4[2] = 0x23391B0B38370B13LL;
    qmemcpy(v5, "3539458369+8", 12);
    for ( j = 0; j <= 35; ++j )
      v8[j + 28] = get_flag((unsigned int)*((char *)v4 + j), seconds);
  }
  printf("DH{%s}", v8);
  return 0;
}

내가 입력할 수 있는 건 seconds. 알맞은 seconds를 입력하면 get_flag 함수가 실행된다.
문제는 rand()값을 어떻게 구하느냐이다.

첫 번째 if문에서 플래그의 앞자리 28개를 출력하고, 두 번째 if문에서 플래그의 뒤 36자리를 출력한다.
각각에 대해서 seconds를 실행하면 된다.

srand(time())이 아니기 때문에 rand()값이 고정이다.
따라서 ctypes를 쓰면 바로 해결이 될 것이다.
일단 저 sleep(seconds)가 신경 쓰이니까 패치하자.

  1. flag

앞자리는 알아낼 수 있는데 뒷자리를 알아내려면 앞자리가 있어야 한다.
그러면 gdb script로 해볼까?

앞자리: DH{c8b48ac08bbe00068ffb6606e2cf}

  1. gdb script

0x555555555407에 break를 걸고 5->3으로 변경하면 된다.
엄... 사실 gdb script 쓸 것도 없이 gdb로 까서 임의로 하면 바로 된다. ㅎ 사실 테스트 용으로 일단 넣어본건데

0개의 댓글