• XSS.stack #1 – первый литературный журнал от юзеров форума

[src] Log searcher in C++

qGodless

(L2) cache
Пользователь
Регистрация
10.07.2022
Сообщения
385
Реакции
106
Hello, i made a log searcher in python a while ago https://xss.pro/threads/80528/, but python was slow as shit for such job, so i remade it in c++

C++:
#include <iostream>
#include <fstream>
#include <unordered_map>
#include <filesystem>
#include <regex>
#include <system_error>
#include <future>
#include <thread>
#include <vector>

using namespace std;
namespace fs = filesystem;

bool VerboseEnabled = false;

void processLogsAsync(const vector<string>& keywords, const string& sourceDirectory, const string& destinationDirectory, promise<void>&& promise) {
    unordered_map<string, ofstream> keywordFiles;
    unordered_map<string, int> keywordCount;

    fs::create_directories(destinationDirectory);

    for (const auto& keyword : keywords) {
        string existingFile = destinationDirectory + "/" + keyword + ".txt";
        if (fs::exists(existingFile)) {
            fs::remove(existingFile);
        }
    }

    error_code ec;
    for (auto it = fs::recursive_directory_iterator(sourceDirectory, ec); it != fs::recursive_directory_iterator(); it.increment(ec)) {
        if (ec) {
            if (VerboseEnabled) cerr << "Error" /*accessing: " << sourceDirectory*/ << ": " << ec.message() << "\n";
            ec.clear();
            continue;
        }

        const auto& entry = *it;

        if (entry.is_regular_file() && entry.path().extension() == ".txt") {
            string filename = entry.path().filename().string();
            regex pattern("password", regex_constants::icase);

            if (regex_search(filename, pattern)) {
                ifstream file(entry.path(), ios::binary);
                if (!file) {

                    if (VerboseEnabled) cerr << "Error opening file " << entry.path() << "\n";

                    continue;
                }

                string line;
                while (getline(file, line)) {
                    for (const auto& keyword : keywords) {
                        if (line.find(keyword) != string::npos) {
                            if (keywordFiles.find(keyword) == keywordFiles.end()) {
                                string outputFile = destinationDirectory + "/" + keyword + ".txt";
                                keywordFiles[keyword] = ofstream(outputFile, ios::app);
                                keywordCount[keyword] = 0;
                            }
                            keywordFiles[keyword] << line << endl;
                            keywordCount[keyword]++;
                            for (int i = 0; i < 2 && getline(file, line); ++i) {
                                keywordFiles[keyword] << line << endl;
                            }
                            keywordFiles[keyword] << endl;
                        }
                    }
                }
            }
        }
    }

    for (auto& [keyword, file] : keywordFiles) {
        file.close();
    }

    for (const auto& pair : keywords) {
        if (keywordCount.find(pair) != keywordCount.end()) {
            cout << "Found " << keywordCount[pair] << " credentials for " << pair << " in " << destinationDirectory << "/" << pair << ".txt" << endl;
        } else {
            cout << "No credentials found for " << pair << endl;
        }
    }

    promise.set_value();
}

void processLogs(const vector<string>& keywords, const string& sourceDirectory, const string& destinationDirectory) {
    const unsigned int numThreads = thread::hardware_concurrency();
    vector<future<void>> futures;

    // Split the keywords into smaller chunks for multithreading
    const size_t chunkSize = (keywords.size() + numThreads - 1) / numThreads;
    for (size_t i = 0; i < keywords.size(); i += chunkSize) {
        const size_t end = min(i + chunkSize, keywords.size());
        vector<string> chunk(keywords.begin() + i, keywords.begin() + end);

        promise<void> promise;
        future<void> future = promise.get_future();
        futures.push_back(move(future));

        thread thread(processLogsAsync, chunk, sourceDirectory, destinationDirectory, move(promise));
        thread.detach();
    }

    // Wait for all threads to finish
    for (auto& future : futures) {
        future.get();
    }
}

// Function to split keywords arguments (netflix.com,paypal.com)
vector<string> split(const string& s, char delimiter) {
    vector<string> tokens;
    string token;
    istringstream tokenStream(s);
    while (getline(tokenStream, token, delimiter)) {
        tokens.push_back(token);
    }
    return tokens;
}

int main(int argc, char* argv[]) {
    if (argc < 2 || string(argv[1]) == "-h" || string(argv[1]) == "--help") {
        cout << "Usage: " << argv[0] << " -k \"netflix.com,paypal.com\" -l Logs -o Results" << endl;
        cout << "  -h, --help              Display this help message." << endl;
        cout << "  -k <Keywords>           Comma-separated list of keywords to search for." << endl;
        cout << "  -l <Logs>               Directory containing logs files." << endl;
        cout << "  -o <destination>        (Optional) Directory to store search results. Default: 'Results'" << endl;
        cout << "  -v <verbose>            (Optional) Turn on verbose If set." << endl;
        cout << endl;
        return 1;
    }

    vector<string> keywords;
    string sourceDirectory;
    string destinationDirectory;
    for (int i = 1; i < argc; ++i) {

        string arg(argv[i]);

        //TODO: Read keywords from file
        if (arg == "-k") {
            if (i + 1 < argc) {
                keywords = split(argv[++i], ',');
            } else {
                cerr << "Error: Missing keywords after -k flag." << endl;
                return 1;
            }
        }
       
        else if (arg == "-l") {
            if (i + 1 < argc) {
                sourceDirectory = argv[++i];
            } else {
                cerr << "Error: Missing source directory after -l flag." << endl;
                return 1;
            }
        }
       
        else if (arg == "-o") {
            if (i + 1 < argc) {
                destinationDirectory = argv[++i];
            } else {
                cerr << "Error: Missing destination directory after -o flag." << endl;
                return 1;
            }
        }

        else if (arg == "-v") {
            cout << "Verbose Mode Enabled" << endl;
            bool* verbosePtr = &VerboseEnabled;
            *verbosePtr = true;
        }
   
        else {
            cerr << "Error: Unknown argument: " << arg << endl;
            return 1;
        }
    }

    if (destinationDirectory.empty()) {
        destinationDirectory = "Results";
    }

    processLogs(keywords, sourceDirectory, destinationDirectory);

    return 0;
}

Compile: download a compiler and run
g++ log_searcher.cpp -o log_searcher.exe -lstdc++fs -std=c++17

Time: Searched a 10gb logs folder in ~1 minute on an old pc
1712585453880.png

Note: under linux systems it gives the error: https://stackoverflow.com/questions/73479857/ mid search and exit due to underlying OS API
 
Последнее редактирование:


Напишите ответ...
  • Вставить:
Прикрепить файлы
Верх