본문 바로가기

CTF

[White Hacker League 2017] Medic

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
int __cdecl main(int argc, const char **argv, const char **envp)
{
  __int64 v3; // rax@1
  const char *v4; // rax@1
  __int64 v5; // rdx@4
  __int64 v6; // rax@5
  __int64 v7; // rax@6
  int result; // eax@7
  __int64 v9; // rdx@7
  int i; // [sp+Ch] [bp-84h]@1
  char v11; // [sp+10h] [bp-80h]@1
  __int64 v12; // [sp+78h] [bp-18h]@1
 
  v12 = *MK_FP(__FS__, 40LL);
  LODWORD(v3) = std::operator<<<std::char_traits<char>>(&std::cout"what is flag?", envp);
  std::ostream::operator<<(v3, &std::endl<char,std::char_traits<char>>);
  std::operator>><char,std::char_traits<char>>(&std::cin&v11);
  v4 = (const char *)fwgs(&v11);
  strcpy(&en, v4);
  for ( i = 0; i < strlen(&en); ++i )
    MagicStack::push((MagicStack *)&ms, *(&en + i));
  if ( (unsigned __int8)check_flag() )
  {
    LODWORD(v6) = std::operator<<<std::char_traits<char>>(&std::cout"good, you are smart student :)", v5);
    std::ostream::operator<<(v6, &std::endl<char,std::char_traits<char>>);
  }
  else
  {
    LODWORD(v7) = std::operator<<<std::char_traits<char>>(&std::cout"no... you should study harder :(", v5);
    std::ostream::operator<<(v7, &std::endl<char,std::char_traits<char>>);
  }
  result = 0;
  v9 = *MK_FP(__FS__, 40LL) ^ v12;
  return result;
}
cs

해당문제를 IDA로 보면 C++로 제작된걸 알 수 있는데 여기서 간단하게 분석해보면 fwgs 함수에서 입력한 문자열을 임의로 정한 base64 table로 encode 하는 걸 알 수 있다.

물론 처음엔 저게 base64 인코딩 하는 건줄 몰랐는데 조금 시간 투자해서 열심히 분석해보니 table만 다르고 base64와 동일하게 encoding 하는걸 알 수 있었다.

그 다음에 encoding 한 문자열 뒤집어서 fake 해쉬값과 secret_md5 해쉬값이랑 xor한 후 resu 배열과 비교하는데 전에 삼성 CTF 하스켈 문제나 xcz.kr base64 암호화 문제 같은 경우에는 브루트포스 했지만 이문제 같은 경우에는 encode한 문자열을 출력시켜주지 않아 파이썬으로 base64 encode, decode 소스를 직접 짜서 해결하였다.

[solve]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
def binary_number(str):
    bin = [0 for i in range(6)]
    for i in range(5-1-1):
        bin[i] = str & 1
        str >>= 1
    return bin
 
 
def demical_number(str):
    num = str[0]
    for i in range(18):
        num = num * 2 + str[i]
    return num
 
 
if __name__ == '__main__':
    b64_table = "ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba9876543210 /="
    dest = []
    s = []
    de = []
    de_str = ''
 
    fake = "J9UFF9EWv9AABCEOHFEKAqUNNnVcIaM0"
    secret_md5 = "5D8F988547D3B4087AE478403145ADC9"
    resu = [0x4F0x380x390x790x1B0x580x3E0x280x2D0x3A0x410x080x4A0x320x1B0x0E0x140x46,
            0x460x060x050x260x580x080x2A0x1A0x5B0x100x4E0x700x370x43]
    encoded_base64 = ''.join(chr(ord(fake[i]) ^ ord(secret_md5[i]) ^ resu[i]) for i in range(len(fake)))[::-1]
 
    str = encoded_base64
    for i in str:
        if i != '=':
            s += binary_number(b64_table.index(i))
 
    arr = []
    for i in range(len(s)):
        arr.append(s[i])
        if (i + 1) % 8 == 0 and i != 0:
            dest.append(arr)
            arr = []
 
    for i in range(len(dest)):
        de.append(demical_number(dest[i]))
 
    for i in range(len(de)):
        de_str += chr(de[i])
 
    print de_str
#CATSEC{IamFinePineApple}
cs


'CTF' 카테고리의 다른 글

[Codegate 2017] Goversing  (0) 2018.03.29
[angstromctf 2017] Product Key  (0) 2018.03.18
[White Hacker League 2017] Ghost  (0) 2018.03.05
[Codegate 2016] floppy  (0) 2018.03.03
[ROOTCTF 2017] Factorization(sandbag)  (0) 2018.02.24