Commit 9ec7e01d authored by Tasos Laskos's avatar Tasos Laskos
Browse files

Merge branch 'release/v1.0.6'

parents c038080f 43a7948b
Showing with 162 additions and 44 deletions
+162 -44
# ChangeLog
## 1.0.6 _(December 07, 2014)_
- `arachni_rpcd` -- Fixed bug causing the `--nickname` option to not be understood.
- `UI::Output` -- Flush output stream after each message.
- `Platform::Manager`
- Removed 'coldfusion`.
- Added `sql` and `nosql` parents for DBs.
- `Check::Auditor#skip?` -- Ignore mutations when checking for redundancies.
- `Browser` -- Fixed issue causing `select` inputs in forms to not be set.
- `Element::Cookie.encode` -- Added '&' to the list of reserved characters.
- `Issue`
- `#recheck` -- Rechecks the existence of the issue.
- `Element::Capabilities`
- `WithNode`
- `#html=` -- Recode string before storing.
- `WithDOM`
- `#dom` -- Return `nil` on `Inputtable::Error`.
- `Auditable` -- Updated response analysis messages to include vector type,
name and action URL.
- `Framework` -- Split into `Parts`:
- `Audit`
- If `Options.platforms` are given, checks which don't support them are
completely skipped.
- `Browser`
- `Check`
- `Data`
- `#pop_page_from_url_queue` -- Fixed issue causing multiple-choice
redirections to cause an error.
- `Platform`
- `Plugin`
- `Report`
- `Scope`
- `State`
- `State::Framework`
- Added `#done?`
- `#abort` -- Fixed exception message.
- Checks
- Active
- `sql_injection` -- Slight payload update to catch double-quote cases.
- `code_injection` -- Slight PHP payload update, to ensure it works in more cases.
- `code_injection_timing` -- Updated payloads to mirror `code_injection`.
- `os_command_injection` -- Updated payloads to handle chained commands.
- `os_command_injection_timing` -- Updated payloads to handle chained commands.
- `path_traversal` -- Fixed MS Windows output pattern.
- `sql_injection_differential` -- Set platform to generic `sql`.
- `no_sql_injection_differential` -- Set platform to generic `nosql`.
- `unvalidated_redirect` -- Disable `follow_location`.
- Passive
- `common_files` -- Added `.svn/all-wcprops`.
## 1.0.5 _(November 14, 2014)_
- Executables
......
**NOTICE**:
* Arachni's license has changed, please see the _LICENSE_ file before working
with the project.
* v1.0 is not backwards compatible with v0.4.
<hr/>
# Arachni - Web Application Security Scanner Framework
<table>
<tr>
<th>Version</th>
<td>1.0.5</td>
<td>1.0.6</td>
</tr>
<tr>
<th>Homepage</th>
......@@ -348,7 +356,6 @@ Active checks engage the web application via its inputs.
- SQL injection (`sql_injection`) -- Error based detection.
- Oracle
- ColdFusion
- InterBase
- PostgreSQL
- MySQL
......
......@@ -12,7 +12,7 @@
#
# @author Tasos "Zapotek" Laskos <tasos.laskos@arachni-scanner.com>
#
# @version 0.2
# @version 0.2.1
#
# @see http://cwe.mitre.org/data/definitions/94.html
# @see http://php.net/manual/en/function.eval.php
......@@ -23,11 +23,11 @@
class Arachni::Checks::CodeInjection < Arachni::Check::Base
def self.rand1
@rand1 ||= '287630581954'
@rand1 ||= '28763'
end
def self.rand2
@rand2 ||= '4196403186331128'
@rand2 ||= '4196403'
end
def self.options
......@@ -41,7 +41,7 @@ class Arachni::Checks::CodeInjection < Arachni::Check::Base
def self.code_strings
# code strings to be injected to the webapp
@code_strings ||= {
php: "echo #{rand1}+#{rand2};",
php: "print #{rand1}+#{rand2};",
perl: "print #{rand1}+#{rand2};",
python: "print #{rand1}+#{rand2}",
asp: "Response.Write\x28#{rand1}+#{rand2}\x29"
......@@ -72,7 +72,7 @@ Injects code snippets and assess whether or not execution was successful.
elements: [ Element::Form, Element::Link, Element::Cookie,
Element::Header, Element::LinkTemplate ],
author: 'Tasos "Zapotek" Laskos <tasos.laskos@arachni-scanner.com>',
version: '0.2',
version: '0.2.1',
platforms: payloads.keys,
issue: {
......
......@@ -14,7 +14,7 @@
#
# @author Tasos "Zapotek" Laskos <tasos.laskos@arachni-scanner.com>
#
# @version 0.3
# @version 0.3.1
#
# @see http://cwe.mitre.org/data/definitions/94.html
# @see http://php.net/manual/en/function.eval.php
......@@ -35,7 +35,7 @@ class Arachni::Checks::CodeInjectionTiming < Arachni::Check::Base
jsp: 'Thread.sleep(__TIME__);',
asp: 'Thread.Sleep(__TIME__);',
}.inject({}) do |h, (platform, payload)|
h[platform] = [ ' ', ' && ', ';' ].map { |sep| "#{sep} #{payload}" }
h[platform] = [ ' %s', ';%s', "\";%s#", "';%s#" ].map { |s| s % payload }
h
end
end
......@@ -54,7 +54,7 @@ a time delay.
elements: [ Element::Form, Element::Link, Element::Cookie,
Element::Header, Element::LinkTemplate ],
author: 'Tasos "Zapotek" Laskos <tasos.laskos@arachni-scanner.com>',
version: '0.3',
version: '0.3.1',
platforms: payloads.keys,
issue: {
......
......@@ -7,7 +7,7 @@
=end
# @author Tasos "Zapotek" Laskos <tasos.laskos@arachni-scanner.com>
# @version 0.1
# @version 0.1.1
class Arachni::Checks::NoSqlInjectionDifferential < Arachni::Check::Base
def self.options
......@@ -40,7 +40,8 @@ that of a vulnerable application.
},
elements: [ Element::Link, Element::Form, Element::Cookie ],
author: 'Tasos "Zapotek" Laskos <tasos.laskos@arachni-scanner.com>',
version: '0.1',
version: '0.1.1',
platforms: [ :nosql ],
issue: {
name: %q{Blind NoSQL Injection (differential analysis)},
......
......@@ -10,7 +10,7 @@
#
# @author Tasos "Zapotek" Laskos <tasos.laskos@arachni-scanner.com>
#
# @version 0.2.1
# @version 0.2.2
#
# @see http://cwe.mitre.org/data/definitions/78.html
# @see http://www.owasp.org/index.php/OS_Command_Injection
......@@ -23,8 +23,8 @@ class Arachni::Checks::OsCmdInjection < Arachni::Check::Base
/(root|mail):.+:\d+:\d+:.+:[0-9a-zA-Z\/]+/im
],
windows: [
/\[boot loader\](.*)\[operating systems\]/im,
/\[fonts\](.*)\[extensions\]/im
/\[boot loader\].*\[operating systems\]/im,
/\[fonts\].*\[extensions\]/im
]
},
format: [ Format::STRAIGHT, Format::APPEND ]
......@@ -49,7 +49,13 @@ class Arachni::Checks::OsCmdInjection < Arachni::Check::Base
}.inject({}) do |h, (platform, payloads)|
h[platform] ||= []
payloads.each do |payload|
h[platform] |= [ '', '&&', '|', ';' ].map { |sep| "#{sep} #{payload}" }
h[platform] << "#{payload}"
['', '\'', '"'].each do |q|
h[platform] |= [ '&&', '|', ';' ].
map { |sep| "#{q} #{sep} #{payload} #{sep} #{q}" }
end
h[platform] << "` #{payload}`"
end
h
......@@ -69,7 +75,7 @@ Tries to find Operating System command injections.
elements: [ Element::Form, Element::Link, Element::Cookie,
Element::Header, Element::LinkTemplate ],
author: 'Tasos "Zapotek" Laskos <tasos.laskos@arachni-scanner.com> ',
version: '0.2.1',
version: '0.2.2',
platforms: payloads.keys,
issue: {
......
......@@ -10,7 +10,7 @@
#
# @author Tasos "Zapotek" Laskos <tasos.laskos@arachni-scanner.com>
#
# @version 0.3
# @version 0.3.1
#
# @see http://cwe.mitre.org/data/definitions/78.html
# @see http://www.owasp.org/index.php/OS_Command_Injection
......@@ -23,8 +23,15 @@ class Arachni::Checks::OsCmdInjectionTiming < Arachni::Check::Base
unix: 'sleep __TIME__',
windows: 'ping -n __TIME__ localhost'
}.inject({}) do |h, (platform, payload)|
h[platform] = [ '', '&', '&&', '|', ';' ].map { |sep| "#{sep} #{payload}" }
h[platform] << "`#{payload}`"
h[platform] ||= []
h[platform] << "#{payload}"
['', '\'', '"'].each do |q|
h[platform] |= [ '&', '&&', '|', ';' ].
map { |sep| "#{q} #{sep} #{payload} #{sep} #{q}" }
end
h[platform] << "` #{payload}`"
h
end
end
......@@ -46,7 +53,7 @@ Tries to find operating system command injections using timing attacks.
elements: [ Element::Form, Element::Link, Element::Cookie,
Element::Header, Element::LinkTemplate ],
author: 'Tasos "Zapotek" Laskos <tasos.laskos@arachni-scanner.com> ',
version: '0.3',
version: '0.3.1',
platforms: payloads.keys,
issue: {
......
......@@ -28,8 +28,8 @@ class Arachni::Checks::PathTraversal < Arachni::Check::Base
/(root|mail):.+:\d+:\d+:.+:[0-9a-zA-Z\/]+/im
],
windows: [
/\[boot loader\](.*)\[operating systems\]/im,
/\[fonts\](.*)\[extensions\]/im
/\[boot loader\].*\[operating systems\]/im,
/\[fonts\].*\[extensions\]/im
],
tomcat: [
/<web\-app/im
......
......@@ -40,7 +40,7 @@ class Arachni::Checks::SqlInjection < Arachni::Check::Base
# Prepares the payloads that will hopefully cause the webapp to output SQL
# error messages if included as part of an SQL query.
def self.payloads
@payloads ||= [ '\'`--', ')' ]
@payloads ||= [ '"\'`--', ')' ]
end
def self.options
......
\[Macromedia\]\[SQLServer JDBC Driver\]
System\.Data\.OleDb\.OleDbException
\[Microsoft\]\[ODBC SQL Server Driver\]
\[Macromedia\]\[SQLServer JDBC Driver\]
\[SqlException
System\.Data\.SqlClient\.SqlException
Unclosed quotation mark after the character string
......
......@@ -14,7 +14,7 @@
#
# @author Tasos "Zapotek" Laskos <tasos.laskos@arachni-scanner.com>
#
# @version 0.4.2
# @version 0.4.3
#
# @see http://cwe.mitre.org/data/definitions/89.html
# @see http://capec.mitre.org/data/definitions/7.html
......@@ -59,7 +59,8 @@ that of a vulnerable application.
},
elements: [ Element::Link, Element::Form, Element::Cookie ],
author: 'Tasos "Zapotek" Laskos <tasos.laskos@arachni-scanner.com>',
version: '0.4.2',
version: '0.4.3',
platforms: [ :sql ],
issue: {
name: %q{Blind SQL Injection (differential analysis)},
......
......@@ -12,7 +12,7 @@
# header field to determine whether the attack was successful.
#
# @author Tasos "Zapotek" Laskos <tasos.laskos@arachni-scanner.com>
# @version 0.2
# @version 0.2.1
# @see http://www.owasp.org/index.php/Top_10_2010-A10-Unvalidated_Redirects_and_Forwards
class Arachni::Checks::UnvalidatedRedirect < Arachni::Check::Base
......@@ -32,7 +32,7 @@ class Arachni::Checks::UnvalidatedRedirect < Arachni::Check::Base
end
def run
audit( self.class.payloads ) do |response, element|
audit( self.class.payloads, submit: { follow_location: false } ) do |response, element|
# If this was a sample/default value submission ignore it, we only
# care about our payloads.
next if !payload? element.seed
......@@ -67,7 +67,7 @@ URL to determine whether the attack was successful.
},
elements: [Element::Form, Element::Link, Element::Cookie, Element::Header],
author: 'Tasos "Zapotek" Laskos <tasos.laskos@arachni-scanner.com>',
version: '0.2',
version: '0.2.1',
issue: {
name: %q{Unvalidated redirect},
......
......@@ -508,3 +508,5 @@ YT
ZA
ZM
ZW
intern
extern
......@@ -6,6 +6,7 @@ CVS/Repository
CVS/Root
CVS/Entries
.svn/wc.db
.svn/all-wcprops
.git/HEAD
_mmServerScripts/MMHTTPDB.php
_mmServerScripts/MMHTTPDB.asp
......
......@@ -896,7 +896,7 @@ class Browser
begin
input.set( value.to_s )
# Disabled inputs and such...
# Disabled inputs and such...
rescue Watir::Exception::ObjectDisabledException,
Watir::Exception::ObjectReadOnlyException,
Selenium::WebDriver::Error::InvalidElementStateError => e
......@@ -904,6 +904,22 @@ class Browser
" because: #{e} [#{e.class}"
end
end
form.selects.each do |input|
name_or_id = name_or_id_for( input )
value = inputs ? inputs[name_or_id] : value_for( input )
begin
input.select_value( value.to_s )
# Disabled inputs and such...
rescue Watir::Exception::ObjectDisabledException,
Watir::Exception::ObjectReadOnlyException,
Watir::Exception::NoValueFoundException,
Selenium::WebDriver::Error::InvalidElementStateError => e
print_debug_level_2 "Could not fill in form select '#{name_or_id}'" <<
" because: #{e} [#{e.class}"
end
end
end
def skip_state?( state )
......
......@@ -380,8 +380,11 @@ module Auditor
#
# @see Page#audit?
def skip?( element )
return true if audited?( element.coverage_id ) ||
!page.audit_element?( element )
# This method also gets called from Auditable#audit to check mutations,
# don't touch these, we're filtering at a higher level here, otherwise
# we might mess up the audit.
return true if !element.mutation? && audited?( element.coverage_id )
return true if !page.audit_element?( element )
# Don't audit elements which have been already logged as vulnerable
# either by us or preferred checks.
......
......@@ -138,27 +138,47 @@ class Base < Component::Base
# @return [Bool]
# `true` if the check can benefit from knowing the platform beforehand,
# `false` otherwise.
#
# @see .platforms
def has_platforms?
platforms.any?
end
# @return [Array<Symbol>] Targeted platforms.
# @return [Array<Symbol>]
# Targeted platforms.
#
# @see .info
def platforms
[info[:platforms]].flatten.compact
@platforms ||= [info[:platforms]].flatten.compact
end
# @param [Array<Symbol, String>] platforms
# List of platforms to check for support.
#
# @return [Boolean]
# `true` if any of the given platforms are supported, `false` otherwise.
def supports_platforms?( platforms )
return true if platforms.empty? || !has_platforms?
# Determine if we've got anything for the given platforms, the same
# way payloads are picked.
foo_data = self.platforms.inject({}) { |h, platform| h.merge!( platform => true ) }
Platform::Manager.new( platforms ).pick( foo_data ).any?
end
# @return [Array<Symbol>] Targeted element types.
# @return [Array<Symbol>]
# Targeted element types.
#
# @see .info
def elements
[info[:elements]].flatten.compact
@elements ||= [info[:elements]].flatten.compact
end
# Schedules self to be run *after* the specified checks and prevents
# auditing elements that have been previously logged by any of these checks.
#
# @return [Array] Check names.
# @return [Array]
# Check names.
def prefer( *args )
@preferred = args.flatten.compact
end
......@@ -170,6 +190,11 @@ class Base < Component::Base
def preferred
@preferred ||= []
end
# @private
def clear_info_cache
@elements = @platforms = nil
end
end
end
......
......@@ -188,9 +188,7 @@ module Differential
signatures[:controls][altered_hash].refine!(res.body) :
Support::Signature.new(res.body)
@data_gathering[:received_responses] += 1
finalize_if_done( opts, signatures )
increase_received_responses( opts, signatures )
end
end
end
......@@ -260,8 +258,7 @@ module Differential
signature_sieve( altered_hash, signatures, pair_hash )
@data_gathering[:received_responses] += 1
finalize_if_done( opts, signatures )
increase_received_responses( opts, signatures )
end
end
end
......
......@@ -245,7 +245,9 @@ module Auditable
submit( options ) do |response|
element = response.request.performer
if !element.audit_options[:silent]
print_status "Analyzing response ##{response.request.id}..."
print_status "Analyzing response ##{response.request.id} for " <<
"#{self.type} input '#{affected_input_name}'" <<
" pointing to: '#{audit_status_message_action}'"
end
exception_jail( false ){ block.call( response, element ) }
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment