
समानांतर SSH सेवा खोज और सुरक्षा ऑडिटर जो किसी भी पोर्ट को स्कैन करता है, SSH बैनरों को मान्य करता है, और होस्ट्स एवं CIDR रेंजों में प्रमाणीकरण विधियों, कमज़ोर क्रिप्टोग्राफ़ी, Terrapin भेद्यता, और पुनः उपयोग की गई होस्ट कुंजियों का ऑडिट करता है।
अपने नेटवर्क पर हर SSH सेवा खोजें, निर्णय लें कि क्या वह आपके मानक को पूरा करती है, और जब वह बदलती है तो सूचित हों।
sshfinder एक एकल Python फ़ाइल है जिसमें कोई आवश्यक निर्भरता नहीं है। इसे CIDR रेंज की ओर इंगित करें और यह SSH को वहाँ खोजता है जहाँ यह वास्तव में सुन रहा है — केवल पोर्ट 22 पर नहीं — प्रत्येक की पुष्टि करता है कि वह वास्तव में SSH बोलता है, इसकी क्रिप्टोग्राफ़िक स्थिति का आकलन करता है, और जब कुछ आपकी नीति में विफल होता है तो गैर-शून्य निकास कोड लौटाता है।
अधिकांश टीमें अपने स्वयं के SSH परिसंपत्ति के बारे में तीन प्रश्नों का उत्तर नहीं दे सकतीं:
मौजूदा उपकरण प्रत्येक इसका एक हिस्सा उत्तर देते हैं और रुक जाते हैं:
| उपकरण | SSH खोजता है | आकलन करता है | पूरे बेड़े में |
|---|---|---|---|
nmap | हाँ | उथला, NSE स्क्रिप्ट के माध्यम से | हाँ |
ssh-audit | नहीं — आप इसे एक होस्ट देते हैं | गहराई से | नहीं |
masscan / zmap | इंटरनेट पैमाने पर | नहीं | हाँ |
sshfinder | हाँ | हाँ | हाँ |
वह अंतर — खोज और आकलन और एक निर्णय, एक ही कलाकृति में — वही है जिसे भरने के लिए यह उपकरण मौजूद है। यदि आपको केवल एक होस्ट का ऑडिट करना है जिसे आप पहले से जानते हैं, तो ssh-audit का उपयोग करें; यह एकल सेवा पर इससे अधिक गहराई तक जाता है।
पेनेट्रेशन परीक्षकों को ऑडिट और SOCKS पिवट उपयोगी लगेगा, लेकिन उपकरण उसी स्कैन को बार-बार उस परिसंपत्ति के खिलाफ चलाने के आसपास आकार दिया गया है जो आपके पास है, एक बार के कार्य के आसपास नहीं।
git clone https://github.com/kabiri-labs/sshfinder.git
cd sshfinder
python sshfinder.py 10.0.0.0/24 -p 22,2222
कोई स्थापना नहीं, कोई निर्भरता नहीं। Python 3.9+ की आवश्यकता है।
यह तीन काम करता है, तीन कमांड में:
# 1. इन्वेंटरी — वहाँ कौन सी SSH है?
python sshfinder.py 10.0.0.0/24 --audit --format csv -o ssh-inventory.csv
# 2. निर्णय — क्या यह हमारे मानक को पूरा करती है? (यदि नहीं तो 3 निकास)
python sshfinder.py 10.0.0.0/24 -p 22,2222 --policy baseline
# 3. विचलन — कल रात से क्या बदला?
python sshfinder.py 10.0.0.0/24 -p 22,2222 --baseline yesterday.json \
--fail-on-drift
सभी 65535 पोर्ट स्कैन करना डिफ़ॉल्ट है, क्योंकि एक गैर-मानक पोर्ट पर SSH सेवा वास्तव में वही है जिसे किसी ने लिखा नहीं है। हर खुला पोर्ट लेबल किया जाता है, इसलिए एक खुला पोर्ट कभी भी चुपचाप SSH के रूप में नहीं गिना जाता:
=== 10.0.0.5 ===
open: 10.0.0.5:22 [SSH], 10.0.0.5:8080 [not ssh]
SSH 10.0.0.5:22 (SSH-2.0-OpenSSH_7.4)
पुष्टि एक वास्तविक RFC 4253 पहचान विनिमय है, तार पर पहले बाइट्स पर एक नज़र नहीं। सर्वर जो पहले एक कानूनी बैनर प्रिंट करते हैं, जो क्लाइंट के स्वयं की पहचान करने की प्रतीक्षा करते हैं, या जिनका बैनर TCP खंडों में विभाजित आता है — सभी सही ढंग से पहचाने जाते हैं — उनमें से प्रत्येक एक भोले कार्यान्वयन में एक गलत नकारात्मक है।
प्रत्येक सेवा की पूरी तस्वीर के लिए --audit जोड़ें:
SSH 10.0.0.5:22 (SSH-2.0-OpenSSH_7.4)
host key: ssh-ed25519 SHA256:T/ZM4jOL4amTsO5K3AaCdg2...
auth: publickey, password [!] password auth enabled
[!] Terrapin (CVE-2023-48795): VULNERABLE
[!] weak ciphers: aes128-cbc
aes128-cbc [weak]: CBC mode is vulnerable to the SSH plaintext-recovery attack (CVE-2008-5161) and, …
साझा SSH होस्ट कुंजियाँ (संभावित साझा/क्लोन किए गए होस्ट):
SHA256:T/ZM4jOL4amTsO5K3AaCdg2...
-> 10.0.0.5:22, 10.0.0.9:22
वह अंतिम ब्लॉक जानने लायक है: मशीनों में पुन: उपयोग की गई होस्ट कुंजी आमतौर पर क्लोन किए गए VM या एक साझा छवि का मतलब है, और इसका मतलब है कि एक होस्ट से समझौता करना उन सभी की पहचान से समझौता करता है।
OpenSSH 10.0 ने mlkem768x25519-sha256 को डिफ़ॉल्ट कुंजी विनिमय बनाया, और 10.1 चेतावनी देता है कि शास्त्रीय सत्र अभी संग्रहीत करें, बाद में डिक्रिप्ट करें कैप्चर के लिए खुले हैं। --pq-report केवल KEXINIT का उपयोग करके बेड़े-स्तर के प्रश्न का सीधे उत्तर देता है — इसलिए इसे किसी तृतीय-पक्ष लाइब्रेरी की आवश्यकता नहीं है:
python sshfinder.py 10.0.0.0/24 -p 22,2222 --pq-report
Post-quantum readiness:
1/3 service(s) negotiate post-quantum key exchange with a current client
[!] no PQ key exchange offered (1):
10.0.0.2:22
[!] pre-standard PQ only (1) - looks post-quantum but is not:
10.0.0.3:22
2 service(s) exposed to store-now-decrypt-later capture; upgrade to OpenSSH 9.0+
pre-standard श्रेणी वह है जो लोगों को पकड़ती है। एक सर्वर जो [email protected] या एक Kyber ड्राफ्ट का विज्ञापन करता है, एल्गोरिदम डंप में पोस्ट-क्वांटम दिखता है, लेकिन OpenSSH ने उस वापस लिए गए पैरामीटर सेट को 2020 में हटा दिया — इसलिए एक वर्तमान क्लाइंट को कोई सामान्य विधि नहीं मिलती और शास्त्रीय क्रिप्टो पर वापस आ जाता है। तैयार के रूप में गिना जाना, बिल्कुल न देखने से भी बदतर होगा।
एक रिपोर्ट एक समस्या का वर्णन करती है। एक नीति एक दावा करती है, और एक बिल्ड को विफल कर सकती है:
python sshfinder.py 10.0.0.0/24 -p 22,2222 --policy baseline; echo "exit $?"
Policy 'baseline':
No password login, no Terrapin exposure, no weak algorithms.
1/3 service(s) pass
[FAIL] 1 service(s):
10.0.0.3:22
- password_auth: password login accepted: publickey, password
- terrapin: vulnerable to Terrapin (CVE-2023-48795)
- post_quantum (warn): post-quantum readiness is absent, ready required
[warn] 1 service(s):
10.0.0.2:22
- post_quantum (warn): post-quantum readiness is absent, ready required
exit 3
तीन नीतियाँ अंतर्निहित हैं — baseline, strict और pq — उस परिणाम के नाम पर जिसे वे लागू करती हैं, वितरण के नाम पर नहीं। नियम fail या warn गंभीरता रखते हैं और --fail-on तय करता है कि कौन से द्वार, इसलिए एक टीम पहले एक चेतावनी के रूप में एक सख्त बार अपना सकती है और बाद में बिना कुछ संपादित किए इसे बढ़ावा दे सकती है।
अपना खुद का JSON के रूप में लिखें:
{
"name": "house-rules",
"description": "What we expect of every SSH service.",
"rules": [
{"check": "password_auth", "severity": "fail"},
{"check": "terrapin", "severity": "fail"},
{"check": "post_quantum", "require": "ready", "severity": "warn"},
{"check": "forbid", "field": "ciphers",
"algorithms": ["3des-cbc", "arcfour"], "severity": "fail"},
{"check": "require", "field": "kex_algorithms",
"algorithms": ["curve25519-sha256"], "severity": "fail"}
]
}
जाँचें: password_auth, terrapin, weak_algorithms, post_quantum (require: ready, legacy या absent के साथ), और kex_algorithms, host_key_algorithms, ciphers या macs के field पर forbid / require।
बाकी सब कुछ एक कठोर त्रुटि है जब नीति लोड होती है, स्कैन शुरू होने से पहले। एक द्वार जो चुपचाप एक नियम को छोड़ देता है जिसे वह समझता नहीं है, कोई द्वार न होने से भी बदतर है: रन हरा हो जाता है और कोई नहीं सीखता कि जाँच कभी निष्पादित नहीं हुई।