Świetny, techniczny artykuł prezentujący, jakie wyzwania czekają twórców obfuscatorów w dobie AI. Dogłębna analiza, jakie metody obfuskacyjne zawodzą w starciu z deobfuskacją przez Claude 4.6 oraz jakie techniki warto zastosować, żeby chociaż wypalić tokeny przy próbach deobfuskacji.
Z okazji rocznicy, okrągłej oczywiście — odkodowania 133541 (tak — stu trzydziestu trzech tysięcy pięciuset czterdziestu jeden) haseł przez mój dekoder online, publikuję kody źródłowe algorytmu dekodowania haseł FTP Total Commandera w formie paczek dla popularnych języków programowania.
Dostępne są paczki dla PHP, Pythona, JS i waszego ukochanego Rust. Kody źródłowe wszystkich paczek są dostępne na moim GitHubie.
Zachęcony pozytywnymi komentarzami dotyczącymi mojego projektu StringEncrypt, postanowiłem zaktualizować wszystko, co się dało i spełnić marzenia fanów tego niezwykłego rozwiązania.
Silnik projektu jest wykorzystany w moich pozostałych narzędziach do masowego, polimorficznego szyfrowania stringów (w AutoIt Obfuscator i JObfuscator).
Szyfrować i generować kod można w następujących językach programowania:
Nowa wersja przynosi ogrom zmian, w tym najważniejsze – wsparcie dla wielu nowych języków programowania, tony bugfixów i najważniejsze – zagnieżdżone pętle polimorficzne.
Zagnieżdżone pętle polimorficzne
Jednym z zarzutów i wektorów ataku na StringEncrypt (w przypadku generatorów np. C/C++) było wykorzystanie narzędzi do ekstrakcji stringów, takich jak flare-floss. Narzędzie to potrafi przeskanować gotowy plik EXE, przeanalizować kod i wyciągnąć nawet zaszyfrowane stringi.
Zgłębiłem temat i cała filozofia tego rozwiązania bazuje na detekcji tzw. tight-loops, czyli ciasnych pętli. flare-floss potrafi rozpoznać krótkie pętle deszyfrujące i poprzez ich emulację wyciągnąć zaszyfrowane stringi, jeśli takie pętle zostały wykorzystane do ich odszyfrowania.
Rozwiązaniem tego problemu było wygenerowanie wielopoziomowo zagnieżdżonych pętli z polimorficznym kodem deszyfrującym co nie wpisuje się już w detekcję prostych pętli.
#!/usr/bin/env python
###############################################################################
#
# String Encrypt WebApi interface usage example.
#
# In this example we will encrypt sample string with default options.
#
# Version : v1.0.1
# Language : Python
# Author : Bartosz Wójcik
# Project page : https://www.stringencrypt.com
# Web page : https://www.pelock.com
#
###############################################################################
#
# include StringEncrypt module
#
from stringencrypt import StringEncrypt
#
# if you don't want to use Python module, you can import it directly from the file
#
#from stringencrypt.stringencrypt import StringEncrypt
#
# create StringEncrypt class instance (we are using our activation code)
#
myStringEncrypt = StringEncrypt("YOUR-API-KEY-HERE") # leave empty for demo mode
#
# encrypt a string using all the default options
#
result = myStringEncrypt.encrypt_string("Hello, world!", "label_encrypted")
#
# result[] array holds the encryption results as well as other information
#
# result["error"] (int) - error code
# result["source"] (string) - decryptor source code
# result["expired"] (boolean) - expiration flag
# result["credits_left"] (int) - number of credits left
# result["credits_total"] (int) - initial number of credits
if result and "error" in result:
# display source code of the decryption code
if result["error"] == StringEncrypt.ErrorCodes.ERROR_SUCCESS:
print(result["source"])
else:
print(f'An error occurred, error code: {result["error"]} ({result["error_string"]})')
else:
print("Something unexpected happen while trying to encrypt the string.")
Pełna wersja
Klucz można zakupić za śmieszne pieniądze lub za darmo go zdobyć, pisząc o tym rozwiązaniu na social mediach, artykułach, na forach czy gdziekolwiek się da z linkiem do strony projektu i krótkim opisem oraz screenshotem. Niewiele, prawda?
Na koniec chciałbym jeszcze raz podziękować wszystkim fanom, którzy w dobie AI zmotywowali mnie do tak dużych aktualizacji – bez waszych słów wsparcia by mi się nie chciało aż tak 🙂
Zmodernizowana i zaktualizowana wersja dekodera polskich dowodów rejestracyjnych, pozwalająca odczytać wszystkie dane ze zdjęcia kodu AZTEC 2D dowodu rejestracyjnego auta.
Zaktualizowana wersja SDK dla JavaScript i TypeScript (pod Node) dostępna na NPM:
Przykłady użycia są banalnie proste. Dekodować można ze zdjęć oraz już zeskanowanych stringów (jeśli masz skaner ręczny).
//
// importuj moduł Dekoder AZTec dla Node.js
//
import { AZTecDecoder } from "aztec-decoder";
// inicjalizuj dekoder (używamy naszego klucza licencyjnego do inicjalizacji)
const decoder = new AZTecDecoder("ABCD-ABCD-ABCD-ABCD");
//
// 1. Dekoduj dane bezpośrednio z pliku graficznego, zwróć wynik jako rozkodowaną tablicę elementów JSON
//
const resultImage = await decoder.decodeImageFromFile("C:\\zdjecie-dowodu.jpg");
// czy udało się zdekodować dane?
if (resultImage?.Status === true) {
// wyświetl rozkodowane dane (są zapisane jako rozkodowana tablica elementów JSON)
console.log(JSON.stringify(resultImage, null, "\t"));
}
//
// 2. Dekoduj dane bezpośrednio z pliku graficznego i zwróć wynik jako rozkodowaną tablicę elementów JSON
//
const resultPng = await decoder.decodeImageFromFile("C:\\zdjecie-kodu-aztec-2d.png");
if (resultPng) {
console.log(JSON.stringify(resultPng, null, "\t"));
}
//
// 3. Dekoduj dane z odczytanego już ciągu znaków (np. wykorzystując skaner ręczny)
//
// zakodowane dane z dowodu rejestracyjnego
const szValue = "ggMAANtYAAJD...";
const resultText = await decoder.decodeText(szValue);
if (resultText) {
console.log(JSON.stringify(resultText, null, "\t"));
}
//
// 4. Dekoduj dane z odczytanego już ciągu znaków zapisanego w pliku (np. wykorzystując skaner ręczny)
//
const resultFile = await decoder.decodeTextFromFile("C:\\odczytany-ciag-znakow-aztec-2d.txt");
if (resultFile) {
console.log(JSON.stringify(resultFile, null, "\t"));
}