sounds.rb 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. module Msf
  2. ###
  3. #
  4. # This class hooks all session creation events and plays a sound
  5. #
  6. ###
  7. class Plugin::EventSounds < Msf::Plugin
  8. attr_accessor :theme, :base, :queue, :queue_thread
  9. attr_reader :try_harder, :excellent, :got_a_shell, :exploit_worked, :wonderful
  10. include Msf::SessionEvent
  11. def play_sound(event)
  12. queue.push(event)
  13. end
  14. def on_session_open(_session)
  15. sound = [
  16. excellent,
  17. got_a_shell,
  18. exploit_worked,
  19. wonderful
  20. ].sample
  21. play_sound(sound)
  22. end
  23. def on_session_close(session, reason = '')
  24. # Cannot find an audio clip of muts saying something suitable for this.
  25. end
  26. def on_session_fail(_reason = '')
  27. play_sound(try_harder)
  28. end
  29. def on_plugin_load; end
  30. def on_plugin_unload; end
  31. def start_sound_queue
  32. self.queue_thread = Thread.new do
  33. loop do
  34. while (event = queue.shift)
  35. path = ::File.join(base, theme, "#{event}.wav")
  36. if ::File.exist?(path)
  37. Rex::Compat.play_sound(path)
  38. else
  39. print_status("Warning: sound file not found: #{path}")
  40. end
  41. end
  42. select(nil, nil, nil, 0.25)
  43. end
  44. rescue ::Exception => e
  45. print_status("Sound plugin: fatal error #{e} #{e.backtrace}")
  46. end
  47. end
  48. def stop_sound_queue
  49. queue_thread.kill if queue_thread
  50. self.queue_thread = nil
  51. self.queue = []
  52. end
  53. def init_sound_paths
  54. @try_harder = 'try_harder'
  55. @excellent = 'excellent'
  56. @got_a_shell = 'got_a_shell'
  57. @exploit_worked = 'exploit_worked'
  58. @wonderful = 'wonderful'
  59. end
  60. def initialize(framework, opts)
  61. super
  62. init_sound_paths
  63. self.queue = []
  64. self.theme = opts['theme'] || 'default'
  65. self.base = File.join(Msf::Config.data_directory, 'sounds')
  66. self.framework.events.add_session_subscriber(self)
  67. start_sound_queue
  68. on_plugin_load
  69. end
  70. def cleanup
  71. on_plugin_unload
  72. framework.events.remove_session_subscriber(self)
  73. stop_sound_queue
  74. end
  75. def name
  76. 'sounds'
  77. end
  78. def desc
  79. 'Automatically plays a sound when various framework events occur'
  80. end
  81. end
  82. end