안녕하세요. 해킹하는 개발자가 되고 싶은 컴공 대학생입니다.
정보 보안 분야에 관심이 많아 드림핵으로 리버스 엔지니어링 학습 중입니다.
드림핵 사이트의 워게임 rev-basic-5 문제 풀이 진행하겠습니다.
https://dreamhack.io/wargame/challenges/19/
문제 유형을 파악하기 위해 Windows의 PowerShell을 이용하여 프로그램을 실행시켜줍니다. 아래와 같이 임의의 문자열을 입력하면 'Wrong'이 출력됩니다.
이를 통해 오답 시 'Wrong', 정답 시 'Correct'가 출력됨을 예측할 수 있습니다.
main 함수를 디컴파일합니다. (단축키 F5)
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_1400011C0("Input : ", argv, envp);
sub_140001220("%256s", v4);
if ( (unsigned int)sub_140001000((__int64)v4) )
puts("Correct");
else
puts("Wrong");
return 0;
}
sub_140001000 함수를 더블클릭하여 함수의 내용을 확인합니다.
__int64 __fastcall sub_140001000(__int64 a1)
{
int i; // [rsp+0h] [rbp-18h]
for ( i = 0; (unsigned __int64)i < 0x18; ++i )
{
if ( *(unsigned __int8 *)(a1 + i + 1) + *(unsigned __int8 *)(a1 + i) != byte_140003000[i] )
return 0i64;
}
return 1i64;
}
함수 sub_140001000의 if절을 확인해보면
a1[i + 1] + a1[i] == byte_140003000[i]
를 만족해야함을 확인할 수 있습니다.
byte_140003000는 IDA에서 더블클릭하여 정보를 확인할 수 있습니다.
a1[1] + a1[0] = byte_140003000[0] = 0xAD
a1[2] + a1[1] = byte_140003000[1] = 0xD8
a1[3] + a1[2] = byte_140003000[2] = 0xCB
...
a1[17] + a1[16] = byte_140003000[16] = 0x4C
a1[18] + a1[17] = byte_140003000[17] = 0x00
마지막 식을 통해 a1[18]과 a1[17]은 unsigned이므로 0임을 파악할 수 있습니다.
이를 바탕으로 코드를 작성합니다.
nums = [0xAD, 0xD8, 0xCB, 0xCB, 0x9D, 0x97, 0xCB, 0xC4, 0x92, 0xA1, 0xD2, 0xD7, 0xD2, 0xD6, 0xA8, 0xA5, 0xDC, 0xC7, 0xAD, 0xA3, 0xA1, 0x98, 0x4C, 0x00]
res = [0] * (len(nums)+1)
res[0x17] = 0
res[0x18] = 0
i = 0
for i in reversed(range(len(nums))) :
res[i] = nums[i] - res[i + 1]
j = 0
for j in range(len(res)) :
print(chr(res[j]), end='')
All_l1fe_3nds_w1th_NULL
a1[17]과 a1[18]이 0임을 깨닫지 못했을 때,
정답이 문자열이라는 가정 하에 아스키코드를 참조하여 코드를 작성했습니다.
j = 0
for j in range(33, 127) :
i = 0
n = 0
res = []
res.append(j)
for i in range(len(nums)) :
res.append(nums[i] - res[i])
for n in range(len(res)) :
print(chr(res[n]), end='')
print()
a1[0]이 될 수 있는 문자를 하나씩 변경해가며 가능한 모든 문장을 확인했습니다.
위와 같이 출력되었고
이 중 가장 정답일 듯한 문장을 찾아냈습니다.
답은 찾았지만 부정확하여 옳은 방법은 아니라 생각됩니다.