본문 바로가기
Security/DreamHack

[DreamHack] Broken Password #634

by 고간디 2024. 6. 14.
int __fastcall main(int argc, const char **argv, const char **envp)
{
  int fd; // [rsp+Ch] [rbp-44h]
  _QWORD *v5; // [rsp+10h] [rbp-40h] BYREF
  __int64 v6; // [rsp+18h] [rbp-38h] BYREF
  char s2[40]; // [rsp+20h] [rbp-30h] BYREF
  unsigned __int64 v8; // [rsp+48h] [rbp-8h]

  v8 = __readfsqword(40u);
  proc_init();
  fd = open("/dev/urandom", 0);
  read(fd, password, 8uLL);
  close(fd);
  puts("can u guess me?");
  sleep(0);
  read_input(s2, 32);
  if ( !strncmp(password, s2, 8uLL) )
  {
    system("cat flag");
  }
  else
  {
    puts("wrong... :p");
    puts("can you try another path? maybe impossible");
    printf("> ");
    read_input(&v5, 8);
    printf("> ");
    read_input(&v6, 8);
    *v5 = v6;
    puts("wish your happy sleep");
  }
  return 0;
}

prob 파일 하나만 주어진다.

 

else 문에 있는 포인터 때문에 저걸로 문제를 풀어야 하는 걸까 고민했었는데 솔직히 저걸로 풀어내는 건 말이 안 된다 생각했다..

 

/dev/urandom은 난수를 뽑아낸다.

뽑아낸 난수가 아마 password 변수로 들어가는 것 같다.

 

strncmp() 함수를 사용해 입력한 값이 password와 일치하면 플래그를 출력해준다.

 


#include <string.h>

int strncmp(const char *string1, const char *string2, size_t count);

두 문자열을 비교하는데 NULL 문자, \0으로 문자열이 끝날 때까지만 비교를 수행한다.

 

string1이 sting2보다 작으면 음수, 같으면 0, 크면 양수를 리턴한다.

주어진 문제에서는 0 을 반환해야 플래그를 얻어낼 수 있다.

 

세 번째 인수로 비교 길이를 전달해주더라도 널 문자를 만나게 되면 비교가 종료된다.

이를 이용해서 문제를 풀어내야 한다.

 


/dev/urandom은 계속해서 값이 바뀌는 난수를 꺼내온다.

 

입력값으로 그냥 엔터를 주면 \0이랑 문자열 비교가 이루어진다.

이때 /dev/urandom의 난수의 첫 값이 00이면 \00랑 비교했을 때 0을 바로 반환하게 된다.

 

하지만 /dev/urandom을 내 맘대로 조작할 수는 없기 때문에 첫 값이 00인 난수가 뽑일 때까지 계속해서 시도해봤다.

256번 시도하면 적어도 1번은 00이 등장할 것이다.

 


계속 엔터값만을 보내다 보면 이렇게 플래그를 얻을 수 있다.

728x90
반응형

댓글