
सार्वभौमिक टेंट ट्रैकिंग, डेटाफ़्लो विश्लेषण और ट्रेसिंग के लिए एक LLVM-आधारित इंस्ट्रूमेंटेशन उपकरण।
PolyTracker एक उपकरण है जो मूल रूप से Automated Lexical Annotation and Navigation of Parsers के लिए बनाया गया था, एक बैक्रोनिम जो केवल इसे The ALAN Parsers Project के रूप में संदर्भित करने के लिए गढ़ा गया था। हालाँकि, यह प्रोग्रामों के डेटा-फ्लो और कंट्रोल-फ्लो विश्लेषण को कुशलतापूर्वक करने के लिए एक सामान्य प्रयोजन उपकरण के रूप में विकसित हो गया है। PolyTracker एक LLVM पास है जो प्रोग्रामों को इंस्ट्रूमेंट करता है ताकि यह ट्रैक कर सके कि इनपुट फ़ाइल के कौन से बाइट्स किन फ़ंक्शनों द्वारा संचालित होते हैं। यह डेटा-फ्लो जानकारी वाला एक डेटाबेस, साथ ही एक रनटाइम ट्रेस आउटपुट करता है। PolyTracker इसके आउटपुट के साथ इंटरैक्ट करने और उसका विश्लेषण करने के लिए एक Python लाइब्रेरी, साथ ही एक इंटरैक्टिव Python REPL भी प्रदान करता है।
PolyTracker का उपयोग PolyFile के साथ मिलकर किया जा सकता है ताकि पार्सर में फ़ंक्शनों के सिमेंटिक उद्देश्य को स्वचालित रूप से निर्धारित किया जा सके। इसमें एक प्रयोगात्मक सुविधा भी है जो किसी पार्सर द्वारा स्वीकार की गई भाषा का प्रतिनिधित्व करने वाला एक कॉन्टेक्स्ट-फ्री ग्रामर उत्पन्न करने में सक्षम है।
Taintgrind जैसे डायनामिक इंस्ट्रुमेंटेशन विकल्पों के विपरीत, PolyTracker लगभग सभी इनपुटों के लिए नगण्य प्रदर्शन ओवरहेड लगाता है, और एक साथ इनपुट के हर बाइट को ट्रैक करने में सक्षम है। PolyTracker LLVM DataFlowSanitizer के फोर्क के रूप में शुरू हुआ और Angora Fuzzer से बहुत प्रेरणा लेता है। हालाँकि, Angora प्रणाली के विपरीत, PolyTracker टेंट के संपूर्ण provenance को ट्रैक करने में सक्षम है। फरवरी 2021 में, LLVM DataFlowSanitizer ने टेंट प्रोवेनेंस को ट्रैक करने के लिए origin tracking नामक एक नई सुविधा जोड़ी। हालाँकि, यह एक बार में अधिकतम 16 टेंट ही ट्रैक कर सकता है, जबकि PolyTracker 231-1 तक ट्रैक कर सकता है।
यह README PolyTracker को स्थापित करने और बाइनरी को संकलित/इंस्ट्रूमेंट करने के लिए सामान्य उपयोग मार्गदर्शिका के रूप में कार्य करता है। इसके Python API के माध्यम से PolyTracker के साथ प्रोग्रामेटिक रूप से इंटरैक्ट करने या इसे विस्तारित करने के साथ-साथ इंस्ट्रूमेंटेड कोड से उत्पन्न रनटाइम ट्रेस के साथ इंटरैक्ट करने के लिए, Python प्रलेखन देखें।
PolyTracker को polytracker नामक Python स्क्रिप्ट के माध्यम से नियंत्रित किया जाता है। आप इसे निम्न चलाकर स्थापित कर सकते हैं
pip3 install polytracker
PolyTracker को चलाने के लिए एक बहुत ही विशेष सिस्टम वातावरण की आवश्यकता होती है, इसलिए लगभग सभी उपयोगकर्ता इसे कंटेनरीकृत वातावरण में चलाने की संभावना रखते हैं। सौभाग्य से, polytracker इसे आसान बनाता है। आपको बस docker स्थापित करना है, फिर चलाएँ:
polytracker docker pull
और
polytracker docker run
बाद वाला कमांड वर्तमान कार्यशील निर्देशिका को PolyTracker Docker कंटेनर में माउंट करेगा और आपको इंस्ट्रूमेंटेड प्रोग्राम बनाने और चलाने की अनुमति देगा।
polytracker नियंत्रण स्क्रिप्ट—जिसे आप अपने होस्ट सिस्टम से या Docker कंटेनर के अंदर से चला सकते हैं—में विभिन्न प्रकार के कमांड हैं, दोनों प्रोग्रामों को इंस्ट्रूमेंट करने के लिए और परिणामी आर्टिफैक्ट्स का विश्लेषण करने के लिए। उदाहरण के लिए, आप निष्पादन में डेटाफ्लो का पता लगा सकते हैं, इंस्ट्रूमेंटेड प्रोग्राम के कंट्रोल फ्लो ग्राफ का पुनर्निर्माण कर सकते हैं, और प्रोग्राम द्वारा स्वीकार किए गए इनपुट से मेल खाता एक कॉन्टेक्स्ट-फ्री ग्रामर भी निकाल सकते हैं। आप निम्न चलाकर इन कमांडों का पता लगा सकते हैं
polytracker --help
polytracker स्क्रिप्ट एक REPL भी है, यदि इसे बिना किसी कमांड लाइन तर्क के चलाया जाए:
$ polytracker
PolyTracker (4.0.0)
https://github.com/trailofbits/polytracker
Type "help" or "commands"
>>> commands
PolyTracker एक build कमांड के साथ भी आता है। यह कमांड उपयोगकर्ता को Blight इंस्ट्रूमेंटेड वातावरण में कोई भी बिल्ड कमांड चलाने की अनुमति देता है। यह एक blight_journal.jsonl फ़ाइल उत्पन्न करेगा जो बिल्ड के दौरान चलाए गए सभी कमांडों को रिकॉर्ड करती है। यदि आपके पास C/C++ टार्गेट है, तो आप polytracker build को आमंत्रित करके और अपना बिल्ड कमांड पास करके इसे इंस्ट्रूमेंट कर सकते हैं:
polytracker build gcc -g -o my_binary my_source.c
किसी बिल्ड टार्गेट को इंस्ट्रूमेंट करने के लिए, instrument-targets कमांड का उपयोग करें। डिफ़ॉल्ट रूप से कमांड आपके वर्तमान कार्यशील निर्देशिका में एक blight_journal.jsonl का उपयोग करके आपके बिल्ड टार्गेट का एक इंस्ट्रूमेंटेड संस्करण बनाएगा। इंस्ट्रूमेंटेड बिल्ड टार्गेट मूल बिल्ड टार्गेट के समान फ्लैग्स का उपयोग करके बनाया जाएगा।
polytracker instrument-targets my_binary
build ऑटोटूल्स या CMake जैसी बिल्ड प्रणाली का उपयोग करने वाले अधिक जटिल प्रोग्रामों का भी समर्थन करता है:
polytracker build cmake .. -DCMAKE_BUILD_TYPE=Release
polytracker build ninja
# or
polytracker build ./configure
polytracker build make
फिर बिल्ड के किसी भी टार्गेट पर instrument-targets चलाएँ:
polytracker instrument-targets a.bin b.so
फिर a.instrumented.bin और b.instrumented.so इंस्ट्रूमेंटेड संस्करण होंगे। वास्तविक दुनिया के प्रोग्रामों को कैसे इंस्ट्रूमेंट किया जा सकता है, इसके उदाहरणों के लिए examples निर्देशिका में Dockerfiles देखें।
इंस्ट्रूमेंटेड सॉफ़्टवेयर अपना आउटपुट POLYDB में निर्दिष्ट पथ पर लिखेगा, या यदि छोड़ दिया जाए तो polytracker.tdag पर। यह एक बाइनरी फ़ाइल है जिस पर निम्न चलाकर कार्य किया जा सकता है:
from polytracker import PolyTrackerTrace, taint_dag
trace = PolyTrackerTrace.load("polytracker.tdag")
tdfile = trace.tdfile
first_node = list(tdfile.nodes)[0]
print(f"First node affects control flow: {first_node.affects_control_flow}")
# Operate on all Range nodes
for index, node in enumerate(tdfile.nodes):
if isinstance(node, taint_dag.TDRangeNode):
print(f"Node {index}: first {node.first}, last {node.last}")
# Access taint forest
tdforest = trace.taint_forest
n1 = tdforest.get_node(1)
print(
f"Forest node {n1.label}. Parent labels: {n1.parent_labels}, "
f"source: {n1.source.path if n1.source is not None else None}, "
f"affects control flow: {n1.affected_control_flow}"
)
आप एक इंस्ट्रूमेंटेड बाइनरी को सीधे REPL से भी चला सकते हैं:
$ polytracker
PolyTracker (4.0.0)
https://github.com/trailofbits/polytracker
Type "help" or "commands"
>>> trace = run_trace("path_to_binary", "path_to_input_file")
यह आवश्यक होने पर इंस्ट्रूमेंटेड बाइनरी को स्वचालित रूप से Docker कंटेनर में चलाएगा।
⚠️ यदि PolyTracker को Docker या VM के अंदर चला रहे हैं: यदि किसी वर्चुअलाइज़्ड वातावरण में चल रहा है और या तो इनपुट फ़ाइल या, विशेष रूप से, आउटपुट डेटाबेस होस्ट OS से मैप या माउंट की गई निर्देशिका में स्थित है, तो PolyTracker बहुत धीमा हो सकता है। यह विशेष रूप से macOS होस्ट से Docker में PolyTracker चलाते समय सत्य है। समाधान यह है कि डेटाबेस को कंटेनर/VM के अंदर एक पथ पर लिखें और फिर इसे बिल्कुल अंत में होस्ट सिस्टम पर कॉपी करें।
Python API प्रलेखन यहाँ उपलब्ध है।