본문 바로가기

Write-up

[DPCTF 2013] 도어락 문제 풀이

반응형

분야 : 리버싱 


이번 문제는 겁나 쉬운 문제이므로 빨리빨리 하도록 하겠습니다.


일단 이 문제는 아이다를 키면 겁나 쉬운문제

올리디버거는 약간 그냥 그런 문제가 됩니다...

(망할 헥스레이 갑...)


일단 아이다를 키고 구조를 보면...


WTF.....


그러나 짱짱리버서 오타해커군이 KSIA 세미나에서 그런말을 하였습니다.

누가누가 분석을 적게하면서 많이 볼수잇나...

음 그래 난 짱리버서이니 하겠지...는 무슨 일단

TEXT VIEW로 가서 EP를 봅니다.


.text:00401000                 push    ebp

.text:00401001                 mov     ebp, esp

.text:00401003                 and     esp, 0FFFFFFF8h

.text:00401006                 sub     esp, 8

.text:00401009                 cmp     ds:IsDebuggerPresent, 0

.text:00401010                 jz      short loc_40101B

.text:00401012                 mov     eax, 1

.text:00401017                 mov     esp, ebp

.text:00401019                 pop     ebp

.text:0040101A                 retn


어서 디버거 성님이 계시네요.

그렇지만 실행하는게 아니므로 PATH


그러나 다음 난관

.text:0040101B                 mov     eax, ds:?endl@std@@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@1@AAV21@@Z ; std::endl(std::basic_ostream<char,std::char_traits<char>> &)

.text:00401020                 push    eax

.text:00401021                 push    ecx

.text:00401022                 mov     ecx, ds:?cout@std@@3V?$basic_ostream@DU?$char_traits@D@std@@@1@A ; std::basic_ostream<char,std::char_traits<char>> std::cout

.text:00401028                 push    offset asc_402124 ; "------------------------------"

.text:0040102D                 push    ecx

.text:0040102E                 call    sub_401390

.text:00401033                 add     esp, 0Ch

.text:00401036                 mov     ecx, eax

.text:00401038                 call    ds:??6?$basic_ostream@DU?$char_traits@D@std@@@std@@QAEAAV01@P6AAAV01@AAV01@@Z@Z ; std::basic_ostream<char,std::char_traits<char>>::operator<<(std::basic_ostream<char,std::char_traits<char>> & (*)(std::basic_ostream<char,std::char_traits<char>> &))

.text:0040103E                 mov     edx, ds:?endl@std@@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@1@AAV21@@Z ; std::endl(std::basic_ostream<char,std::char_traits<char>> &)

.text:00401044                 mov     eax, ds:?cout@std@@3V?$basic_ostream@DU?$char_traits@D@std@@@1@A ; std::basic_ostream<char,std::char_traits<char>> std::cout

.text:00401049                 push    edx

.text:0040104A                 push    ecx

.text:0040104B                 push    offset aSuperHardHouse ; "Super hard houseKey Protection"

.text:00401050                 push    eax

.text:00401051                 call    sub_401390

.text:00401056                 add     esp, 0Ch

.text:00401059                 mov     ecx, eax

.text:0040105B                 call    ds:??6?$basic_ostream@DU?$char_traits@D@std@@@std@@QAEAAV01@P6AAAV01@AAV01@@Z@Z ; std::basic_ostream<char,std::char_traits<char>>::operator<<(std::basic_ostream<char,std::char_traits<char>> & (*)(std::basic_ostream<char,std::char_traits<char>> &))

.text:00401061                 mov     ecx, ds:?endl@std@@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@1@AAV21@@Z ; std::endl(std::basic_ostream<char,std::char_traits<char>> &)

.text:00401067                 mov     edx, ds:?cout@std@@3V?$basic_ostream@DU?$char_traits@D@std@@@1@A ; std::basic_ostream<char,std::char_traits<char>> std::cout

.text:0040106D                 push    ecx

.text:0040106E                 push    ecx

.text:0040106F                 push    offset asc_402124 ; "------------------------------"

.text:00401074                 push    edx

.text:00401075                 call    sub_401390

.text:0040107A                 add     esp, 0Ch

.text:0040107D                 mov     ecx, eax

.text:0040107F                 call    ds:??6?$basic_ostream@DU?$char_traits@D@std@@@std@@QAEAAV01@P6AAAV01@AAV01@@Z@Z ; std::basic_ostream<char,std::char_traits<char>>::operator<<(std::basic_ostream<char,std::char_traits<char>> & (*)(std::basic_ostream<char,std::char_traits<char>> &))

.text:00401085                 mov     eax, ds:?endl@std@@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@1@AAV21@@Z ; std::endl(std::basic_ostream<char,std::char_traits<char>> &)

.text:0040108A                 push    eax

.text:0040108B                 push    ecx

