
आक्रामक सुरक्षा पेलोड के लिए पॉलीमॉर्फिक बाइनरी एन्कोडर। LFSR-आधारित फीडबैक लूप, गार्बेज इंस्ट्रक्शन इंजेक्शन और मल्टी-इटरेशन ऑबफस्केशन के साथ शेलकोड को एन्कोड करता है ताकि स्टैटिक डिटेक्शन से बचा जा सके।
SGN एक polymorphic बाइनरी एन्कोडर है जो आक्रामक सुरक्षा (offensive security) उद्देश्यों के लिए है, जैसे कि स्टैटिक रूप से अज्ञेय (undetectable) बाइनरी पेलोड उत्पन्न करना। यह दिए गए बाइनरी निर्देशों को LFSR के समान एन्कोड करने के लिए एक additive feedback loop का उपयोग करता है। यह परियोजना मूल Shikata ga nai का golang में कई सुधारों के साथ पुनःकार्यान्वयन (reimplementation) है।
[!WARNING]
यह परियोजना हाल ही में Rust में पोर्ट की गई है। यह पोर्ट मूल डिज़ाइन और व्यवहार को बनाए रखता है, लेकिन keystone टेक्स्ट असेंबलर को शुद्ध-Rust असेंबलर से बदल देता है, इसलिए — यह एक साधारण से बिल्ड हो जाता है। पुराने Go संस्करण के लिए शाखा देखें।
cargo buildआक्रामक सुरक्षा समुदाय के लिए, shikata ga nai एन्कोडर का मूल कार्यान्वयन अब तक का सबसे अच्छा shellcode एन्कोडर माना जाता है (until now)। लेकिन वर्षों से सुरक्षा शोधकर्ताओं ने डिकोडर स्टब (decoder stub) का स्टैटिक रूप से पता लगाने के लिए कई कमियाँ खोजी हैं (संबंधित कार्य FireEye लेख)। इस परियोजना का मुख्य उद्देश्य एक बेहतर एन्कोडर बनाना था जो दिए गए बाइनरी को इस हद तक एन्कोड करे कि वह पूरी तरह से यादृच्छिक डेटा के समान हो और डिकोडर की उपस्थिति का पता लगाना संभव न हो।
आखिरकार x64 shellcode सही ढंग से एन्कोड किए गए!LFSR कुंजी घटाकर 1 बाइट कर दी गईडिकोडर स्टब भी छद्म-यादृच्छिक स्कीमा के साथ एन्कोड किया गया हैस्टब बिना किसी लूप शर्त के खुद को डिकोड करता है!!keystone के साथ यादृच्छिक कचरा निर्देश जनरेटर जोड़ा गयाकोई भी रजिस्टर क्लोबर नहीं होता (वैकल्पिक प्रस्तावना, polymorphism कम कर सकती है)प्रत्येक एन्कोडिंग पास:
--plain न दिया जाए, स्टब को स्वयं एक यादृच्छिक प्रति-रन स्कीमा
सिफर (XOR/ADD/SUB/ROL/ROR/NOT DWORDs पर) से एन्क्रिप्ट करता है और एक
स्व-स्थान-खोज (self-locating) स्कीमा डिकोडर जोड़ता है, ताकि डिकोडर भी
यादृच्छिक डेटा जैसा दिखे;--enc बार दोहराता है;cargo install sgn
आप प्री-कंपाइल्ड बाइनरी भी यहाँ प्राप्त कर सकते हैं।
उपयोग
-h काफी स्व-व्याख्यात्मक है, यदि आप देखना चाहते हैं कि पर्दे के पीछे क्या हो रहा है तो -v का उपयोग करें ( ͡° ͜ʖ ͡°)_/¯
__ _ __ __ _
___ / / (_) /_____ _/ /____ _ ___ ____ _ ___ ___ _(_)
(_-</ _ \/ / '_/ _ `/ __/ _ `/ / _ `/ _ `/ / _ \/ _ `/ /
/___/_//_/_/_/\_\\_,_/\__/\_,_/ \_, /\_,_/ /_//_/\_,_/_/
========[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
उदाहरण:
sgn -i shellcode.bin -o encoded.bin -a 64 --badchars '\x00\x0a\x0d'
निम्नलिखित छवि एन्कोडर के लिए एक बुनियादी कार्यप्रवाह आरेख है। लेकिन ध्यान रखें कि कचरा निर्देशों, डिकोडरों और स्कीमा डिकोडरों के आकार, स्थान और क्रम प्रत्येक पुनरावृत्ति पर बदलते रहेंगे।
LFSR प्रायिकता स्थान (probability space) के संदर्भ में काफी शक्तिशाली है। और भी अधिक polymorphism के लिए, अनएन्कोडेड कच्चे पेलोड की शुरुआत में कचरा निर्देश जोड़े जाते हैं। नीचे दी गई छवि LFSR के अभिलक्षणिक बहुपद (characteristic polynomial) का साथी मैट्रिक्स (companion matrix) दिखाती है और बीज को स्तंभ सदिश (column vector) के रूप में दर्शाते हुए, Fibonacci विन्यास में k चरणों के बाद रजिस्टर की स्थिति को प्रदर्शित करती है।
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());
examples/encode_binary.rs देखें।
cargo test
सुइट में सिफर राउंड-ट्रिप यूनिट परीक्षणों के साथ-साथ वास्तविक निष्पादन परीक्षण भी शामिल हैं:
एन्कोडेड x64 shellcode को निष्पादन योग्य मैप करके प्रक्रिया में चलाया जाता है, और x86 shellcode
को cc -m32 हेल्पर हार्नेस के माध्यम से निष्पादित किया जाता है (यदि 32-बिट
टूलचेन मौजूद नहीं है तो स्वचालित रूप से छोड़ दिया जाता है)। दोनों आर्किटेक्चर का परीक्षण plain,
schema, multi-layer और safe-register मोड में किया जाता है, जिसमें एक यादृच्छिक स्ट्रेस लूप भी शामिल है।
iced-x86 के टाइप किए गए असेंबलर API का उपयोग करता है; डिकोडर स्टब को RIP-सापेक्ष
एड्रेसिंग (x64) और एक call/pop दो-पास योजना (x86) के चारों ओर फिर से बनाया गया।random_byte अब पूरी 0..=255 सीमा में फैला हुआ है, और
कचरा-आकार बजट (--max) को प्रति-ब्लॉक सीमा के रूप में लगातार लागू किया जाता है।