CVE-2020-3323 and CVE-2020-3331 are described as unauthenticated remote code execution, while CVE-2020-3330 is a system account with default password. They were discovered by Larryxi of XDSEC, and Gyengtak Kim, Jeongun Baek, and Sanghyuk Lee of GeekPwn.
Knowing nothing about these specific issues, I initially answered that they should download firmware files and perform patch diffing, looking for memory corruption fixes like “strcpy” magically morphing into “strncpy”. As I went through the advisories, I couldn’t resist the urge to do it myself, especially when these issues are similar to the ones I reported. I think it’s a nice exercise in identifying my own blind spots :)
I started by downloading the two most recent version of Cisco RV110W firmware (188.8.131.52 and 184.108.40.206) and extracting them with binwalk.
Now we need to find what changed between these two updates. We will hash each file from the squashfs filesystem using MD5 and then compare fingerprints using diff.
Let’s start by building the hash files:
Then we can run diff:
It appears that Cisco simply removed utelnetd binary from the firmware. It makes sense given that this service can’t be enabled from the web UI. Probably an artifact left from internal testing.
Anyway, utelnetd - like any good unix tool - rely on /bin/login to authenticate users. It’s a built-in binary that uses /etc/shadow to authenticate users. The shadow file is absent from the firmware squashfs file system so it must be generated when the device boots up.
Let’s search for references to /etc/shadow:
/sbin/rc is a good candidate. That binary is executed during Linux initialization procedure. Let’s run strings on it and look for references to /etc/shadow:
And voilà ! We now know that the static default credentials belonged to the admin user. However we only have the md5crypt hash of that password. Let’s run hashcat with rockyou and some rules: