Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ vulnerable and configurable in its vulnerability.

Route | Required parameters | Optional Parameters
--- | --- | ---
`/timing/conditional_hashing` | `login` | `delta`
`/timing/conditional_hashing` | `email` | `delta`
`/timing/string_comparison` | `password` | `delta`
`/timing/login` | `login`, `password` | `delta`
`/timing/login` | `email`, `password` | `delta`
`/timing/basic_auth` | `password` | `delta`
`/injections/sql/raw_sql` | `name` |
`/injections/sql/raw_where` | `name` |
Expand All @@ -27,7 +27,7 @@ Edit `.env` to contain appropriate values, then
## Timing Vulnerabilities
### Conditional Hashing

The `login` parameter is the email address to test for inclusion in the
The `email` parameter is the email address to test for inclusion in the
"database," and is required.

The `delta` URL parameter can be provided to tell the application the timing
Expand All @@ -48,7 +48,7 @@ comparison (that is, no additional delay is introduced).

### Login

`login` and `password` parameters are required.
`email` and `password` parameters are required.

This endpoint simply combines conditional hashing and insecure string comparison
for a full vulnerable login experience. A provided `delta` parameter will be
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ def index
end

def interpolation
render plain: injection_command.execute
render html: injection_command.execute
end

private
Expand Down
18 changes: 12 additions & 6 deletions app/controllers/timing_vulnerabilities_controller.rb
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
class TimingVulnerabilitiesController < ApplicationController
def login
user_result = user_finder.execute
comparator_result = string_comparator.execute
determine_access(user_result && comparator_result)
user_result = ConditionalHashing.new(timing_params[:email],
delta: timing_params[:delta]
).execute
actual_password = Camel.where(email: timing_params[:email]).pluck(:password).first
comparator_result = InsecureStringComparison.new(timing_params[:password],
against: actual_password
).execute
determine_access(user_result && comparator_result, set: timing_params[:email])
end

def conditional_hashing
Expand Down Expand Up @@ -30,7 +35,7 @@ def index
private

def user_finder
@user_finder ||= ConditionalHashing.new(timing_params[:login],
@user_finder ||= ConditionalHashing.new(timing_params[:email],
delta: timing_params[:delta])
end

Expand All @@ -40,11 +45,12 @@ def string_comparator
end

def timing_params
params.permit(:login, :password, :delta)
params.permit(:email, :password, :delta)
end

def determine_access(bool)
def determine_access(bool, set: nil)
if bool
session[:email] = set if set
render plain: "Authorized", status: :ok
else
render plain: "Unauthorized", status: :unauthorized
Expand Down
5 changes: 5 additions & 0 deletions app/models/camel.rb
Original file line number Diff line number Diff line change
@@ -1,2 +1,7 @@
class Camel < ApplicationRecord
validates :name, presence: true
validates :breed, presence: true
validates :email, presence: true
validates_uniqueness_of :email
validates :password, presence: true
end
7 changes: 1 addition & 6 deletions app/services/conditional_hashing.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ def initialize(login, delta: max_delta)

# Return value is whether @login is valid
def execute
found = valid_logins.include?(login)
found = Camel.where(email: login).present?
sleep(delta) if found
found
end
Expand All @@ -22,13 +22,8 @@ def hint
attr_reader :login, :delta

MAX_DELTA = 0.10
LOGINS = %w(charles@poodles.com camel@sahara.com bactrian@dev.null dromedary@dev.null).freeze

def max_delta
MAX_DELTA
end

def valid_logins
LOGINS
end
end
9 changes: 3 additions & 6 deletions app/services/insecure_string_comparison.rb
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
# Performs insecure string comparison, wherein the first non-matching byte
# causes an early return.
class InsecureStringComparison
def initialize(candidate, delta: max_delta)
def initialize(candidate, delta: max_delta, against: BITSTREAM)
@delta = [max_delta, delta.to_f].min
@candidate = candidate.to_s.bytes
@bitstream = against.to_s
end

def execute
Expand Down Expand Up @@ -39,12 +40,8 @@ def hint

MAX_DELTA = 0.05

def bitstream
BITSTREAM
end

def max_delta
MAX_DELTA
end
attr_reader :candidate, :delta
attr_reader :candidate, :delta, :bitstream
end
4 changes: 3 additions & 1 deletion app/services/template_injection.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,14 @@ def hint
end

def execute
erb.result
erb.result.html_safe
end

private

def interpolate(string)
<<-EOF.strip_heredoc
<html><body><pre>
+--------------------------------------+
| Hello, #{string} |
+--------------------------------------+
Expand All @@ -24,6 +25,7 @@ def interpolate(string)
`-,,, ,_ ;'~U'
_,-' ,'`-__; '--.
(_/'~~ ''''(;
</pre></body></html>
EOF
end

Expand Down
6 changes: 5 additions & 1 deletion config/application.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@

module Camelflage
class Application < Rails::Application
# config.api_only = true
config.action_dispatch.default_headers = {
'X-Frame-Options' => 'SAMEORIGIN',
'X-XSS-Protection' => '0',
'X-Content-Type-Options' => 'nosniff'
}
end
end
2 changes: 2 additions & 0 deletions config/routes.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
Rails.application.routes.draw do
post :login, to: 'timing_vulnerabilities#login'

resource :timing, controller: 'timing_vulnerabilities', only: [] do
get :index
match :login, via: %i(post get)
Expand Down
7 changes: 7 additions & 0 deletions db/migrate/20170512021209_add_login_fields_to_camels.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
class AddLoginFieldsToCamels < ActiveRecord::Migration[5.0]
def change
add_column :camels, :email, :string, unique: true
add_column :camels, :password, :string
add_column :camels, :is_admin, :boolean, default: false
end
end
16 changes: 11 additions & 5 deletions db/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,20 @@
#
# It's strongly recommended that you check this file into your version control system.

ActiveRecord::Schema.define(version: 20161224052218) do
ActiveRecord::Schema.define(version: 20170512021209) do

# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"

create_table "camels", force: :cascade do |t|
t.string "name", null: false
t.string "breed", null: false
t.string "name", null: false
t.string "breed", null: false
t.string "notes"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "email"
t.string "password"
t.boolean "is_admin", default: false
end

end
27 changes: 24 additions & 3 deletions db/seeds.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,24 @@
Camel.create!(name: "Perl", breed: "dromedary", notes: "Enjoys regex")
Camel.create!(name: "Joe", breed: "dromedary", notes: "Particularly cool")
Camel.create!(name: "Alphons", breed: "bactrian", notes: "Has pretty eyes")
Camel.create!(name: "Perl",
breed: "dromedary",
notes: "Enjoys regex",
email: "perl@perl.org",
password: "3usq7#bJCn4E",
is_admin: true)
Camel.create!(name: "Joe",
breed: "dromedary",
notes: "Particularly cool",
email: "joe@camel.com",
password: "love",
is_admin: false)
Camel.create!(name: "Alphons",
breed: "bactrian",
notes: "Has pretty eyes",
email: "alphons@perl.net",
password: "zKQ4xFZn!7g%",
is_admin: false)
Camel.create!(name: "Charles",
breed: "ACTUALLY A POODLE",
notes: "How did a dog get in the camels table computers are hard",
email: "charles@poodleparade.com",
password: "i<3p0rkC#opz",
is_admin: false)
8 changes: 4 additions & 4 deletions public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ <h1>Camelflage</h1>
</tr>
<tr>
<td><code>/timing/conditional_hashing</code></td>
<td><code>login</code></td>
<td><code>email</code></td>
<td><code>delta</code></td>
</tr>
<tr>
Expand All @@ -22,7 +22,7 @@ <h1>Camelflage</h1>
</tr>
<tr>
<td><code>/timing/login</code></td>
<td><code>login</code>, <code>password</code></td>
<td><code>email</code>, <code>password</code></td>
<td><code>delta</code></td>
</tr>
<tr>
Expand Down Expand Up @@ -56,7 +56,7 @@ <h2>Timing Vulnerabilities</h2>

<h3>Conditional Hashing</h3>

<p>The <code>login</code> parameter is the email address to test for inclusion in the
<p>The <code>email</code> parameter is the email address to test for inclusion in the
&quot;database,&quot; and is required.</p>

<p>The <code>delta</code> URL parameter can be provided to tell the application the timing
Expand All @@ -77,7 +77,7 @@ <h3>Insecure string comparison</h3>

<h3>Login</h3>

<p><code>login</code> and <code>password</code> parameters are required.</p>
<p><code>email</code> and <code>password</code> parameters are required.</p>

<p>This endpoint simply combines conditional hashing and insecure string comparison
for a full vulnerable login experience. A provided <code>delta</code> parameter will be
Expand Down