
Polymorpher Binärcodierer für offensive Security-Payloads. Kodiert Shellcode mit LFSR-basierter Rückkopplungsschleife, Einschleusung nutzloser Anweisungen und Verschleierung über mehrere Iterationen, um statische Erkennung zu umgehen.
SGN ist ein polymorpher Binärcode-Encoder für offensive Sicherheitszwecke, etwa um statisch nicht erkennbare Binär-Payloads zu erzeugen. Er verwendet eine additive Rückkopplungsschleife, um gegebene Binärbefehle ähnlich wie LFSR zu kodieren. Dieses Projekt ist die Neuimplementierung des ursprünglichen Shikata ga nai in Go mit vielen Verbesserungen.
[!WARNING]
Das Projekt wurde kürzlich nach Rust portiert. Dieser Port behält das ursprüngliche Design und Verhalten bei, ersetzt jedoch den Keystone-Textassembler durch den reinen Rust-iced-x86-Assembler, sodass keine nativen Bibliotheksabhängigkeiten bestehen — er lässt sich mit einem einfachencargo builderstellen. Im sgn-go-Zweig finden Sie die alte Go-Version.
Für die Offensive-Security-Community gilt die ursprüngliche Implementierung des Shikata-ga-nai-Encoders als bester Shellcode-Encoder (bisher). Im Laufe der Jahre fanden Sicherheitsforscher jedoch mehrere Fallstricke beim statischen Erkennen des Decoder-Stubs (verwandte Arbeit: FireEye-Artikel). Das Hauptmotiv für dieses Projekt war es, einen besseren Encoder zu schaffen, der die übergebenen Binärdaten so weit kodiert, dass sie mit völlig zufälligen Daten identisch sind und das Vorhandensein eines Decoders nicht erkannt werden kann.
Finally properly encoded x64 shellcodes !LFSR key reduced to 1 byteDecoder stub is also encoded with a psudo random schemaStub decodes itself WITHOUT using any loop conditions !!Random garbage instruction generator added with keystoneNon of the registers are clobbered (optional preable, may reduce polimorphism)Jeder Kodierungsdurchlauf:
--plain angegeben ist, verschlüsselt es den Stub selbst mit einer zufälligen, pro Lauf erzeugten Schema-
Chiffre (XOR/ADD/SUB/ROL/ROR/NOT über DWORDs) und stellt einen selbstlokalisierenden
Schema-Decoder voran, sodass sogar der Decoder wie Zufallsdaten aussieht;--enc-Mal mit neuen Seeds;cargo install sgn
Sie können die vorkompilierten Binärdateien auch HIER erhalten.
Verwendung
-h ist ziemlich selbsterklärend; verwenden Sie -v, wenn Sie sehen möchten, was hinter den Kulissen passiert ( ͡° ͜ʖ ͡°)_/¯
__ _ __ __ _
___ / / (_) /_____ _/ /____ _ ___ ____ _ ___ ___ _(_)
(_-</ _ \/ / '_/ _ `/ __/ _ `/ / _ `/ _ `/ / _ \/ _ `/ /
/___/_//_/_/_/\_\\_,_/\__/\_,_/ \_, /\_,_/ /_//_/\_,_/_/
========[Author:-Ege-Balcı-]====/___/=======v2.0.2=========
┻━┻ ︵ヽ(`Д´)ノ︵ ┻━┻ (ノ ゜Д゜)ノ ︵ 仕方がない
sgn [OPTIONS]
Options:
-i, --input <INPUT> Input binary path
-o, --out <OUT> Encoded output binary name (default: <input>.sgn)
-a, --arch <ARCH> Binary architecture (32/64) [default: 64]
-c, --enc <ENC> Number of times to encode the binary [default: 1]
-M, --max <MAX> Maximum bytes per garbage block [default: 50]
--plain Do not encode the decoder stub
--ascii Generate a fully ASCII-printable payload (slow)
-S, --safe Preserve all register values (no clobber)
--badchars <BADCHARS> Avoid these bytes, hex format (e.g. \x00\x0a)
-v, --verbose Verbose mode
-h, --help Print help
-V, --version Print version
Beispiel:
sgn -i shellcode.bin -o encoded.bin -a 64 --badchars '\x00\x0a\x0d'
Das folgende Bild ist ein grundlegendes Ablaufdiagramm für den Encoder. Beachten Sie jedoch, dass sich Größen, Positionen und Reihenfolgen der Garbage-Anweisungen, Decoder und Schema-Decoder bei jeder Iteration ändern.
Das LFSR selbst ist im Hinblick auf den Wahrscheinlichkeitsraum ziemlich leistungsfähig. Für noch mehr Polymorphismus werden am Anfang des unkodierten Roh-Payloads Garbage-Anweisungen angehängt. Das folgende Bild zeigt die Begleitmatrix des charakteristischen Polynoms des LFSR und, wenn der Seed als Spaltenvektor angegeben wird, den Zustand des Registers in der Fibonacci-Konfiguration nach k Schritten.
use sgn::Encoder;
let shellcode = std::fs::read("payload.bin")?;
let mut encoder = sgn::Encoder::new(64)?;
let encoded = encoder.encode(&shellcode)?;
println!("encoded {} bytes", encoded.len());
Siehe examples/encode_binary.rs.
cargo test
Die Suite enthält Unit-Tests für den Chiffre-Roundtrip sowie echte Ausführungstests: Kodierter x64-Shellcode wird als ausführbar gemappt und prozessintern ausgeführt, und x86-Shellcode wird über eine cc -m32-Hilfsharness ausgeführt (wird automatisch übersprungen, wenn keine 32-Bit-Toolchain vorhanden ist). Beide Architekturen werden in den Modi Plain, Schema, mehrschichtig und Safe-Register getestet, einschließlich einer randomisierten Stress-Schleife.
iced-x86 anstelle von Keystone-Assemblytext; die Decoder-Stubs wurden um RIP-relative Adressierung (x64) und ein call/pop-Zweipass-Schema (x86) neu aufgebaut.random_byte umfasst jetzt den vollständigen Bereich 0..=255, und das Garbage-Größenbudget (--max) wird konsistent als Obergrenze pro Block angewendet.