Szyfrowanie stringów w C++ | StringCrypt

W dzisiejszym wpisie prezentuje Tobie autorską klasę StringCrypter służącą do szyfrowania łańcuchów tekstowych w języku programowania C++. Klasa jest bardzo prosta w użyciu. Wystarczy utworzyć jej instancje przekazując do konstruktora klucz szyfrujący i skorzystać z dwóch dostępnych metod takich jak encryptString i decryptString.

Olbrzymią zaletą tej zaimplementowanej klasy jest możliwość wykorzystania zwróconych wyników w innych kodach źródłowych lub tekstowych plikach konfiguracyjnych. Zaszyfrowany string jest przekształcany do specjalnie zaimplementowanego formatu, który wykorzystuje szesnastkowy system liczbowy. Dzięki temu zabiegowi dane wyjściowe nie posiadają w sobie dziwnych szlaczków znanych z tablicy ASCII i mogą zostać wykorzystywane bez żadnej zmiany kodowania w edytorach programistycznych. Oczywiście jeśli chcesz i szukasz tylko sposobu na konwersje typu string do hex lub hex do string w języku C++ to możesz delikatnie zmodyfikować kasę StringCrypt. Przykład praktycznego wykorzystania naszego skryptu szyfrującego stringi, znajduje się na końcu tego wpisu.

Szyfrowanie string w C++ – przykład użycia

Jeśli chcesz użyć naszej klasy wystarczy, że umieścisz pliki stringCrypter.h i stringCrypter.cpp w folderze ze swoim projektem i dołączysz ją za pomocą dyrektywy preprocesora #include tak jak ma to miejsce na poniższym przykładzie.

#include <iostream>
#include "StringCrypter.h"
using namespace std;

int main()
{
    //encryption key
    StringCrypter *obj = new StringCrypter("a9d1r6cx4x9v0d5p7w4m5k29v9xc02457sc64u1h");

    //encrypt
    string password = obj->encryptString("H3ll0 world p@ssword!");
    cout << password << endl;

    //decrypt
    string plainText = obj->decryptString(password);
    cout << plainText << endl;
    return 0;
}

Wynik działania powyższego programu

x
Kompilacja i wynik działania powyższego kodu źródłowego programu korzystającego z zaimplementowanej klasy StringCrypter.

Plik nagłówkowy StringCrypter.h

#ifndef STRINGCRYPTER_H
#define STRINGCRYPTER_H
#include <iostream>
#include <cstring>

using namespace std;

class StringCrypter
{
public:
    StringCrypter(string key);
    string encryptString(string text);
    string decryptString(string text);

private:
    string encryptDecrypt(string text, bool encrypted);
    string strToHex(const string &text);
    string hexToStr(const string &text);
    string xorKey;
};

#endif // STRINGCRYPTER_H

Implementacja klasy StringCrypter.cpp

/*
https://haker.edu.pl/
*/

#include "StringCrypter.h"

StringCrypter::StringCrypter(string key)
{
    this->xorKey = key;
}

string StringCrypter::strToHex(const string &text)
{
    string hexCharset = "0123456789ABCDEF";
    string result;
    int textLenght = text.length();
    result.reserve(2 * textLenght);
    for (int i = 0; i < textLenght; i++)
    {
        const unsigned char c = text[i];
        result.push_back(hexCharset[c >> 4]);
        result.push_back(hexCharset[c & 15]);
    }
    return result;
}

string StringCrypter::hexToStr(const string &text)
{
    const char *const hexCharset = "0123456789ABCDEF";
    string result;
    int textLenght = text.length();
    result.reserve(textLenght / 2);
    for (int i = 0; i < textLenght; i += 2)
    {
        char tmp1 = text[i];
        const char *p = lower_bound(hexCharset, hexCharset + 16, tmp1);
        char tmp2 = text[i + 1];
        const char *q = lower_bound(hexCharset, hexCharset + 16, tmp2);
        result.push_back(((p - hexCharset) << 4) | (q - hexCharset));
    }
    return result;
}

string StringCrypter::encryptDecrypt(string text, bool encrypted)
{
    if (encrypted)
        text = hexToStr(text);

    string key = this->xorKey;
    string result = text;
    for (int i = 0; i < text.size(); i++)
        result[i] = (int)(text[i] ^ key[i % key.length()]);

    if (encrypted)
        return result;
    else
        return strToHex(result);
}

string StringCrypter::encryptString(string text)
{
    return this->encryptDecrypt(text, false);
}

string StringCrypter::decryptString(string text)
{
    return this->encryptDecrypt(text, true);
}

Praktyczny przykład z szyfrowaniem zmiennych

Na samym wstępie warto zapoznać się z jednym z poprzednich wpisów na naszym blogu. Dotyczył on dynamicznego ładowania i wykorzystywania funkcji WinAPI wprost z bibliotek DLL systemu operacyjnego Microsoft Windows. Ma to na celu zmniejszanie wykrywalności aplikacji przez mechanizmy analizy statycznej i heurystycznej programów antywirusowych.

Zmniejszanie wykrywalności wskaźnikami w C++

Być może może już się domyśliłeś, że poprzednią technikę można zastosować właśnie z naszą klasą szyfrującą ciągi tekstowe. Wystarczy, że nazwy funkcji i bibliotek DLL umieścimy zaszyfrowane w zmiennych lub stałych w programie i będziemy mogli je potem odszyfrowywać i ładować tylko wtedy, kiedy są potrzebne. Skrócona lista kroków które musisz wykonać:

Lista kroków zmniejszających wykrywalność

  1. Zaszyfruj nazwy funkcji dowolnym kluczem szyfrującym
  2. Zaszyfruj nazwy bibliotek dowolnym kluczem szyfrującym
  3. Umieść ich zaszyfrowane wersje w zmiennych, stałych lub pliku
  4. Umieść klucz szyfrujący w zmiennej, stałej,pliku lub pobieraj go z internetu w sposób dynamiczny
  5. Przed uruchomieniem wskaźników funkcyjnych ładujących funkcje WinAPI, odszyfruj funkcje i bibliotekę którą chcesz użyć

Kod źródłowy z przykładem

Zaszyfrowaliśmy sobie napis z przykładową nazwą funkcji CopyFileA i nazwą biblioteki Kernel32.dll za pomocą klucza szyfrującego a9d1r6cx4x9v0d5p7w4m5k29v9xc02457sc64u1h. Następnie wszystkie trzy wartości umieściliśmy w kodzie źródłowym.

encrypt String function in C++
Zaszyfrowane do dalszego użytkowania nazwy funkcji i bibliotek DLL

Teraz wystarczy, że użyjemy uzyskane zaszyfrowane wartości tekstowe w kodzie źródłowym tak jak ma to miejsce na poniższym listingu kodu.

#include <windows.h>
#include "StringCrypter.h"
using namespace std;

BOOL myCopyFile(LPCTSTR source, LPCTSTR destination)
{
    typedef BOOL(WINAPI * _CF)
    (
        LPCTSTR lpExistingFileName,
        LPCTSTR lpNewFileName,
        BOOL bFailIfExists
    );

    StringCrypter *obj = new StringCrypter("a9d1r6cx4x9v0d5p7w4m5k29v9xc02457sc64u1h");
    const char * encryptFunction = "22561448345F0F1D75";
    const char * encryptLibrary = "2A5C165F175A504A1A1C551A";

    _CF dynamicCopyFunction = (_CF)GetProcAddress(GetModuleHandle(obj->decryptString(encryptLibrary).c_str()), obj->decryptString(encryptFunction).c_str());

    return dynamicCopyFunction(source, destination, true);
}

int main()

{
    myCopyFile("C:\\Users\\HakerEduPL\\Desktop\\malw.exe", "C:\\Users\\sirsm\\Desktop\\backup.exe");
    return 0;
}

W linijce 14-18 widzimy w jak prosty sposób używamy zaszyfrowanych funkcji w naszej aplikacji. Nazwy funkcji i bibliotek odszyfrowane są ze stringów dopiero wtedy, gdy są nam potrzebne. Oczywiście klasę możesz użyć do zupełnie innych powiązanych celów takich jak:

  • Ukrywanie przed analizą w ciągach tekstowych adresów e-mail/haseł,
  • Szyfrowania zbieranych logów,
  • Zaciemnianiem komunikacji sieciowej w architekturze klient-serwer.

Jeśli klasa w przyszłości ulegnie jakiejś zmianie to warto zaglądać i obserwować nasze nowe konto GitHub HakerEduPL.

Jeśli interesuje Cię język C++ to zapraszam Cię również do obejrzenia zapisu transmisji na żywo na YouTube o C++. Zapraszamy Ciebie również na naszego fanpage #HakerEduPL. To by było na tyle i zachęcamy Ciebie do rozszerzania swojej wiedzy na temat programowania.

8 thoughts to “Szyfrowanie stringów w C++ | StringCrypt”

      1. witam, będziesz w przyszłości kończył tego keyloggera i przepisywał na obiektowy c++ lub dodawał opcję wysyłania logów mailem? pozdrawiam

  1. Wiele serwisów o hackingu wymarło. Ten blog jest świetny.
    Super jakby autor bloga znalazł czasami choć chwilę, żeby podtrzymać tę stronę przy życiu.
    Artykuły są na prawdę ciekawe.

    1. Autot strony nie ma czasu czasem zrobi liva na kanale na yt (HakerEduPL) wiec polecam na yt zobaczyc i dzwoneczka zostawic ;>

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *