프로그램을 리버싱 하다보면 401024 부분에 CMP EAX, ESI를 한 뒤 TRUE면 40103D로 점프하는것을 볼 수 있다. JE를 JNE로 바꿔주면 CMP가 FALSE여도 점프하게 만들 수 있을 것 같다. 따라서 JE(74 15)를 JNE(75 15)로 바꾸게 되면 문제의 조건을 우회하게 되어 풀리게 될 것 이다.
//dllmain.cpp
#include "stdio.h"
#include "windows.h"
#include "pch.h"
DWORD WINAPI CodeHooking(LPVOID lParam)
{
LPVOID TargetAddr = (LPVOID)0x401026; //0x401026 == JE SHORT 0040103D
DWORD OldProtect = 0;
// 0x401026 부터 1바이트 -> 권한 PAGE_READWRITE
VirtualProtect(TargetAddr, 1, PAGE_READWRITE, &OldProtect);
// [74 15] JE -> [75 15] JNE
*((LPBYTE)TargetAddr + 0) = 0x75;
return 0;
}
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
HANDLE hThread = NULL;
switch (fdwReason)
{
case DLL_PROCESS_ATTACH:
hThread = CreateThread(NULL, 0, CodeHooking, NULL, 0, NULL);
CloseHandle(hThread);
}
return TRUE;
}
//DLLinjector.cpp
#include <stdio.h>
#include <Windows.h>
void InjectDLL(DWORD pid, LPCSTR dll);
int main()
{
DWORD pid = NULL;
/*todo: path 수정할 것*/
const char* path = "C:\\\\Users\\\\dooly\\\\Desktop\\\\AISECU 2\\\\rev\\\\DLLInjector\\\\Release\\\\hack.dll";
if (GetFileAttributesA(path) == 0xffffffff)
{
printf("DLL not found.\\n");
return 1;
}
while (true)
{
printf("Target Process PID: ");
scanf_s("%d", &pid);
if (pid == 0) break;
InjectDLL(pid, path);
}
return 0;
}
void InjectDLL(DWORD pid, LPCSTR dll)
{
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
if (NULL == hProcess)
{
printf("Process not found\\n");
return;
}
LPVOID lpAddr = VirtualAllocEx(hProcess, NULL, strlen(dll) + 1, MEM_COMMIT, PAGE_READWRITE);
if (lpAddr)
{
WriteProcessMemory(hProcess, lpAddr, dll, strlen(dll), NULL);
LPTHREAD_START_ROUTINE pfnLoadLibraryA =
(LPTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandleA("kernel32.dll"), "LoadLibraryA");
if (pfnLoadLibraryA)
{
HANDLE hThread = CreateRemoteThread(hProcess, NULL, 0, pfnLoadLibraryA, lpAddr, 0, NULL);
if (hThread)
{
printf("Injection successful!\\n");
WaitForSingleObject(hThread, INFINITE);
CloseHandle(hThread);
}
else
{
printf("Injection failure.\\n");
}
}
VirtualFreeEx(hProcess, lpAddr, 0, MEM_RELEASE);
}
else
{
printf("VirtualAllocEx() failure.\\n");
return;
}
CloseHandle(hProcess);
}
위 코드를 빌드 이후 수업시간에 사용한 DLLinjector.cpp를 이용하여 프로세스에 injection하면 문제가 풀린다.
공격 성공 이후 ollydbg에 프로세스를 attach 해서 살펴보면 00401026 이 74 15에서 75 15로 바뀐걸 볼 수 있습니다.