드림핵 baisc #6을 보면 입력값을 맞으면 "Correct" , 틀리면 "Wrong"으로 출력된다.
baisc문제만 동일한 패턴으로 보이는 " __unwind { // __GSHandlerCheck" 해당 코드로 들어간다.
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;
}
들어가 보면 해당 코드가 나온다.
if ( (unsigned int)sub_140001000((__int64)v4) )
sub_140001000가 답을 가지고 있기에 이를 집중적으로 파고 들어가야 한다.
클릭을 하고 나면 아래에 코드가 나타난다.
int64 __fastcall sub_140001000(__int64 a1)
{
int i; // [rsp+0h] [rbp-18h]
for ( i = 0; (unsigned __int64)i < 0x12; ++i )
{
if ( byte_140003020[*(unsigned __int8 *)(a1 + i)] != byte_140003000[i] )
return 0i64;
}
return 1i64;
}
그럼 두 개의 바이트 값인 byte_140003000, byte_140003020이 나오며, 이 값을 다시 또 클릭해 보면 새로운 값이 나온다.
data:0000000140003000 byte_140003000 db 0, 4Dh, 51h, 50h, 0EFh, 0FBh, 0C3h, 0CFh, 92h, 45h
.data:0000000140003000 ; DATA XREF: sub_140001000+40↑o
.data:000000014000300A db 4Dh, 0CFh, 0F5h, 4, 40h, 50h, 43h, 63h, 0Eh dup(0)
.data:0000000140003020 ; unsigned __int8 byte_140003020[256]
.data:0000000140003020 byte_140003020 db 63h, 7Ch, 77h, 7Bh, 0F2h, 6Bh, 6Fh, 0C5h, 30h, 1, 67h
.data:0000000140003020 ; DATA XREF: sub_140001000+31↑o
.data:000000014000302B db 2Bh, 0FEh, 0D7h, 0ABh, 76h, 0CAh, 82h, 0C9h, 7Dh, 0FAh
.data:0000000140003035 db 59h, 47h, 0F0h, 0ADh, 0D4h, 0A2h, 0AFh, 9Ch, 0A4h, 72h
.data:000000014000303F db 0C0h, 0B7h, 0FDh, 93h, 26h, 36h, 3Fh, 0F7h, 0CCh, 34h
.data:0000000140003049 db 0A5h, 0E5h, 0F1h, 71h, 0D8h, 31h, 15h, 4, 0C7h, 23h
.data:0000000140003053 db 0C3h, 18h, 96h, 5, 9Ah, 7, 12h, 80h, 0E2h, 0EBh, 27h
.data:000000014000305E db 0B2h, 75h, 9, 83h, 2Ch, 1Ah, 1Bh, 6Eh, 5Ah, 0A0h, 52h
.data:0000000140003069 db 3Bh, 0D6h, 0B3h, 29h, 0E3h, 2Fh, 84h, 53h, 0D1h, 0
.data:0000000140003073 db 0EDh, 20h, 0FCh, 0B1h, 5Bh, 6Ah, 0CBh, 0BEh, 39h, 4Ah
.data:000000014000307D db 4Ch, 58h, 0CFh, 0D0h, 0EFh, 0AAh, 0FBh, 43h, 4Dh, 33h
.data:0000000140003087 db 85h, 45h, 0F9h, 2, 7Fh, 50h, 3Ch, 9Fh, 0A8h, 51h, 0A3h
.data:0000000140003092 db 40h, 8Fh, 92h, 9Dh, 38h, 0F5h, 0BCh, 0B6h, 0DAh, 21h
.data:000000014000309C db 10h, 0FFh, 0F3h, 0D2h, 0CDh, 0Ch, 13h, 0ECh, 5Fh, 97h
.data:00000001400030A6 db 44h, 17h, 0C4h, 0A7h, 7Eh, 3Dh, 64h, 5Dh, 19h, 73h
.data:00000001400030B0 db 60h, 81h, 4Fh, 0DCh, 22h, 2Ah, 90h, 88h, 46h, 0EEh
.data:00000001400030BA db 0B8h, 14h, 0DEh, 5Eh, 0Bh, 0DBh, 0E0h, 32h, 3Ah, 0Ah
.data:00000001400030C4 db 49h, 6, 24h, 5Ch, 0C2h, 0D3h, 0ACh, 62h, 91h, 95h, 0E4h
.data:00000001400030CF db 79h, 0E7h, 0C8h, 37h, 6Dh, 8Dh, 0D5h, 4Eh, 0A9h, 6Ch
.data:00000001400030D9 db 56h, 0F4h, 0EAh, 65h, 7Ah, 0AEh, 8, 0BAh, 78h, 25h
.data:00000001400030E3 db 2Eh, 1Ch, 0A6h, 0B4h, 0C6h, 0E8h, 0DDh, 74h, 1Fh, 4Bh
.data:00000001400030ED db 0BDh, 8Bh, 8Ah, 70h, 3Eh, 0B5h, 66h, 48h, 3, 0F6h, 0Eh
.data:00000001400030F8 db 61h, 35h, 57h, 0B9h, 86h, 0C1h, 1Dh, 9Eh, 0E1h, 0F8h
.data:0000000140003102 db 98h, 11h, 69h, 0D9h, 8Eh, 94h, 9Bh, 1Eh, 87h, 0E9h
.data:000000014000310C db 0CEh, 55h, 28h, 0DFh, 8Ch, 0A1h, 89h, 0Dh, 0BFh, 0E6h
.data:0000000140003116 db 42h, 68h, 41h, 99h, 2Dh, 0Fh, 0B0h, 54h, 0BBh, 16h
이 값을 구하기 위해선 프로그래밍을 해야 한다.
또한 저 값을 다 구할 순 있으나 반으로 나눠서 만들어 계산한다.
1번째 블록
db 2Bh, 0FEh, 0D7h, 0ABh, 76h, 0CAh, 82h, 0C9h, 7Dh, 0FAh
.data:0000000140003035 db 59h, 47h, 0F0h, 0ADh, 0D4h, 0A2h, 0AFh, 9Ch, 0A4h, 72h
.data:000000014000303F db 0C0h, 0B7h, 0FDh, 93h, 26h, 36h, 3Fh, 0F7h, 0CCh, 34h
.data:0000000140003049 db 0A5h, 0E5h, 0F1h, 71h, 0D8h, 31h, 15h, 4, 0C7h, 23h
.data:0000000140003053 db 0C3h, 18h, 96h, 5, 9Ah, 7, 12h, 80h, 0E2h, 0EBh, 27h
.data:000000014000305E db 0B2h, 75h, 9, 83h, 2Ch, 1Ah, 1Bh, 6Eh, 5Ah, 0A0h, 52h
.data:0000000140003069 db 3Bh, 0D6h, 0B3h, 29h, 0E3h, 2Fh, 84h, 53h, 0D1h, 0
.data:0000000140003073 db 0EDh, 20h, 0FCh, 0B1h, 5Bh, 6Ah, 0CBh, 0BEh, 39h, 4Ah
.data:000000014000307D db 4Ch, 58h, 0CFh, 0D0h, 0EFh, 0AAh, 0FBh, 43h, 4Dh, 33h
.data:0000000140003087 db 85h, 45h, 0F9h, 2, 7Fh, 50h, 3Ch, 9Fh, 0A8h, 51h, 0A3h
.data:0000000140003092 db 40h, 8Fh, 92h, 9Dh, 38h, 0F5h, 0BCh, 0B6h, 0DAh, 21h
.data:000000014000309C db 10h, 0FFh, 0F3h, 0D2h
2번째 블록
0CDh, 0Ch, 13h, 0ECh, 5Fh, 97h
.data:00000001400030A6 db 44h, 17h, 0C4h, 0A7h, 7Eh, 3Dh, 64h, 5Dh, 19h, 73h
.data:00000001400030B0 db 60h, 81h, 4Fh, 0DCh, 22h, 2Ah, 90h, 88h, 46h, 0EEh
.data:00000001400030BA db 0B8h, 14h, 0DEh, 5Eh, 0Bh, 0DBh, 0E0h, 32h, 3Ah, 0Ah
.data:00000001400030C4 db 49h, 6, 24h, 5Ch, 0C2h, 0D3h, 0ACh, 62h, 91h, 95h, 0E4h
.data:00000001400030CF db 79h, 0E7h, 0C8h, 37h, 6Dh, 8Dh, 0D5h, 4Eh, 0A9h, 6Ch
.data:00000001400030D9 db 56h, 0F4h, 0EAh, 65h, 7Ah, 0AEh, 8, 0BAh, 78h, 25h
.data:00000001400030E3 db 2Eh, 1Ch, 0A6h, 0B4h, 0C6h, 0E8h, 0DDh, 74h, 1Fh, 4Bh
.data:00000001400030ED db 0BDh, 8Bh, 8Ah, 70h, 3Eh, 0B5h, 66h, 48h, 3, 0F6h, 0Eh
.data:00000001400030F8 db 61h, 35h, 57h, 0B9h, 86h, 0C1h, 1Dh, 9Eh, 0E1h, 0F8h
.data:0000000140003102 db 98h, 11h, 69h, 0D9h, 8Eh, 94h, 9Bh, 1Eh, 87h, 0E9h
.data:000000014000310C db 0CEh, 55h, 28h, 0DFh, 8Ch, 0A1h, 89h, 0Dh, 0BFh, 0E6h
.data:0000000140003116 db 42h, 68h, 41h, 99h, 2Dh, 0Fh, 0B0h, 54h, 0BBh, 16h
byte_140003000인 값은 4D, 51, 50, EF, FB, C3, CF, 92 , 45, 4D, CF, F5, 04, 40, 50, 43, 63
byte_140003020인 값은 63, 7C, 77, 7B, F2, 6B, 6F, C5, 30, 01, 67, 2B, FE, D7, AB, 76, CA, 82, C9, 7D, FA, 59, 47, F0, AD, D4, A2, AF, 9C, A4, 72, C0, B7, FD, 93, 26, 36, 3F, F7, CC, 34, A5, E5, F1, 71, D8, 31, 15, 04, C7, 23, C3, 18, 96, 05, 9A, 07, 12, 80, E2, EB, 27, B2, 75, 09, 83, 2C, 1A, 1B, 6E, 5A, A0, 52, 3B, D6, B3, 29, E3, 2F, 84, 53, D1, 00, ED, 20, FC, B1, 5B, 6A, CB, BE, 39, 4A, 4C, 58, CF, D0, EF, AA, FB, 43, 4D, 33, 85, 45, F9, 02, 7F, 50, 3C, 9F, A8, 51, A3, 40, 8F, 92, 9D, 38, F5, BC, B6, DA, 21, 10, FF, F3, D2
앞 뒤에 0과 h를 빼고 프로그래밍 과정 중 "0x"를 넣어서 바이트를 계산해야 함
파이썬으로 개발하면 이러한 형태로 나온다.
str1 = [
0x00, 0x4D, 0x51, 0x50, 0xEF, 0xFB, 0xC3, 0xCF, 0x92, 0x45,
0x4D, 0xCF, 0xF5, 0x04, 0x40, 0x50, 0x43, 0x63
]
str2 = [
0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76,
0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0,
0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC, 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,
0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75,
0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84,
0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B, 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,
0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8,
0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2
]
str3 = bytearray(19)
for i in range(18):
for j in range(128):
if str2[j] == str1[i]:
str3[i] = j
break
print(str3.decode("utf-8"))
위 코드를 컴파일 돌려보면 출력 값으로 "Replac3_the_w0rld"가 나온다.
해당 값을 input에 넣으면 Correct가 떠서 flag를 획득할 수 있다.
해당 문제를 제출하면 된다.
이 문제를 풀 때 시간이 상당히 많이 소요되서 힘들었다..

'Security > Reverse Engineering' 카테고리의 다른 글
리버스 엔지니어링, 밑 바닥부터 시작하기 (5) (0) | 2024.04.13 |
---|---|
리버스 엔지니어링, 밑 바닥부터 시작하기 (4) (2) | 2023.11.01 |
리버스 엔지니어링, 밑 바닥부터 시작하기 (2) (2) | 2023.10.28 |
리버스 엔지니어링, 밑 바닥부터 시작하기 (1) (1) | 2023.10.27 |
리버스 엔지니어링, 밑 바닥부터 시작하기 (2) | 2023.10.25 |