credential_collection_spec.rb 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393
  1. require 'spec_helper'
  2. require 'metasploit/framework/credential_collection'
  3. RSpec.describe Metasploit::Framework::CredentialCollection do
  4. subject(:collection) do
  5. described_class.new(
  6. nil_passwords: nil_passwords,
  7. blank_passwords: blank_passwords,
  8. pass_file: pass_file,
  9. password: password,
  10. user_as_pass: user_as_pass,
  11. user_file: user_file,
  12. username: username,
  13. userpass_file: userpass_file,
  14. prepended_creds: prepended_creds,
  15. additional_privates: additional_privates,
  16. additional_publics: additional_publics,
  17. password_spray: password_spray
  18. )
  19. end
  20. before(:each) do
  21. # The test suite overrides File.open(...) calls; fall back to the normal behavior for any File.open calls that aren't explicitly mocked
  22. allow(File).to receive(:open).with(anything).and_call_original
  23. allow(File).to receive(:open).with(anything, anything).and_call_original
  24. allow(File).to receive(:open).with(anything, anything, anything).and_call_original
  25. end
  26. let(:nil_passwords) { nil }
  27. let(:blank_passwords) { nil }
  28. let(:username) { "user" }
  29. let(:password) { "pass" }
  30. let(:user_file) { nil }
  31. let(:pass_file) { nil }
  32. let(:user_as_pass) { nil }
  33. let(:userpass_file) { nil }
  34. let(:prepended_creds) { [] }
  35. let(:additional_privates) { [] }
  36. let(:additional_publics) { [] }
  37. let(:password_spray) { false }
  38. describe "#each" do
  39. specify do
  40. expect { |b| collection.each(&b) }.to yield_with_args(Metasploit::Framework::Credential)
  41. end
  42. context "when given a user_file and password" do
  43. let(:username) { nil }
  44. let(:user_file) do
  45. filename = "foo"
  46. stub_file = StringIO.new("asdf\njkl\n")
  47. allow(File).to receive(:open).with(filename,/^r/).and_yield stub_file
  48. filename
  49. end
  50. specify do
  51. expect { |b| collection.each(&b) }.to yield_successive_args(
  52. Metasploit::Framework::Credential.new(public: "asdf", private: password),
  53. Metasploit::Framework::Credential.new(public: "jkl", private: password),
  54. )
  55. end
  56. end
  57. context "when given a pass_file and username" do
  58. let(:password) { nil }
  59. let(:pass_file) do
  60. filename = "foo"
  61. stub_file = StringIO.new("asdf\njkl\n")
  62. allow(File).to receive(:open).with(filename,/^r/).and_return stub_file
  63. filename
  64. end
  65. specify do
  66. expect { |b| collection.each(&b) }.to yield_successive_args(
  67. Metasploit::Framework::Credential.new(public: username, private: "asdf"),
  68. Metasploit::Framework::Credential.new(public: username, private: "jkl"),
  69. )
  70. end
  71. end
  72. context "when given a userspass_file" do
  73. let(:username) { nil }
  74. let(:password) { nil }
  75. let(:userpass_file) do
  76. filename = "foo"
  77. stub_file = StringIO.new("asdf jkl\nfoo bar\n")
  78. allow(File).to receive(:open).with(filename,/^r/).and_yield stub_file
  79. filename
  80. end
  81. specify do
  82. expect { |b| collection.each(&b) }.to yield_successive_args(
  83. Metasploit::Framework::Credential.new(public: "asdf", private: "jkl"),
  84. Metasploit::Framework::Credential.new(public: "foo", private: "bar"),
  85. )
  86. end
  87. end
  88. context "when given a pass_file and user_file" do
  89. let(:password) { nil }
  90. let(:username) { nil }
  91. let(:user_file) do
  92. filename = "user_file"
  93. stub_file = StringIO.new("asdf\njkl\n")
  94. allow(File).to receive(:open).with(filename,/^r/).and_yield stub_file
  95. filename
  96. end
  97. let(:pass_file) do
  98. filename = "pass_file"
  99. stub_file = StringIO.new("asdf\njkl\n")
  100. allow(File).to receive(:open).with(filename,/^r/).and_return stub_file
  101. filename
  102. end
  103. specify do
  104. expect { |b| collection.each(&b) }.to yield_successive_args(
  105. Metasploit::Framework::Credential.new(public: "asdf", private: "asdf"),
  106. Metasploit::Framework::Credential.new(public: "asdf", private: "jkl"),
  107. Metasploit::Framework::Credential.new(public: "jkl", private: "asdf"),
  108. Metasploit::Framework::Credential.new(public: "jkl", private: "jkl"),
  109. )
  110. end
  111. end
  112. context "when given a pass_file and user_file and password spray" do
  113. let(:password) { nil }
  114. let(:username) { nil }
  115. let(:password_spray) { true }
  116. let(:pass_file) do
  117. filename = "pass_file"
  118. stub_file = StringIO.new("password1\npassword2\n")
  119. allow(File).to receive(:open).with(filename,/^r/).and_yield stub_file
  120. filename
  121. end
  122. let(:user_file) do
  123. filename = "user_file"
  124. stub_file = StringIO.new("user1\nuser2\nuser3\n")
  125. allow(File).to receive(:open).with(filename,/^r/).and_return stub_file
  126. filename
  127. end
  128. specify do
  129. expect { |b| collection.each(&b) }.to yield_successive_args(
  130. Metasploit::Framework::Credential.new(public: "user1", private: "password1"),
  131. Metasploit::Framework::Credential.new(public: "user2", private: "password1"),
  132. Metasploit::Framework::Credential.new(public: "user3", private: "password1"),
  133. Metasploit::Framework::Credential.new(public: "user1", private: "password2"),
  134. Metasploit::Framework::Credential.new(public: "user2", private: "password2"),
  135. Metasploit::Framework::Credential.new(public: "user3", private: "password2"),
  136. )
  137. end
  138. end
  139. context 'when given a username and password' do
  140. let(:password) { 'password' }
  141. let(:username) { 'root' }
  142. specify do
  143. expected = [
  144. Metasploit::Framework::Credential.new(public: 'root', private: 'password'),
  145. ]
  146. expect { |b| collection.each(&b) }.to yield_successive_args(*expected)
  147. end
  148. end
  149. context 'when given a pass_file, user_file, password spray and a default username' do
  150. let(:password) { nil }
  151. let(:username) { 'root' }
  152. let(:password_spray) { true }
  153. let(:pass_file) do
  154. filename = "pass_file"
  155. stub_file = StringIO.new("password1\npassword2\n")
  156. allow(File).to receive(:open).with(filename,/^r/).and_yield stub_file
  157. filename
  158. end
  159. let(:user_file) do
  160. filename = "user_file"
  161. stub_file = StringIO.new("user1\nuser2\nuser3\n")
  162. allow(File).to receive(:open).with(filename,/^r/).and_return stub_file
  163. filename
  164. end
  165. specify do
  166. expected = [
  167. Metasploit::Framework::Credential.new(public: "root", private: "password1"),
  168. Metasploit::Framework::Credential.new(public: "user1", private: "password1"),
  169. Metasploit::Framework::Credential.new(public: "user2", private: "password1"),
  170. Metasploit::Framework::Credential.new(public: "user3", private: "password1"),
  171. Metasploit::Framework::Credential.new(public: "root", private: "password2"),
  172. Metasploit::Framework::Credential.new(public: "user1", private: "password2"),
  173. Metasploit::Framework::Credential.new(public: "user2", private: "password2"),
  174. Metasploit::Framework::Credential.new(public: "user3", private: "password2"),
  175. ]
  176. expect { |b| collection.each(&b) }.to yield_successive_args(*expected)
  177. end
  178. end
  179. context 'when given a pass_file, user_file, password spray and additional privates' do
  180. let(:password) { nil }
  181. let(:username) { 'root' }
  182. let(:password_spray) { true }
  183. let(:additional_privates) { ['foo'] }
  184. let(:pass_file) do
  185. filename = "pass_file"
  186. stub_file = StringIO.new("password1\npassword2\n")
  187. allow(File).to receive(:open).with(filename,/^r/).and_yield stub_file
  188. filename
  189. end
  190. let(:user_file) do
  191. filename = "user_file"
  192. stub_file = StringIO.new("user1\nuser2\nuser3\n")
  193. allow(File).to receive(:open).with(filename,/^r/).and_return stub_file
  194. filename
  195. end
  196. specify do
  197. expected = [
  198. Metasploit::Framework::Credential.new(public: "root", private: "password1"),
  199. Metasploit::Framework::Credential.new(public: "user1", private: "password1"),
  200. Metasploit::Framework::Credential.new(public: "user2", private: "password1"),
  201. Metasploit::Framework::Credential.new(public: "user3", private: "password1"),
  202. Metasploit::Framework::Credential.new(public: "root", private: "password2"),
  203. Metasploit::Framework::Credential.new(public: "user1", private: "password2"),
  204. Metasploit::Framework::Credential.new(public: "user2", private: "password2"),
  205. Metasploit::Framework::Credential.new(public: "user3", private: "password2"),
  206. Metasploit::Framework::Credential.new(public: "root", private: "foo"),
  207. Metasploit::Framework::Credential.new(public: "user1", private: "foo"),
  208. Metasploit::Framework::Credential.new(public: "user2", private: "foo"),
  209. Metasploit::Framework::Credential.new(public: "user3", private: "foo"),
  210. ]
  211. expect { |b| collection.each(&b) }.to yield_successive_args(*expected)
  212. end
  213. end
  214. context 'when given a username, user_file and pass_file' do
  215. let(:password) { nil }
  216. let(:username) { 'my_username' }
  217. let(:user_file) do
  218. filename = "user_file"
  219. stub_file = StringIO.new("asdf\njkl\n")
  220. allow(File).to receive(:open).with(filename, /^r/).and_yield stub_file
  221. filename
  222. end
  223. let(:pass_file) do
  224. filename = "pass_file"
  225. stub_file = StringIO.new("asdf\njkl\n")
  226. allow(File).to receive(:open).with(filename, /^r/).and_return stub_file
  227. filename
  228. end
  229. it do
  230. expect { |b| collection.each(&b) }.to yield_successive_args(
  231. Metasploit::Framework::Credential.new(public: "my_username", private: "asdf"),
  232. Metasploit::Framework::Credential.new(public: "my_username", private: "jkl"),
  233. Metasploit::Framework::Credential.new(public: "asdf", private: "asdf"),
  234. Metasploit::Framework::Credential.new(public: "asdf", private: "jkl"),
  235. Metasploit::Framework::Credential.new(public: "jkl", private: "asdf"),
  236. Metasploit::Framework::Credential.new(public: "jkl", private: "jkl")
  237. )
  238. end
  239. end
  240. context "when :user_as_pass is true" do
  241. let(:user_as_pass) { true }
  242. specify do
  243. expect { |b| collection.each(&b) }.to yield_successive_args(
  244. Metasploit::Framework::Credential.new(public: username, private: password),
  245. Metasploit::Framework::Credential.new(public: username, private: username),
  246. )
  247. end
  248. end
  249. context "when :nil_passwords is true" do
  250. let(:nil_passwords) { true }
  251. specify do
  252. expect { |b| collection.each(&b) }.to yield_successive_args(
  253. Metasploit::Framework::Credential.new(public: username, private: nil),
  254. Metasploit::Framework::Credential.new(public: username, private: password),
  255. )
  256. end
  257. end
  258. context "when :blank_passwords is true" do
  259. let(:blank_passwords) { true }
  260. specify do
  261. expect { |b| collection.each(&b) }.to yield_successive_args(
  262. Metasploit::Framework::Credential.new(public: username, private: password),
  263. Metasploit::Framework::Credential.new(public: username, private: ""),
  264. )
  265. end
  266. end
  267. end
  268. describe "#empty?" do
  269. context "when only :userpass_file is set" do
  270. let(:username) { nil }
  271. let(:password) { nil }
  272. let(:userpass_file) { "test_file" }
  273. specify do
  274. expect(collection.empty?).to eq false
  275. end
  276. end
  277. context "when :username is set" do
  278. context "and :password is set" do
  279. specify do
  280. expect(collection.empty?).to eq false
  281. end
  282. end
  283. context "and :password is not set" do
  284. let(:password) { nil }
  285. specify do
  286. expect(collection.empty?).to eq true
  287. end
  288. context "and :nil_passwords is true" do
  289. let(:nil_passwords) { true }
  290. specify do
  291. expect(collection.empty?).to eq false
  292. end
  293. end
  294. context "and :blank_passwords is true" do
  295. let(:blank_passwords) { true }
  296. specify do
  297. expect(collection.empty?).to eq false
  298. end
  299. end
  300. end
  301. end
  302. context "when :username is not set" do
  303. context "and :password is not set" do
  304. let(:username) { nil }
  305. let(:password) { nil }
  306. specify do
  307. expect(collection.empty?).to eq true
  308. end
  309. context "and :prepended_creds is not empty" do
  310. let(:prepended_creds) { [ "test" ] }
  311. specify do
  312. expect(collection.empty?).to eq false
  313. end
  314. end
  315. context "and :additional_privates is not empty" do
  316. let(:additional_privates) { [ "test_private" ] }
  317. specify do
  318. expect(collection.empty?).to eq true
  319. end
  320. end
  321. context "and :additional_publics is not empty" do
  322. let(:additional_publics) { [ "test_public" ] }
  323. specify do
  324. expect(collection.empty?).to eq true
  325. end
  326. end
  327. end
  328. end
  329. end
  330. describe "#prepend_cred" do
  331. specify do
  332. prep = Metasploit::Framework::Credential.new(public: "foo", private: "bar")
  333. collection.prepend_cred(prep)
  334. expect { |b| collection.each(&b) }.to yield_successive_args(
  335. prep,
  336. Metasploit::Framework::Credential.new(public: username, private: password),
  337. )
  338. end
  339. end
  340. end