Szyfrowanie plików w C++ (XOR/Crypter/Packer)

Siemanko! Dzisiaj zajmiemy się troszkę programowaniem w C++. Aby, zrozumieć w pełni tą lekcje trzeba mieć już jakieś podstawy z programowania komputerów. W internecie jest multum darmowych kursów C++, więc wymyślanie koła na nowo jest raczej passe i nie w stylu hakerów. Przedstawimy kompletny kod źródłowy potrafiący szyfrować dowolne pliki za pomocą jednej z prostszych metod kryptograficznych czyli alternatywy wykluczającej (XOR). Program został napisany i przetestowany w środowisku Code::Blocks w wersji 13.12 z kompilatorem MinGW w systemie Windows. Wydaje mi się, że kod jest w miarę przenośny i bez problemu zostanie skompilowany i uruchomiony również na innych systemach operacyjnych takich jak Linux.

Do wpisu dołączony jest film demonstrujący działanie naszego programu i objaśniającym kilka kwestii. Wideo dostępne jest na naszym kanale na YouTube zupełnie za darmo. Warto subskrybować, łapkować i być na bieżąco! 🙂

Szyfrowanie plików XOR

Przed przystąpieniem do czytania dalszej części wpisu obowiązkowo należy przestudiować działanie szyfru xor. Jak wiadomo informatyka to matematyka ;-). W skrócie xor jest wykorzystywany w logice matematycznej oraz w elektronice (bramki logiczne) do działań logicznych.

tablica prawdy xor
Tablica prawdy funkcji XOR. Tylko z dwóch różnych wartości wynika prawda.

Ważną cechą xora jest jego odwracalność. Dwa ciągi binarne (którymi na marginesie mówiąc są wszystkie pliki w systemie) po podwójnym zastosowaniu xora wracają do pierwotnej formy. Tą właśnie własność dzisiaj wykorzystamy.

Przykład XOR

Mamy ciąg 10101 i chcemy go sksorować z kluczem 11111.

10101
XOR
11111
=
01010

Jak widać uzyskaliśmy zupełnie inną wartość binarną niż pierwotna. Lecz, gdy nową wartość znów połączymy z kluczem za pomocą xora dostaniemy wartość pierwotną.

01010
XOR
11111
=
10101

Z tej właściwości wynika fakt, że za pomocą danego klucza szyfrującego możemy utworzyć szyfrogram (wiadomość zaszyfrowana) a następnie tylko za pomocą tego samego klucza możemy go odszyfrować.

Szyfrowanie xor w C++

W języku C++ istnieje gotowy operator bitowy służący do xorowania (^). Poniżej umieszczamy gotowy kod źródłowy programu, który otwiera podany plik w trybie binarnym i za pomocą podanego klucza iteracyjnie bit po bicie xoruje je tworząc zupełnie nowy plik. Zezwalamy na pełne użytkowanie bez żadnych ograniczeń tego kodu, jego modyfikacje jak i włączanie do produktów darmowych i komercyjnych.

/*
 * File:   szyfrowanieXor.cpp
 * Author: haker.edu.pl
 * License: MIT (X11)
 * Created on 07 pazdziernika 2015
 */
#include <cstdio>
#include <cstring>

using namespace std;

bool xorek(const char * plikXorowany, const char *plikWyjsciowy, const char *klucz)
{
    FILE *plik = fopen(plikXorowany, "rb");
    FILE *zaszyfrowany = fopen(plikWyjsciowy, "wb");

    if (plik!=NULL && zaszyfrowany!=NULL)
    {
        //udane otwarcie pliku do zaszyfrowania i wyjsciowego
        int length = strlen(klucz);
        int znak, xorChar;
        int mod = 0;

        //szyfrowanie XOR znak po znaku
        do
        {
            if (mod >= length)
                mod=0;
            znak = fgetc(plik);
            xorChar = znak^klucz[mod];
            mod++;
            if (znak != EOF)
                fputc(xorChar, zaszyfrowany);
        }
        while (znak != EOF);

        //zapisywanie plikow (zamykanie)
        if (fclose(zaszyfrowany)==0 && fclose(plik)==0)
            return true;
        else
            return false;

    }
    else
        return false;
}

