
sgn v1.0.0-rs
आक्रामक सुरक्षा पेलोड के लिए पॉलीमॉर्फिक बाइनरी एन्कोडर। LFSR-आधारित फीडबैक लूप, गार्बेज इंस्ट्रक्शन इंजेक्शन और मल्टी-इटरेशन ऑबफस्केशन के साथ शेलकोड को एन्कोड करता है ताकि स्टैटिक डिटेक्शन से बचा जा सके।
SGN एक polymorphic बाइनरी एन्कोडर है जो आक्रामक सुरक्षा (offensive security) उद्देश्यों के लिए है, जैसे कि स्टैटिक रूप से अज्ञेय (undetectable) बाइनरी पेलोड उत्पन्न करना। यह दिए गए बाइनरी निर्देशों को LFSR के समान एन्कोड करने के लिए एक additive feedback loop का उपयोग करता है। यह परियोजना मूल Shikata ga nai का golang में कई सुधारों के साथ पुनःकार्यान्वयन (reimplementation) है।
[!WARNING]
यह परियोजना हाल ही में Rust में पोर्ट की गई है। यह पोर्ट मूल डिज़ाइन और व्यवहार को बनाए रखता है, लेकिन keystone टेक्स्ट असेंबलर को शुद्ध-Rusticed-x86असेंबलर से बदल देता है, इसलिए कोई native library निर्भरता नहीं है — यह एक साधारणcargo buildसे बिल्ड हो जाता है। पुराने Go संस्करण के लिए sgn-go शाखा देखें।
क्यों?
आक्रामक सुरक्षा समुदाय के लिए, shikata ga nai एन्कोडर का मूल कार्यान्वयन अब तक का सबसे अच्छा shellcode एन्कोडर माना जाता है (until now)। लेकिन वर्षों से सुरक्षा शोधकर्ताओं ने डिकोडर स्टब (decoder stub) का स्टैटिक रूप से पता लगाने के लिए कई कमियाँ खोजी हैं (संबंधित कार्य FireEye लेख)। इस परियोजना का मुख्य उद्देश्य एक बेहतर एन्कोडर बनाना था जो दिए गए बाइनरी को इस हद तक एन्कोड करे कि वह पूरी तरह से यादृच्छिक डेटा के समान हो और डिकोडर की उपस्थिति का पता लगाना संभव न हो।
- 64 बिट समर्थन।
आखिरकार x64 shellcode सही ढंग से एन्कोड किए गए! - नया छोटा डिकोडर स्टब।
LFSR कुंजी घटाकर 1 बाइट कर दी गई - छद्म-यादृच्छिक स्कीमा के साथ एन्कोडेड स्टब।
डिकोडर स्टब भी छद्म-यादृच्छिक स्कीमा के साथ एन्कोड किया गया है - कोई दृश्य लूप शर्त नहीं
स्टब बिना किसी लूप शर्त के खुद को डिकोड करता है!! - डिकोडर स्टब अस्पष्टीकरण।
keystone के साथ यादृच्छिक कचरा निर्देश जनरेटर जोड़ा गया - सुरक्षित रजिस्टर विकल्प।
कोई भी रजिस्टर क्लोबर नहीं होता (वैकल्पिक प्रस्तावना, polymorphism कम कर सकती है)
यह कैसे काम करता है
प्रत्येक एन्कोडिंग पास:
- (वैकल्पिक) एक रजिस्टर-पुनर्स्थापना प्रत्यय (safe mode) जोड़ता है;
- शुरुआत में यादृच्छिक, मान-संरक्षण करने वाले कचरा निर्देश जोड़ता है;
- पेलोड को ADFL (additive feedback loop) सिफर से साइफर करता है और एक लूप-मुक्त डिकोडर स्टब जोड़ता है जो इसे रनटाइम पर उलट देता है;
- जब तक
--plainन दिया जाए, स्टब को स्वयं एक यादृच्छिक प्रति-रन स्कीमा सिफर (XOR/ADD/SUB/ROL/ROR/NOTDWORDs पर) से एन्क्रिप्ट करता है और एक स्व-स्थान-खोज (self-locating) स्कीमा डिकोडर जोड़ता है, ताकि डिकोडर भी यादृच्छिक डेटा जैसा दिखे; - वैकल्पिक रूप से नए बीजों (seeds) के साथ
--encबार दोहराता है; - (वैकल्पिक) एक रजिस्टर-सहेज उपसर्ग (safe mode) जोड़ता है।
स्थापना
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 मोड में किया जाता है, जिसमें एक यादृच्छिक स्ट्रेस लूप भी शामिल है।
पोर्ट पर नोट्स
- निर्देश निर्माण keystone असेंबली टेक्स्ट के बजाय
iced-x86के टाइप किए गए असेंबलर API का उपयोग करता है; डिकोडर स्टब को RIP-सापेक्ष एड्रेसिंग (x64) और एकcall/popदो-पास योजना (x86) के चारों ओर फिर से बनाया गया। - स्कीमा सिफर सीधे CPU के नेटिव लिटिल-एंडियन DWORD दृश्य में व्यक्त किया गया है, जो मूल के मिश्रित बिग/लिटिल-एंडियन अंकगणित के बराबर लेकिन अधिक स्पष्ट है।
- मूल का मृत कोड (अप्रयुक्त ~3k-पंक्ति निर्देश-सेट तालिका और वह "असुरक्षित कचरा" (unsafe garbage) जनरेटर जिसे कभी कॉल नहीं किया गया) हटा दिया गया।
- छोटे सुधार:
random_byteअब पूरी0..=255सीमा में फैला हुआ है, और कचरा-आकार बजट (--max) को प्रति-ब्लॉक सीमा के रूप में लगातार लागू किया जाता है।