
सार्वभौमिक टेंट ट्रैकिंग, डेटाफ़्लो विश्लेषण और ट्रेसिंग के लिए एक 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 प्रणाली के विपरीत, PolyTracker टेंट के संपूर्ण को ट्रैक करने में सक्षम है। फरवरी 2021 में, LLVM DataFlowSanitizer ने टेंट प्रोवेनेंस को ट्रैक करने के लिए नामक एक नई सुविधा जोड़ी। हालाँकि, यह एक बार में अधिकतम 16 टेंट ही ट्रैक कर सकता है, जबकि PolyTracker 2-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 प्रलेखन यहाँ उपलब्ध है।
रनटाइम पर, PolyTracker इंस्ट्रुमेंटेशन पर्यावरण चरों के माध्यम से निर्दिष्ट कई कॉन्फ़िगरेशन पैरामीटरों की तलाश करता है। यह बाइनरी को पुनः संकलित किए बिना इंस्ट्रुमेंटेशन पैरामीटरों को संशोधित करने की अनुमति देता है।
PolyTracker टार्गेट प्रोग्रामों को पुनः संकलित करने से बचने के लिए पर्यावरण चरों के रूप में कॉन्फ़िगरेशन पैरामीटर स्वीकार करता है। पर्यावरण चरों का वर्तमान सेट जो PolyTracker समर्थन करता है वह है:
POLYDB: A path to which to save the output database (default is polytracker.tdag)
WLLVM_ARTIFACT_STORE: Provides a path to an existing directory to store artifact/manifest for all build targets
POLYTRACKER_TAINT_ARGV: Set to '1' to use argv as a taint source.
POLYTRACKER_STDIN_SOURCE: Set to '1' to use stdin as a taint source.
POLYTRACKER_STDOUT_SINK: Set to '1' to use stdout as a taint sink.
POLYTRACKER_STDERR_SINK: Set to '1' to use stderr as a taint sink.
Polytracker अपने कॉन्फ़िगरेशन पैरामीटरों को निम्न क्रम में सेट करेगा:
DFSan यह निर्धारित करने के लिए ABI सूचियों का उपयोग करता है कि उसे किन फ़ंक्शनों को स्वचालित रूप से इंस्ट्रूमेंट करना चाहिए, किन फ़ंक्शनों को अनदेखा करना चाहिए, और कौन से कस्टम फ़ंक्शन रैपर मौजूद हैं। अधिक जानकारी के लिए dfsan प्रलेखन देखें।
बड़े सॉफ़्टवेयर प्रोजेक्टों को बनाने का प्रयास समय लेने वाला हो सकता है, विशेष रूप से पुराने/असमर्थित प्रोजेक्ट। बिल्ड प्रणाली को संशोधित करने का प्रयास करना और भी अधिक समय लेने वाला है ताकि यह dfsan/हमारे इंस्ट्रुमेंटेशन जैसे परिवर्तनों का समर्थन कर सके।
polytracker/scripts में स्थित एक स्क्रिप्ट है जिसे आप किसी भी ELF लाइब्रेरी पर चला सकते हैं और यह अनदेखा करने हेतु फ़ंक्शनों की एक सूची आउटपुट करेगी। हम इसका उपयोग तब करते हैं जब हम libpng जैसी किसी विशिष्ट लाइब्रेरी या प्रोग्राम के अन्य उप-घटकों से गुजरने वाली जानकारी को ट्रैक नहीं करना चाहते हैं। Dockerfile-listgen.demo सामान्य ओपन सोर्स लाइब्रेरीज़ बनाने के लिए मौजूद है ताकि हम ये सूचियाँ बना सकें।
यह स्क्रिप्ट DataFlowSanitizer के पास मौजूद चीज़ का थोड़ा संशोधित संस्करण है, जो सिस्टम लाइब्रेरीज़ को अनदेखा करने पर केंद्रित है। मूल स्क्रिप्ट dfsan_rt में पाई जा सकती है।
इस Git रिपॉज़िटरी को चेक आउट करें। रूट से, या तो आधार PolyTracker Docker इमेज बनाएँ:
pip3 install -e ".[dev]" && polytracker docker rebuild
या बस DockerHub से नवीनतम पूर्व-निर्मित संस्करण खींचें:
docker pull trailofbits/polytracker:latest
MuPDF पार्सर पर चलने वाले PolyTracker के डेमो के लिए यह कमांड चलाएँ:
docker build -t trailofbits/polytracker-demo-mupdf -f examples/pdf/Dockerfile-mupdf.demo .
mutool_track /polytracker/the_klondike/mupdf/build/debug में बनाया जाएगा। mutool_track चलाने से polytracker.tdag आउटपुट होगा जिसमें टेंट विश्लेषण द्वारा प्रदान की गई जानकारी होती है।
Poppler utils संस्करण 0.84.0 पर चलने वाले PolyTracker के डेमो के लिए यह कमांड चलाएँ:
docker build -t trailofbits/polytracker-demo-poppler -f examples/pdf/Dockerfile-poppler.demo .
सभी poppler utils /polytracker/the_klondike/poppler-0.84.0/build/utils में स्थित होंगे।
cd /polytracker/the_klondike/poppler-0.84.0/build/utils
./pdfinfo_track some_pdf.pdf
मान लीजिए आप PolyTracker कोडबेस को विस्तारित करने या TDAG ट्रेस का विश्लेषण करने में थोड़ा और गहराई से जाना चाहते हैं, और आप भारी अनुकूलित LLVM संस्करण स्थापित करके अपने स्थानीय वातावरण को गड़बड़ नहीं करना चाहते हैं।
यदि आप Ubuntu में काम कर रहे हैं और अपेक्षाकृत साफ 22.04 या 24.04 बेस से शुरू कर रहे हैं, तो linked Gist PolyTracker बेस कंटेनर का एक कार्यशील पासथ्रू संस्करण प्राप्त करने के चरणों का विवरण देता है। बेस कंटेनर सभी निर्भरताओं के साथ एक विकास वातावरण प्रदान करता है जिसमें आप सीधे काम कर सकते हैं, या विस्तार कर सकते हैं (जैसा हमने उदाहरण Dockerfiles में किया है)।
Python और C++ दोनों यूनिट परीक्षणों को PolyTracker Docker कंटेनर के अंदर चलाया जाना चाहिए।
unittests/ में Catch2 यूनिट परीक्षण कंटेनर के भीतर /polytracker-build/unittests/src/taintdag/ में रहते हैं। Docker कंटेनर के भीतर परीक्षण बाइनरी को निम्न के साथ चलाएँ
cd /polytracker-build/unittests/src/taintdag/ && ./tests-taintdag
tests/ में Python यूनिट परीक्षणों के लिए स्थानीय परीक्षण C++ प्रोग्रामों की आवश्यकता होती है जिन्हें परीक्षण फिक्स्चर इंस्ट्रूमेंट करेंगे। उन्हें कार्यशील में Pytest का उपयोग करके चलाएँ
pytest tests
या निम्न के साथ किसी एकल परीक्षण फ़ाइल को चलाने के लिए pytest का उपयोग करें
pytest tests/test_foo.py
PolyTracker वर्तमान में केवल Linux पर चलता है, क्योंकि DataFlow Sanitizer द्वारा समर्थित एकमात्र प्रणाली यही है। यह सीमा केवल अन्य OS के सिस्टम कॉल के लिए सिमेंटिक्स के समर्थन की कमी के कारण है, जिसे भविष्य में जोड़ा जा सकता है। हालाँकि, इसका मतलब है कि गैर-Linux प्रणाली पर PolyTracker चलाने के लिए Docker स्थापित होना आवश्यक होगा।
टेंट गतिशील रूप से लोड की गई लाइब्रेरीज़ के माध्यम से प्रचारित नहीं होंगे जब तक कि उन लाइब्रेरीज़ को PolyTracker का उपयोग करके स्रोत से संकलित नहीं किया गया हो, या PolyTracker में लागू लाइब्रेरी कॉल के लिए विशिष्ट समर्थन न हो। वर्तमान में अधिकांश गैर-इंस्ट्रूमेंटेड C मानक लाइब्रेरी कॉल के माध्यम से टेंट प्रचारित करने का समर्थन है। स्पष्ट करने के लिए, गैर-इंस्ट्रूमेंटेड फ़ंक्शनों का उपयोग करने वाले प्रोग्राम अभी भी सामान्य रूप से चलेंगे, हालाँकि, असमर्थित लाइब्रेरी कॉल द्वारा किए गए संचालन टेंट का प्रचार नहीं करेंगे। हम वर्तमान में C++ प्रोग्रामों के लिए मजबूत समर्थन जोड़ने पर काम कर रहे हैं, लेकिन वर्तमान में सर्वोत्तम परिणाम C प्रोग्रामों से मिलेंगे।
यदि Docker के साथ समस्याएँ हैं, तो PolyTracker और जो भी डेमो आप चलाने का प्रयास कर रहे हैं, दोनों के लिए सिस्टम प्रून करने का प्रयास करें और --no-cache के साथ बिल्ड करें।
PolyTracker का सबसे खराब स्थिति प्रदर्शन तब सामने आता है जब मेमोरी में एक एकल बाइट स्रोत फ़ाइल से बड़ी संख्या में इनपुट बाइट्स द्वारा एक साथ टेंटेड होता है। यह सबसे आम है जब बड़े ब्लॉक आकार वाले कम्प्रेशन और क्रिप्टोग्राफिक एल्गोरिदम को इंस्ट्रूमेंट किया जाता है। इस व्यवहार के लिए कई शमन उपायों पर वर्तमान में शोध और विकास किया जा रहा है।
यहाँ कुछ सार्वजनिक रूप से उपलब्ध चीज़ें हैं जो हमने PolyTracker के साथ की हैं। यदि आप किसी और चीज़ के बारे में जानते हैं जिसे आप यहाँ सूचीबद्ध देखना चाहेंगे, तो कृपया हमें बताएँ!
mapping और cavities) ट्रेस विश्लेषण कार्यक्षमता का उपयोग किया और Trail of Bits ब्लॉग पर इसके बारे में लिखा।यह शोध Trail of Bits द्वारा Galois के उप-ठेकेदार के रूप में SafeDocs कार्यक्रम के तहत Defense Advanced Research Projects Agency (DARPA) से वित्तपोषण के साथ विकसित किया गया था। यह Apache 2.0 लाइसेंस के अंतर्गत लाइसेंस प्राप्त है। © 2019, Trail of Bits।
कृपया [email protected] का उपयोग करके हमसे संपर्क करें।