int main (int argc, char *argv[])
{
    //obsluga programu za pomoca argumentow
    if (argc>=3)
    {
        if (xorek(argv[1], argv[2], argv[3]))
            printf("Poprawnie zaszyfrowano plik %s kluczem %s!", argv[1], argv[3]);
        else
            printf("Niezdefiniowany blad!");

    }
    else
    {
        //gdy za mala liczba argumentow
        printf("\nUzycie: \n%s <nazwa_pliku> <plik_wynikowy> <klucz>", argv[0]);
    }
    return 0;
}

W powyższym kodzie oczywiście najważniejsza jest nasza zdefiniowana funkcja xorek. Przyjmuje ona jako argumenty:

  • plikXorowany – nazwę pliku który chcemy zaszyfrować,
  • plikWyjsciowy – nazwa pliku zaszyfrowanego który powstanie po xorowaniu,
  • klucz – klucz szyfrujący.

Program za pomocą podanych argumentów otwiera plik do zaszyfrowania i tworzy dodatkowo nowy zaszyfrowany plik. Następnie czyta znak po znaku plik do zaszyfrowania i wykonuje operacje bitową xor każdego znaku z odpowiednią pozycją znaku w kluczu. Na samym końcu zapisuje i zamyka bezpiecznie nowy plik funkcją fclose.

W funkcji main() zaimplementowaliśmy obsługę programu z pomocą tablicy argumentów argv. Program jest bardzo prosty, więc zrozumienie go osobie która chociaż trochę zna podstawy C++ nie powinno być problemem. Kluczową kwestia jest tutaj zrozumienie jednej z elementarnych operacji logicznych xor.

Zastosowanie programu XOR


Naszą funkcję xorek() można wykorzystać w swoich pierwszych edukacyjnych projektach hakerskich. W końcu najlepszą obroną jest atak. Przykładowym zastosowaniem naszej funkcji xorek() jest właśnie zabezpieczenie pliku na dysku za pomocą klucza, który tylko my znamy. Jest to taki domowej roboty TrueCrypt ;-). Oczywiście logiczny jest fakt, że im dłuższy i złożony jest klucz szyfrujący tym plik zostanie lepiej zaciemniony przed okiem osób trzecich.

Innym nieco ciemniejszym zastosowaniem wykorzystywanym xora przez hakerów crackerów twórców malware jest zmniejszenie wykrywalności plików/wirusów/spyware/keyloggerów w celu uzyskania pliku FUD i oszukania programów antywirusowych…

Działanie programu XOR (WIDEO)

Poniżej przedstawiamy uzupełnienie naszego wpisu demonstrujące działanie szyfrowania XOR i jego potencjalnego zastosowania. Oprócz samego zabezpieczenia pliku, cyberprzestępca może utworzyć niewykrywalne pliki przez antywirusy które mogą zagrozić systemom operacyjnym zwykłych użytkowników. Nie istotne jest wtedy czy osoba posiada pakiet ochronny czy też nie.

Zmniejszenie wykrywalności pliku (FUD)

Do zmniejszenia wykrywalności służą tzn. cryptery/packery. Nasza gotowa funkcja może posłużyć crackerowi do stworzenia takiej aplikacji z wykorzystaniem prostego XORa.

Jak to ma działać przedstawie w krokach dla osób ambitniejszych takich jak Ty, skoro to czytasz.

  1. Stwórz aplikacje z naszą funkcją xorek(), który szyfruje wykrywalnego wirusa za pomocą z góry zdefiniowanego klucza np: tajnyklucz
  2. Stwórz drugi program, który ponownie używa naszej funkcji xorek() odszyfrowując wirusa za pomocą tajnyklucz
  3. Program zaraz po odszyfrowaniu musi uruchomić nowo utworzony plik za pomocą np: funkcji system() z standardowej biblioteki cstdlib
  4. Gotowe
Crypter XOR - schemat blokowy
Działanie przykładowego cryptera XOR zmniejszający wykrywalność pliku.

Zasoby aplikacji

