标题 简介 类型 公开时间
关联规则 关联知识 关联工具 关联文档 关联抓包
参考1(官网)
参考2
参考3
详情
[SAFE-ID: JIWO-2024-102]   作者: 闲云野鸡 发表于: [2017-07-20]  [2017-07-20]被用户:枫叶 修改过

本文共 [2226] 位读者顶过

Summary

Axis M3004 security camera

When we began a security analysis of remote configuration services last year, we had no idea it would lead us to uncover vulnerabilities that affect so many users. We have been studying the prevalence and nature of the vulnerabilities that arise in remote configuration services, so when we approached the M3004, we specifically sought out such a service. We began by enumerating all open ports and examined the code which handled incoming data. The service we found was wsd, a service that imports a third party library from gSOAP by Genivia. We discovered the vulnerability by using IDA Pro, a reverse engineering tool, to examine all code that wrote incoming data to stack buffers.

[出自:jiwo.org]

A function displayed in IDA Pro

We reached the vulnerable code by sending a POST command to the ONVIF service available on port 80. We were able to observe the internals of the service and the results of our code by activating ssh through the webserver and then remotely debugging the service with gdbserver, which was already installed on the camera. After verifying the vulnerability by observing it crash at a value we set when the overflow overwrote the stored return pointer on the stack, our next challenge was to gain code execution.

Although there was no limit to how many bytes we could write to the stack, we could not execute code on it, and a filter required that all the values we sent be greater than 31. We used a technique called Return Oriented Programming (ROP) to write addresses to the stack to force the program to execute code snippets in libc so we could circumvent the non-executable stack. Through this technique, we allocated executable space, copied our shellcode to that space, and directed execution to it. Although the requirement that all the addresses we used needed to have values greater than 31 restricted us somewhat, we were still able to gain code execution.

Once we reached this step, we wrote shellcode, which again contained all values greater than 31, to open a port and allow a remote user to connect to a shell. At this point we had gained code execution by exploiting Devil's Ivy (CVE-2017-9765). Due to Axis's security settings, this exploit only grants access to a shell as an unprivileged user on the M3004. However, we were able to execute commands from the ONVIF specification that only a privileged user would normally be allowed. We were able to reset the camera to its factory defaults and take control of the camera, reboot it to prevent an operator from viewing the feed, and change network settings.

Read on for the full technical details or scroll to the bottom to see a video demonstration.

Access


We began our process by downloading the latest firmware for the M3004 camera from Axis’s website. They do require an account to download firmware, but did not verify that we were a legitimate customer. We became Nate Johnson, reachable at a throwaway email address, and immediately had access to the camera’s firmware. We extracted the file system and Linux kernel using binwalk with the Jefferson extractor for JFFS2 file systems.

The output from binwalk
We ran nmap to scan the camera for open ports and found 1900 (upnp), 3702 (ws-discover) and 5353 (mdns) open. After some analysis of the file system, we found that ws-discover was associated with wsd, a service which handled the SOAP protocol. wsd imports libsoap.so (from gSOAP by Genivia) to parse incoming SOAP messages, which we scrutinized for any code which wrote incoming data to the stack. We used IDA Pro to look for stack buffers, and then manually traced back the source of any data copied into them. Using this technique, it only took one day of looking through assembly code to spot this vulnerability.

Imported functions from libsoap.so

Analysis

One piece of code caught our attention in the function soap_get() that wrote incoming data to an 0x40 byte stack buffer. The code operates in a loop that checks for the end character ‘?’ or an end of data indicator as an end condition rather than counting the number of bytes it has written to the 0x40 byte stack buffer.

The vulnerable code loop in soap_get()
soap_get() stack
In the screenshot above, R6 is the data counter, set to the size of the stack buffer, R9 is the stack buffer pointer, and R5 is the incoming byte read from the network. If the data counter in R6 is less than zero, the function skips writing to the buffer, but continues to read in data using j_soap_getchar(). By writing enough data to wsd to wrap the counter around to a positive number again, we could write data to the stack past the 0x40 byte limit. This takes a few minutes, but there is no limit on the amount of incoming data, and it is simple enough to send using netcat. We calculated that we needed to send 0x8000000 bytes to wrap the counter around to a positive number, 0x40 to fill up the fixed length stack buffer, and another 0x30 more before we could overwrite the stored return address.
We reached this vulnerability by sending a POST command to “/onvif/device_service” on port 80, which was handed off from the webserver to the wsd service. To send 0x80000070 bytes, we generated a text file beginning with “POST /onvif/device_service” followed by a new line and “