From 73ede8dc523a594affae86ff996f3aa061b95489 Mon Sep 17 00:00:00 2001 From: Brandan Geise Date: Mon, 6 Jul 2015 19:20:19 -0400 Subject: [PATCH 1/6] Added Metasploit plugin that uses King Phisher's REST API --- data/msf/README.md | 52 +++++++++++++ data/msf/sms.rb | 186 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 238 insertions(+) create mode 100755 data/msf/README.md create mode 100755 data/msf/sms.rb diff --git a/data/msf/README.md b/data/msf/README.md new file mode 100755 index 00000000..6cbebb5d --- /dev/null +++ b/data/msf/README.md @@ -0,0 +1,52 @@ +# SMS Plugin +The [SMS](./sms.rb) plugin uses King Phisher's [REST API](https://king-phisher.readthedocs.org/en/latest/server_api/rest_api.html?highlight=sms#get--_-api-sms-send) to send SMS messages when a new [Metasploit](https://github.com/rapid7/metasploit-framework) session is received. King Phisher's REST API is accessible externally which allows running the SMS plugin, within Metasploit, on a system other than the King Phisher server. The system running Metasploit only needs to be able to make a HTTP GET request to the King Phisher server. + +## King Phisher Configuration +Edit King Phisher's `server_config.yml` file, under the `rest_api` set the `enabled` value to `true`. + +Change the `token` value from `null` to a secret string that will be used to access the King Phisher server's REST API remotely. Running this one-liner in Linux will return a randomly generated 32 character string. + +`cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 32 | head -n 1` + +Save the server configuration file and restart the King Phisher server. + +## Metasploit Configuration and Usage +Add the [sms.rb](./sms.rb) file to your Metasploit [plugins](https://github.com/rapid7/metasploit-framework/tree/master/plugins) directory. + +If this is the first time using the SMS plugin you will need to set four values which will be saved in `~/.msf4/sms.yaml`. On future use these settings will automatically be loaded and do not need to be set again. Additionally, you can see descriptions of the SMS plugin commands by running `help` in msfconsole. + +* Start Metasploit and load the SMS plugin. + + `load sms` + +* Set the domain name of your King Phisher server. + + `sms_set_server king-phisher.com` + +* Set the King Phisher server's REST API token. + + `sms_set_token 0123456789abcdefABCDEF` + +* Set the cellphone number where you would like to receive SMS messages. + + `sms_set_number 0123456789` + +* Set your cell phone carrier. Currently King Phisher supports AT&T, Boost, Sprint, T-Mobile, Verizon, Virgin Mobile. + + `sms_set_carrier Boost` + +* Before saving, review your plugin settings. + + `sms_show_params` + +* If everything looks good, save your settings. + + `sms_save` + +* Start the SMS plugin, which will wait for incoming sessions. + + `sms_start` + +* When finished, stop the SMS plugin. + + `sms_stop` diff --git a/data/msf/sms.rb b/data/msf/sms.rb new file mode 100755 index 00000000..6c94353b --- /dev/null +++ b/data/msf/sms.rb @@ -0,0 +1,186 @@ +# Copyright (c) 2015, Brandan [coldfusion] +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +require 'uri' +module Msf + + class Plugin::SessionSMS < Msf::Plugin + include Msf::SessionEvent + + if not defined?(Sms_yaml) + Sms_yaml = "#{Msf::Config.get_config_root}/sms.yaml" + end + + def initialize(framework, opts) + super + add_console_dispatcher(SMSCommandDispatcher) + end + + def cleanup + self.framework.events.remove_session_subscriber(@inst) + remove_console_dispatcher('sms') + end + + def name + "sms" + end + + def desc + "Sends a SMS message when recieving a new session through the use of the King Phisher's REST API." + end + + class SMSCommandDispatcher < Plugin::SessionSMS + include Msf::Ui::Console::CommandDispatcher + + @king_phisher_server = nil + @king_phisher_token = nil + @sms_number = nil + @sms_carrier = nil + + def on_session_open(session) + print_status("Session received sending SMS...") + begin + http_client = Rex::Proto::Http::Client.new("#{@king_phisher_server}") + http_client.connect + request = http_client.request_cgi({ + 'uri' => '/_/api/sms/send', + 'query' => "token=#{@king_phisher_token}&message=Shells+On+Deck!!+Session:+#{session.sid}&phone_number=#{@sms_number}&carrier=#{@sms_carrier}" + }) + response = http_client.send_recv(request) + rescue Exception => e + print_error("Exception occured, you done goofed!") + ensure + http_client.close + end + end + + def name + "sms" + end + + def read_settings + read = nil + if File.exist?(Sms_yaml) + ldconfig = YAML.load_file("#{Sms_yaml}") + @king_phisher_server = ldconfig['king_phisher_server'] + @king_phisher_token = ldconfig['king_phisher_token'] + @sms_number = ldconfig['sms_number'] + @sms_carrier = ldconfig['sms_carrier'] + read = true + else + return read + end + return read + end + + def commands + { + 'sms_start' => "Start SMS alerts for new sessions", + 'sms_stop' => "Stop SMS alerts for new sessions", + 'sms_save' => "Save SMS settings to #{Sms_yaml}", + 'sms_set_server' => "Set domain name of the King Phisher server", + 'sms_set_token' => "Set King Phisher's API token", + 'sms_set_number' => "Set number to send SMS alerts to on new session", + 'sms_set_carrier' => "Set carrier for sending SMS messages", + 'sms_show_params' => "Shows currently set or saved parameters" + } + end + + def cmd_sms_start + if read_settings() + self.framework.events.add_session_subscriber(self) + print_good("Starting SMS plugin, monitoring sessions...") + else + print_error("Could not read SMS settings!") + end + end + + def cmd_sms_stop + print_good("Stopping SMS alerting!") + self.framework.events.remove_session_subscriber(self) + end + + def cmd_sms_save + if @king_phisher_server and @king_phisher_token and @sms_number and @sms_carrier + config = { + 'king_phisher_server' => @king_phisher_server, + 'king_phisher_token' => @king_phisher_token, + 'sms_number' => @sms_number, + 'sms_carrier' => @sms_carrier + } + File.open(Sms_yaml, 'w') do |out| + YAML.dump(config, out) + end + print_good("All parameters saved to #{Sms_yaml}") + else + print_error("You have not provided all the parameters!") + end + end + + def cmd_sms_set_server(*args) + if args.length > 0 + print_status("Setting the King Phisher server to #{args[0]}") + @king_phisher_server = args[0] + else + print_error("Please provide the domain name of your King Phisher server!") + end + end + + def cmd_sms_set_token(*args) + if args.length > 0 + print_status("Setting King Phisher's REST API token to #{args[0]}") + @king_phisher_token = args[0] + else + print_error("Please provide the REST API token of your King Phisher server!") + end + end + + def cmd_sms_set_number(*args) + if args[0].length == 10 + print_status("Setting SMS number to #{args[0]}") + @sms_number = args[0] + else + print_error("Please provide a valid SMS number!") + end + end + + def cmd_sms_set_carrier(*args) + if args.length > 0 and ['AT&T', 'Boost', 'Sprint', 'T-Mobile', 'Verizon', 'Virgin Mobile'].include? "#{args[0]}" + print_status("Setting SMS carrier to #{args[0]}") + @sms_carrier = args[0] + else + print_error("Please provide a valid SMS carrier (AT&T, Boost, Sprint, T-Mobile, Verizon, Virgin Mobile)!") + end + end + + def cmd_sms_show_params + if read_settings() + print_status("Parameters:") + print_good("King Phisher Server: #{@king_phisher_server}") + print_good("King Phisher Token: #{@king_phisher_token}") + print_good("SMS Number: #{@sms_number}") + print_good("SMS Carrier: #{@sms_carrier}") + else + print_error("Could not read settings from #{Sms_yaml}!") + end + end + end + end +end \ No newline at end of file From 514cc8789aa21254a44f11f2d6d4811d31b9e2c0 Mon Sep 17 00:00:00 2001 From: Spencer McIntyre Date: Tue, 7 Jul 2015 13:18:17 -0400 Subject: [PATCH 2/6] Minor ruby changes to the meatsploit plugin --- data/msf/README.md | 2 +- data/msf/sms.rb | 160 ++++++++++++++++++++++++--------------------- 2 files changed, 86 insertions(+), 76 deletions(-) mode change 100755 => 100644 data/msf/README.md mode change 100755 => 100644 data/msf/sms.rb diff --git a/data/msf/README.md b/data/msf/README.md old mode 100755 new mode 100644 index 6cbebb5d..7894c574 --- a/data/msf/README.md +++ b/data/msf/README.md @@ -11,7 +11,7 @@ Change the `token` value from `null` to a secret string that will be used to acc Save the server configuration file and restart the King Phisher server. ## Metasploit Configuration and Usage -Add the [sms.rb](./sms.rb) file to your Metasploit [plugins](https://github.com/rapid7/metasploit-framework/tree/master/plugins) directory. +Add the [sms.rb](./sms.rb) file to your Metasploit `~/.msf4/plugins` directory. If this is the first time using the SMS plugin you will need to set four values which will be saved in `~/.msf4/sms.yaml`. On future use these settings will automatically be loaded and do not need to be set again. Additionally, you can see descriptions of the SMS plugin commands by running `help` in msfconsole. diff --git a/data/msf/sms.rb b/data/msf/sms.rb old mode 100755 new mode 100644 index 6c94353b..5b4f4083 --- a/data/msf/sms.rb +++ b/data/msf/sms.rb @@ -1,32 +1,39 @@ # Copyright (c) 2015, Brandan [coldfusion] # -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: # -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of the nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. # -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + require 'uri' -module Msf +module Msf class Plugin::SessionSMS < Msf::Plugin include Msf::SessionEvent - if not defined?(Sms_yaml) - Sms_yaml = "#{Msf::Config.get_config_root}/sms.yaml" - end + CARRIERS = ['AT&T', 'Boost', 'Sprint', 'T-Mobile', 'Verizon', 'Virgin Mobile'] def initialize(framework, opts) super @@ -46,6 +53,10 @@ def desc "Sends a SMS message when recieving a new session through the use of the King Phisher's REST API." end + def sms_yaml + "#{Msf::Config.get_config_root}/sms.yaml" + end + class SMSCommandDispatcher < Plugin::SessionSMS include Msf::Ui::Console::CommandDispatcher @@ -55,7 +66,7 @@ class SMSCommandDispatcher < Plugin::SessionSMS @sms_carrier = nil def on_session_open(session) - print_status("Session received sending SMS...") + print_status('Session received, sending SMS...') begin http_client = Rex::Proto::Http::Client.new("#{@king_phisher_server}") http_client.connect @@ -65,7 +76,7 @@ def on_session_open(session) }) response = http_client.send_recv(request) rescue Exception => e - print_error("Exception occured, you done goofed!") + print_error('Exception occured, you done goofed!') ensure http_client.close end @@ -76,62 +87,60 @@ def name end def read_settings - read = nil - if File.exist?(Sms_yaml) - ldconfig = YAML.load_file("#{Sms_yaml}") - @king_phisher_server = ldconfig['king_phisher_server'] - @king_phisher_token = ldconfig['king_phisher_token'] - @sms_number = ldconfig['sms_number'] - @sms_carrier = ldconfig['sms_carrier'] - read = true - else - return read - end - return read + return false unless File.exist?(sms_yaml) + + ldconfig = YAML.load_file(sms_yaml) + @king_phisher_server = ldconfig['king_phisher_server'] + @king_phisher_token = ldconfig['king_phisher_token'] + @sms_number = ldconfig['sms_number'] + @sms_carrier = ldconfig['sms_carrier'] + return true end def commands { - 'sms_start' => "Start SMS alerts for new sessions", - 'sms_stop' => "Stop SMS alerts for new sessions", - 'sms_save' => "Save SMS settings to #{Sms_yaml}", - 'sms_set_server' => "Set domain name of the King Phisher server", - 'sms_set_token' => "Set King Phisher's API token", - 'sms_set_number' => "Set number to send SMS alerts to on new session", - 'sms_set_carrier' => "Set carrier for sending SMS messages", - 'sms_show_params' => "Shows currently set or saved parameters" + 'sms_start' => 'Start SMS alerts for new sessions', + 'sms_stop' => 'Stop SMS alerts for new sessions', + 'sms_save' => "Save SMS settings to #{sms_yaml}", + 'sms_set_server' => 'Set domain name of the King Phisher server', + 'sms_set_token' => 'Set King Phisher\'s API token', + 'sms_set_number' => 'Set number to send SMS alerts to on new session', + 'sms_set_carrier' => 'Set carrier for sending SMS messages', + 'sms_show_params' => 'Shows currently set or saved parameters' } end def cmd_sms_start - if read_settings() - self.framework.events.add_session_subscriber(self) - print_good("Starting SMS plugin, monitoring sessions...") - else - print_error("Could not read SMS settings!") + unless read_settings + print_error('Could not read SMS settings!') + return end + + self.framework.events.add_session_subscriber(self) + print_good('Starting SMS plugin, monitoring sessions...') end def cmd_sms_stop - print_good("Stopping SMS alerting!") + print_good('Stopping SMS alerting!') self.framework.events.remove_session_subscriber(self) end def cmd_sms_save - if @king_phisher_server and @king_phisher_token and @sms_number and @sms_carrier - config = { - 'king_phisher_server' => @king_phisher_server, - 'king_phisher_token' => @king_phisher_token, - 'sms_number' => @sms_number, - 'sms_carrier' => @sms_carrier - } - File.open(Sms_yaml, 'w') do |out| - YAML.dump(config, out) - end - print_good("All parameters saved to #{Sms_yaml}") - else - print_error("You have not provided all the parameters!") + unless @king_phisher_server && @king_phisher_token && @sms_number && @sms_carrier + print_error('You have not provided all the parameters!') + return + end + + config = { + 'king_phisher_server' => @king_phisher_server, + 'king_phisher_token' => @king_phisher_token, + 'sms_number' => @sms_number, + 'sms_carrier' => @sms_carrier + } + File.open(sms_yaml, 'w') do |out| + YAML.dump(config, out) end + print_good("All parameters saved to #{sms_yaml}") end def cmd_sms_set_server(*args) @@ -139,7 +148,7 @@ def cmd_sms_set_server(*args) print_status("Setting the King Phisher server to #{args[0]}") @king_phisher_server = args[0] else - print_error("Please provide the domain name of your King Phisher server!") + print_error('Please provide the domain name of your King Phisher server!') end end @@ -148,39 +157,40 @@ def cmd_sms_set_token(*args) print_status("Setting King Phisher's REST API token to #{args[0]}") @king_phisher_token = args[0] else - print_error("Please provide the REST API token of your King Phisher server!") + print_error('Please provide the REST API token of your King Phisher server!') end end def cmd_sms_set_number(*args) - if args[0].length == 10 + if args[0].length == 10 print_status("Setting SMS number to #{args[0]}") @sms_number = args[0] else - print_error("Please provide a valid SMS number!") + print_error('Please provide a valid SMS number!') end end def cmd_sms_set_carrier(*args) - if args.length > 0 and ['AT&T', 'Boost', 'Sprint', 'T-Mobile', 'Verizon', 'Virgin Mobile'].include? "#{args[0]}" + if args.length > 0 && CARRIERS.include?(args[0]) print_status("Setting SMS carrier to #{args[0]}") @sms_carrier = args[0] else - print_error("Please provide a valid SMS carrier (AT&T, Boost, Sprint, T-Mobile, Verizon, Virgin Mobile)!") + print_error("Please provide a valid SMS carrier (#{CARRIERS.join(', ')})!") end end def cmd_sms_show_params - if read_settings() - print_status("Parameters:") - print_good("King Phisher Server: #{@king_phisher_server}") - print_good("King Phisher Token: #{@king_phisher_token}") - print_good("SMS Number: #{@sms_number}") - print_good("SMS Carrier: #{@sms_carrier}") - else - print_error("Could not read settings from #{Sms_yaml}!") + unless read_settings + print_error("Could not read settings from #{sms_yaml}!") + return end + + print_status('Parameters:') + print_good(" King Phisher Server: #{@king_phisher_server}") + print_good(" King Phisher Token: #{@king_phisher_token}") + print_good(" SMS Number: #{@sms_number}") + print_good(" SMS Carrier: #{@sms_carrier}") end end end -end \ No newline at end of file +end From 577a113bb6c742ee7ec1fc84b0d0fe2b389ddc6e Mon Sep 17 00:00:00 2001 From: Spencer McIntyre Date: Tue, 7 Jul 2015 13:30:42 -0400 Subject: [PATCH 3/6] Formatting updates to the msf plugin README file --- data/msf/README.md | 45 ++++++++++++++++++++++++++++++--------------- 1 file changed, 30 insertions(+), 15 deletions(-) diff --git a/data/msf/README.md b/data/msf/README.md index 7894c574..b3ae243e 100644 --- a/data/msf/README.md +++ b/data/msf/README.md @@ -1,52 +1,67 @@ # SMS Plugin -The [SMS](./sms.rb) plugin uses King Phisher's [REST API](https://king-phisher.readthedocs.org/en/latest/server_api/rest_api.html?highlight=sms#get--_-api-sms-send) to send SMS messages when a new [Metasploit](https://github.com/rapid7/metasploit-framework) session is received. King Phisher's REST API is accessible externally which allows running the SMS plugin, within Metasploit, on a system other than the King Phisher server. The system running Metasploit only needs to be able to make a HTTP GET request to the King Phisher server. +The [SMS](sms) plugin uses King Phisher's [REST API](rest-api-docs) to send SMS +messages when a new [Metasploit](metasploit) session is received. King Phisher's +REST API is accessible externally which allows running the SMS plugin within +Metasploit, on a system other than the King Phisher server. The system running +Metasploit only needs to be able to make a HTTP GET request to the King Phisher +server. ## King Phisher Configuration -Edit King Phisher's `server_config.yml` file, under the `rest_api` set the `enabled` value to `true`. +Edit King Phisher's `server_config.yml` file, under the `rest_api` set the +`enabled` value to `true`. -Change the `token` value from `null` to a secret string that will be used to access the King Phisher server's REST API remotely. Running this one-liner in Linux will return a randomly generated 32 character string. +Change the `token` value from `null` to a secret string that will be used to +access the King Phisher server's REST API remotely. Running this one-liner in +Linux will return a randomly generated 32 character string which can be used. -`cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 32 | head -n 1` +```cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 32 | head -n 1``` Save the server configuration file and restart the King Phisher server. ## Metasploit Configuration and Usage -Add the [sms.rb](./sms.rb) file to your Metasploit `~/.msf4/plugins` directory. +Add the [sms.rb](sms) file to your Metasploit `~/.msf4/plugins` directory. -If this is the first time using the SMS plugin you will need to set four values which will be saved in `~/.msf4/sms.yaml`. On future use these settings will automatically be loaded and do not need to be set again. Additionally, you can see descriptions of the SMS plugin commands by running `help` in msfconsole. +If this is the first time using the SMS plugin, you will need to set four values +which will be saved in `~/.msf4/sms.yaml`. On future use, these settings will +automatically be loaded and do not need to be set again. Additionally you can +see descriptions of the SMS plugin commands by running `help` in msfconsole. -* Start Metasploit and load the SMS plugin. + * Start Metasploit and load the SMS plugin. `load sms` -* Set the domain name of your King Phisher server. + * Set the domain name of your King Phisher server. `sms_set_server king-phisher.com` -* Set the King Phisher server's REST API token. + * Set the King Phisher server's REST API token. `sms_set_token 0123456789abcdefABCDEF` -* Set the cellphone number where you would like to receive SMS messages. + * Set the cellphone number where you would like to receive SMS messages. `sms_set_number 0123456789` -* Set your cell phone carrier. Currently King Phisher supports AT&T, Boost, Sprint, T-Mobile, Verizon, Virgin Mobile. + * Set your cell phone carrier. Currently King Phisher supports AT&T, Boost, Sprint, T-Mobile, Verizon, Virgin Mobile. `sms_set_carrier Boost` -* Before saving, review your plugin settings. + * Before saving, review your plugin settings. `sms_show_params` -* If everything looks good, save your settings. + * If everything looks good, save your settings. `sms_save` -* Start the SMS plugin, which will wait for incoming sessions. + * Start the SMS plugin, which will wait for incoming sessions. `sms_start` -* When finished, stop the SMS plugin. + * When finished, stop the SMS plugin. `sms_stop` + +[metasploit]: https://github.com/rapid7/metasploit-framework +[rest-api-docs]: https://king-phisher.readthedocs.org/en/latest/server_api/rest_api.html?highlight=sms#get--_-api-sms-send +[sms]: ./sms.rb From 03813d7e652a303b9389f53bdf7aef2db15cd857 Mon Sep 17 00:00:00 2001 From: Spencer McIntyre Date: Tue, 7 Jul 2015 14:31:02 -0400 Subject: [PATCH 4/6] Include a response_sent attribute in AbortRequestError --- docs/source/king_phisher/errors.rst | 7 +++++++ king_phisher/errors.py | 6 +++++- king_phisher/server/server.py | 5 +++-- 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/docs/source/king_phisher/errors.rst b/docs/source/king_phisher/errors.rst index b9e788ad..86c7ed7b 100644 --- a/docs/source/king_phisher/errors.rst +++ b/docs/source/king_phisher/errors.rst @@ -8,9 +8,16 @@ Exceptions ---------- .. autoexception:: king_phisher.errors.KingPhisherError + :show-inheritance: .. autoexception:: king_phisher.errors.KingPhisherAbortRequestError + :show-inheritance: + :members: + :special-members: __init__ + .. autoexception:: king_phisher.errors.KingPhisherDatabaseError + :show-inheritance: .. autoexception:: king_phisher.errors.KingPhisherInputValidationError + :show-inheritance: diff --git a/king_phisher/errors.py b/king_phisher/errors.py index 7cb02cac..f8f355f1 100644 --- a/king_phisher/errors.py +++ b/king_phisher/errors.py @@ -42,7 +42,11 @@ class KingPhisherAbortRequestError(KingPhisherError): An exception that can be raised which when caught will cause the handler to immediately stop processing the current request. """ - pass + def __init__(self, response_sent=False): + """ + :param bool response_sent: Whether or not a response has already been sent to the client. + """ + self.response_sent = response_sent class KingPhisherDatabaseError(KingPhisherError): """ diff --git a/king_phisher/server/server.py b/king_phisher/server/server.py index 5b035a19..447f7fca 100644 --- a/king_phisher/server/server.py +++ b/king_phisher/server/server.py @@ -172,8 +172,9 @@ def _do_http_method(self, *args, **kwargs): self.server.throttle_semaphore.acquire() try: http_method_handler(*args, **kwargs) - except errors.KingPhisherAbortRequestError: - self.respond_not_found() + except errors.KingPhisherAbortRequestError as error: + if not error.response_sent: + self.respond_not_found() finally: self.server.throttle_semaphore.release() do_GET = _do_http_method From 7026a97b195a072bb2eb9271f37f5929a7a71460 Mon Sep 17 00:00:00 2001 From: Spencer McIntyre Date: Tue, 14 Jul 2015 11:24:40 -0400 Subject: [PATCH 5/6] Add documentation for the release steps [ci skip] --- docs/source/change_log.rst | 2 ++ docs/source/index.rst | 1 + docs/source/release_steps.rst | 34 ++++++++++++++++++++++++++++++++++ 3 files changed, 37 insertions(+) create mode 100644 docs/source/release_steps.rst diff --git a/docs/source/change_log.rst b/docs/source/change_log.rst index a50f97f4..3239b602 100644 --- a/docs/source/change_log.rst +++ b/docs/source/change_log.rst @@ -17,6 +17,8 @@ Version 0.2.1 * Support reloading message templates when they change from an external editor * Support for pulling the client IP from a cookie set by an upstream proxy * Support for embedding training videos from YouTube +* Added a Metasploit plugin for using the REST API to send SMS messages +* Support for exporting visit information to GeoJSON Version 0.2.0 ^^^^^^^^^^^^^ diff --git a/docs/source/index.rst b/docs/source/index.rst index 2b1f02a4..10dada8a 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -23,6 +23,7 @@ the `GitHub homepage`_. server_api/index.rst environment_vars.rst change_log.rst + release_steps.rst Indices and tables ================== diff --git a/docs/source/release_steps.rst b/docs/source/release_steps.rst new file mode 100644 index 00000000..1c9e5f6a --- /dev/null +++ b/docs/source/release_steps.rst @@ -0,0 +1,34 @@ +Release Steps +============= + +This document contains the steps that are followed for each point version +release of King Phisher. + +Pre Release Steps +----------------- + +#. Test and fix any issues with the Windows MSI build +#. Ensure unit tests pass with Python 2.7 & Python 3.4 +#. Remove the version label +#. Create the final Windows build +#. Update the change log + +Release Steps +------------- + +#. Commit the final changes, and ensure the commit is signed +#. Create a signed tag of the release commit +#. Merge dev into master and push both to GitHub +#. Create a new release on GitHub + + #. Upload the final Windows build + #. Insert the changes from the change log + +#. Update the Docker build +#. Publicize the release + +Post Release Steps +------------------ + +#. Increment the version number on the dev branch and re-set the version label +#. Update Python packages with pip From de2fcece05db3fd3a127234b6aa0417d3759b88e Mon Sep 17 00:00:00 2001 From: Spencer McIntyre Date: Tue, 14 Jul 2015 11:32:29 -0400 Subject: [PATCH 6/6] Set the version to 0.2.1 final --- docs/source/change_log.rst | 2 +- docs/source/release_steps.rst | 7 ++++--- king_phisher/version.py | 6 +++--- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/docs/source/change_log.rst b/docs/source/change_log.rst index 3239b602..14f62674 100644 --- a/docs/source/change_log.rst +++ b/docs/source/change_log.rst @@ -10,7 +10,7 @@ Version 0.2.x Version 0.2.1 ^^^^^^^^^^^^^ -*In Progress* +Released :release:`0.2.1` on July 14th, 2015 * Added syntax highlighting to the message edit tab * Technical documentation improvements, including documenting the REST API diff --git a/docs/source/release_steps.rst b/docs/source/release_steps.rst index 1c9e5f6a..350c0cec 100644 --- a/docs/source/release_steps.rst +++ b/docs/source/release_steps.rst @@ -16,9 +16,10 @@ Pre Release Steps Release Steps ------------- -#. Commit the final changes, and ensure the commit is signed -#. Create a signed tag of the release commit -#. Merge dev into master and push both to GitHub +#. Create a final signed commit on the dev branch +#. Push the dev branch to GitHub and ensure the Travis-CI build passes +#. Merge dev into master and push master to GitHub +#. Create and push a signed tag of the release commit #. Create a new release on GitHub #. Upload the final Windows build diff --git a/king_phisher/version.py b/king_phisher/version.py index 2dbbcdbe..faeab41b 100644 --- a/king_phisher/version.py +++ b/king_phisher/version.py @@ -35,14 +35,14 @@ version_info = collections.namedtuple('version_info', ['major', 'minor', 'micro'])(0, 2, 1) """A tuple representing the version information in the format ('major', 'minor', 'micro')""" -version_label = 'beta' -"""A version lable such as alpha or beta.""" +version_label = '' +"""A version label such as alpha or beta.""" version = "{0}.{1}.{2}".format(version_info.major, version_info.minor, version_info.micro) """A string representing the full version information.""" # distutils_version is compatible with distutils.version classes distutils_version = version -"""A string sutiable for being parsed by :py:mod:`distutils.version` classes.""" +"""A string suitable for being parsed by :py:mod:`distutils.version` classes.""" if version_label: version += '-' + version_label