.text:0040108C                 mov     ecx, ds:?cout@std@@3V?$basic_ostream@DU?$char_traits@D@std@@@1@A ; std::basic_ostream<char,std::char_traits<char>> std::cout

.text:00401092                 push    offset asc_402124 ; "------------------------------"

.text:00401097                 push    ecx

.text:00401098                 call    sub_401390

.text:0040109D                 add     esp, 0Ch

.text:004010A0                 mov     ecx, eax

.text:004010A2                 call    ds:??6?$basic_ostream@DU?$char_traits@D@std@@@std@@QAEAAV01@P6AAAV01@AAV01@@Z@Z ; std::basic_ostream<char,std::char_traits<char>>::operator<<(std::basic_ostream<char,std::char_traits<char>> & (*)(std::basic_ostream<char,std::char_traits<char>> &))

.text:004010A8                 mov     edx, ds:?endl@std@@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@1@AAV21@@Z ; std::endl(std::basic_ostream<char,std::char_traits<char>> &)

.text:004010AE                 mov     eax, ds:?cout@std@@3V?$basic_ostream@DU?$char_traits@D@std@@@1@A ; std::basic_ostream<char,std::char_traits<char>> std::cout

.text:004010B3                 push    edx

.text:004010B4                 push    ecx

.text:004010B5                 push    offset aHideFunctionIn ; "******HIDE FUNCTION INFO******"

.text:004010BA                 push    eax

.text:004010BB                 call    sub_401390

.text:004010C0                 add     esp, 0Ch

.text:004010C3                 mov     ecx, eax

.text:004010C5                 call    ds:??6?$basic_ostream@DU?$char_traits@D@std@@@std@@QAEAAV01@P6AAAV01@AAV01@@Z@Z ; std::basic_ostream<char,std::char_traits<char>>::operator<<(std::basic_ostream<char,std::char_traits<char>> & (*)(std::basic_ostream<char,std::char_traits<char>> &))

.text:004010CB                 mov     ecx, ds:?endl@std@@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@1@AAV21@@Z ; std::endl(std::basic_ostream<char,std::char_traits<char>> &)

.text:004010D1                 mov     edx, ds:?cout@std@@3V?$basic_ostream@DU?$char_traits@D@std@@@1@A ; std::basic_ostream<char,std::char_traits<char>> std::cout

.text:004010D7                 push    ecx

.text:004010D8                 push    ecx

.text:004010D9                 push    offset asc_402124 ; "------------------------------"

.text:004010DE                 push    edx

.text:004010DF                 call    sub_401390

.text:004010E4                 add     esp, 0Ch

.text:004010E7                 mov     ecx, eax

.text:004010E9                 call    ds:??6?$basic_ostream@DU?$char_traits@D@std@@@std@@QAEAAV01@P6AAAV01@AAV01@@Z@Z ; std::basic_ostream<char,std::char_traits<char>>::operator<<(std::basic_ostream<char,std::char_traits<char>> & (*)(std::basic_ostream<char,std::char_traits<char>> &))

.text:004010EF                 mov     eax, ds:?cout@std@@3V?$basic_ostream@DU?$char_traits@D@std@@@1@A ; std::basic_ostream<char,std::char_traits<char>> std::cout

.text:004010F4                 push    offset aInputFunctionN ; "Input function number to execute : "

.text:004010F9                 push    eax

.text:004010FA                 call    sub_401390

.text:004010FF                 lea     ecx, [esp+10h+var_4]

.text:00401103                 push    ecx

.text:00401104                 push    offset Format   ; "%d"

.text:00401109                 call    ds:scanf

.text:0040110F                 mov     edx, [esp+18h+var_4]

.text:00401113                 push    edx

.text:00401114                 call    sub_401130

.text:00401119                 add     esp, 14h

.text:0040111C                 xor     eax, eax

.text:0040111E                 mov     esp, ebp

.text:00401120                 pop     ebp

.text:00401121                 retn

KIAA........

이게 전형적인 c++입니다.

겁나 어렵... 게 보이지만 분석 조금만 해보다 보면..

std::cout<<""<<std::endl (일반적으로 std는 using namespace std; 로..)


해석하면 print 해주고 나서 기능 부분을 입력받습니다.


어셈에 지겨울 때 쯤...

저는 hex-ray 성님을 꺼내 간단하게 줄입니다.


에프뽜이브!!!!!


int __cdecl sub_401130(int a1)

{

  int result; // eax@3

  char v2; // [sp+0h] [bp-24h]@4


  if ( a1 == 19960215 )

  {

    result = printf("Givemethecake\n");

  }

  else

  {

    if ( a1 == 20131117 )

    {

      printf("Input password : ");

      scanf("%s", &v2);

      result = sub_4011C0();

    }

    else

    {

      result = puts("Wrong ");

    }

  }

  return result;

}


만약 19960215가 나오면 givemethecake 띄웁니다

(이 글을 보는 여러분은 매년 2월 15일날 저에게 생일케잌을 주셔야 합니다 끆)

... ㅈㅅ


일단 20131117을 누르면 password를 누르라는게 뜹니다. ㅎㅎ

그리고 sub_4011C0 함수로 이동하게 되는데요...


이 함수로 이.동


int __usercall sub_4011C0<eax>(const char *a1<esi>)

{

  signed int v1; // eax@4

  char v2; // dl@5

  char v3; // dl@5

  char v4; // dl@5

  const char *v6; // [sp-4h] [bp-5Ch]@2

  int v7; // [sp+0h] [bp-58h]@4

  int v8; // [sp+4h] [bp-54h]@4

  int v9; // [sp+8h] [bp-50h]@4

  int v10; // [sp+Ch] [bp-4Ch]@4

  int v11; // [sp+10h] [bp-48h]@4

  int v12; // [sp+14h] [bp-44h]@4

  int v13; // [sp+18h] [bp-40h]@4

  int v14; // [sp+1Ch] [bp-3Ch]@4

  int v15; // [sp+20h] [bp-38h]@4

  int v16; // [sp+24h] [bp-34h]@4

  int v17; // [sp+28h] [bp-30h]@4

  int v18; // [sp+2Ch] [bp-2Ch]@4

  int v19; // [sp+30h] [bp-28h]@4

  char Dest; // [sp+34h] [bp-24h]@6

  char v21; // [sp+44h] [bp-14h]@5

  char v22; // [sp+45h] [bp-13h]@5

  char v23; // [sp+46h] [bp-12h]@5

  char v24; // [sp+47h] [bp-11h]@5

  char v25; // [sp+48h] [bp-10h]@5

  char v26[11]; // [sp+49h] [bp-Fh]@5


  if ( strlen(a1) >= 0x1E )

  {

    v6 = "Buffer overflow!";

    return puts(v6);

  }

  if ( strcmp(a1, "Ehdvlfdl") )

  {

    v6 = "not match";

    return puts(v6);

  }

  puts("Unlock success!");

  v7 = 100;

  v11 = 100;

  v8 = 108;

  v13 = 108;

  v18 = 108;

  v9 = 119;

  v10 = 106;

  v12 = 118;

  v14 = 102;

  v15 = 101;

  v16 = 111;

  v17 = 102;

  v19 = 0;

  v1 = 0;

  do

  {

    v2 = *((_BYTE *)&v8 + 4 * v1);

    *(&v21 + v1) += *((_BYTE *)&v7 + 4 * v1);

    *(&v22 + v1) += v2;

    v3 = *((_BYTE *)&v10 + 4 * v1);

    *(&v23 + v1) += *((_BYTE *)&v9 + 4 * v1);

    *(&v24 + v1) += v3;

    v4 = *((_BYTE *)&v12 + 4 * v1);

    *(&v25 + v1) += *((_BYTE *)&v11 + 4 * v1);

    v26[v1] += v4;

    v1 += 6;

  }

  while ( v1 < 12 );

  return sprintf(&Dest, "%s", &v21);

}


음...음... 예

이 부분 해석하면 만약에 패스워드가 Ehdvlfdl 라면 sprintf 함수 소환

아니면 틀림


그러면 Ehdvlfdl 입력하고 난 다음 부분에 sprintf 에 찍힐 곳이 정답이므로..


  v7 = 100;

  v11 = 100;

  v8 = 108;

  v13 = 108;

  v18 = 108;

  v9 = 119;

  v10 = 106;

  v12 = 118;

  v14 = 102;

  v15 = 101;

  v16 = 111;

  v17 = 102;

  v19 = 0;

  v1 = 0;

  do

  {

    v2 = *((_BYTE *)&v8 + 4 * v1);

    *(&v21 + v1) += *((_BYTE *)&v7 + 4 * v1);

    *(&v22 + v1) += v2;

    v3 = *((_BYTE *)&v10 + 4 * v1);

    *(&v23 + v1) += *((_BYTE *)&v9 + 4 * v1);

    *(&v24 + v1) += v3;

    v4 = *((_BYTE *)&v12 + 4 * v1);

    *(&v25 + v1) += *((_BYTE *)&v11 + 4 * v1);

    v26[v1] += v4;

    v1 += 6;

  }

  while ( v1 < 12 );

  return sprintf(&Dest, "%s", &v21);


이 부분에 집중합니다.

이 부분은 12 번 돌린다는 건데

저 위를 아스키 코드로 바꿔서 하는게 정답이므로 일단 저는 출제자이므로 코딩은 알아서..ㅎㅎ


ascii 로 변환하면

Key is dlwjdvlfeofl

반응형