제리의 블로그

picoCTF 2018 be-quick-or-be-dead-2 Reversing 본문

CTF/reversing

picoCTF 2018 be-quick-or-be-dead-2 Reversing

j3rrry 2018. 10. 13. 02:00

be-quick-or-be-dead-2 - Points: 275 - (Solves: 393)

요약

본 Writeup 에서는 바이너리 패치하지 않고
파이썬 코드를 짜서 풀었습니다.

바이너리는 alarm(3) 알람 3초를 걸어놓은 상태에서
피보나치 수열 1015번째를 연산하여 나온 값을 이용해서
flag 를 디코딩하고 있었다.

피보나치 연산이 3초 안에 일어나지 않기 때문에
SIGALRM 시그널을 받고 종료되도록 핸들링된다.

피보나치 연산을 해주는 사이트에서 1015번째 수를 알아내서
int형에 맞추어 key 값을 넣어주고
decrypt_flag 해주면 된다.

Description

As you enjoy this music even more, another executable be-quick-or-be-dead-2 shows up.
Can you run this fast enough too?
You can also find the executable in /problems/be-quick-or-be-dead-2_0_04f4c579185361da6918bbc2fc9dcb7b.



void __cdecl set_timer()
{
  if ( __sysv_signal(SIGALRM, alarm_handler) == -1 )
  {
    printf(
      "\n\nSomething went terribly wrong. \nPlease contact the admins with \"be-quick-or-be-dead-2.c:%d\".\n",
      59LL);
    exit(0);
  }
  alarm(3u);
}
3초 알람을 설정하는 부분



int calculate_key()
{
  return fib(1015LL);
}
피보나치 1015번째 수를 연산하는 부분



코드

flag = '''5D AA 5D B8 6D 97 78 AC  5B AB 5B 88 56 AA 5C B8
5F A2 5D B4 5B 9C 4D B2  42 B6 5B B9 57 A6 61 B4
54 AD 61 B5 53 9C 5A B8  59 A6 61 B1 59 B0 4A 88
0E F0 5B E5 0E F6 0F B2  46'''.split()
flag = map(lambda x: int(x, 16), flag)

key = 0xD73EC32D

def get_byte(v1, n):
    if n == 0:
        return v1 & 0xff
    elif n == 1:
        return v1 >> 8 & 0xff
    elif n == 2:
        return v1 >> 16 & 0xff
    elif n == 3:
        return v1 >> 24 & 0xff

def decrypt_flag(a1):
  v1 = a1
  for i in range(0x39):
    flag[i] ^= get_byte(v1, i & 3)
    if i & 3 == 3:
      v1 += 1
  return ''.join(map(chr, flag))


print decrypt_flag(key)
이거 돌리면 플래그 나온다.


Comments