Kwestią najważniejszą jest jak ukryć w drugim programie zaszyfrowanego niewykrywalnego już w tej postaci wirusa. Sposobów jest wiele. Cyberprzestępca może użyć zasobów aplikacji dodając tego zaszyfrowanego wirusa do programu drugiego (jest to tzn. stub). Następnie przy uruchomieniu wypakować na dysk twardy, odszyfrować i uruchomić.

Doklejenie kodu wirusa

Innym rozwiązaniem jest doklejenie do tego stuba odszyfrującego i uruchamiającego wirusa, kodu zaszyfrowanego wirusa. Haker robi to na końcu pliku binarnego (można to zrobić właśnie za pomocą poznanej w wpisie funkcji fopen) a następnie zaimplementować specjalną funkcję w programie która ten ciąg odczyta z siebie (z końca), wypakuje na dysk i odszyfruje. Są to zwykłe operacje na ciągach tekstowych (stringach).

Dołączenie zaszyfrowanej binarki pliku

Lamerską metodą może być dołączenie dwóch plików w folderze, czyli stuba odszyfrującego i uruchamiającego wirusa no i samego zaszyfrowanego wirusa. Stub odszyfrowuje plik który znajduje się obok i uruchamia.

Wirus downloader

Jeszcze inną metodą może być stworzenie dowloadera pliku wirusa zaszyfrowanego z internetu. Program pobiera zaszyfrowanego wirusa po cichu na dysk z Internetu. Następnie go odszyfrowuje i uruchamia.

Inne metody na cryptera i FUD

Sposobów i metod jest dużo więcej. Przykładem może być np: wczytywanie dynamiczne kodu wirusa z pamięci (RunPE). Pożądaną cechą dla cyberprzestępcy jest tzn. FUD pliku (full undetectable). FUD oznacza, że plik jest w pełni niewykrywalny przez antywirusy na chwilę obecną.

Podsumowanie szyfrowania plików XOR

Piękno programowania i sztuki hakerskiej (nie myl z przestępcami!) polega na mnogości rozwiązań i kreatywności. Tylko od Twojej wiedzy i umiejętności zależy jak kreatywnie rozwiążesz problem ze swojej rzeczywistości. Haker wcale nie musi być komputerowym maniakiem. Każda osoba kreatywna, która wykorzystuje rzeczywistość w sposób niekonwencjonalny jest hakerem.

Jeśli podoba Ci się ten wpis i chcesz być na bieżąco zlajkuj nas na Facebooku TUTAJ. Mamy też kanał na YouTube, Twittera, Pinteresta i Google+ ale o tym nie wspomnę ;-).

Być może spodobają Ci się jeszcze inne nasze wpisy:

Pamiętaj! Bądź na każdym kroku do przodu i kreatywny! A może Wy macie jakieś ciekawe pomysły i patenty na siebie? Tym stwierdzeniem kończę wpis. 😉

4 thoughts to “Szyfrowanie plików w C++ (XOR/Crypter/Packer)”

  1. Bardo podoba mi się seria o cpp, fajnie by było gdybyś kontynował, i omówił troche, takie pojęcia jak wykorzystanie C++ sieciowo tzn. jak działają socksy, jakieś biblioteki sieciowe dla cpp, konkretnie chodzi mi o wysyłanie i możliowość odbierania pakietów, ( taki prosty komunikator konsolowy ), oraz wysyłanie plików na serwer,

  2. Cześć. Sorry, że odkopuję post ale chodzi mi o to, jak wywalić z tego programu „obsluga programu za pomoca argumentow”. Kombinuję nad tym około 1 godziny. Zawsze jakieś błędy mi wywala. Dziękuję za pomoc!

    1. Błąd wywala w linii 50? Nie powinno tak być, ponieważ jest to zwykły komentarz języka programowania C++. Wyczuwam jakiś problem z kodowaniem znaków Twojego edytora.

  3. Cześć, bardzo dziękuję za kod, użyłem go w moim programie do szyfrowania lokalnej bazy danych SQLite 🙂
    Mam pytanie czy można tym zaszyfrować cały folder?

Dodaj komentarz

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