Skip to content

Commit

Permalink
Add a support for a custom user agent.
Browse files Browse the repository at this point in the history
  • Loading branch information
Yana Nesterenko authored and PatrickTulskie committed Jan 29, 2023
1 parent 8ff17e5 commit e2ed151
Show file tree
Hide file tree
Showing 6 changed files with 60 additions and 13 deletions.
4 changes: 4 additions & 0 deletions bin/concuss
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ OptionParser.new do |opts|
opts.on("-t", "--test-string STRING", "Set a custom test string. If none specified, it sets a random string to match on.") do |v|
options[:test_string] = v
end

opts.on("-a", "--user-agent STRING", "Set a custom user agent. If none specified, it defaults to Concuss/#{Concuss::VERSION}") do |v|
options[:user_agent] = v
end
end.parse!

if ARGV[0].nil?
Expand Down
7 changes: 4 additions & 3 deletions lib/concuss.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,20 @@
class Concuss
class Error < StandardError; end

attr_reader :url, :file, :header_set, :headers, :test_string
attr_reader :url, :file, :header_set, :headers, :test_string, :user_agent

def initialize(url:, file: nil, header_set: :all, test_string: nil)
def initialize(url:, file: nil, header_set: :all, test_string: nil, user_agent: nil)
@url = url
@file = file
@header_set = file.nil? ? header_set : :file
@test_string = test_string
@user_agent = user_agent

@headers = Concuss::Headers.new(header_set: @header_set, file: @file).group
end

def attack!
runner = Concuss::Runner.new(headers: headers, url: url, test_string: test_string)
runner = Concuss::Runner.new(headers: headers, url: url, test_string: test_string, user_agent: user_agent)

runner.run
end
Expand Down
1 change: 0 additions & 1 deletion lib/concuss/headers.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ class Concuss::Headers
'Range',
'Referer',
'TE',
'User-Agent',
'Upgrade',
'Via',
'Warning'
Expand Down
12 changes: 9 additions & 3 deletions lib/concuss/runner.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,26 @@
require 'net/http'

class Concuss::Runner
attr_reader :headers, :url, :test_string
DEFAULT_USER_AGENT = "Concuss/#{Concuss::VERSION}"

attr_reader :headers, :url, :test_string, :user_agent

def initialize(headers:, url:, test_string: nil)
def initialize(headers:, url:, test_string: nil, user_agent: nil)
@headers = headers
@url = url
@test_string = test_string || SecureRandom.hex(25)
@user_agent = user_agent || DEFAULT_USER_AGENT
end

def run
uri = URI(@url)

@headers.each do |header|
response = Net::HTTP.get_response(uri,
{ header => test_string }
{
header => test_string,
'User-Agent' => user_agent
}
)

if response.code == "200" && response.body.include?(@test_string)
Expand Down
34 changes: 31 additions & 3 deletions spec/concuss/runner_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
let(:headers) { ['X-Test-Header1', 'X-Test-Header2'] }
let(:url) { 'http://test.com' }
let(:test_string) { 'teststring' }
let(:runner) { Concuss::Runner.new(headers: headers, url: url, test_string: test_string) }
let(:runner) { Concuss::Runner.new(headers: headers, url: url, test_string: test_string, user_agent: user_agent) }
let(:user_agent) { 'Mozilla/5.0' }

describe '#initialize' do
it 'sets the headers' do
Expand All @@ -18,23 +19,50 @@
it 'sets the test string' do
expect(runner.test_string).to eq(test_string)
end

it 'sets the user_agent' do
expect(runner.user_agent).to eq(user_agent)
end
end

describe '#run' do
let(:mock_response) { double(code: '200', body: test_string) }

before(:each) do
# mock the request to return a 200 status code
allow(Net::HTTP).to receive(:get_response).and_return(double(code: '200', body: test_string))
allow(Net::HTTP).to receive(:get_response).and_return(mock_response)
end

it 'sends a request for each of the headers' do
allow(Net::HTTP).to receive(:get_response).and_return(double(code: '200', body: test_string)).twice
allow(Net::HTTP).to receive(:get_response).and_return(mock_response).twice
runner.run
end

it 'outputs the header, status code, and result' do
expect { runner.run }.to output("X-Test-Header1 - 200 - HIT\nX-Test-Header2 - 200 - HIT\n").to_stdout
end

it 'uses the custom user_agent' do
expect(Net::HTTP).to receive(:get_response).with(URI(url),
{
'User-Agent' => user_agent,
headers.first => test_string
}
)
runner.run
end

it 'uses the DEFAULT_USER_AGENT' do
runner = Concuss::Runner.new(headers: headers, url: url, test_string: test_string)
expect(Net::HTTP).to receive(:get_response).with(URI(url),
{
'User-Agent' => Concuss::Runner::DEFAULT_USER_AGENT,
headers.first => test_string
}
)
runner.run
end

context 'when the response body does not include the test string' do
before(:each) do
# mock the request to return a 200 status code and body without the test string
Expand Down
15 changes: 12 additions & 3 deletions spec/concuss_spec.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# frozen_string_literal: true

RSpec.describe Concuss do
let(:user_agent) { 'Mozilla/5.0' }

it "has a version number" do
expect(Concuss::VERSION).not_to be nil
end
Expand All @@ -18,14 +20,16 @@
concuss = Concuss.new(
url: 'https://example.com',
file: file_path,
test_string: 'example'
test_string: 'example',
user_agent: user_agent
)

expect(concuss.url).to eq('https://example.com')
expect(concuss.file).to eq(file_path)
expect(concuss.header_set).to eq(:file)
expect(concuss.test_string).to eq('example')
expect(concuss.headers).to eq(fake_headers)
expect(concuss.user_agent).to eq(user_agent)
end

it 'sets a default header_set if none are passed in' do
Expand All @@ -41,10 +45,15 @@

describe '#attack!' do
it 'creates a new instance of Concuss::Runner' do
concuss = Concuss.new(url: 'https://example.com')
concuss = Concuss.new(url: 'https://example.com', user_agent: user_agent)
runner = double('runner')
expect(runner).to receive(:run)
expect(Concuss::Runner).to receive(:new).with(url: 'https://example.com', headers: Concuss::Headers.new(header_set: :all).group, test_string: nil).and_return(runner)
expect(Concuss::Runner).to receive(:new).with(
url: 'https://example.com',
user_agent: user_agent,
headers: Concuss::Headers.new(header_set: :all).group,
test_string: nil
).and_return(runner)
concuss.attack!
end
end
Expand Down

0 comments on commit e2ed151

Please sign in to comment.