Easy Rev


핵심 코드를 보면 아래 코드 리턴 값이 10이면 된다.


v18 = __readfsqword(0x28u);

  v2 = 0;

  v3 = 3;

  v4 = 0;

  v8 = 79;

  v9 = 4;

  v10 = 36;

  v11 = 628;

  v12 = 117;

  v13 = 62;

  v14 = 2458;

  v15 = -101;

  v16 = 41;

  v17 = 239;

  for ( i = 0; i <= 9; ++i )

  {

    if ( v4 % 3 )

    {

      if ( v4 % 3 == 1 )

        v3 -= i;

      else

        v3 += i;

    }

    else

    {

      v3 *= i;

    }

    *(_DWORD *)(a1 + 4LL * i) = v3 ^ *(_DWORD *)(4LL * i + a1);

    ++v4;

  }

  for ( j = 0; j <= 9; ++j )

    *(_DWORD *)(4LL * j + a1) ^= 0xFu;

  for ( k = 0; k <= 9; ++k )

  {

    if ( *(_DWORD *)(4LL * k + a1) == *(&v8 + k) )

      ++v2;

  }

  return v2;

}



코드가 간단해서 리턴값을 대충 아래와 같이 구해주면 어떤 값이 나오는데 이걸 키 값으로 문제에서 제공해준 플래그 파일을 ubuntu 16.04 환경의 openssl로 aes-256-cbc 형식에 맞춰 복호화 해주면 된다.


get_key.py


table = [79, 4, 36, 628, 117, 62, 2458, -101, 41, 239]

result = []


for i in xrange(10):

    result.append(table[i] ^ 0x0F)


v3 = 3

v4 = 0

key = 0

for i in xrange(10):

    if (v4 % 3):

        if (v4 % 3 == 1):

            v3 -= i

        else:

            v3 += i

    else:

        v3 *= i

    result[i] ^= v3

    key += result[i]

    v4 += 1


print key



seori


쭉 디버깅하다보면 아래 코드에서 특정 리소스 값을 가져온 다음 간단한 xor 연산을 통해 복호화를 한다. 복호화된 값을 디버깅을 통해 확인해보면 jpeg 파일 헤더인걸 볼 수 있고 이 값을 쭉 긁어서 실행해보면 이미지 파일 내 플래그가 나온다.


int __cdecl sub_F211E0(int a1)

{

  int v1; // eax

  int v2; // eax

  int v3; // eax

  int v4; // eax

  int v5; // eax

  int v6; // eax

  int v7; // ST0C_4

  int v8; // eax

  int v9; // eax

  int v10; // eax

  char v12; // [esp+4h] [ebp-1Ch]

  int v13; // [esp+8h] [ebp-18h]

  void *Dst; // [esp+14h] [ebp-Ch]

  DWORD v15; // [esp+18h] [ebp-8h]

  DWORD i; // [esp+1Ch] [ebp-4h]


  v1 = sub_F21400(std::cout, "Hi FRIEND!");

  std::basic_ostream<char,std::char_traits<char>>::operator<<(v1, sub_F21740);

  v2 = sub_F21400(std::cout, "I HAVE PRETTY CAT. DO YOU WANT TO SEE A CAT? ");

  std::basic_ostream<char,std::char_traits<char>>::operator<<(v2, sub_F21740);

  v3 = sub_F21400(std::cout, "UNFORTUNATELY THE CAT IS HIDING :( ");

  std::basic_ostream<char,std::char_traits<char>>::operator<<(v3, sub_F21740);

  v4 = sub_F21400(std::cout, "FIND MY CAT!");

  std::basic_ostream<char,std::char_traits<char>>::operator<<(v4, sub_F21740);

  sub_F210F0();

  v12 = sub_F21080(a1);

  hModule = LoadLibraryW(L"Seori.exe");

  hResInfo = FindResourceW(hModule, (LPCWSTR)0x65, L"SEORI");

  v15 = SizeofResource(hModule, hResInfo);

  hResData = LoadResource(hModule, hResInfo);

  dword_F25380 = (int)LockResource(hResData);

  v13 = dword_F25380;

  Dst = malloc((v15 + 1) | -__CFADD__(v15, 1));

  memset(Dst, 0, v15 + 1);

  for ( i = 0; i < v15; ++i )

    *((_BYTE *)Dst + i) = v12 ^ *(_BYTE *)(i + v13);

  v5 = std::basic_ostream<char,std::char_traits<char>>::operator<<(std::cout, sub_F21740);

  v6 = std::basic_ostream<char,std::char_traits<char>>::operator<<(v5, -122569430);

  std::basic_ostream<char,std::char_traits<char>>::operator<<(v6, v7);

  v8 = sub_F21400(std::cout, "HAVE YOU SEEN MY CAT?");

  std::basic_ostream<char,std::char_traits<char>>::operator<<(v8, sub_F21740);

  v9 = sub_F21400(std::cout, "I THINK MY CAT IS REALLY CUTE.");

  std::basic_ostream<char,std::char_traits<char>>::operator<<(v9, sub_F21740);

  v10 = sub_F21400(std::cout, "I HOPE TO FIND MY CAT!");

  std::basic_ostream<char,std::char_traits<char>>::operator<<(v10, sub_F21740);

  return 0;

}



