리버스 엔지니어링

[리버싱] 윈도우에서 아무것도 설치하지 않고 Hex Data 수정

Injel me 2020. 7. 1. 18:56

이번 글은 저번 메모장 시간/날짜 표시 변경 과 연결되는 이야기를 해 보려 한다.

윈도우에서 16진수 데이터를 다룰 수 있는 도구는 없다. 맞는가?

Debug.exe를 통해 도스시절 어셈블리 수정, 메모리 수정이 가능하다는 글을 봤기도 했고 검색도 했지만 사용법을 아직 모르겠어서 정리를 하지 않았다.

윈도우에서 기본으로 제공해 주는 메모장, 워드패드는 16진수를 지원하지 않는다. 정확히는 아스키코드 상(또는 유니코드상으로라도) 표시할 수 있는 문자만 표시한다.

가령, 0x77 등의 바이트는 출력하지 못하거나 공백으로 출력해 버린다는 소리이다.
그래서 16진수를 에디터처럼 다룰 수 없다고 알고있다.

그러나 우리의 윈도우 개발자는 더 발전된 커맨드라인 창, Windows PowerShell을 만들어냈고, 윈도우 7 이상부터는 기본적으로 깔려 있다.(윈도우 기본 파일이다)

그리고 나는 외국 포럼 등에서 가능한 방법을 찾아 내었다!

기본적으로 윈도우 파워쉘은 .Net이 주 축을 이루는 프로그램이다.

대부분의 명령어, 변수를 만들어 내는 것 등은 닷넷 오브젝트를 사용하고, 닷넷 함수를 사용한다.
심지어는 닷넷 특정 명령어에 한해 닷넷의 명령어를 직접 사용이 가능하다.

포럼에서 봤던 내용을 그대로 적어보겠다. 적은 명령어는 파란색이다.



PS C:\Users\user > $bytes = [System.IO.File]::ReadAllBytes("C:\파일.exe")
PS C:\Users\user > $bytes[0x오프셋] = 0x바이트
PS C:\Users\user > [System.IO.File]::WriteAllBytes("C:\파일.exe", $bytes)


일련의 과정을 통해 파일의 바이트를, 즉 hex data를 읽어 파일에 쓰는 것을 윈도우가 직접 허용한다.

엑세스의 문제는 파일 소유자나 파일의 쓰기 권한이 없을 때 일어나는, powershell의 문제가 아닌 독립적인 문제이다.

엑세스 오류가 나지 않고 잘 실행이 된다면, 윈도우에서 일련의 번거로운 과정으로라도 아무 프로그램도 깔지 않고 hex data를 수정할 수 있다.


이런 식으로 말이다.

실행 후 메모장을 켜 보면,

우리가 예전에 패치했던 대로 잘 패치되는 것을 볼 수 있다.


확장된 커맨드 창, Windows PowerShell은 막강한 힘을 가지고 있다고 많은 사람들이 말한다. PowerShell 스크립팅을 활용한 해킹 방법 등등.
우리는 여기서 파워쉘로 16진수 데이터를 파일에 쓰는 작업을 할 수 있다는 것을 알았다.

단순히 여기서 그치지 않고, 가령 인트라넷같이 인터넷을 사용할 수 없는 망에 있을 때 어떤 파일의 hex data를 모조리 알고, 암기를 한 사람이 있다면, 인터넷 없이 실행파일을 써 낼수도 있을 것이다. 가능하지 않은 일은 아니다. 쉘코드를 외워 다니는 사람도 있다고 알고있기 때문이다.

또한, 파워쉘의 닷넷 기반 명령어들을 사용하는데 있어 변수와 스크립팅, 단축어를 통해 더욱 쉽게 만들고 사용할 수 있을 것이라 감히 예상해본다.


--수정

'이를 사용해서 연습 겸' 메모장을 자동으로 패치시켜주는 프로그램을 작성했다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
#include <stdio.h>
#include <stdlib.h>
 
#define CSIZE 15
 
char batchfile[CSIZE][256= {
    "@echo off",
    "set file=\"c:\\Windows\\System32\\notepad.exe\"",
    "takeown /f %file%",
    "icacls %file% /grant Users:F",
    "powershell set-executionpolicy RemoteSigned",
    "echo $file = %file% > .\\patch.ps1",
    "echo $bytes = [System.IO.File]::ReadAllBytes($file) >> .\\patch.ps1",
    "echo $offset = 0x8c3f >> .\\patch.ps1",
    "echo $bytes[$offset] = 0x28 >> .\\patch.ps1",
    "echo $bytes[$offset + 1] = 0xfc >> .\\patch.ps1",
    "echo $offset = 0x8c65 >> .\\patch.ps1",
    "echo $bytes[$offset] = 0x5c >> .\\patch.ps1",
    "echo $bytes[$offset + 1] = 0xff >> .\\patch.ps1",
    "echo [System.IO.File]::WriteAllBytes($file, $bytes) >> .\\patch.ps1",
    "powershell .\\patch.ps1"
};
 
int main(int argc, char const *argv[])
{
    int mode;
    if (argc == 2) {
        mode = atoi(argv[1]);
    }
    else {
        printf("<option> : number\n");
        printf("\t1 : patch\n");
        printf("\t2 : reverse\n");
 
        printf("\noption : ");
        scanf("%d"&mode);
    }
 
    if (mode != 1 && mode != 2) {
        printf("option invalid!\n");
        system("pause");
        return 1;
    }
    if (mode == 2) {
        batchfile[7][19= '6';
        batchfile[7][20= '5';
 
        batchfile[10][19= '3';
        batchfile[10][20= 'f';
    }
 
    FILE * fp;
 
    fp = fopen(".\\batch.bat""w");
 
    if (fp == NULL) {
        printf("fopen fail\n");
        return 1;
    }
 
    for (int i = 0; i < CSIZE; i++) fprintf(fp, "%s\n", batchfile[i]);
    fclose(fp);
 
    system(".\\batch.bat");
 
    system("del -y .\\batch.bat");
    system("del -y .\\patch.ps1");
 
    printf("patch clear!\n");
    system("pause");
 
    return 0;
}
cs


프로그램을 실행시킬 때 인자를 줘서 프로그램을 실행시켜줘도 되고, 그냥 클릭해도 된다.

실행 시 이런식으로 뜨고 패치가 진행된다.

파일 권한과 소유를 바꾸는 cmd 명령어를 배치파일을 생성해 사용하기 때문에 프로그램은 관리자 권한으로 실행되는 것이 위의 윈도우 파워쉘 명령어의 파일 권한 문제로 인한 액세스 문제가 뜨지 않고 정상적으로 패치될 것이다.

notepad_autopatcher