Jaeseo's Information Security Story

Codeengn Basic RCE 16번 문제 본문

Write UP/Codeengn - basic

Codeengn Basic RCE 16번 문제

Jaeseokim 2019. 12. 3. 11:58

Basic RCE L16

Name이 CodeEngn일때 Serial을 구하시오

일단 문제를 풀기전에 PE 분석을 하고 시작합니다.

아무런 패킹 조치가 안되어 있는 것을 확인 했으니 IDA로 분석을 해봅니다.

일단 main 함수가 바로 보이고 C++로 짜여진 형태로 예상이 됩니다.

int __cdecl main(int argc, const char **argv, const char **envp)
{
  HANDLE v3; // eax
  _DWORD *v4; // eax
  unsigned int v5; // eax
  HANDLE v6; // eax
  HANDLE v7; // eax
  int v9; // [esp+0h] [ebp-A8h]
  unsigned int size; // [esp+1Ch] [ebp-8Ch]
  int v11; // [esp+30h] [ebp-78h]
  struct SjLj_Function_Context fctx; // [esp+34h] [ebp-74h]
  void *v13; // [esp+58h] [ebp-50h]
  int *v14; // [esp+5Ch] [ebp-4Ch]
  int v15; // [esp+68h] [ebp-40h]
  unsigned int v16; // [esp+6Ch] [ebp-3Ch]
  char v17; // [esp+70h] [ebp-38h]
  unsigned int v18; // [esp+88h] [ebp-20h]
  int v19; // [esp+8Ch] [ebp-1Ch]
  char v20; // [esp+90h] [ebp-18h]

  size = 16;
  _alloca(0x10u);
  fctx.personality = (_Unwind_Personality_Fn)__gxx_personality_sj0;
  fctx.lsda = dword_43DDE4;
  fctx.jbuf[0] = &v20;
  v13 = &loc_4016D4;
  v14 = &v9;
  _Unwind_SjLj_Register(&fctx);
  __main();
  fctx.call_site = -1;
  system("Title ReWrit's Crackme #5");
  system("mode con: Cols=31 Lines=16");
  v3 = GetStdHandle(0xFFFFFFF5);
  SetConsoleTextAttribute(v3, 0xEu);
  std::ostream::operator<<(&std::cout, std::endl<char,std::char_traits<char>>);
  std::operator<<<std::char_traits<char>>((int)&std::cout, " ReWrit's Crackme#5\n");
  std::operator<<<std::char_traits<char>>((int)&std::cout, " *****************************\n");
  std::operator<<<std::char_traits<char>>((int)&std::cout, " * This is my 5th crackme,   *\n");
  std::operator<<<std::char_traits<char>>((int)&std::cout, " * i hope you will enjoy it. *\n");
  std::operator<<<std::char_traits<char>>((int)&std::cout, " *****************************\n");
  std::operator<<<std::char_traits<char>>((int)&std::cout, "\n\n");
  std::operator<<<std::char_traits<char>>((int)&std::cout, " Enter your Name: ");
  // 메인 출력 메세지 및 Name 입력을 해다라는 안내 메세지를 출력
  v19 = 0;
  v18 = 0;
  std::string::string((std::string *)&v17);
  //v17에 string 형태로 받는다는 선언
  fctx.call_site = 1;
  v4 = (_DWORD *)std::operator>><char,std::char_traits<char>,std::allocator<char>>(&std::cin, &v17);
  //이 부분을 해석해볼려고 해봤지만 동적으로 분석을 해봐도 정확히 잘모르겠네요.... ㅠㅠ
  //V4부분에 00441EEC 라는 값이 저장이 되는데 이부분은 정확하게 무엇을 하는지 잘 모르겠습니다...
  v9 = (int)v4 + *(_DWORD *)(*v4 - 12);
  //00441EEC+(00441EEC-12)
  if ( std::basic_ios<char,std::char_traits<char>>::operator void *(v9) )
  {
    ++v19;
    v5 = std::string::length((std::string *)&v17);
    //v5에 Name에 해당하는 문자열의 길이를 저장
    if ( v5 > v18 )
    //만약 v5가 v18보다 크면 v18에 v17(Name)의 길이를 저장
      v18 = std::string::length((std::string *)&v17);
    v16 = 12 * v18 * 12 * v18 * 12 * v18 + 23;
    //v16에 12 * Name의 길이 * 12 * Name의 길이 * 12 * Name의 길이 + 23를 저장
    //Name이 CodeEngn 일때 884759
    fctx.call_site = 1;
    std::operator<<<std::char_traits<char>>((int)&std::cout, " Enter your Password: ");
    std::istream::operator>>(&std::cin, &v15);
    //Password를 v15에 입력을 받음
    v16 *= 708225;
    //이때 CodeEngn일때의 계산 결과 값은 6,325,271,499,225 이지만 unsigned int의 범위를 넘어 가기 때문에 4byte에 해당하는 결과 값만 저장 91 E4C6 0D97 -> E4C6 0D97‬ == 3,838,184,855‬
    //기존 계산된 v16에 708225를 곱함
    if ( v15 == v16 )
    //만약 그 값이 동일 하다면 성공 메세지 출력
    {
      v6 = GetStdHandle(0xFFFFFFF5);
      SetConsoleTextAttribute(v6, 0xAu);
      std::ostream::operator<<(&std::cout, std::endl<char,std::char_traits<char>>);
      std::operator<<<std::char_traits<char>>((int)&std::cout, " Good Job!\n");
      std::operator<<<std::char_traits<char>>((int)&std::cout, " =)");
    }
    else
    {
      fctx.call_site = 1;
      v7 = GetStdHandle(0xFFFFFFF5);
      SetConsoleTextAttribute(v7, 0xCu);
      std::ostream::operator<<(&std::cout, std::endl<char,std::char_traits<char>>);
      std::operator<<<std::char_traits<char>>((int)&std::cout, " Wrong password!\n");
      std::operator<<<std::char_traits<char>>((int)&std::cout, " =/");
    }
    system("pause > null");
    system("del null");
    fctx.call_site = -1;
    std::string::~string((std::string *)&v17);
    v11 = 0;
  }
  else
  {
    fctx.call_site = -1;
    std::string::~string((std::string *)&v17);
    v11 = 0;
  }
  _Unwind_SjLj_Unregister(&fctx);
  return v11;
}

프로그램을 분석해 보니 Name이 CodeEngn 일때의 Serial은 3838184855‬ 이라는 것을 확인할 수 있습니다.

AUTH:3838184855‬

'Write UP > Codeengn - basic' 카테고리의 다른 글

Codeengn Basic RCE 15번 문제  (0) 2019.12.01
Codeengn Basic RCE 14번 문제  (0) 2019.12.01
Codeengn Basic RCE 13번 문제  (0) 2019.11.30
Codeengn Basic RCE 12번 문제  (0) 2019.11.30
Codeengn Basic RCE 11번 문제  (0) 2019.11.30
Comments