encoded_payload_spec.rb 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. require 'spec_helper'
  2. require 'msf/core/encoded_payload'
  3. RSpec.describe Msf::EncodedPayload do
  4. include_context 'Msf::Simple::Framework#modules loading'
  5. before do
  6. ancestor_reference_names = [
  7. # Excellent rank
  8. 'x86/shikata_ga_nai',
  9. # Great rank
  10. 'x86/call4_dword_xor',
  11. 'x86/xor_dynamic',
  12. 'generic/none',
  13. ]
  14. expect_to_load_module_ancestors(
  15. ancestor_reference_names: ancestor_reference_names,
  16. module_type: 'encoder',
  17. modules_path: modules_path,
  18. )
  19. # Improve test performance - return only the test modules that we're interested in
  20. allow(framework.encoders).to receive(:rank_modules).and_wrap_original do |original, *args|
  21. ranked_modules = original.call(*args)
  22. ranked_modules.select do |ref_name, _metadata|
  23. ancestor_reference_names.include?(ref_name)
  24. end
  25. end
  26. end
  27. let(:ancestor_reference_names) {
  28. # A module that doesn't require any datastore junk to generate
  29. %w{singles/linux/x86/shell_bind_tcp}
  30. }
  31. let(:module_type) {
  32. 'payload'
  33. }
  34. let(:reference_name) {
  35. 'linux/x86/shell_bind_tcp'
  36. }
  37. let(:payload) {
  38. load_and_create_module(
  39. ancestor_reference_names: ancestor_reference_names,
  40. module_type: module_type,
  41. reference_name: reference_name
  42. )
  43. }
  44. subject(:encoded_payload) do
  45. described_class.new(framework, payload, reqs)
  46. end
  47. let(:badchars) { nil }
  48. let(:reqs) { { 'BadChars' => badchars } }
  49. it 'is an Msf::EncodedPayload' do
  50. expect(encoded_payload).to be_a(described_class)
  51. end
  52. describe '.create' do
  53. subject(:encoded_payload) do
  54. described_class.create(payload, { 'BadChars' => badchars } )
  55. end
  56. specify { expect(encoded_payload).to respond_to(:encoded) }
  57. it 'is an Msf::EncodedPayload' do
  58. expect(encoded_payload).to be_a(described_class)
  59. end
  60. context 'when passed a valid payload instance' do
  61. # don't ever actually generate payload bytes
  62. before(:example) do
  63. allow_any_instance_of(described_class).to receive(:generate)
  64. end
  65. it 'returns an Msf::EncodedPayload instance' do
  66. expect(encoded_payload).to be_a(described_class)
  67. end
  68. end
  69. end
  70. describe '#arch' do
  71. context 'when payload is linux/x86 reverse tcp' do
  72. let(:ancestor_reference_names) {
  73. %w{singles/linux/x86/shell_reverse_tcp}
  74. }
  75. let(:reference_name) {
  76. 'linux/x86/shell_reverse_tcp'
  77. }
  78. it 'returns ["X86"]' do
  79. expect(encoded_payload.arch).to eq [ARCH_X86]
  80. end
  81. end
  82. context 'when payload is linux/x64 reverse tcp' do
  83. let(:ancestor_reference_names) {
  84. %w{singles/linux/x64/shell_reverse_tcp}
  85. }
  86. let(:reference_name) {
  87. 'linux/x64/shell_reverse_tcp'
  88. }
  89. it 'returns ["X86_64"]' do
  90. expect(encoded_payload.arch).to eq [ARCH_X64]
  91. end
  92. end
  93. end
  94. describe '#generate' do
  95. let!(:generate) { encoded_payload.generate }
  96. context 'with no badchars' do
  97. let(:badchars) { nil }
  98. specify 'returns the raw value' do
  99. expect(encoded_payload.generate("RAW")).to eql("RAW")
  100. end
  101. end
  102. context 'with bad characters: "\\0"' do
  103. let(:badchars) { "\0".force_encoding('binary') }
  104. context 'when the payload contains the bad characters' do
  105. specify 'chooses x86/shikata_ga_nai' do
  106. expect(encoded_payload.encoder.refname).to eq("x86/shikata_ga_nai")
  107. end
  108. specify do
  109. expect(encoded_payload.encoded).not_to include(badchars)
  110. end
  111. end
  112. context 'when the payload does not contain the bad characters' do
  113. specify 'returns the raw value' do
  114. expect(encoded_payload.generate("RAW")).to eql("RAW")
  115. end
  116. end
  117. end
  118. context 'with bad characters: "\\xD9\\x00"' do
  119. let(:badchars) { "\xD9\x00".force_encoding('binary') }
  120. specify 'chooses x86/xor_dynamic' do
  121. expect(encoded_payload.encoder.refname).to eq("x86/xor_dynamic")
  122. end
  123. specify do
  124. expect(encoded_payload.encoded).not_to include(badchars)
  125. end
  126. end
  127. context 'with windows/meterpreter_bind_tcp and bad characters: "\\x00\\x0a\\x0d"' do
  128. let(:badchars) { "\x00\x0a\x0d".force_encoding('binary') }
  129. let(:ancestor_reference_names) {
  130. %w{singles/windows/meterpreter_bind_tcp}
  131. }
  132. let(:reference_name) {
  133. 'windows/meterpreter_bind_tcp'
  134. }
  135. specify 'chooses x86/xor_dynamic' do
  136. expect(encoded_payload.encoder.refname).to eq("x86/xor_dynamic")
  137. end
  138. specify do
  139. expect(encoded_payload.encoded).not_to include(badchars)
  140. end
  141. end
  142. end
  143. end