Skip to content

Commit 8926a07

Browse files
committed
Add Remove and KillProcess modules
1 parent c463add commit 8926a07

File tree

9 files changed

+412
-0
lines changed

9 files changed

+412
-0
lines changed

modules/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ add_subdirectory(StealToken)
3030
add_subdirectory(Upload)
3131
add_subdirectory(Cat)
3232
add_subdirectory(MkDir)
33+
add_subdirectory(Remove)
34+
add_subdirectory(KillProcess)
3335
add_subdirectory(Tree)
3436
add_subdirectory(WmiExec)
3537
add_subdirectory(KeyLogger)

modules/KillProcess/CMakeLists.txt

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
include_directories(../)
2+
add_library(KillProcess SHARED KillProcess.cpp)
3+
set_property(TARGET KillProcess PROPERTY MSVC_RUNTIME_LIBRARY "MultiThreaded")
4+
target_link_libraries(KillProcess )
5+
add_custom_command(TARGET KillProcess POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy
6+
$<TARGET_FILE:KillProcess> "${CMAKE_SOURCE_DIR}/Release/Modules/$<TARGET_FILE_NAME:KillProcess>"
7+
)
8+
9+
if(WITH_TESTS)
10+
add_executable(testsKillProcess tests/testsKillProcess.cpp KillProcess.cpp)
11+
target_link_libraries(testsKillProcess )
12+
add_custom_command(TARGET testsKillProcess POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy
13+
$<TARGET_FILE:testsKillProcess> "${CMAKE_SOURCE_DIR}/Tests/$<TARGET_FILE_NAME:testsKillProcess>")
14+
15+
add_test(NAME testsKillProcess COMMAND "${CMAKE_SOURCE_DIR}/Tests/$<TARGET_FILE_NAME:testsKillProcess>")
16+
endif()
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
#include "KillProcess.hpp"
2+
3+
#include "Common.hpp"
4+
5+
#include <cstring>
6+
#ifdef __linux__
7+
#include <signal.h>
8+
#include <unistd.h>
9+
#elif _WIN32
10+
#include <windows.h>
11+
#endif
12+
13+
using namespace std;
14+
15+
constexpr std::string_view moduleName = "killProcess";
16+
constexpr unsigned long long moduleHash = djb2(moduleName);
17+
18+
#ifdef _WIN32
19+
__declspec(dllexport) KillProcess* KillProcessConstructor()
20+
{
21+
return new KillProcess();
22+
}
23+
#else
24+
__attribute__((visibility("default"))) KillProcess* KillProcessConstructor()
25+
{
26+
return new KillProcess();
27+
}
28+
#endif
29+
30+
KillProcess::KillProcess()
31+
#ifdef BUILD_TEAMSERVER
32+
: ModuleCmd(std::string(moduleName), moduleHash)
33+
#else
34+
: ModuleCmd("", moduleHash)
35+
#endif
36+
{
37+
}
38+
39+
KillProcess::~KillProcess()
40+
{
41+
}
42+
43+
std::string KillProcess::getInfo()
44+
{
45+
std::string info;
46+
#ifdef BUILD_TEAMSERVER
47+
info += "killProcess Module:\n";
48+
info += "Terminate a process by PID.\n";
49+
info += "\nUsage:\n";
50+
info += " - killProcess <pid>\n";
51+
#endif
52+
return info;
53+
}
54+
55+
int KillProcess::init(std::vector<std::string> &splitedCmd, C2Message &c2Message)
56+
{
57+
#if defined(BUILD_TEAMSERVER) || defined(BUILD_TESTS)
58+
if (splitedCmd.size() >= 2)
59+
{
60+
c2Message.set_instruction(splitedCmd[0]);
61+
c2Message.set_pid(std::stoi(splitedCmd[1]));
62+
}
63+
else
64+
{
65+
c2Message.set_returnvalue(getInfo());
66+
return -1;
67+
}
68+
#endif
69+
return 0;
70+
}
71+
72+
#define ERROR_KILL_PROCESS 1
73+
int KillProcess::process(C2Message &c2Message, C2Message &c2RetMessage)
74+
{
75+
int pid = c2Message.pid();
76+
c2RetMessage.set_instruction(c2RetMessage.instruction());
77+
c2RetMessage.set_pid(pid);
78+
#ifdef __linux__
79+
if (kill(pid, SIGKILL) == 0)
80+
{
81+
c2RetMessage.set_returnvalue("Killed.");
82+
}
83+
else
84+
{
85+
c2RetMessage.set_errorCode(ERROR_KILL_PROCESS);
86+
}
87+
#elif _WIN32
88+
HANDLE hProcess = OpenProcess(PROCESS_TERMINATE, FALSE, pid);
89+
if (hProcess)
90+
{
91+
BOOL ok = TerminateProcess(hProcess, 1);
92+
CloseHandle(hProcess);
93+
if (ok)
94+
c2RetMessage.set_returnvalue("Killed.");
95+
else
96+
c2RetMessage.set_errorCode(ERROR_KILL_PROCESS);
97+
}
98+
else
99+
{
100+
c2RetMessage.set_errorCode(ERROR_KILL_PROCESS);
101+
}
102+
#endif
103+
return 0;
104+
}
105+
106+
int KillProcess::errorCodeToMsg(const C2Message &c2RetMessage, std::string& errorMsg)
107+
{
108+
#ifdef BUILD_TEAMSERVER
109+
if (c2RetMessage.errorCode() == ERROR_KILL_PROCESS)
110+
errorMsg = "Failed: Could not kill process";
111+
#endif
112+
return 0;
113+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#pragma once
2+
3+
#include "ModuleCmd.hpp"
4+
5+
class KillProcess : public ModuleCmd
6+
{
7+
public:
8+
KillProcess();
9+
~KillProcess();
10+
11+
std::string getInfo();
12+
13+
int init(std::vector<std::string>& splitedCmd, C2Message& c2Message);
14+
int process(C2Message& c2Message, C2Message& c2RetMessage);
15+
int errorCodeToMsg(const C2Message &c2RetMessage, std::string& errorMsg);
16+
int osCompatibility() {return OS_LINUX | OS_WINDOWS;}
17+
};
18+
19+
#ifdef _WIN32
20+
extern "C" __declspec(dllexport) KillProcess * KillProcessConstructor();
21+
#else
22+
extern "C" __attribute__((visibility("default"))) KillProcess * KillProcessConstructor();
23+
#endif
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
#include "../KillProcess.hpp"
2+
#include "../../ModuleCmd/Tools.hpp"
3+
#include <chrono>
4+
#include <thread>
5+
#ifdef __linux__
6+
#include <signal.h>
7+
#include <sys/wait.h>
8+
#elif _WIN32
9+
#include <windows.h>
10+
#endif
11+
12+
bool testKillProcess();
13+
14+
int main()
15+
{
16+
bool res;
17+
std::cout << "[+] testKillProcess" << std::endl;
18+
res = testKillProcess();
19+
if (res)
20+
std::cout << "[+] Sucess" << std::endl;
21+
else
22+
std::cout << "[-] Failed" << std::endl;
23+
24+
return !res;
25+
}
26+
27+
bool testKillProcess()
28+
{
29+
bool ok = true;
30+
31+
int pid;
32+
#ifdef __linux__
33+
pid = launchProcess("sleep 30");
34+
std::this_thread::sleep_for(std::chrono::seconds(1));
35+
#elif _WIN32
36+
pid = launchProcess("C:\\Windows\\System32\\notepad.exe");
37+
Sleep(1000);
38+
#endif
39+
40+
KillProcess kp;
41+
std::vector<std::string> cmd = {"killProcess", std::to_string(pid)};
42+
C2Message msg, ret;
43+
kp.init(cmd, msg);
44+
msg.set_pid(pid);
45+
kp.process(msg, ret);
46+
47+
#ifdef __linux__
48+
ok &= ret.errorCode() == -1;
49+
#elif _WIN32
50+
HANDLE h = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, pid);
51+
if (h)
52+
{
53+
DWORD code = 0;
54+
bool alive = GetExitCodeProcess(h, &code) && code == STILL_ACTIVE;
55+
CloseHandle(h);
56+
ok &= !alive;
57+
}
58+
else
59+
{
60+
ok &= true;
61+
}
62+
#endif
63+
return ok;
64+
}

modules/Remove/CMakeLists.txt

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
include_directories(../)
2+
add_library(Remove SHARED Remove.cpp)
3+
set_property(TARGET Remove PROPERTY MSVC_RUNTIME_LIBRARY "MultiThreaded")
4+
target_link_libraries(Remove )
5+
add_custom_command(TARGET Remove POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy
6+
$<TARGET_FILE:Remove> "${CMAKE_SOURCE_DIR}/Release/Modules/$<TARGET_FILE_NAME:Remove>"
7+
)
8+
9+
if(WITH_TESTS)
10+
add_executable(testsRemove tests/testsRemove.cpp Remove.cpp)
11+
target_link_libraries(testsRemove )
12+
add_custom_command(TARGET testsRemove POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy
13+
$<TARGET_FILE:testsRemove> "${CMAKE_SOURCE_DIR}/Tests/$<TARGET_FILE_NAME:testsRemove>")
14+
15+
add_test(NAME testsRemove COMMAND "${CMAKE_SOURCE_DIR}/Tests/$<TARGET_FILE_NAME:testsRemove>")
16+
endif()

modules/Remove/Remove.cpp

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
#include "Remove.hpp"
2+
3+
#include "Common.hpp"
4+
5+
#include <filesystem>
6+
#include <cstring>
7+
8+
using namespace std;
9+
namespace fs = std::filesystem;
10+
11+
constexpr std::string_view moduleName = "remove";
12+
constexpr unsigned long long moduleHash = djb2(moduleName);
13+
14+
#ifdef _WIN32
15+
__declspec(dllexport) Remove* RemoveConstructor()
16+
{
17+
return new Remove();
18+
}
19+
#else
20+
__attribute__((visibility("default"))) Remove* RemoveConstructor()
21+
{
22+
return new Remove();
23+
}
24+
#endif
25+
26+
Remove::Remove()
27+
#ifdef BUILD_TEAMSERVER
28+
: ModuleCmd(std::string(moduleName), moduleHash)
29+
#else
30+
: ModuleCmd("", moduleHash)
31+
#endif
32+
{
33+
}
34+
35+
Remove::~Remove()
36+
{
37+
}
38+
39+
std::string Remove::getInfo()
40+
{
41+
std::string info;
42+
#ifdef BUILD_TEAMSERVER
43+
info += "remove Module:\n";
44+
info += "Delete a file or directory.\n";
45+
info += "\nUsage:\n";
46+
info += " - remove <path>\n";
47+
#endif
48+
return info;
49+
}
50+
51+
int Remove::init(std::vector<std::string> &splitedCmd, C2Message &c2Message)
52+
{
53+
#if defined(BUILD_TEAMSERVER) || defined(BUILD_TESTS)
54+
if (splitedCmd.size() >= 2)
55+
{
56+
std::string path;
57+
for (size_t i = 1; i < splitedCmd.size(); ++i)
58+
{
59+
if (!path.empty())
60+
path += " ";
61+
path += splitedCmd[i];
62+
}
63+
c2Message.set_instruction(splitedCmd[0]);
64+
c2Message.set_cmd(path);
65+
}
66+
else
67+
{
68+
c2Message.set_returnvalue(getInfo());
69+
return -1;
70+
}
71+
#endif
72+
return 0;
73+
}
74+
75+
#define ERROR_REMOVE 1
76+
int Remove::process(C2Message &c2Message, C2Message &c2RetMessage)
77+
{
78+
std::string path = c2Message.cmd();
79+
c2RetMessage.set_instruction(c2RetMessage.instruction());
80+
c2RetMessage.set_cmd(path);
81+
82+
std::error_code ec;
83+
fs::remove_all(path, ec);
84+
if (!ec)
85+
{
86+
c2RetMessage.set_returnvalue("Removed.");
87+
}
88+
else
89+
{
90+
c2RetMessage.set_errorCode(ERROR_REMOVE);
91+
}
92+
return 0;
93+
}
94+
95+
int Remove::errorCodeToMsg(const C2Message &c2RetMessage, std::string& errorMsg)
96+
{
97+
#ifdef BUILD_TEAMSERVER
98+
if (c2RetMessage.errorCode() == ERROR_REMOVE)
99+
errorMsg = "Failed: Could not remove path";
100+
#endif
101+
return 0;
102+
}

modules/Remove/Remove.hpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#pragma once
2+
3+
#include "ModuleCmd.hpp"
4+
5+
class Remove : public ModuleCmd
6+
{
7+
public:
8+
Remove();
9+
~Remove();
10+
11+
std::string getInfo();
12+
13+
int init(std::vector<std::string>& splitedCmd, C2Message& c2Message);
14+
int process(C2Message& c2Message, C2Message& c2RetMessage);
15+
int errorCodeToMsg(const C2Message &c2RetMessage, std::string& errorMsg);
16+
int osCompatibility() {return OS_LINUX | OS_WINDOWS;}
17+
};
18+
19+
#ifdef _WIN32
20+
extern "C" __declspec(dllexport) Remove * RemoveConstructor();
21+
#else
22+
extern "C" __attribute__((visibility("default"))) Remove * RemoveConstructor();
23+
#endif

0 commit comments

Comments
 (0)