v0.1 - initial commit
This commit is contained in:
@@ -0,0 +1,166 @@
|
||||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
// Функция для парсинга PEB и поиска WinExec
|
||||
FARPROC FindWinExec() {
|
||||
// Получаем PEB через FS регистр
|
||||
#ifdef _WIN64
|
||||
PPEB pPEB = (PPEB)__readgsqword(0x60);
|
||||
#else
|
||||
PPEB pPEB = (PPEB)__readfsdword(0x30);
|
||||
#endif
|
||||
|
||||
// Получаем LDR (Loader Data)
|
||||
PPEB_LDR_DATA pLDR = pPEB->Ldr;
|
||||
|
||||
// Проходим по списку загруженных модулей
|
||||
LIST_ENTRY* pModuleList = &pLDR->InMemoryOrderModuleList;
|
||||
LIST_ENTRY* pEntry = pModuleList->Flink;
|
||||
|
||||
// Ищем kernel32.dll
|
||||
while (pEntry != pModuleList) {
|
||||
PLDR_DATA_TABLE_ENTRY pModule = CONTAINING_RECORD(pEntry, LDR_DATA_TABLE_ENTRY, InMemoryOrderLinks);
|
||||
|
||||
// Проверяем имя модуля
|
||||
WCHAR* moduleName = pModule->BaseDllName.Buffer;
|
||||
if (moduleName && wcsstr(moduleName, L"kernel32.dll")) {
|
||||
HMODULE hKernel32 = (HMODULE)pModule->DllBase;
|
||||
|
||||
// Ищем WinExec в kernel32.dll
|
||||
FARPROC pWinExec = GetProcAddress(hKernel32, "WinExec");
|
||||
if (pWinExec) {
|
||||
printf("[+] Found WinExec at: 0x%p\n", pWinExec);
|
||||
return pWinExec;
|
||||
}
|
||||
}
|
||||
pEntry = pEntry->Flink;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Функция для открытия и парсинга .exe файла
|
||||
void ParseExeFile(const char* filename) {
|
||||
HANDLE hFile = CreateFileA(
|
||||
filename,
|
||||
GENERIC_READ,
|
||||
FILE_SHARE_READ,
|
||||
NULL,
|
||||
OPEN_EXISTING,
|
||||
FILE_ATTRIBUTE_NORMAL,
|
||||
NULL
|
||||
);
|
||||
|
||||
if (hFile == INVALID_HANDLE_VALUE) {
|
||||
printf("[-] Failed to open file: %s\n", filename);
|
||||
return;
|
||||
}
|
||||
|
||||
// Читаем DOS заголовок
|
||||
IMAGE_DOS_HEADER dosHeader;
|
||||
DWORD bytesRead;
|
||||
if (!ReadFile(hFile, &dosHeader, sizeof(dosHeader), &bytesRead, NULL)) {
|
||||
printf("[-] Failed to read DOS header\n");
|
||||
CloseHandle(hFile);
|
||||
return;
|
||||
}
|
||||
|
||||
// Проверяем сигнатуру DOS
|
||||
if (dosHeader.e_magic != IMAGE_DOS_SIGNATURE) {
|
||||
printf("[-] Invalid DOS signature\n");
|
||||
CloseHandle(hFile);
|
||||
return;
|
||||
}
|
||||
|
||||
// Переходим к PE заголовку
|
||||
SetFilePointer(hFile, dosHeader.e_lfanew, NULL, FILE_BEGIN);
|
||||
|
||||
// Читаем PE сигнатуру
|
||||
DWORD peSignature;
|
||||
ReadFile(hFile, &peSignature, sizeof(peSignature), &bytesRead, NULL);
|
||||
|
||||
if (peSignature != IMAGE_NT_SIGNATURE) {
|
||||
printf("[-] Invalid PE signature\n");
|
||||
CloseHandle(hFile);
|
||||
return;
|
||||
}
|
||||
|
||||
// Читаем файловый заголовок
|
||||
IMAGE_FILE_HEADER fileHeader;
|
||||
ReadFile(hFile, &fileHeader, sizeof(fileHeader), &bytesRead, NULL);
|
||||
|
||||
printf("[+] File is a valid PE executable\n");
|
||||
printf("[+] Number of sections: %d\n", fileHeader.NumberOfSections);
|
||||
printf("[+] Size of optional header: %d\n", fileHeader.SizeOfOptionalHeader);
|
||||
|
||||
// Читаем опциональный заголовок
|
||||
IMAGE_OPTIONAL_HEADER32 optionalHeader;
|
||||
ReadFile(hFile, &optionalHeader, sizeof(optionalHeader), &bytesRead, NULL);
|
||||
|
||||
printf("[+] Entry point: 0x%X\n", optionalHeader.AddressOfEntryPoint);
|
||||
printf("[+] Image base: 0x%X\n", optionalHeader.ImageBase);
|
||||
|
||||
// Читаем секции
|
||||
printf("\n[+] Sections:\n");
|
||||
for (int i = 0; i < fileHeader.NumberOfSections; i++) {
|
||||
IMAGE_SECTION_HEADER sectionHeader;
|
||||
ReadFile(hFile, §ionHeader, sizeof(sectionHeader), &bytesRead, NULL);
|
||||
|
||||
printf(" %s - VA: 0x%X, Size: 0x%X\n",
|
||||
sectionHeader.Name,
|
||||
sectionHeader.VirtualAddress,
|
||||
sectionHeader.SizeOfRawData);
|
||||
}
|
||||
|
||||
CloseHandle(hFile);
|
||||
}
|
||||
|
||||
// Функция-победитель (win)
|
||||
void win(void) {
|
||||
printf("flag{ret2win_but_its_WINDOWS}\n");
|
||||
|
||||
// Находим WinExec через PEB
|
||||
FARPROC pWinExec = FindWinExec();
|
||||
if (pWinExec) {
|
||||
// Запускаем калькулятор через WinExec
|
||||
typedef void (*WinExec_t)(LPCSTR, UINT);
|
||||
WinExec_t WinExec_func = (WinExec_t)pWinExec;
|
||||
WinExec_func("mspaint.exe", SW_SHOW);
|
||||
printf("[+] paint launched!\n");
|
||||
}
|
||||
}
|
||||
|
||||
// Уязвимая функция
|
||||
void vulnerable_function() {
|
||||
char buf[16];
|
||||
|
||||
printf("enter your data:\n");
|
||||
scanf("%s", buf);
|
||||
|
||||
printf("try again\n");
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
printf("=== Windows Buffer Overflow CTF Challenge ===\n\n");
|
||||
|
||||
// Если передан аргумент, парсим .exe файл
|
||||
if (argc > 1) {
|
||||
printf("[*] Parsing PE file: %s\n", argv[1]);
|
||||
ParseExeFile(argv[1]);
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
// Демонстрируем поиск WinExec через PEB
|
||||
printf("[*] Finding WinExec via PEB parsing...\n");
|
||||
FARPROC pWinExec = FindWinExec();
|
||||
if (pWinExec) {
|
||||
printf("[+] WinExec found at: 0x%p\n", pWinExec);
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
// Вызываем уязвимую функцию
|
||||
vulnerable_function();
|
||||
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user