mirror of
https://github.com/maxDcb/C2Core
synced 2026-06-08 15:48:01 +00:00
errorCodeToMsg
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -19,6 +19,7 @@ public:
|
||||
int init(std::vector<std::string>& splitedCmd, C2Message& c2Message);
|
||||
int initConfig(const nlohmann::json &config);
|
||||
int process(C2Message& c2Message, C2Message& c2RetMessage);
|
||||
int errorCodeToMsg(const C2Message& c2RetMessage, std::string& errorMsg) override;
|
||||
int osCompatibility()
|
||||
{
|
||||
return OS_WINDOWS;
|
||||
|
||||
@@ -183,6 +183,25 @@ int main()
|
||||
ok &= expect(module.init(cmd, message) == 0, "dummy exe should be accepted in spoofed-parent mode");
|
||||
ok &= expectAssemblyMessage(message, dummyPath, "2", "--flag", "dummy exe spoofed-parent mode");
|
||||
}
|
||||
|
||||
{
|
||||
AssemblyExec module;
|
||||
nlohmann::json config;
|
||||
config["process"] = "Z:\\c2core_missing_assemblyexec_target.exe";
|
||||
ok &= expect(module.initConfig(config) == 0, "initConfig should accept a custom process path");
|
||||
|
||||
C2Message message;
|
||||
message.set_args("1");
|
||||
message.set_data("raw-bytes");
|
||||
C2Message retMessage;
|
||||
|
||||
ok &= expect(module.process(message, retMessage) == 0, "missing process target should return through C2Message");
|
||||
ok &= expect(retMessage.errorCode() > 0, "missing process target should set an error code");
|
||||
ok &= expect(retMessage.returnvalue().find("Error: Process failed to start") != std::string::npos, "missing process target should explain the failure");
|
||||
std::string errorMsg;
|
||||
ok &= expect(module.errorCodeToMsg(retMessage, errorMsg) == 0, "missing process target should map error text");
|
||||
ok &= expect(errorMsg == retMessage.returnvalue(), "missing process target error text should come from returnvalue");
|
||||
}
|
||||
}
|
||||
|
||||
return ok ? 0 : 1;
|
||||
|
||||
@@ -12,6 +12,12 @@ constexpr unsigned long long moduleHash = djb2(moduleName);
|
||||
|
||||
#define BUFSIZE 512
|
||||
|
||||
namespace
|
||||
{
|
||||
constexpr int ERROR_OPEN_PROCESS = 1;
|
||||
constexpr int ERROR_CREATE_PROCESS = 2;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
__declspec(dllexport) Chisel* A_ChiselConstructor()
|
||||
@@ -189,13 +195,22 @@ int Chisel::process(C2Message &c2Message, C2Message &c2RetMessage)
|
||||
{
|
||||
pid = c2Message.pid();
|
||||
HANDLE hProc=OpenProcess(PROCESS_ALL_ACCESS,FALSE,pid);
|
||||
TerminateProcess(hProc,9);
|
||||
if(hProc == NULL)
|
||||
{
|
||||
c2RetMessage.set_errorCode(ERROR_OPEN_PROCESS);
|
||||
result = "OpenProcess failed.";
|
||||
}
|
||||
else
|
||||
{
|
||||
TerminateProcess(hProc,9);
|
||||
CloseHandle(hProc);
|
||||
result="Chisel stoped.\n";
|
||||
}
|
||||
|
||||
c2RetMessage.set_instruction(c2RetMessage.instruction());
|
||||
c2RetMessage.set_pid(pid);
|
||||
c2RetMessage.set_cmd("stop");
|
||||
|
||||
result="Chisel stoped.\n";
|
||||
c2RetMessage.set_returnvalue(result);
|
||||
return 0;
|
||||
}
|
||||
@@ -226,6 +241,7 @@ int Chisel::process(C2Message &c2Message, C2Message &c2RetMessage)
|
||||
else
|
||||
{
|
||||
result += "CreateProcess failed.";
|
||||
c2RetMessage.set_errorCode(ERROR_CREATE_PROCESS);
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -238,6 +254,17 @@ int Chisel::process(C2Message &c2Message, C2Message &c2RetMessage)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Chisel::errorCodeToMsg(const C2Message &c2RetMessage, std::string &errorMsg)
|
||||
{
|
||||
#if defined(BUILD_TEAMSERVER) || defined(C2CORE_BUILD_TESTS) || defined(C2CORE_BUILD_FUNCTIONAL_TESTS)
|
||||
if (c2RetMessage.errorCode() > 0)
|
||||
{
|
||||
errorMsg = c2RetMessage.returnvalue();
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Chisel::followUp(const C2Message &c2RetMessage)
|
||||
{
|
||||
int pid = c2RetMessage.pid();
|
||||
|
||||
@@ -15,6 +15,7 @@ public:
|
||||
int init(std::vector<std::string>& splitedCmd, C2Message& c2Message);
|
||||
int process(C2Message& c2Message, C2Message& c2RetMessage);
|
||||
int followUp(const C2Message &c2RetMessage);
|
||||
int errorCodeToMsg(const C2Message& c2RetMessage, std::string& errorMsg) override;
|
||||
int osCompatibility()
|
||||
{
|
||||
return OS_WINDOWS;
|
||||
|
||||
@@ -39,6 +39,21 @@ int main()
|
||||
ok &= expect(message.pid() == 0, "non-numeric pid should map to zero with current parser");
|
||||
}
|
||||
|
||||
{
|
||||
Chisel module;
|
||||
C2Message message;
|
||||
message.set_cmd("stop");
|
||||
message.set_pid(2147483647);
|
||||
C2Message ret;
|
||||
|
||||
ok &= expect(module.process(message, ret) == 0, "missing chisel pid should return through C2Message");
|
||||
ok &= expect(ret.errorCode() > 0, "missing chisel pid should set an error code");
|
||||
ok &= expect(ret.returnvalue().find("OpenProcess failed") != std::string::npos, "missing chisel pid should explain the failure");
|
||||
std::string errorMsg;
|
||||
ok &= expect(module.errorCodeToMsg(ret, errorMsg) == 0, "missing chisel pid should map error text");
|
||||
ok &= expect(errorMsg == ret.returnvalue(), "missing chisel pid error text should come from returnvalue");
|
||||
}
|
||||
|
||||
{
|
||||
Chisel module;
|
||||
std::vector<std::string> cmd = {"chisel", "missing.exe", "client", "host:8000", "R:socks"};
|
||||
|
||||
@@ -25,6 +25,11 @@ using namespace std;
|
||||
constexpr std::string_view moduleName = "coffLoader";
|
||||
constexpr unsigned long long moduleHash = djb2(moduleName);
|
||||
|
||||
namespace
|
||||
{
|
||||
constexpr int ERROR_COFF_EXECUTION = 1;
|
||||
}
|
||||
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
@@ -130,11 +135,26 @@ int CoffLoader::process(C2Message &c2Message, C2Message &c2RetMessage)
|
||||
std::string result = coffLoader(payload, functionName, args);
|
||||
|
||||
c2RetMessage.set_instruction(c2RetMessage.instruction());
|
||||
if (result.find("Failed") != std::string::npos)
|
||||
{
|
||||
c2RetMessage.set_errorCode(ERROR_COFF_EXECUTION);
|
||||
}
|
||||
c2RetMessage.set_returnvalue(result);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CoffLoader::errorCodeToMsg(const C2Message &c2RetMessage, std::string &errorMsg)
|
||||
{
|
||||
#if defined(BUILD_TEAMSERVER) || defined(C2CORE_BUILD_TESTS) || defined(C2CORE_BUILD_FUNCTIONAL_TESTS)
|
||||
if (c2RetMessage.errorCode() > 0)
|
||||
{
|
||||
errorMsg = c2RetMessage.returnvalue();
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
std::string CoffLoader::coffLoader(std::string& payload, std::string& functionName, std::string& args)
|
||||
{
|
||||
@@ -193,4 +213,4 @@ std::string CoffLoader::coffLoader(std::string& payload, std::string& functionNa
|
||||
#endif
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ public:
|
||||
|
||||
int init(std::vector<std::string>& splitedCmd, C2Message& c2Message);
|
||||
int process(C2Message& c2Message, C2Message& c2RetMessage);
|
||||
int errorCodeToMsg(const C2Message& c2RetMessage, std::string& errorMsg) override;
|
||||
int osCompatibility()
|
||||
{
|
||||
return OS_WINDOWS;
|
||||
|
||||
@@ -35,5 +35,16 @@ int main()
|
||||
std::filesystem::remove(coff);
|
||||
}
|
||||
|
||||
{
|
||||
CoffLoader module;
|
||||
C2Message ret;
|
||||
ret.set_errorCode(1);
|
||||
ret.set_returnvalue("Failed to run/parse the COFF file\n");
|
||||
std::string errorMsg;
|
||||
|
||||
ok &= expect(module.errorCodeToMsg(ret, errorMsg) == 0, "COFF execution failure should map error text");
|
||||
ok &= expect(errorMsg == ret.returnvalue(), "COFF execution error text should come from returnvalue");
|
||||
}
|
||||
|
||||
return ok ? 0 : 1;
|
||||
}
|
||||
|
||||
+1474
-1426
File diff suppressed because it is too large
Load Diff
@@ -14,6 +14,7 @@ public:
|
||||
|
||||
int init(std::vector<std::string>& splitedCmd, C2Message& c2Message);
|
||||
int process(C2Message& c2Message, C2Message& c2RetMessage);
|
||||
int errorCodeToMsg(const C2Message& c2RetMessage, std::string& errorMsg) override;
|
||||
int osCompatibility()
|
||||
{
|
||||
return OS_WINDOWS;
|
||||
|
||||
@@ -39,5 +39,16 @@ int main()
|
||||
ok &= expect(module.init(cmd, message) == -1, "ReadMemory should reject missing size");
|
||||
}
|
||||
|
||||
{
|
||||
Evasion module;
|
||||
C2Message ret;
|
||||
ret.set_errorCode(1);
|
||||
ret.set_returnvalue("Error opening remote process and thread.");
|
||||
std::string errorMsg;
|
||||
|
||||
ok &= expect(module.errorCodeToMsg(ret, errorMsg) == 0, "evasion execution failure should map error text");
|
||||
ok &= expect(errorMsg == ret.returnvalue(), "evasion execution error text should come from returnvalue");
|
||||
}
|
||||
|
||||
return ok ? 0 : 1;
|
||||
}
|
||||
|
||||
@@ -11,6 +11,12 @@ using namespace std;
|
||||
constexpr std::string_view moduleName = "inject";
|
||||
constexpr unsigned long long moduleHash = djb2(moduleName);
|
||||
|
||||
namespace
|
||||
{
|
||||
constexpr int ERROR_OPEN_PROCESS = 1;
|
||||
constexpr int ERROR_CREATE_PROCESS = 2;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
#include <tlhelp32.h>
|
||||
@@ -423,8 +429,27 @@ int Inject::process(C2Message &c2Message, C2Message &c2RetMessage)
|
||||
|
||||
c2RetMessage.set_instruction(c2RetMessage.instruction());
|
||||
c2RetMessage.set_cmd(c2Message.cmd());
|
||||
if (result.find("OpenProcess failed.") != std::string::npos)
|
||||
{
|
||||
c2RetMessage.set_errorCode(ERROR_OPEN_PROCESS);
|
||||
}
|
||||
else if (result.find("CreateProcess failed.") != std::string::npos)
|
||||
{
|
||||
c2RetMessage.set_errorCode(ERROR_CREATE_PROCESS);
|
||||
}
|
||||
c2RetMessage.set_returnvalue(result);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Inject::errorCodeToMsg(const C2Message &c2RetMessage, std::string &errorMsg)
|
||||
{
|
||||
#if defined(BUILD_TEAMSERVER) || defined(C2CORE_BUILD_TESTS) || defined(C2CORE_BUILD_FUNCTIONAL_TESTS)
|
||||
if (c2RetMessage.errorCode() > 0)
|
||||
{
|
||||
errorMsg = c2RetMessage.returnvalue();
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@ public:
|
||||
int initConfig(const nlohmann::json &config);
|
||||
int init(std::vector<std::string>& splitedCmd, C2Message& c2Message);
|
||||
int process(C2Message& c2Message, C2Message& c2RetMessage);
|
||||
int errorCodeToMsg(const C2Message& c2RetMessage, std::string& errorMsg) override;
|
||||
int osCompatibility()
|
||||
{
|
||||
return OS_WINDOWS;
|
||||
|
||||
@@ -239,7 +239,11 @@ int main()
|
||||
C2Message retMessage;
|
||||
|
||||
ok &= expect(module.process(message, retMessage) == 0, "process should return normally for an invalid pid");
|
||||
ok &= expect(retMessage.errorCode() > 0, "invalid pid should set an error code");
|
||||
ok &= expect(retMessage.returnvalue() == "OpenProcess failed.", "invalid pid should report OpenProcess failure");
|
||||
std::string errorMsg;
|
||||
ok &= expect(module.errorCodeToMsg(retMessage, errorMsg) == 0, "invalid pid should map error text");
|
||||
ok &= expect(errorMsg == retMessage.returnvalue(), "invalid pid error text should come from returnvalue");
|
||||
}
|
||||
|
||||
{
|
||||
@@ -255,7 +259,11 @@ int main()
|
||||
C2Message retMessage;
|
||||
|
||||
ok &= expect(module.process(message, retMessage) == 0, "spawn injection failure path should return normally");
|
||||
ok &= expect(retMessage.errorCode() > 0, "invalid spawn target should set an error code");
|
||||
ok &= expect(retMessage.returnvalue() == "CreateProcess failed.", "invalid spawn target should report CreateProcess failure");
|
||||
std::string errorMsg;
|
||||
ok &= expect(module.errorCodeToMsg(retMessage, errorMsg) == 0, "invalid spawn target should map error text");
|
||||
ok &= expect(errorMsg == retMessage.returnvalue(), "invalid spawn target error text should come from returnvalue");
|
||||
}
|
||||
|
||||
{
|
||||
|
||||
@@ -13,6 +13,11 @@ using namespace std;
|
||||
constexpr std::string_view moduleName = "ls";
|
||||
constexpr unsigned long long moduleHash = djb2(moduleName);
|
||||
|
||||
namespace
|
||||
{
|
||||
constexpr int ERROR_LIST_DIRECTORY = 1;
|
||||
}
|
||||
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
@@ -83,11 +88,26 @@ int ListDirectory::process(C2Message &c2Message, C2Message &c2RetMessage)
|
||||
|
||||
c2RetMessage.set_instruction(c2RetMessage.instruction());
|
||||
c2RetMessage.set_cmd(path);
|
||||
if (outCmd.find("Error:") == 0)
|
||||
{
|
||||
c2RetMessage.set_errorCode(ERROR_LIST_DIRECTORY);
|
||||
}
|
||||
c2RetMessage.set_returnvalue(outCmd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ListDirectory::errorCodeToMsg(const C2Message &c2RetMessage, std::string &errorMsg)
|
||||
{
|
||||
#if defined(BUILD_TEAMSERVER) || defined(C2CORE_BUILD_TESTS) || defined(C2CORE_BUILD_FUNCTIONAL_TESTS)
|
||||
if (c2RetMessage.errorCode() > 0)
|
||||
{
|
||||
errorMsg = c2RetMessage.returnvalue();
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct HumanReadable {
|
||||
std::uintmax_t size{};
|
||||
private: friend
|
||||
@@ -127,10 +147,18 @@ std::string ListDirectory::listDirectory(const std::string& path)
|
||||
if(actualPath.empty())
|
||||
actualPath=std::filesystem::current_path().string();
|
||||
|
||||
std::error_code e;
|
||||
if (!std::filesystem::exists(actualPath, e))
|
||||
{
|
||||
result += "Error: ";
|
||||
result += e ? e.message() : "path does not exist";
|
||||
result += "\n";
|
||||
return result;
|
||||
}
|
||||
|
||||
result += actualPath;
|
||||
result += ":\n";
|
||||
|
||||
std::error_code e;
|
||||
for (const filesystem::directory_entry& file : filesystem::directory_iterator(actualPath, e))
|
||||
{
|
||||
try
|
||||
@@ -188,4 +216,4 @@ std::string ListDirectory::listDirectory(const std::string& path)
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ public:
|
||||
|
||||
int init(std::vector<std::string>& splitedCmd, C2Message& c2Message);
|
||||
int process(C2Message& c2Message, C2Message& c2RetMessage);
|
||||
int errorCodeToMsg(const C2Message& c2RetMessage, std::string& errorMsg) override;
|
||||
int osCompatibility()
|
||||
{
|
||||
return OS_LINUX | OS_WINDOWS;
|
||||
|
||||
@@ -72,7 +72,11 @@ bool testListDirectory()
|
||||
c2Message.set_cmd(invalidPath);
|
||||
listDirectory->process(c2Message, c2RetMessage);
|
||||
std::cout << "invalid result: \n" << c2RetMessage.returnvalue() << std::endl;
|
||||
if (c2RetMessage.returnvalue() != invalidPath + ":\n") {
|
||||
std::string errorMsg;
|
||||
listDirectory->errorCodeToMsg(c2RetMessage, errorMsg);
|
||||
if (c2RetMessage.errorCode() <= 0
|
||||
|| c2RetMessage.returnvalue().find("Error:") != 0
|
||||
|| errorMsg != c2RetMessage.returnvalue()) {
|
||||
ok = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,6 +42,14 @@ __attribute__((visibility("default"))) Script * ScriptConstructor()
|
||||
|
||||
namespace
|
||||
{
|
||||
constexpr int ERROR_SCRIPT_EXECUTION = 1;
|
||||
constexpr int ERROR_UNSUPPORTED_SCRIPT_TYPE = 2;
|
||||
constexpr int ERROR_TEMP_SCRIPT_PATH = 3;
|
||||
constexpr int ERROR_TEMP_SCRIPT_WRITE = 4;
|
||||
constexpr int ERROR_CREATE_PIPE = 5;
|
||||
constexpr int ERROR_SET_HANDLE_INFO = 6;
|
||||
constexpr int ERROR_CREATE_PROCESS = 7;
|
||||
|
||||
#ifdef _WIN32
|
||||
bool hasWindowsScriptExtension(const std::string& path)
|
||||
{
|
||||
@@ -75,7 +83,7 @@ namespace
|
||||
return tempPath.string();
|
||||
}
|
||||
|
||||
std::string runWindowsScriptFile(const std::string& scriptPath)
|
||||
std::string runWindowsScriptFile(const std::string& scriptPath, int& errorCode)
|
||||
{
|
||||
std::string result;
|
||||
|
||||
@@ -88,12 +96,14 @@ namespace
|
||||
HANDLE pipeWrite = nullptr;
|
||||
if (!CreatePipe(&pipeRead, &pipeWrite, &securityAttributes, 0))
|
||||
{
|
||||
errorCode = ERROR_CREATE_PIPE;
|
||||
return "CreatePipe failed.";
|
||||
}
|
||||
if (!SetHandleInformation(pipeRead, HANDLE_FLAG_INHERIT, 0))
|
||||
{
|
||||
CloseHandle(pipeRead);
|
||||
CloseHandle(pipeWrite);
|
||||
errorCode = ERROR_SET_HANDLE_INFO;
|
||||
return "SetHandleInformation failed.";
|
||||
}
|
||||
|
||||
@@ -135,6 +145,7 @@ namespace
|
||||
if (!created)
|
||||
{
|
||||
CloseHandle(pipeRead);
|
||||
errorCode = ERROR_CREATE_PROCESS;
|
||||
return "CreateProcess failed.";
|
||||
}
|
||||
|
||||
@@ -221,6 +232,7 @@ int Script::process(C2Message &c2Message, C2Message &c2RetMessage)
|
||||
const std::string script = c2Message.data();
|
||||
|
||||
std::string result;
|
||||
int errorCode = 0;
|
||||
|
||||
#ifdef __linux__
|
||||
|
||||
@@ -229,11 +241,15 @@ int Script::process(C2Message &c2Message, C2Message &c2RetMessage)
|
||||
std::unique_ptr<FILE, decltype(&pclose)> pipe(popen(script.c_str(), "r"), pclose);
|
||||
if (!pipe)
|
||||
{
|
||||
throw std::runtime_error("popen() filed!");
|
||||
result = "popen() failed.";
|
||||
errorCode = ERROR_SCRIPT_EXECUTION;
|
||||
}
|
||||
while (fgets(buffer.data(), buffer.size(), pipe.get()) != nullptr)
|
||||
else
|
||||
{
|
||||
result += buffer.data();
|
||||
while (fgets(buffer.data(), buffer.size(), pipe.get()) != nullptr)
|
||||
{
|
||||
result += buffer.data();
|
||||
}
|
||||
}
|
||||
|
||||
#elif _WIN32
|
||||
@@ -241,6 +257,7 @@ int Script::process(C2Message &c2Message, C2Message &c2RetMessage)
|
||||
if (!hasWindowsScriptExtension(c2Message.inputfile()))
|
||||
{
|
||||
result = "Unsupported script type on Windows. Use .bat or .cmd.";
|
||||
errorCode = ERROR_UNSUPPORTED_SCRIPT_TYPE;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -248,21 +265,28 @@ int Script::process(C2Message &c2Message, C2Message &c2RetMessage)
|
||||
if (tempScriptPath.empty())
|
||||
{
|
||||
result = "Failed to create temporary script path.";
|
||||
errorCode = ERROR_TEMP_SCRIPT_PATH;
|
||||
}
|
||||
else
|
||||
{
|
||||
{
|
||||
std::ofstream tempScript(tempScriptPath, std::ios::binary);
|
||||
tempScript.write(script.data(), static_cast<std::streamsize>(script.size()));
|
||||
if (!tempScript.good())
|
||||
{
|
||||
result = "Failed to write temporary script.";
|
||||
errorCode = ERROR_TEMP_SCRIPT_WRITE;
|
||||
}
|
||||
}
|
||||
|
||||
if (!std::filesystem::exists(tempScriptPath))
|
||||
if (errorCode == 0 && !std::filesystem::exists(tempScriptPath))
|
||||
{
|
||||
result = "Failed to write temporary script.";
|
||||
errorCode = ERROR_TEMP_SCRIPT_WRITE;
|
||||
}
|
||||
else
|
||||
else if (errorCode == 0)
|
||||
{
|
||||
result = runWindowsScriptFile(tempScriptPath);
|
||||
result = runWindowsScriptFile(tempScriptPath, errorCode);
|
||||
std::error_code ignored;
|
||||
std::filesystem::remove(tempScriptPath, ignored);
|
||||
}
|
||||
@@ -272,7 +296,22 @@ int Script::process(C2Message &c2Message, C2Message &c2RetMessage)
|
||||
#endif
|
||||
|
||||
c2RetMessage.set_instruction(c2Message.instruction());
|
||||
if (errorCode > 0)
|
||||
{
|
||||
c2RetMessage.set_errorCode(errorCode);
|
||||
}
|
||||
c2RetMessage.set_returnvalue(result);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Script::errorCodeToMsg(const C2Message &c2RetMessage, std::string &errorMsg)
|
||||
{
|
||||
#if defined(BUILD_TEAMSERVER) || defined(C2CORE_BUILD_TESTS) || defined(C2CORE_BUILD_FUNCTIONAL_TESTS)
|
||||
if (c2RetMessage.errorCode() > 0)
|
||||
{
|
||||
errorMsg = c2RetMessage.returnvalue();
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ public:
|
||||
|
||||
int init(std::vector<std::string>& splitedCmd, C2Message& c2Message);
|
||||
int process(C2Message& c2Message, C2Message& c2RetMessage);
|
||||
int errorCodeToMsg(const C2Message& c2RetMessage, std::string& errorMsg) override;
|
||||
int osCompatibility()
|
||||
{
|
||||
return OS_LINUX | OS_WINDOWS;
|
||||
|
||||
@@ -98,7 +98,11 @@ int main()
|
||||
|
||||
ok &= expect(module.init(cmd, message) == 0, "unsupported Windows script extension should still be transportable");
|
||||
ok &= expect(module.process(message, ret) == 0, "unsupported Windows script extension should return cleanly");
|
||||
ok &= expect(ret.errorCode() > 0, "unsupported Windows script extension should set an error code");
|
||||
ok &= expectContains(ret.returnvalue(), "Unsupported script type on Windows", "unsupported Windows script extension should explain the rule");
|
||||
std::string errorMsg;
|
||||
ok &= expect(module.errorCodeToMsg(ret, errorMsg) == 0, "unsupported Windows script extension should map error text");
|
||||
ok &= expect(errorMsg == ret.returnvalue(), "unsupported Windows script error text should come from returnvalue");
|
||||
std::filesystem::remove(script);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -94,6 +94,12 @@ int Shell::followUp(const C2Message &c2RetMessage)
|
||||
|
||||
int Shell::errorCodeToMsg(const C2Message &c2RetMessage, std::string &errorMsg)
|
||||
{
|
||||
if(c2RetMessage.errorCode() > 0)
|
||||
{
|
||||
errorMsg = c2RetMessage.returnvalue().empty()
|
||||
? "Failed to start shell."
|
||||
: c2RetMessage.returnvalue();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -211,6 +217,7 @@ int Shell::process(C2Message &c2Message, C2Message &c2RetMessage)
|
||||
if(startShell() != 0)
|
||||
{
|
||||
c2RetMessage.set_errorCode(1);
|
||||
c2RetMessage.set_returnvalue("Failed to start shell.");
|
||||
return 0;
|
||||
}
|
||||
if(cmd.empty())
|
||||
@@ -279,6 +286,7 @@ int Shell::process(C2Message &c2Message, C2Message &c2RetMessage)
|
||||
if(startShell() != 0)
|
||||
{
|
||||
c2RetMessage.set_errorCode(1);
|
||||
c2RetMessage.set_returnvalue("Failed to start shell.");
|
||||
return 0;
|
||||
}
|
||||
if(cmd.empty())
|
||||
|
||||
@@ -108,6 +108,9 @@ int main()
|
||||
C2Message ret;
|
||||
branchOk &= test_helpers::expect(shell.process(message, ret) == 0, "missing shell process should return through C2Message");
|
||||
branchOk &= test_helpers::expect(ret.errorCode() == 1, "missing shell program should set error code 1");
|
||||
std::string errorMsg;
|
||||
branchOk &= test_helpers::expect(shell.errorCodeToMsg(ret, errorMsg) == 0, "missing shell program should map error text");
|
||||
branchOk &= test_helpers::expect(errorMsg.find("Failed to start shell") != std::string::npos, "missing shell program should expose process error text");
|
||||
ok &= branchOk;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -119,6 +119,14 @@ namespace
|
||||
constexpr std::string_view moduleName = "spawnAs";
|
||||
constexpr unsigned long long moduleHash = djb2(moduleName);
|
||||
|
||||
namespace
|
||||
{
|
||||
constexpr int ERROR_INVALID_PARAMETERS = 1;
|
||||
constexpr int ERROR_MISSING_COMMAND = 2;
|
||||
constexpr int ERROR_UNSUPPORTED_PLATFORM = 3;
|
||||
constexpr int ERROR_PROCESS_CREATION = 4;
|
||||
}
|
||||
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
@@ -417,6 +425,7 @@ int SpawnAs::process(C2Message &c2Message, C2Message &c2RetMessage)
|
||||
if (splitedList.size() < 3)
|
||||
{
|
||||
c2RetMessage.set_returnvalue("Invalid command parameters received.\n");
|
||||
c2RetMessage.set_errorCode(ERROR_INVALID_PARAMETERS);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -431,6 +440,7 @@ int SpawnAs::process(C2Message &c2Message, C2Message &c2RetMessage)
|
||||
#ifdef __linux__
|
||||
|
||||
result = "Only supported on Windows.\n";
|
||||
c2RetMessage.set_errorCode(ERROR_UNSUPPORTED_PLATFORM);
|
||||
|
||||
#elif _WIN32
|
||||
|
||||
@@ -442,6 +452,7 @@ int SpawnAs::process(C2Message &c2Message, C2Message &c2RetMessage)
|
||||
if (commandLineW.empty())
|
||||
{
|
||||
c2RetMessage.set_returnvalue("Missing command to execute.\n");
|
||||
c2RetMessage.set_errorCode(ERROR_MISSING_COMMAND);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -680,6 +691,7 @@ int SpawnAs::process(C2Message &c2Message, C2Message &c2RetMessage)
|
||||
c2RetMessage.set_instruction(c2RetMessage.instruction());
|
||||
c2RetMessage.set_cmd(cmd);
|
||||
c2RetMessage.set_returnvalue(result);
|
||||
c2RetMessage.set_errorCode(ERROR_PROCESS_CREATION);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -57,5 +57,19 @@ int main()
|
||||
ok &= expect(module.init(cmd, message) == -1, "missing command should be rejected");
|
||||
}
|
||||
|
||||
{
|
||||
SpawnAs module;
|
||||
C2Message message;
|
||||
message.set_cmd("alice");
|
||||
C2Message ret;
|
||||
|
||||
ok &= expect(module.process(message, ret) == -1, "invalid packed parameters should be rejected");
|
||||
ok &= expect(ret.errorCode() > 0, "invalid packed parameters should set an error code");
|
||||
ok &= expect(ret.returnvalue().find("Invalid command parameters") != std::string::npos, "invalid packed parameters should explain the error");
|
||||
std::string errorMsg;
|
||||
ok &= expect(module.errorCodeToMsg(ret, errorMsg) == 0, "invalid packed parameters should map error text");
|
||||
ok &= expect(errorMsg == ret.returnvalue(), "invalid packed parameter error text should come from returnvalue");
|
||||
}
|
||||
|
||||
return ok ? 0 : 1;
|
||||
}
|
||||
|
||||
+29
-1
@@ -14,6 +14,11 @@ using namespace std;
|
||||
constexpr std::string_view moduleName = "tree";
|
||||
constexpr unsigned long long moduleHash = djb2(moduleName);
|
||||
|
||||
namespace
|
||||
{
|
||||
constexpr int ERROR_TREE_DIRECTORY = 1;
|
||||
}
|
||||
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
@@ -84,11 +89,26 @@ int Tree::process(C2Message &c2Message, C2Message &c2RetMessage)
|
||||
|
||||
c2RetMessage.set_instruction(c2RetMessage.instruction());
|
||||
c2RetMessage.set_cmd(path);
|
||||
if (outCmd.find("Error:") == 0)
|
||||
{
|
||||
c2RetMessage.set_errorCode(ERROR_TREE_DIRECTORY);
|
||||
}
|
||||
c2RetMessage.set_returnvalue(outCmd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Tree::errorCodeToMsg(const C2Message &c2RetMessage, std::string &errorMsg)
|
||||
{
|
||||
#if defined(BUILD_TEAMSERVER) || defined(C2CORE_BUILD_TESTS) || defined(C2CORE_BUILD_FUNCTIONAL_TESTS)
|
||||
if (c2RetMessage.errorCode() > 0)
|
||||
{
|
||||
errorMsg = c2RetMessage.returnvalue();
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
std::string Tree::iterProcess(const std::string& path, int depth)
|
||||
{
|
||||
@@ -104,6 +124,14 @@ std::string Tree::iterProcess(const std::string& path, int depth)
|
||||
actualPath=std::filesystem::current_path().string();
|
||||
|
||||
std::error_code e;
|
||||
if (!std::filesystem::exists(actualPath, e))
|
||||
{
|
||||
result += "Error: ";
|
||||
result += e ? e.message() : "path does not exist";
|
||||
result += "\n";
|
||||
return result;
|
||||
}
|
||||
|
||||
for (const filesystem::directory_entry& file : filesystem::directory_iterator(actualPath, e))
|
||||
{
|
||||
try
|
||||
@@ -144,4 +172,4 @@ std::string Tree::iterProcess(const std::string& path, int depth)
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ public:
|
||||
|
||||
int init(std::vector<std::string>& splitedCmd, C2Message& c2Message);
|
||||
int process(C2Message& c2Message, C2Message& c2RetMessage);
|
||||
int errorCodeToMsg(const C2Message& c2RetMessage, std::string& errorMsg) override;
|
||||
int osCompatibility()
|
||||
{
|
||||
return OS_LINUX | OS_WINDOWS;
|
||||
|
||||
@@ -79,7 +79,11 @@ bool testTree()
|
||||
tree->init(cmd, msg);
|
||||
msg.set_cmd(invalid.string());
|
||||
tree->process(msg, ret);
|
||||
ok &= ret.returnvalue().empty();
|
||||
std::string errorMsg;
|
||||
tree->errorCodeToMsg(ret, errorMsg);
|
||||
ok &= ret.errorCode() > 0;
|
||||
ok &= ret.returnvalue().find("Error:") == 0;
|
||||
ok &= errorMsg == ret.returnvalue();
|
||||
}
|
||||
|
||||
// ----- no argument -----
|
||||
|
||||
Reference in New Issue
Block a user