This post is as much about the penetration testing process and mindset as it is about the vulnerability I discovered in a network monitoring program called PRTG Network Monitor. This vulnerability was discovered and reported to Paessler AG, the company that develops the application. I agreed to wait at least 90 days to disclose the vulnerability, to give the company time to fix it and their customer’s time to apply the patch. The patch was released on April 20, 2018 and the vulnerability was assigned a CVE of CVE-2018-9276. More details on the release can be found here. I finally have time to disclose this issue.
I was performing a penetration test recently and really hadn’t found much on the scoped servers and other systems, so I began reviewing accessible services and applications to target for default/weak credential testing. I was browsing through the available web applications and came across the PRTG network monitoring tool on one of the hosts. I was hopeful, as network monitoring tools are valuable targets that by definition have connectivity to most other systems and can often execute programs as part of their alerting/notification features. I quickly navigated to the documentation for the tool and found the default credentials of “prtgadmin / prtgadmin”:
Lo and behold the credentials worked. I was now pretty excited as network monitoring tools are typically a quick path to full domain compromise. Many network monitoring tools include the capability of running external programs as part of a “notification” as a feature. PRTG is no exception, however; as I quickly found out, it does not allow you to run just any executable or script of your choosing:
The instance that I found did not have any available programs to run outside of two demo scripts. Paessler AG confirmed that this is a security feature. PRTG requires any executables or scripts used in a notification to be uploaded to a specific directory on the server. There are no methods in the web application that can be used to upload a script or executable to use as a notification:
This is where the hacker/penetration tester mindset comes in to play. My initial thought was to move on to the next thing on the test. I had previously searched Exploit-DB and other sources for any vulnerabilities relating to PRTG and did not identify anything useful for the current version. I figured if no one else had reported a bug, then it probably didn’t exist. I began reviewing other potential targets for default/weak credentials. After a few minutes of reviewing other available services, the thought occurred to me that maybe one of the included demo scripts was vulnerable to command injection and no one had tested it out before. I decided it didn’t hurt to try.
PRTG is available to download as a demo for free, so I installed the tool on one of my own systems. One thing I was curious about was what kind of permissions I would have with a default install. If there were a command injection vulnerability, then it would be running under whatever permissions were provided to the application/service. The installation on my server confirmed that by default the PRTG services are running as “Local System”:
This was great news as if the demo scripts were vulnerable to command injection then I would start with elevated access on the server (giving me the ability to add an account to the local “administrators” group, or run Mimikatz, or perform other actions limited to administrators).
I then reviewed the “Demo” batch script, which appeared to be vulnerable to command injection attacks upon first glance, but all attempts to inject commands into this notification option failed. It is assumed that the user input is modified prior to being passed to the script in a way that mitigates command injection for the batch script. The contents of the batch file are provided below:
I then reviewed the “Demo” PowerShell script code, as shown below:
I noted that the argument supplied in the “Parameter” field of the “Notifications” configuration is passed directly into the PowerShell script without any sanitization, resulting in the ability into inject any other PowerShell code. I was hopeful that the application did not modify the input in any way, similar to the batch script.
I discovered the “C:\ProgramData\Paessler\PRTG Network Monitor\PRTG Configuration.dat” file while reviewing the PRTG application and monitoring files to which the application was writing or from which it was reading. The contents appeared to contain all values passed as part of a notification, among other things. I decided to begin testing out what if anything was encoded on my test server. The initial test looked something like the following screenshot:
I saved the test notification and reviewed the results, confirming that some characters were encoded but many useful characters were not:
A quick test confirmed that entering the following value into the “Parameter” field of a new notification, and then running the notification, would result in creation of a local account on the host:
test.txt;net user pentest p3nT3st! /add
I now had command execution on the host and had compromised the host in short order.
First of all, kudos to Paessler AG as they implemented a security control around the notifications feature where most network monitoring tools allow you to run any executable you want, and secondly because they were very responsive to my notification and developed a patch within two months of disclosure. Second of all, test all the things. I try to stick to a methodology of testing even the very low probability issues. That mindset and methodology paid off in this case and has in many others. Many times it doesn’t work (because it is low probability after all), but when it does it is absolutely worth it.
I needed to setup some new systems for mobile application penetration tests at the start of January and part of this process includes importing Burp’s certificate for traffic interception. I have set this up in the past but it seems to change fairly regularly with newer versions of Android emulators.
I installed the latest version of Android Studio and setup an android virtual device (AVD) emulator based on Nougat (Android 7.0). I reviewed all the various guides I could find, but none of them quite worked correctly. I eventually figured it out, got the systems setup, and moved on, but then last week I came across a Tweet by ropnop for his blog titled “Configuring Burp Suite with Android Nougat.” It is a great guide, but part of the steps are what specifically did not work for me and resulted in a lot of troubleshooting. This inspired me to write this post as others might be experiencing the same thing for AVD’s created/run with Android Studio.
I will not provide detailed screenshots of all of the steps, as the above post by ropnop does a great job. The key steps are:
- Export Burp’s certificate in DER format
- Convert the certificate from DER to PEM format: openssl x509 -inform DER –in burpmobile.der -out burpmobile.pem -outform PEM
- Get the hash of the certificate: openssl x509 -inform PEM -subject_hash_old -in burpmobile.pem | head -1
- Rename the PEM certificate to the hash output above with an extension of .0 (that is a zero): mv burpmobile.pem <hash>.0
The next steps then changed a little bit on all the machines in which I performed this task. The Google documentation, and ropnop’s guide, each uses adb next to obtain root access and then remount the /system directory as read-write. This is necessary as you must copy the certificate to the system directory. When I performed these steps, everything seemed to work. The commands all completed successfully and a ‘mount -v’ showed /system as being mounted as read-write. However, as soon as I attempted to copy the certificate to the proper directory in /system, I received a write error and then a subsequent execution of ‘mount -v’ showed /system as being mounted read-only. Weird.
I began looking at ways to start the AVD myself vs. using the tools within Android Studio. I came across documentation for the emulator.exe tool here and noticed the ‘-writable-system’ command line switch. This ended up being the key to resolving my issue. The final steps for me ended up being to start the emulator directly with the ‘-writeable-system’ switch, get root access, set /system to read-write, then upload the certificate:
- Start the emulator: emulator.exe -writable-system -camera-back none -camera-front none -netdelay none -netspeed full -avd <Name of AVD>
- Get root access: Run: adb -s <emulator_id> root
- Mount /system as read-write: adb -s <emulator_id> remount
- Upload the certificate to the AVD: adb -s <emulator_id> push C:\Tools\burp\<hash>.0 /storage/emulated/0/Download/
- Access the AVD shell: adb -s <emulator_id> shell
- Move the certificate to the appropriate directory: mv /storage/emulated/0/Download/<hash>.0 /system/etc/security/cacerts/
- Set the appropriate permissions on the certificate: chmod 644 /system/etc/security/cacerts/<hash>.0
One other issue I ran into on a few of the installs was Android Studio setting specific files in the AVD directory to read-only. I have no idea why this occurred on a handful of these but it did. The only thing I could think of is that these were installed almost a week later and maybe the installer pulled in updates as part of the process that causes this issue ¯\_(ツ)_/¯. The fix required three changes to this process:
- Use Windows attrib command to remove the read-only flag from all files in the AVD directory: attrib -r C:\Users\<username>\.android\avd\<Name of AVD> /S /D
- Use the ‘-no-snapshot-load’ command line switch on step #1 above with emulator.exe to perform a cold boot and completely disable Quick Boot mode
- Configure my AVD with Android Studio to disable support for Quick Boot
I have read some good posts on password spraying over the past few years, along with reviewing and using a few tools to perform this type of attack. For reference, Black Hills has a few good posts here, here, and here, and MDSec posted a cool article on Lync along with a tool here. I’ve implemented password spraying into my methodology to some extent, but was never really satisfied with how I was doing it. The biggest problem I had was the time scoped for an assessment combined with the likelihood for account lockout policies.
The rockyou password list is way too large (~14,344,392 passwords) to ever get through if account lockouts are enabled. Most customers that I have worked with implement password policies that require complexity to some extent, but even then the complex password count in the rockyou list is over 42,000 unique passwords. However, based on a recent assessment, I had some ideas popup to refine my methodology for this type of attack. I am sure many other people are doing this, but I hadn’t read anything written on the subject (I am sure someone out there has written about similar methodologies though).
I was recently performing a wireless penetration test for a company using WPA2-Enterprise. I setup an evil twin AP using hostpad that was patched with the Wireless Pwnage Edition (WPE) patch. I was only able to obtain the challenge-response from one client, as it appeared most were correctly configured, so I wasn’t overly confident in cracking the password. Nevertheless, I fired up hashcat and fed it the rockyou password list, which is typically the first one I try. To my surprise, the password was cracked within a second or so and ended up being a complex variant of the word password (using upper case, lower case, a special character, and a number). This got me thinking on how I could use some distance comparison techniques to further reduce my password spraying list, as it is likely that the top passwords from rockyou are still frequently used, but with minor modifications to meet corporate password policy complexity requirements.
The plan was to take the complex passwords from rockyou as well as top used rockyou passwords, and then perform a distance test between them using the Damerau-Levenshtein algorithm. I arbitrarily chose the top 20 passwords that weren’t all numbers using the rockyou-withcount.txt list from here. I created a script to automate this for me. The script defaults to setting a minimum password length of 7 and maximum of 12 based on my experience with password policy minimums at previously assessed customers, in addition to password lengths for successfully cracked credentials – it is not all that common for normal users to choose a password greater than 12 characters (even that is probably high). This process reduced the total unique passwords count down to 921 with a distance of 4 or lower, and 252 with a distance of 3 or lower. This is a much more manageable size.
I created a companion script that will take a list of users, list of passwords, and URI to perform a password spraying attack against Outlook Web Access, Outlook Anywhere, or ActiveSync (I will probably add more services later, such as SMB, WMI, RDP, etc). This script can be configured to stop after a successful authentication, as well as set an account lockout threshold and account lockout timer such that the script pauses authentication tests until the timer is up. You can download the Python script that will perform the distance test along with this password spraying script (PowerSniper – hat tip to @dafthack‘s MailSniper tool and @domchell‘s LyncSniper tool) here: https://github.com/codewatchorg/PowerSniper.
MailSniper can already perform password spraying against Outlook Web Access and Outlook Anywhere, so that is probably a better option if account lockouts aren’t a concern (I didn’t see support for avoiding locking out accounts), as I am sure his code is better than mine – note though that we have slightly different approaches in the authentication.
I wrote a blog post on the technique used by this plugin here a while back. Many WAF devices can be tricked into believing a request is from itself, and therefore trusted, if specific headers are present. The basics of the bypass approach can be found in an HP blog post here.
I have been implementing Match/Replace rules in Burp to auto-add these headers to requests sent to sites protected by WAFs for a while but decided to create a plugin that could be used to add the headers to active scans, repeater requests, intruder requests, etc. I came across this article from Fishnet Security that really got the ball rolling.
First, I implemented the plugin in Python as that was quick and easy and I actually needed it pretty quick on a recent project. Then I did some quick research on how to implement it as a Java extension to enhance efficiency.
To use this plugin to add the necessary headers, first you need to either download the Python version of the plugin, the Java version of the plugin, or the Java source and compile yourself. Once you have the plugin, start up Burp and navigate to “Extender->Extensions” and click the “Add” button. Choose an extension type of “Java”, if using the Java Plugin, or “Python”, if using the Python version, and then navigate to the extension path. The configuration should look something like:
The plugin should now be loaded and display something like:
Now you need to navigate to “Options->Sessions” and then click on the “Add” button for the “Session Handling Rules” configuration section as shown below:
Give the rule a name and then click the “Add” button in the “Rule Actions” section, and choose “Invoke a Burp extension” as shown below:
You should be able to select “Bypass WAF” in the drop down box as seen below:
Click “Ok” and then select the “Scope” tab. Enable all the tools that you want to be in scope for the extension and then set the scope. I like to enable scope for all tools and limit scope on requests to those that have been added to the suite scope as seen in below:
Bypass WAF contains the following features:
- Users can modify the X-Originating-IP, X-Forwarded-For, X-Remote-IP, X-Remote-Addr headers sent in each request. This is probably the top bypass technique i the tool. It isn’t unusual for a WAF to be configured to trust itself (127.0.0.1) or an upstream proxy device, which is what this bypass targets.
- The “Content-Type” header can remain unchanged in each request, removed from all requests, or by modified to one of the many other options for each request. Some WAFs will only decode/evaluate requests based on known content types, this feature targets that weakness.
- The “Host” header can also be modified. Poorly configured WAFs might be configured to only evaluate requests based on the correct FQDN of the host found in this header, which is what this bypass targets.
- The request type option allows the Burp user to only use the remaining bypass techniques on the given request method of “GET” or “POST”, or to apply them on all requests.
- The path injection feature can leave a request unmodified, inject random path info information (/path/to/example.php/randomvalue?restofquery), or inject a random path parameter (/path/to/example.php;randomparam=randomvalue?resetofquery). This can be used to bypass poorly written rules that rely on path information.
- The path obfuscation feature modifies the last forward slash in the path to a random value, or by default does nothing. The last slash can be modified to one of many values that in many cases results in a still valid request but can bypass poorly written WAF rules that rely on path information.
- The parameter obfuscation feature is language specific. PHP will discard a + at the beginning of each parameter, but a poorly written WAF rule might be written for specific parameter names, thus ignoring parameters with a + at the beginning. Similarly, ASP discards a % at the beginning of each parameter.
- The “Set Configuration” button activates all the settings that you have chosen.
All of these features can be combined to provide multiple bypass options. I intend to add the following features, at a minimum, to future versions:
- HTTP Parameter Pollution – Automatically perform HPP attacks on GET/POST parameters.
- HTTP Requests Smuggling – Automatically perform an HTTP request smuggling attack on each request where a dummy request is added to the beginning and the real (smuggled) request is added at the end.
I have been adding features rapidly and it is very possible that the above will be in the code by the time anyone actually reads this.
That is all you need to do. You can get the extension here.
I perform quite a few web app assessments throughout the year. Two of the primary tools in my handbag for a web app assessment are Burp Suite Pro and SQLMap. Burp Suite is a great general purpose web app assessment tool, but if you perform web app assessments you probably already know because you are probably already using it. SQLMap complements Burp Suite nicely with its great SQL injection capabilities. It has astounded me in the past, as flexible and extensible as Burp is, that no one has written a better plugin to integrate the two (or maybe they did and I just missed it).
The plugins that I have come across in the past fit in one of two categories:
- They generate the command line arguments that you want to run, and then you have to copy those arguments to the command line and run SQLMap yourself (like co2); or
- They kick off a SQLMap scan and essentially display what you would see if run in a console window (like gason)
I’m not much of a developer, so I never really considered attempting to integrate the two myself until the other day that I was browsing in the SQLMap directory on my machine recently and noticed the file sqlmapapi.py. I’d never noticed it before (I’m not sure why), but when I did I immediately started looking into the purpose of the script. The sqlmapapi.py file is essentially a web server with a RESTful interface that enables you to configure, start, stop, and get the results from SQLMap scans by passing it options via JSON requests. This immediately struck me as an easy way in which to integrate Burp with SQLMap.
I began researching the API and was very fortunate that someone already did the leg work for me. The following blog post outlines the API: http://volatile-minds.blogspot.com/2013/04/unofficial-sqlmap-restful-api.html. Once I had the API down I set out to write the plugin. The key features that I wanted to integrate were:
- The ability to start the API from within Burp. Note that this is not recommend as one of the limitations of Jython is that when you start a process with popen, you can’t get the PID, which means you can’t stop the process from within Jython (you have to manually kill it).
- A context menu option for sending a request in Burp to the plugin.
- A menu for editing and configuring the request prior to sending to SQLMap.
- A thread that continuously checks up on executed scans to identify whether there were any findings.
- Addition of information enumerated from successful SQLMap scans to the Burp Scanner Results list.
All of those features have been integrated into this first release. I have limited ability to test so I appreciate anyone that can use the plugin and provide feedback. Some general notes on the plugin development:
- This is the first time I’ve attempted to develop a Burp plugin. The fact that I was able to do so with relative ease shows how easy the Burp guys have made it.
- This is also the first time I’ve used Jython, or used any Java GUI code.
- The code probably looks awful and I need more comments. See points 1 & 2 above and add in the fact that I’m not a developer.
I reviewed the source code for numerous plugins to help me understand the nuances of working with Python/Jython/Java and integrating with Burp. The source of the following plugins was reviewed to help me understand how to build this:
The first thing that you need to do is download the beta version of Jython, which can be found on the site here. The 2.7 beta version is required as the plugin uses the JSON module and older stable releases do not include this module. Note that this version of Jython relies on Java 1.7 or 1.8 – it will not run on older versions. Navigate to the “Extender->Options” tab in Burp and configure the path to Jython as show in the screenshot below:
Next, you need to load the plugin by navigating to the “Extender->Extensions” tab and clicking the add button. Configure the path to the plugin as shown below:
The SQLMap API server must be started in order to perform scans. This can be performed in the “SQLiPy->SQLMap API” tab of the plugin by entering the appropriate IP, port, path to Python, and path to the sqlmapapi.py file as displayed in the options below:
The other and better option would be to manually start the SQLMap API server on your system (or any other system on which SQLMap is installed). This is better as a limitation of Jython is that it doesn’t return the PID of the process executed by popen, as describe above, and therefore there is no way to kill the process from within Burp (it has to be done manually). The command line options are as follows:
python sqlmapapi.py -s -H <IP> -p <Port>
Now that you have setup Jython in Burp, the plugin is loaded, and the SQLMap API is running, you can get ready to start some SQLMap scans. The plugin creates a context menu option of “SQLiPy Scan” that can be used by right mouse clicking from the “Request” tab within the “Proxy” or “Target” interfaces as shown in the screenshot:
This will take the request and auto populate information in the “SQLiPy->Sqlmap Scanner” tab similar to what you see below:
Configure the options that you want for the injection testing and make sure to set the SQLMap API IP and Port if you didn’t use the plugin to start the API (otherwise these are prefilled in). Then you are ready to begin injection testing after clicking the “Start Scan” button. Progress and informational messages on scans and other plugin activities are displayed in the extensions “Output” tab similar to what is shown below:
Starting a scan will result in a thread being executed that periodically checks on the process of the injection attack. Updates on the status of plugin tasks will show up in the extensions “Output” tab, including completion of an injection test. If the tested page is vulnerable to SQL injection, then the plugin will add an entry to the “Scanner->Results” tab that includes everything SQLMap was able to enumerate on the vulnerable host based on the options you chose in the “SQLiPy->SQLMap Scanner” tab. The results will look similar to the following screenshot:
This plugin has been tested on:
- Burp Suite 1.6 and 1.6.05
- SQLMap 1.0
- Python 2.7.2 and 2.7.7
- Java 1.7.0_03, 1.7.0_60, and 1.8.0_11
- Jython 2.7 Beta 3
- Windows 7 and 8.1
- Linux (Fedora 20)
Some things I would like to do with the plugin in the future:
- Use a real layout manager instead of null (I know this is a bad practice)
- Convert to Java for performance and other reasons
- Separate functionality out into smaller classes
- Add more and better comments
- Cleanup variable names and such
- Possible addition of other SQLMap options
You can grab the plugin on my GitHub page at here. Enjoy!
I have updated my dirscalate tool to now include support for NTLM, BASIC, Digest, or cookie based authentication to the web application with the directory traversal vulnerability. If you are unfamiliar with the tool, see my post here.
Previously, if the site required authentication, you would have had to proxy dirscalate through something like Burp to add authentication. Now, you can pass credentials to dirscalate and it will handle the authentication to the site. It’s not a huge update, but it is nice to have if the vulnerability resides on a page that requires authentication.
The new options are:
--ntlmuser NTLMUSER use NTLM authentication with this username (format of domain \ username) (default: None) --ntlmpass NTLMPASS use NTLM authentication with this password (default: None) --basicuser BASICUSER use BASIC authentication with this username (default: None) --basicpass BASICPASS use BASIC authentication with this password (default: None) --digestuser DIGESTUSER use DIGEST authentication with this username (default: None) --digestpass DIGESTPASS use DIGEST authentication with this password (default: None) --cookie COOKIE use a previously established session cookie (default: None)
You can get the latest version of the tool on GitHub here.
I wrote a post a while back on turning a directory traversal vulnerability into root access on Unix or Linux systems. The post and a tool I wrote to help facilitate attacks can be found here. These vulnerabilities can be fun because they are often rated as moderate risks, with CVSS scores around 5.0, and therefore go unremediated.
I came across a Windows host with a directory traversal vulnerability issue recently and realized I should write a Windows based post for this class of vulnerability. Many times, the example for the exploit is that you can obtain win.ini, and thus the person responsible for patching thinks ‘yippy, you can read win.ini’ and the issue isn’t patched. However, there are some critical Windows system files that can be retrieved if you know where to look.
The most likely files to be leveraged to obtain access to a Windows host are the SAM, SYSTEM, and SECURITY files that store registry data, including password hashes in LM, NTLM, and MSCACHE format. The active files are locked by Windows when it is booted and therefore are unlikely to be accessible with a directory traversal attack. What we want are the backup copies or repair versions that are often found on virtually all versions of Windows.
Common backup/recovery directories for these files include:
Leveraging the directory traversal attack to retrieve one of these files would involve sending the directory traversal string, followed by one of the above paths, followed by SAM, SYSTEM, or SECURITY. Usually, ten levels deep in the directory traversal will work. An example:
Try each path, and if you aren’t having success then try encoding (..%2f or %2e%2e%2f) or double encoding (..%252f or %252e%252e%252f) the directory traversal portion of the payload.
Once you have the files you can attempt to crack any stored passwords. My first choice is to load the file in Ophcrack with the various free rainbow tables (XP free fast, Vista free, Vista special, and XP special) and begin cracking. To do this, launch Ophcrack and select Load->Encrypted SAM as shown below.
Now begin to crack away. If you don’t have any success here, then try using Ophcrack’s online submission tool found here. If you still aren’t having success, then you might need to attempt to crack any cached passwords from previously logged on users.
I use Cain to get the hashes, but I use Hashcat to crack them as it is much faster. First, you need to browse to the “Cracker” tab in Cain and then click on MS-Cache Hashes on the left hand side of the interface. Right mouse click in the right hand side of the interface and click “Add to list” as shown below.
You will then need to add the paths to the SYSTEM and SECURITY files so that Cain can pull out the usernames and cached hashes. An example is show below.
I then write down these hash values and the usernames and save them in a file in the format of hash:username, one per line. You can attempt to crack the password in Cain, but it isn’t going to be very fast. I like to use Hashcat with a decent GPU for this task as it is blazing fast in comparison. I did a little research, and one of the best values in terms of performance and cost are the GeForce GTX 750 Ti OC based GPU’s. You can see a chart here that shows these cards as being one of the highest in performance of SHA1 cracking per dollar, and similarly good value in cracking other hashes. I picked one up for $145 and was able to run through every possible combination for a 1 to 7 character password in 16 hours (my quad core i5 with 8GB of RAM estimated it would take 72 days – that’s what it’s like without a GPU).
I suggest first attempting to use a password list like rockyou, as you can run through this list faster than brute forcing. Given I have an NVidia based card, I use cudaHashcat with a command similar to the following example.
cudaHashcat64.exe -m 1100 -n 32 myhashfile.txt rockyou.txt
The ‘-m 1100’ tells Hashcat that this is a MS-Cache based hash, the ‘-n 32’ tells Hashcat to use 32 threads, then I pass the file with the hashes and usernames, and then the password list. Another option is to use the Hashcat rules for rockyou with something similar to the example below.
cudaHashcat64.exe -m 1100 -n 32 -r rules\rockyou-30000.rule myhashfile.txt rockyou.txt
If these attempts are unsuccessful and you have a day or two to attempt cracking, then run all combinations of up to a 7 or 8 character password. Here is an example that I use that is for up to a 7 character password with all character sets (upper and lower case alphabet, numbers, and special characters).
cudaHashcat64.exe -m 1100 -n 32 -a 3 myhashfile.txt ?a?a?a?a?a?a?a
The ‘-a 3’ tells Hashcat to use brute force mode and the ‘?a?a?a?a?a?a?a’ string tells Hashcat to test all character sets up to 7 characters in length. This command took the system with the above listed NVidia card 16 hours and was over 69 trillion combinations.
Another option is to use the directory traversal vulnerability to obtain unattended installation, sysprep, or image capture answer files for servers and workstations. These files are created for unattended installations created by sysprep, often remain on systems long past initial system setup, and frequently store cleartext (or base64 encoded) credentials used to join the system to the domain. These files are often named ‘unattend.xml’, ‘autounattend.xml’, ‘sysprep.xml’, ‘sysprep.inf’, or ‘wdscapture.inf’ and can be found in one of the following locations:
Assuming you are successful in cracking a password that can be used on the network, the next step is to escalate until you have domain administrator level access. See my previous posts here and here for some techniques on escalating access in a Windows environment.
Note that these types of attacks can be successful against all directory traversal vulnerabilities in all types of software, such as FTP, TFTP, web applications, and other types of systems.
I hope others have success with these techniques. Happy Hunting!
I was recently asked to perform an application penetration test of a Java based fat client. The application used JNLP and communicated with a backend web service. The steps for this are documented elsewhere, but as a brief guide they require:
- Loading the JDSer-NG plugin for Burp
- Configuring Java to proxy through Burp
- Downloading all associated JARs into a libs directory in the same directory from which Burp was launched
- Launching the application and testing
The first two requirements are easy enough. The extension is easily downloaded and loaded within Burp, and configuring Java’s proxy settings through the Java control panel is easy as well.
The third requirement is easy if the site doesn’t require any authentication to access the JNLP file or associated JARs. There is a Java based application named jnlpdownloader that can be used to automatically download the associated JAR files. The reason these are required is that JDSer-NG must load these JAR files to appropriately deserialize and then reserialize data transferred in the communication so that the requests/responses can be man-in-the-middled. This can be a bit of a pain though if access to the JNLP file or JAR files requires authentication through an established session with a cookie, or BASIC/DIGEST/NTLM authentication. Unfortunately, in my experience, authentication is often required.
I decided to resolve this small issue by writing a Python based script that downloads the JAR files and can work with cookie, BASIC, DIGEST, or NTLM based authentication. The tool is also named jnlpdownloader and can be found on GitHub here.
Usage information for the script follows:
usage: jnlpdownloader.py [-h] --link LINK [--ntlmuser NTLMUSER] [--ntlmpass NTLMPASS] [--basicuser BASICUSER] [--basicpass BASICPASS] [--digestuser DIGESTUSER] [--digestpass DIGESTPASS] [--cookie COOKIE] Download JAR files associated with a JNLP file optional arguments: -h, --help show this help message and exit --link LINK the full URL to the JNLP file (must include http(s)://) (default: None) --ntlmuser NTLMUSER use NTLM authentication with this username (format of domain \\ username) (default: None) --ntlmpass NTLMPASS use NTLM authentication with this password (default: None) --basicuser BASICUSER use BASIC authentication with this username (default: None) --basicpass BASICPASS use BASIC authentication with this password (default: None) --digestuser DIGESTUSER use DIGEST authentication with this username (default: None) --digestpass DIGESTPASS use DIGEST authentication with this password (default: None) --cookie COOKIE use a previously established sessions cookie (default: None) Example: jnlpdownloader.py --link https://www.example.com/jnlp/sample.jnlp
Hopefully this script is helpful to others.