본문 바로가기
Reversing/드림핵

[Dreamhack] rev-basic-8

by L3m0n S0ju 2021. 4. 12.

 

 

 


문제에서 주어진 파일을 IDA Pro 7.5 디컴파일러로 디컴파일한 결과 아래와 같은 코드가 출력된다.

 

 

int __cdecl main(int argc, const char **argv, const char **envp)
{
  char v4[256]; // [rsp+20h] [rbp-118h] BYREF

  memset(v4, 0, sizeof(v4));
  sub_1400011B0("Input : ", argv, envp);
  sub_140001210("%256s", v4);
  if ( (unsigned int)sub_140001000(v4) )
    puts("Correct");
  else
    puts("Wrong");
  return 0;
}


__int64 __fastcall sub_140001000(__int64 a1)
{
  int i; // [rsp+0h] [rbp-18h]

  for ( i = 0; (unsigned __int64)i < 0x15; ++i )
  {
    if ( (unsigned __int8)(-5 * *(_BYTE *)(a1 + i)) != byte_140003000[i] )
      return 0i64;
  }
  return 1i64;
}

 


 

 

문제의 핵심은 if 안의 조건문이다.

 

if ( (unsigned __int8)(-5 * *(_BYTE *)(a1 + i)) != byte_140003000[i] ) 

 

내용을 요약하면 다음과 같다.

 

(-5) * 입력한 문자 = 140003000에 저장된 문자

 

해당 식을 for 문이 끝날 때까지 만족한다면 Correct를 출력한다. 여기서 -5는 정수이므로 4바이트 문자는 1바이트이다. 4바이트와 1바이트를 계산하면 1바이트 높은 주소부분을 0으로 채우고 4바이트로 만든 다음에 계산한다. 다음으로 unsigned __int8으로 형변환이 되므로 앞에 3바이트를 날려버린다. 그리고 140003000에 저장된 문자와 비교한다.

 

 


 

movsxd  rax, [rsp+18h+var_18]
mov     rcx, [rsp+18h+arg_0]
movzx   eax, byte ptr [rcx+rax]
imul    eax, 0FBh
and     eax, 0FFh
movsxd  rcx, [rsp+18h+var_18]
lea     rdx, byte_140003000
movzx   ecx, byte ptr [rdx+rcx]
cmp     eax, ecx
jz      short loc_140001053

 

 


위 코드는 조건문의 어셈블리 코드 부분이다. 주목해야할 점은 (-5)가 0FBh로 계산되고 있다는 점이다.

 

movzx   eax, byte ptr [rcx+rax] //입력한 문자를 eax에 저장한다.

imul    eax, 0FBh //입력한 문자에 0xFB(=-5)를 곱한다.

and     eax, 0FFh //높은 주소 3바이트를 날리고 1바이트로 만든다.

 

 

지금까지 내용을 요약하면 아래 식을 만족시키면 된다.

 

0xFB * 입력한 문자 = 140003000에 저장된 문자

 

0xFB와 입력한 문자의 곱이 올림수가 생기는 경우의수는 256가지다. 예를 들어 곱셈의 결과를 1바이트로 변환했을때 값을 a라고 하면 a, a+0x100, a+0x200, ... , a+0x9800, a+0x9900 과 같이 256가지의 경우의 수가 있으므로 브루트포스로 입력한 문자열을 추론하겠다. exploit 코드는 아래와 같다.

 


 

 

#include<stdio.h>
#include<stdlib.h>

int main(void)
{
    char buf[]={0xAC, 0xF3, 0x0C, 0x25, 0xA3, 0x10, 0xB7, 0x25, 0x16, 0xC6, 0xB7, 0xBC, 0x07, 0x25, 0x02, 0xD5, 0xC6,      0x11, 0x07, 0xC5,0x00 };

    int a;
    for(int j=0;j<21;j++)
    {  
        for(int i=0;i<256;i++)
        {  
        a=buf[j]+i*256;
        if(a%0xfb==0)
        {
            printf("%c",a/0xfb);
        }
    }
}


플래그: Did_y0u_brute_force?

'Reversing > 드림핵' 카테고리의 다른 글

[Dreamhack] rev-basic-6  (0) 2021.07.17
[Dreamhack] rev-basic-7  (0) 2021.03.30
[Dreamhack] rev-basic-5  (0) 2021.03.30
[Dreamhack] rev-basic-4  (0) 2021.03.30
[Dreamhack] rev-basic-3  (0) 2021.03.30

댓글