
BARF : एक बहु-प्लेटफ़ॉर्म ओपन सोर्स बाइनरी विश्लेषण और रिवर्स इंजीनियरिंग फ्रेमवर्क
बाइनरी कोड का विश्लेषण कंप्यूटर विज्ञान और सॉफ्टवेयर इंजीनियरिंग के कई क्षेत्रों में एक महत्वपूर्ण गतिविधि है, जिसमें सॉफ्टवेयर सुरक्षा और प्रोग्राम विश्लेषण से लेकर रिवर्स इंजीनियरिंग तक शामिल है। मैन्युअल बाइनरी विश्लेषण एक कठिन और समय लेने वाला कार्य है, और ऐसे सॉफ्टवेयर उपकरण हैं जो मानव विश्लेषकों को स्वचालित या सहायता करने का प्रयास करते हैं। हालाँकि, इनमें से अधिकांश उपकरणों में कई तकनीकी और व्यावसायिक प्रतिबंध हैं जो शैक्षणिक और व्यवसायी समुदायों के एक बड़े हिस्से तक पहुँच और उपयोग को सीमित करते हैं। BARF एक ओपन सोर्स बाइनरी विश्लेषण फ्रेमवर्क है जिसका उद्देश्य सूचना सुरक्षा अनुशासन में सामान्य बाइनरी कोड विश्लेषण कार्यों की एक विस्तृत श्रृंखला का समर्थन करना है। यह एक स्क्रिप्टेबल प्लेटफॉर्म है जो कई आर्किटेक्चर से इंस्ट्रक्शन लिफ्टिंग, एक इंटरमीडिएट रिप्रेजेंटेशन में बाइनरी अनुवाद, कोड विश्लेषण प्लगइन्स के लिए एक एक्सटेंसिबल फ्रेमवर्क और डीबगर्स, SMT सॉल्वर्स और इंस्ट्रुमेंटेशन टूल्स जैसे बाहरी उपकरणों के साथ इंटरऑपरेशन का समर्थन करता है। फ्रेमवर्क मुख्य रूप से मानव-सहायक विश्लेषण के लिए डिज़ाइन किया गया है लेकिन इसे पूरी तरह से स्वचालित किया जा सकता है।
BARF प्रोजेक्ट में BARF और संबंधित उपकरण और पैकेज शामिल हैं। अब तक इस परियोजना में निम्नलिखित आइटम शामिल हैं:
अधिक जानकारी के लिए देखें:
वर्तमान स्थिति:
| नवीनतम रिलीज़ | v0.6.0 |
|---|---|
| URL | https://github.com/programa-stic/barf-project/releases/tag/v0.6.0 |
| परिवर्तन लॉग | https://github.com/programa-stic/barf-project/blob/v0.6.0/CHANGELOG.md |
सभी पैकेज Ubuntu 16.04 (x86_64) पर परीक्षण किए गए थे।
BARF बाइनरी विश्लेषण और रिवर्स इंजीनियरिंग के लिए एक Python पैकेज है। यह कर सकता है:
ELF, PE, आदि) में बाइनरी प्रोग्राम लोड करना,यह वर्तमान में विकास के अधीन है।
BARF निम्नलिखित SMT सॉल्वर्स पर निर्भर करता है:
निम्नलिखित कमांड आपके सिस्टम पर BARF स्थापित करता है:
$ sudo python setup.py install
आप इसे स्थानीय रूप से भी स्थापित कर सकते हैं:
$ sudo python setup.py install --user
यह एक बहुत ही सरल उदाहरण है जो दिखाता है कि बाइनरी फ़ाइल कैसे खोलें और प्रत्येक निर्देश को उसके इंटरमीडिएट भाषा (REIL) में अनुवाद के साथ प्रिंट करें।
from barf import BARF
# बाइनरी फ़ाइल खोलें।
barf = BARF("examples/misc/samples/bin/branch4.x86")
# असेंबली निर्देश प्रिंट करें।
for addr, asm_instr, reil_instrs in barf.translate():
print("{:#x} {}".format(addr, asm_instr))
# REIL अनुवाद प्रिंट करें।
for reil_instr in reil_instrs:
print("\t{}".format(reil_instr))
हम CFG को पुनर्प्राप्त भी कर सकते हैं और इसे .dot फ़ाइल में सहेज सकते हैं।
# CFG पुनर्प्राप्त करें।
cfg = barf.recover_cfg()
# CFG को .dot फ़ाइल में सहेजें।
cfg.save("branch4.x86_cfg")
हम SMT सॉल्वर का उपयोग करके कोड पर प्रतिबंधों की जांच कर सकते हैं। उदाहरण के लिए, मान लें कि आपके पास निम्नलिखित कोड है:
80483ed: 55 push ebp
80483ee: 89 e5 mov ebp,esp
80483f0: 83 ec 10 sub esp,0x10
80483f3: 8b 45 f8 mov eax,DWORD PTR [ebp-0x8]
80483f6: 8b 55 f4 mov edx,DWORD PTR [ebp-0xc]
80483f9: 01 d0 add eax,edx
80483fb: 83 c0 05 add eax,0x5
80483fe: 89 45 fc mov DWORD PTR [ebp-0x4],eax
8048401: 8b 45 fc mov eax,DWORD PTR [ebp-0x4]
8048404: c9 leave
8048405: c3 ret
और आप जानना चाहते हैं कि कोड निष्पादित करने के बाद eax रजिस्टर में एक विशिष्ट मान प्राप्त करने के लिए आपको मेमोरी स्थानों ebp-0x4, ebp-0x8 और ebp-0xc में कौन से मान निर्दिष्ट करने होंगे।
सबसे पहले, हम निर्देशों को विश्लेषक घटक में जोड़ते हैं।
from barf import BARF
# ELF फ़ाइल खोलें
barf = BARF("examples/misc/samples/bin/constraint1.x86")
# विश्लेषण करने के लिए निर्देश जोड़ें।
for addr, asm_instr, reil_instrs in barf.translate(0x80483ed, 0x8048401):
for reil_instr in reil_instrs:
barf.code_analyzer.add_instruction(reil_instr)
फिर, हम प्रत्येक रुचि के चर के लिए व्यंजक उत्पन्न करते हैं और उन पर वांछित प्रतिबंध जोड़ते हैं।
ebp = barf.code_analyzer.get_register_expr("ebp", mode="post")
# पूर्व शर्तें: चर a और b के लिए श्रेणी निर्धारित करें
a = barf.code_analyzer.get_memory_expr(ebp-0x8, 4, mode="pre")
b = barf.code_analyzer.get_memory_expr(ebp-0xc, 4, mode="pre")
for constr in [a >= 2, a <= 100, b >= 2, b <= 100]:
barf.code_analyzer.add_constraint(constr)
# पश्च शर्तें: परिणाम के लिए वांछित मान निर्धारित करें
c = barf.code_analyzer.get_memory_expr(ebp-0x4, 4, mode="post")
for constr in [c >= 26, c <= 28]:
barf.code_analyzer.add_constraint(constr)
अंत में, हम जांचते हैं कि क्या हमारे द्वारा स्थापित प्रतिबंधों को हल किया जा सकता है।
if barf.code_analyzer.check() == 'sat':
print("[+] संतोषजनक! संभावित असाइनमेंट:")
# व्यंजकों के लिए ठोस मान प्राप्त करें
a_val = barf.code_analyzer.get_expr_value(a)
b_val = barf.code_analyzer.get_expr_value(b)
c_val = barf.code_analyzer.get_expr_value(c)
# मान प्रिंट करें
print("- a: {0:#010x} ({0})".format(a_val))
print("- b: {0:#010x} ({0})".format(b_val))
print("- c: {0:#010x} ({0})".format(c_val))
assert a_val + b_val + 5 == c_val
else:
print("[-] असंतोषजनक!")
आप इन और अधिक उदाहरणों को examples निर्देशिका में देख सकते हैं।
फ्रेमवर्क तीन मुख्य घटकों में विभाजित है: core, arch और analysis।
इस घटक में आवश्यक मॉड्यूल शामिल हैं:
REIL: REIL भाषा के लिए परिभाषाएँ प्रदान करता है। यह एक एम्यूलेटर और एक पार्सर भी लागू करता है।SMT: Z3 और CVC4 SMT सॉल्वर के साथ इंटरफेस करने के साधन प्रदान करता है। साथ ही, यह REIL निर्देशों को SMT व्यंजकों में अनुवाद करने की कार्यक्षमता प्रदान करता है।BI: Binary Interface मॉड्यूल प्रसंस्करण के लिए बाइनरी फ़ाइलों को लोड करने के लिए जिम्मेदार है (यह PEFile और PyELFTools का उपयोग करता है।)प्रत्येक समर्थित आर्किटेक्चर को एक उप-घटक के रूप में प्रदान किया जाता है जिसमें निम्नलिखित मॉड्यूल शामिल हैं।
Architecture: आर्किटेक्चर का वर्णन करता है, अर्थात् रजिस्टर, मेमोरी पता आकार।Translator: प्रत्येक समर्थित निर्देश के लिए REIL में अनुवादक प्रदान करता है।Disassembler: डिसएसेम्बलिंग कार्यक्षमताएँ प्रदान करता है (यह Capstone का उपयोग करता है।)Parser: निर्देश को स्ट्रिंग से ऑब्जेक्ट रूप में बदलता है।अब तक इस घटक में मॉड्यूल शामिल हैं: Control-Flow Graph, Call Graph और Code Analyzer। पहले दो क्रमशः CFG और CG पुनर्प्राप्ति के लिए कार्यक्षमता प्रदान करते हैं। बाद में, यह SMT सॉल्वर संबंधित कार्यक्षमता के लिए एक उच्च-स्तरीय इंटरफ़ेस है।
BARFgadgets एक Python स्क्रिप्ट है जो BARF पर निर्मित है और आपको बाइनरी प्रोग्राम के अंदर ROP गैजेट्स को खोजने, वर्गीकृत करने और सत्यापित करने देती है। खोज चरण बाइनरी के अंदर सभी ret-, jmp- और call-समाप्त गैजेट्स को ढूंढता है। वर्गीकरण चरण पहले से पाए गए गैजेट्स को निम्नलिखित प्रकारों के अनुसार वर्गीकृत करता है:
यह निर्देश एम्यूलेशन के माध्यम से किया जाता है। अंत में, सत्यापन चरण में दूसरे चरण में प्रत्येक गैजेट को निर्दिष्ट शब्दार्थ को सत्यापित करने के लिए SMT सॉल्वर का उपयोग करना शामिल है।
usage: BARFgadgets [-h] [--version] [--bdepth BDEPTH] [--idepth IDEPTH] [-u]
[-c] [-v] [-o OUTPUT] [-t] [--sort {addr,depth}] [--color]
[--show-binary] [--show-classification] [--show-invalid]
[--summary SUMMARY] [-r {8,16,32,64}]
filename
Tool for finding, classifying and verifying ROP gadgets.
positional arguments:
filename Binary file name.
optional arguments:
-h, --help show this help message and exit
--version Display version.
--bdepth BDEPTH Gadget depth in number of bytes.
--idepth IDEPTH Gadget depth in number of instructions.
-u, --unique Remove duplicate gadgets (in all steps).
-c, --classify Run gadgets classification.
-v, --verify Run gadgets verification (includes classification).
-o OUTPUT, --output OUTPUT
Save output to file.
-t, --time Print time of each processing step.
--sort {addr,depth} Sort gadgets by address or depth (number of
instructions) in ascending order.
--color Format gadgets with ANSI color sequences, for output
in a 256-color terminal or console.
--show-binary Show binary code for each gadget.
--show-classification
Show classification for each gadget.
--show-invalid Show invalid gadget, i.e., gadgets that were
classified but did not pass the verification process.
--summary SUMMARY Save summary to file.
-r {8,16,32,64} Filter verified gadgets by operands register size.
अधिक जानकारी के लिए, README देखें।
BARFcfg एक Python स्क्रिप्ट है जो BARF पर निर्मित है और आपको बाइनरी प्रोग्राम के कंट्रोल-फ्लो ग्राफ को पुनर्प्राप्त करने देती है।
usage: BARFcfg [-h] [-s SYMBOL_FILE] [-f {txt,pdf,png,dot}] [-t]
[-d OUTPUT_DIR] [-b] [--show-reil]
[--immediate-format {hex,dec}] [-a | -r RECOVER]
filename
Tool for recovering CFG of a binary.
positional arguments:
filename Binary file name.
optional arguments:
-h, --help show this help message and exit
-s SYMBOL_FILE, --symbol-file SYMBOL_FILE
Load symbols from file.
-f {txt,pdf,png,dot}, --format {txt,pdf,png,dot}
Output format.
-t, --time Print process time.
-d OUTPUT_DIR, --output-dir OUTPUT_DIR
Output directory.
-b, --brief Brief output.
--show-reil Show REIL translation.
--immediate-format {hex,dec}
Output format.
-a, --recover-all Recover all functions.
-r RECOVER, --recover RECOVER
Recover specified functions by address (comma
separated).
BARFcg एक Python स्क्रिप्ट है जो BARF पर निर्मित है और आपको बाइनरी प्रोग्राम के कॉल ग्राफ को पुनर्प्राप्त करने देती है।
usage: BARFcg [-h] [-s SYMBOL_FILE] [-f {pdf,png,dot}] [-t] [-a | -r RECOVER]
filename
Tool for recovering CG of a binary.
positional arguments:
filename Binary file name.
optional arguments:
-h, --help show this help message and exit
-s SYMBOL_FILE, --symbol-file SYMBOL_FILE
Load symbols from file.
-f {pdf,png,dot}, --format {pdf,png,dot}
Output format.
-t, --time Print process time.
-a, --recover-all Recover all functions.
-r RECOVER, --recover RECOVER
Recover specified functions by address (comma
separated).
PyAsmJIT x86_64/ARM असेंबली कोड जनरेशन और निष्पादन के लिए एक Python पैकेज है।
यह पैकेज x86_64/ARM से REIL में BARF निर्देश अनुवाद का परीक्षण करने के लिए विकसित किया गया था। मुख्य विचार कोड के टुकड़ों को मूल रूप से चलाने में सक्षम होना है। फिर, उसी टुकड़े का REIL में अनुवाद किया जाता है और REIL VM में निष्पादित किया जाता है। अंत में, दोनों अंतिम संदर्भों (मूल निष्पादन के माध्यम से प्राप्त और एम्यूलेशन से) की तुलना अंतर के लिए की जाती है।
अधिक जानकारी के लिए, PyAsmJIT देखें।
BSD 2-Clause License. अधिक जानकारी के लिए, LICENSE देखें।