Command Injection
Host (Domain) at the syscmd.htm endpoint of the administrator page: command inspection is possible where input is made.

function saveClick() {
var hostObj = document.formSysCmd.sysHost;
var cmd = document.formSysCmd.sysCmd.value;
if (cmd == "ping" || cmd == "traceroute") {
if (hostObj.value == "") {
alert(syscmd_host + syscmd_empty_alert);
hostObj.value = hostObj.defaultValue;
hostObj.focus();
return false;
}
}
return true;
}
In the syscmd.htm file, the saveClick() function checks whether cmd == "ping" or cmd == "traceroute". It then retrieves the value entered by the user using var hostObj = document.formSysCmd.sysHost; and stores it in hostObj.
<form action="/boafrm/formSysCmd" method="POST" name="formSysCmd">
The formSysCmd.sysHost value is then sent to /boafrm/formSysCmd because of the <form> tag in the HTML.
The formSysCmd processing code is present in the /bin/boa file of the firmware on tew831dr.
int __fastcall sysform(_DWORD *a1) {
int v2; // $s5
_BYTE *v3; // $s4
int v4; // $v0
const char *syshost_input_save; // $s1
int v6; // $v0
int v7; // $s2
int v8; // $s6
int *v9; // $s6
int i; // $s3
_DWORD *v11; // $a0
int v12; // $s3
int v13; // $v0
_BYTE v15[24]; // [sp+28h] [-218h] BYREF
_BYTE cmd_input_save[256]; // [sp+40h] [-200h] BYREF
char syshost_input_save_buf[256]; // [sp+140h] [-100h] BYREF
memcpy(v15, off_45C178, sizeof(v15));
memset(syshost_input_save_buf, 0, sizeof(syshost_input_save_buf));
v2 = syshost_input(a1, (int)"submit-url", (int)"");
v3 = (_BYTE *)syshost_input(a1, (int)"sysCmd", (int)"");
syshost_input_save = (const char *)syshost_input(a1, (int)"sysHost", (int)"");
v4 = syshost_input(a1, (int)"checkNum", (int)"4");
v7 = atoi(v4);
v6 = syshost_input(a1, (int)"sysMagic", (int)"");
if (!v7) {
v7 = 4;
}
v8 = v6;
if (!*v3) {
LABEL_19:
v11 = a1;
return sub_40AE5C(v11, v2);
}
if (strcmp(v3, "telnetd")) {
v9 = (int *)v15;
for (i = 0;; ++i) {
v13 = *v9;
v9 += 2;
if (!v13) {
break;
}
if (!strcmp(v3, v13)) {
if (!*syshost_input_save) {
goto LABEL_19;
}
if (!strchr(syshost_input_save, 59) ||
sub_44856C(0, syshost_input_save, 59, syshost_input_save_buf, 256) == -1) {
printf("\\n%s[%d] sysHost = %s\\n", "fmmgmt.c", 4656, syshost_input_save);
strncpy(syshost_input_save_buf, syshost_input_save, 256);
v12 = 8 * i;
} else {
printf("\\n%s[%d] sysHost = %s, entry = %s\\n", "fmmgmt.c", 4651, syshost_input_save, syshost_input_save_buf);
v12 = 8 * i;
}
snprintf(cmd_input_save, 256, "%s %d %s 2>&1 > %s", *(const char **)&v15[v12 + 4], v7,
syshost_input_save_buf, "/tmp/syscmd.log");
goto LABEL_17;
}
}
goto LABEL_19;
}
if (!strcmp(v8, "535A5943")) {
snprintf(cmd_input_save, 100, "telnetd & 2>&1 > %s", "/tmp/syscmd.log");
LABEL_17:
cmd_run(cmd_input_save);
v11 = a1;
} else {
v11 = a1;
}
return sub_40AE5C(v11, v2);
}
In the sysform function:
syshost_input_save = (const char *)syshost_input(a1, (int)"sysHost", (int)"");
This part retrieves the input value, which is the command entered by the user. For example, if the user enters 127.0.0.1 | cat /etc/passwd, the value is stored in syshost_input_save. Then:
strncpy(syshost_input_save_buf, syshost_input_save, 256);
This code constructs a command string using snprintf and stores it in cmd_input_save. For example: