Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Path: blob/master/spec/tools/md5_lookup_spec.rb
Views: 11768
load Metasploit::Framework.root.join('tools/password/md5_lookup.rb').to_path1require 'spec_helper'23require 'stringio'45RSpec.describe Md5LookupUtility do67#8# Init some data9#1011let(:input_data) do12'098f6bcd4621d373cade4e832627b4f6'13end1415let(:bad_input_data) do16''17end1819let(:good_result) do20'test'21end2223let(:empty_result) do24''25end2627let(:good_json_response) do28%Q|{ "status":true, "result":"test", "message":"" }|29end3031let(:bad_json_response) do32%Q|{ "status":false, "result":"", "message":"not found" }|33end3435let(:db_source) do36'i337.net'37end3839let(:input_file) do40'input.txt'41end4243let(:output_file) do44'output.txt'45end4647let(:options) do48{49:databases => [db_source],50:outfile => output_file,51:input => input_file52}53end5455subject do56Md5LookupUtility::Md5Lookup.new57end5859def set_expected_response(body)60res = Rex::Proto::Http::Response.new61res.code = 20062res.body = body63res64end6566def set_send_request_cgi(body)67allow(subject).to receive(:send_request_cgi) do |opts|68set_expected_response(body)69end70end7172#73# Tests start here74#757677describe Md5LookupUtility::Disclaimer do7879let(:group_name) { 'MD5Lookup' }80let(:setting_name) { 'waiver' }81let(:data) { true }82let(:t_path) { 'filepath' }8384def stub_save85ini = Rex::Parser::Ini.new(t_path)86allow(ini).to receive(:to_file).with(any_args)87allow(Rex::Parser::Ini).to receive(:new).and_return(ini)88return ini89end9091def stub_load(with_setting=true)92if with_setting93ini = stub_save94disclaimer.save_waiver95else96ini = Rex::Parser::Ini.new(t_path)97end9899allow(Rex::Parser::Ini).to receive(:new).and_return(ini)100return ini101end102103subject(:disclaimer) do104Md5LookupUtility::Disclaimer.new105end106107describe '#ack' do108context 'When \'Y\' is entered' do109it 'returns true' do110agree = "Y\n"111allow($stdin).to receive(:gets).and_return(agree)112get_stdout { expect(disclaimer.ack).to be_truthy }113end114end115end116117describe '#save_waiver' do118context 'when waiver is true' do119it 'saves the wavier setting' do120ini = stub_save121disclaimer.save_waiver122expect(ini[group_name]).to eq({setting_name=>true})123end124end125end126127describe '#has_waiver?' do128context 'when there is a waiver' do129it 'returns true' do130ini = stub_load(true)131expect(disclaimer.send(:has_waiver?)).to be_truthy132end133end134135context 'when there is no waiver' do136it 'returns false' do137ini = stub_load(false)138expect(disclaimer.send(:has_waiver?)).to be_falsey139end140end141end142143describe '#save_setting' do144context 'when a setting is given' do145it 'saves the setting' do146ini = stub_save147disclaimer.send(:save_setting, setting_name, data)148expect(ini[group_name]).to eq({setting_name=>true})149end150end151end152153describe '#load_setting' do154end155156end157158159describe Md5LookupUtility::Md5Lookup do160161describe '.new' do162it 'returns a Md5LookupUtility::Md5Lookup instance' do163expect(subject).to be_a(Md5LookupUtility::Md5Lookup)164end165end166167describe '#lookup' do168169context 'when a hash is found' do170it 'returns the cracked result' do171set_send_request_cgi(good_json_response)172expect(subject.lookup(input_data, db_source)).to eq(good_result)173end174end175176context 'when a hash is not found' do177it 'returns an empty result' do178set_send_request_cgi(bad_json_response)179expect(subject.lookup(input_data, db_source)).to eq(empty_result)180end181end182end183184describe '#get_json_results' do185context 'when JSON contains the found result' do186it 'returns the cracked result' do187res = set_expected_response(good_json_response)188expect(subject.send(:get_json_result, res)).to eq(good_result)189end190end191192context 'when there is no JSON data' do193it 'returns an empty result' do194res = set_expected_response('')195expect(subject.send(:get_json_result, res)).to eq(empty_result)196end197end198end199200end201202203describe Md5LookupUtility::Driver do204205let(:expected_result) {206{207:hash => input_data,208:cracked_hash => good_result,209:credit => db_source210}211}212213before(:example) do214expect(Md5LookupUtility::OptsConsole).to receive(:parse).with(any_args).and_return(options)215allow(File).to receive(:open).with(input_file, 'rb').and_yield(StringIO.new(input_data))216allow(File).to receive(:new).with(output_file, 'wb').and_return(StringIO.new)217end218219subject do220Md5LookupUtility::Driver.new221end222223describe '.new' do224it 'returns a Md5LookupUtility::Driver instance' do225expect(subject).to be_a(Md5LookupUtility::Driver)226end227end228229describe '#run' do230context 'when a hash is found' do231it 'prints a \'found\' message' do232disclaimer = Md5LookupUtility::Disclaimer.new233allow(disclaimer).to receive(:has_waiver?).and_return(true)234allow(Md5LookupUtility::Disclaimer).to receive(:new).and_return(disclaimer)235allow(subject).to receive(:get_hash_results).and_yield(expected_result)236output = get_stdout { subject.run }237expect(output).to include('Found:')238end239end240end241242describe '#save_result' do243context 'when a result is given' do244it 'writes the result to file' do245subject.send(:save_result, expected_result)246expect(subject.instance_variable_get(:@output_handle).string).to include(good_result)247end248end249end250251describe '#get_hash_results' do252context 'when a hash is found' do253it 'yields a result' do254search_engine = Md5LookupUtility::Md5Lookup.new255allow(search_engine).to receive(:lookup).and_return(good_result)256allow(Md5LookupUtility::Md5Lookup).to receive(:new).and_return(search_engine)257258expect{ |b| subject.send(:get_hash_results, input_file, [db_source], &b) }.to yield_with_args(expected_result)259end260end261end262263describe '#extract_hashes' do264context 'when a MD5 file is supplied' do265it 'yields the MD5 hash' do266expect{ |b| subject.send(:extract_hashes, input_file, &b) }.to yield_with_args(input_data)267end268end269270context 'when an empty file is supplied' do271before do272allow(File).to receive(:open).with(input_file, 'rb').and_yield(StringIO.new(''))273end274275it 'yields nothing' do276expect{ |b| subject.send(:extract_hashes, input_file, &b) }.not_to yield_control277end278end279end280281describe '#is_md5_format?' do282context 'when a valid MD5 is given' do283it 'returns true' do284expect(subject.send(:is_md5_format?,input_data)).to be_truthy285end286end287288context 'when a non-MD5 value is given' do289it 'returns false' do290expect(subject.send(:is_md5_format?, bad_input_data)).to be_falsey291end292end293end294295end296297298describe Md5LookupUtility::OptsConsole do299let(:valid_argv) { "-i #{input_file} -d all -o #{output_file}".split }300301let(:invalid_argv) { "".split }302303subject do304Md5LookupUtility::OptsConsole305end306307describe '.parse' do308context 'when valid arguments are passed' do309let(:opts) { subject.parse(valid_argv) }310311before(:example) do312allow(File).to receive(:exist?).and_return(true)313end314315it 'returns the input file path' do316expect(opts[:input]).to eq(input_file)317end318319it 'returns the output file path' do320expect(opts[:outfile]).to eq(output_file)321end322323it 'returns the databases in an array' do324expect(opts[:databases]).to be_a(Array)325expect(opts[:databases]).to include(db_source)326end327end328329context 'when the required input file is not set' do330before(:example) do331allow(File).to receive(:exist?).and_return(false)332end333334it 'raises an OptionParser::MissingArgument error' do335expect{subject.parse(invalid_argv)}.to raise_error(OptionParser::MissingArgument)336end337end338339end340341342describe '.extract_db_names' do343let(:list) {'i337,invalid'}344context 'when database symbols \'i337\' and \'invalid\' are given' do345it 'returns i337.net in an array' do346db_names = subject.extract_db_names(list)347expect(db_names).to be_a(Array)348expect(db_names).to include(db_source)349end350end351end352353describe '.get_database_symbols' do354it 'returns an array' do355expect(subject.get_database_symbols).to be_a(Array)356end357end358359describe '.get_database_names' do360it 'returns an array' do361expect(subject.get_database_names).to be_a(Array)362end363end364end365366end367368369