test_encoders.rb 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. #
  2. # Simple script to test a group of encoders against every exploit in the framework,
  3. # specifically for the exploits badchars, to see if a payload can be encoded. We ignore
  4. # the target arch/platform of the exploit as we just want to pull out real world bad chars.
  5. #
  6. msfbase = __FILE__
  7. while File.symlink?(msfbase)
  8. msfbase = File.expand_path(File.readlink(msfbase), File.dirname(msfbase))
  9. end
  10. $:.unshift(File.expand_path(File.join(File.dirname(msfbase), '..', '..', 'lib')))
  11. require 'msfenv'
  12. $msf = Msf::Simple::Framework.create
  13. EXPLOITS = $msf.exploits
  14. def print_line(message)
  15. $stdout.puts(message)
  16. end
  17. def format_badchars(badchars)
  18. str = ''
  19. if (badchars)
  20. badchars.each_byte do |b|
  21. str << "\\x%02X" % [ b ]
  22. end
  23. end
  24. str
  25. end
  26. def encoder_v_payload(encoder_name, payload, verbose = false)
  27. success = 0
  28. fail = 0
  29. EXPLOITS.each_module do |name, mod|
  30. exploit = mod.new
  31. print_line("\n#{encoder_name} v #{name} (#{format_badchars(exploit.payload_badchars)})") if verbose
  32. begin
  33. encoder = $msf.encoders.create(encoder_name)
  34. raw = encoder.encode(payload, exploit.payload_badchars, nil, nil)
  35. success += 1
  36. rescue
  37. print_line(" FAILED! badchars=#{format_badchars(exploit.payload_badchars)}\n") if verbose
  38. fail += 1
  39. end
  40. end
  41. return [ success, fail ]
  42. end
  43. def generate_payload(name)
  44. payload = $msf.payloads.create(name)
  45. # set options for a reverse_tcp payload
  46. payload.datastore['LHOST'] = '192.168.2.1'
  47. payload.datastore['RHOST'] = '192.168.2.254'
  48. payload.datastore['RPORT'] = '5432'
  49. payload.datastore['LPORT'] = '4444'
  50. # set options for an exec payload
  51. payload.datastore['CMD'] = 'calc'
  52. # set generic options
  53. payload.datastore['EXITFUNC'] = 'thread'
  54. return payload.generate
  55. end
  56. def run(encoders, payload_name, verbose = false)
  57. payload = generate_payload(payload_name)
  58. table = Rex::Text::Table.new(
  59. 'Header' => 'Encoder v Payload Test - ' + ::Time.new.strftime("%d-%b-%Y %H:%M:%S"),
  60. 'Indent' => 4,
  61. 'Columns' => [ 'Encoder Name', 'Success', 'Fail' ]
  62. )
  63. encoders.each do |encoder_name|
  64. success, fail = encoder_v_payload(encoder_name, payload, verbose)
  65. table << [ encoder_name, success, fail ]
  66. end
  67. return table
  68. end
  69. if ($0 == __FILE__)
  70. print_line("[+] Starting.\n")
  71. encoders = [
  72. 'x86/bloxor',
  73. 'x86/shikata_ga_nai',
  74. 'x86/jmp_call_additive',
  75. 'x86/fnstenv_mov',
  76. 'x86/countdown',
  77. 'x86/call4_dword_xor'
  78. ]
  79. payload_name = 'windows/shell/reverse_tcp'
  80. verbose = false
  81. result_table = run(encoders, payload_name, verbose)
  82. print_line("\n\n#{result_table.to_s}\n\n")
  83. print_line("[+] Finished.\n")
  84. end