블로그 이전했습니다. https://jeongzero.oopy.io/
[CodeEngine] Malware Analysis L05
본문 바로가기
워게임/CodeEngn

[CodeEngine] Malware Analysis L05

728x90

1. 문제


//int Malware_L05(char *StartOfData,char *Output,int SizeOfData)
#include <stdio.h>
int main()
{
    char *StartOfData = "hellohellohellohello";
    char *Output;
    int SizeOfData = 20;
    int encoded = 0, i, l = 0;
    char Table[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
    long buffer, buffer2;
    do
    {
        for (i = 3; i >= 0; i--, l++)
        {
            buffer2 = buffer;
            buffer2 &= 0x3f; // 6bit
            *(Output + i) = Table[buffer2];
            buffer >>= 6; // buffer = buffer >> 6
        }
        Output += 4;
        encoded += 4;
        SizeOfData -= 3;
        if (l == 76 && SizeOfData > 3)
        {
            *Output = 0xd;
            Output++;
            *Output = 0xa;
            Output++;
            encoded += 2;
            l = 0;
        }

    } while (SizeOfData != 0);
    return encoded;
}

위 함수가 뭐를 하는지를 알아야한다

2. 접근방법


딱 봐도 데이터를 인코딩하는것 같다. 중간 생략된 부분이 있지만 Table에서 특정 인덱스의 값을 가져와서 처리를 한다. 처음엔 그냥 encodeing, cryto 저렇게 답을 넣어봤지만 아니였다. 어떤 인코딩 기법인지를 정확히 써야하나..

이럴때 상수들을 검색해보는것이다. Table값에 들어있는 문자열을 검색해보면 단번에 어떤 알고리즘인지 나온다

정답은 바로 base64다. 확인해 보니 정답이 맞긴한데, 생각해보니 모듈가져다가 그냥 base64로 인코딩/디코딩만 해봤지 어떤 원리로 구현된 인코딩 기법인지는 생각해보지 않았다. 이 참에 한번 알아보자

3. 풀이


base64 인코딩이란 64진수 형태로 데이터를 표현하는 방식을 말한다. 컴퓨터는 2진 형태로 정보를 처리한다. 따라서 컴퓨터에서 base64를 표현하기 위해 2^6(=64), 즉 최소 6bit가 필요한데, 8bit기준으로 컴퓨터는 동작한다.

따라서 6과 8의 최소공배수인 24bit를 단위로 하여 base64는 데이터를 처리한다.

원본 데이터가 3바이트(24bit)라면 이를 6bit씩 쪼개 총 4개의 블럭이 생긴다. 따라서 base64 인코딩 결과는 4의 배수이다. 만약 원본데이터가 6bit의 배수가 아니라면 남는 영역을 0으로 채우고 이를 '=' 문자로 표시한다

보통 인터넷 상에서 메일이나 사진, 등의 데이터를 전송할 때 base64 인코딩을 통해서 동일하게 데이처를 처리할 수 있도록 한다. 이는 64개의 아스키 값을 이용해서 표현하게 된다

table = ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/

위 사진에서 쪼갠 6bit의 이진 데이터가 table의 인덱스 값으로 들어가고, 그 인덱스에 해당하는 값이 인코딩된 결과이다. 만약 원본 데이터의 bit가 4의 배수가 아니라면

위 64개의 아스키 값으로 어떻게 표현하는지 살펴보자.

원본 데이터가 'a' 라고 해보자. 이는 아스키 값으로 0x61이고 2진수로 01100001 이다.

이를 6비트로 쪼개면 011000 010000 000000 000000 으로 표현할 수 있다

각 자리를 10진수로 나타내면 24, 16, 0, 0 이며, 이 총 4개는 위 table의 인덱스값이다.

패딩으로 채운 0은 '=' 으로 표시한다

  • 011000 ⇒ table[24] : Y
  • 010000 ⇒ table[16] : Q
  • 0 ⇒ '='
  • 0 ⇒ '='

base64('a') ⇒ 'YQ=='

헌데 만일 @(0x40) 같은 문자를 인코딩하려고 하면 이는 2진수로 01000000 이고 6bit씩 쪼개면

  • 010000
  • 00

이다. 첫 6bit는 16이고 두번째는 0 이여서 각각 table[16], table[0] 이다

하지만 그 이상은 입력된 데이터가 없으므로 나머지 6bit 2개가 '=' 으로 채워진다

4. 몰랐던 개념


  • base64 원리
728x90

'워게임 > CodeEngn' 카테고리의 다른 글

[CodeEngine] Malware Analysis L07  (0) 2021.01.23
[CodeEngine] Malware Analysis L06  (0) 2021.01.23
[CodeEngine] Basic RCE L10  (0) 2021.01.21
[CodeEngine] Malware Analysis L03  (0) 2021.01.21
[CodeEngine] Malware Analysis L02  (0) 2021.01.20