Skip to content

Commit

Permalink
Added the --cookie and --cookie-param options to ronin http (cl…
Browse files Browse the repository at this point in the history
…oses #168).
  • Loading branch information
postmodern committed Nov 3, 2023
1 parent 370f2c8 commit 1adc8a6
Show file tree
Hide file tree
Showing 3 changed files with 140 additions and 0 deletions.
39 changes: 39 additions & 0 deletions lib/ronin/cli/commands/http.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
require 'ronin/cli/printing/http'
require 'ronin/cli/http_shell'
require 'ronin/support/network/http'
require 'ronin/support/network/http/cookie'

require 'command_kit/options/verbose'
require 'addressable/uri'
Expand Down Expand Up @@ -60,6 +61,8 @@ module Commands
# -u chrome-linux|chrome-macos|chrome-windows|chrome-iphone|chrome-ipad|chrome-android|firefox-linux|firefox-macos|firefox-windows|firefox-iphone|firefox-ipad|firefox-android|safari-macos|safari-iphone|safari-ipad|edge,
# --user-agent The User-Agent to use
# -H, --header "NAME: VALUE" Adds a header to the request
# -C, --cookie COOKIE Sets the Cookie header
# -c, --cookie-param NAME=VALUE Sets an additional cookie param
# -B, --body STRING The request body
# -F, --body-file FILE Sends the file as the request body
# -f, --form-data NAME=VALUE Adds a value to the form data
Expand Down Expand Up @@ -199,6 +202,35 @@ class Http < ValueProcessorCommand
@headers[name] = value
end

option :cookie, short: '-C',
value: {
type: String,
usage: 'COOKIE'
},
desc: 'Sets the Cookie header' do |cookie|
cookie = Support::Network::HTTP::Cookie.parse(cookie)

if @cookie
@cookie.merge!(cookie)
else
@cookie = cookie
end
end

option :cookie_param, short: '-c',
value: {
type: /[^\s=]+=\w+/,
usage: 'NAME=VALUE'
},
desc: 'Sets an additional cookie param' do |param|
name, value = param.split('=',2)

# lazy initialize the cookie
@cookie ||= Support::Network::HTTP::Cookie.new

@cookie[name] = value
end

option :body, short: '-B',
value: {
type: String,
Expand Down Expand Up @@ -262,6 +294,11 @@ class Http < ValueProcessorCommand
# @return [Hash{String => String}]
attr_reader :headers

# The optional `Cookie` header to send.
#
# @return [Ronin::Support::Network::HTTP::Cookie, nil]
attr_reader :cookie

# Optional `User-agent` string to use.
#
# @return [String, nil]
Expand Down Expand Up @@ -294,6 +331,7 @@ def initialize(**kwargs)
@proxy = nil
@http_method = :get
@headers = {}
@cookie = nil
@user_agent = nil
@query_params = {}
@form_data = {}
Expand Down Expand Up @@ -347,6 +385,7 @@ def process_value(url)
begin
Support::Network::HTTP.request(
@http_method, uri, proxy: @proxy,
cookie: @cookie,
user_agent: @user_agent,
query_params: @query_params,
headers: @headers,
Expand Down
6 changes: 6 additions & 0 deletions man/ronin-http.1.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,12 @@ Send HTTP requests or spawn an interactive HTTP shell.
`-H`, `--header` "*NAME*: *VALUE*"
Adds a header to the request.

`-C`, `--cookie` *COOKIE*
Sets the raw `Cookie` header.

`-c`, `--cookie-param` *NAME*`=`*VALUE*
Sets an additional `Cookie` param using the given *NAME* and *VALUE*.

`-B`, `--body` *STRING*
The request body.

Expand Down
95 changes: 95 additions & 0 deletions spec/cli/commands/http_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@
expect(subject.user_agent).to be(nil)
end

it "must default #cookie to nil" do
expect(subject.cookie).to be(nil)
end

it "must default #query_params to an empty Hash" do
expect(subject.query_params).to eq({})
end
Expand All @@ -38,6 +42,96 @@
subject { described_class.new(stdout: stdout) }

describe "#option_parser" do
context "when the '--cookie \"...\"' option is parsed" do
let(:cookie_name1) { 'a' }
let(:cookie_value1) { '1' }
let(:cookie_name2) { 'b' }
let(:cookie_value2) { '2' }
let(:cookie) do
"#{cookie_name1}=#{cookie_value1}; #{cookie_name2}=#{cookie_value2}"
end

let(:argv) { ['--cookie', cookie] }

before { subject.option_parser.parse(argv) }

it "must set #cookie to the parsed Ronin::Support::Network::HTTP::Cookie" do
expect(subject.cookie).to be_kind_of(Ronin::Support::Network::HTTP::Cookie)
expect(subject.cookie.to_h).to eq(
{
cookie_name1 => cookie_value1,
cookie_name2 => cookie_value2
}
)
end

context "when #cookie is already set" do
let(:cookie_name3) { 'c' }
let(:cookie_value3) { '3' }
let(:cookie_name4) { 'a' }
let(:cookie_value4) { 'x' }
let(:cookie2) do
"#{cookie_name3}=#{cookie_value3}; #{cookie_name4}=#{cookie_value4}"
end

let(:argv) { ['--cookie', cookie, '--cookie', cookie2] }

it "must merged the parsed cookie params into #cookie" do
expect(subject.cookie).to be_kind_of(Ronin::Support::Network::HTTP::Cookie)
expect(subject.cookie.to_h).to eq(
{
cookie_name2 => cookie_value2,
cookie_name3 => cookie_value3,
cookie_name4 => cookie_value4
}
)
end
end
end

context "when the '--cookie-param name=value' option is parsed" do
let(:cookie_name) { 'a' }
let(:cookie_value) { '1' }

let(:argv) { ['--cookie-param', "#{cookie_name}=#{cookie_value}"] }

before { subject.option_parser.parse(argv) }

it "must set #cookie to a Ronin::Support::Network::HTTP::Cookie containing the parsed name and param" do
expect(subject.cookie).to be_kind_of(Ronin::Support::Network::HTTP::Cookie)
expect(subject.cookie.to_h).to eq(
{
cookie_name => cookie_value
}
)
end

context "when #cookie is already set" do
let(:cookie_name2) { 'b' }
let(:cookie_value2) { '2' }
let(:cookie_name3) { 'a' }
let(:cookie_value3) { 'x' }

let(:argv) do
[
'--cookie-param', "#{cookie_name}=#{cookie_value}",
'--cookie-param', "#{cookie_name2}=#{cookie_value2}",
'--cookie-param', "#{cookie_name3}=#{cookie_value3}"
]
end

it "must merged the parsed cookie params into #cookie" do
expect(subject.cookie).to be_kind_of(Ronin::Support::Network::HTTP::Cookie)
expect(subject.cookie.to_h).to eq(
{
cookie_name2 => cookie_value2,
cookie_name3 => cookie_value3
}
)
end
end
end

context "when --shell is given a non-http URL" do
it do
expect {
Expand Down Expand Up @@ -123,6 +217,7 @@
expect(Ronin::Support::Network::HTTP).to receive(:request).with(
subject.http_method, uri, proxy: subject.proxy,
user_agent: subject.user_agent,
cookie: subject.cookie,
query_params: subject.query_params,
headers: subject.headers,
body: subject.body,
Expand Down

0 comments on commit 1adc8a6

Please sign in to comment.