J._.n3utr0n


파일을 실행해서 디버깅해보면 drop.exe란 파일을 드랍한 다음 svchost.exe 프로세스를 생성해서 해당 프로세스에 drop.exe파일 내용을 삽입하고 drop.exe를 삭제한다. 디버깅을 통해 drop.exe를 삭제하지 않도록 한 후에 해당 파일을 ida로 다시 까보면 아래와 같이 플래그를 뿌려주는 코드가 나온다.


int __cdecl __noreturn main(int argc, const char **argv, const char **envp)

{

  char v3; // [esp+8h] [ebp-24h]

  int v4; // [esp+9h] [ebp-23h]

  int v5; // [esp+Dh] [ebp-1Fh]

  int v6; // [esp+11h] [ebp-1Bh]

  int v7; // [esp+15h] [ebp-17h]

  int v8; // [esp+19h] [ebp-13h]

  int v9; // [esp+1Dh] [ebp-Fh]

  int v10; // [esp+21h] [ebp-Bh]

  __int16 v11; // [esp+25h] [ebp-7h]

  char v12; // [esp+27h] [ebp-5h]


  v3 = -10;

  v4 = -762125422;

  v5 = -825702001;

  v6 = -627256692;

  v7 = -1663312432;

  v8 = -640377722;

  v9 = -1663840048;

  v10 = -791751733;

  v11 = -25128;

  v12 = 0;

  sub_10A1040("flag is : %s\n", &v3);

  exit(1);

}


근데 플래그에 해당하는 값이 뭔가 암호화된 것 같은 값이다. 플래그를 뿌려주는 함수들을 쭉쭉타고 들어가봐도 별다른게 없었다. 여기서 엄청 헤맸는데 헥스레이를 너무 맹신한게 문제였다. 해당 함수를 어셈으로 확인해보면 특정 분기 조건이 무조건 참이라 실행되지 않는 함수가 있다. 해당 함수를 보면 실제 플래그 복호화 루틴이 나온다. 디버깅으로 분기 조건을 수정해 복호화 루틴타게 해주면 플래그가 나온다.












'CTF > Writeup' 카테고리의 다른 글

Radar CTF 2019 Inj3c7  (0) 2019.04.05
Encrypt CTF 2019 Write up  (0) 2019.04.05
b00t2root CTF 2019 Web Writeup  (0) 2019.03.31
Securinets CTF Quals 2019 AutomateMe  (0) 2019.03.26
Securinets CTF Quals 2019 Web Writeup  (0) 2019.03.25
블로그 이미지

JeonYoungSin

메모 기록용 공간

,