evil-proxy 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +22 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +114 -0
- data/Rakefile +2 -0
- data/evil-proxy.gemspec +23 -0
- data/lib/evil-proxy.rb +7 -0
- data/lib/evil-proxy/async.rb +19 -0
- data/lib/evil-proxy/httpproxy.rb +83 -0
- data/lib/evil-proxy/httprequest.rb +11 -0
- data/lib/evil-proxy/selenium.rb +19 -0
- data/lib/evil-proxy/store.rb +61 -0
- data/lib/evil-proxy/version.rb +3 -0
- metadata +85 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: f4c501bef2b64e58b8393c8cc73a6516739f8b87
|
4
|
+
data.tar.gz: 9f8c54251a54e7f68cb47b04363ea746ed0956e1
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: dc6113ee6f3043cc8ddd8e70dc4423dc717281c5eb589cbc878531fa2019b280b09d1fbb8c9ae789d7b2c1ce8d93d4ad44f061a7c6ff8b67506838c44dc85b4c
|
7
|
+
data.tar.gz: c598d95d33cdbaf4ec131697f3b95015f39f5a31dda3fe8043522d912d9ed9bbf0a0ad903fa51e251def4f3f7829facaa4af45aa4bc20f5873028408312cc8e1
|
data/.gitignore
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
*.gem
|
2
|
+
*.rbc
|
3
|
+
.bundle
|
4
|
+
.config
|
5
|
+
.yardoc
|
6
|
+
Gemfile.lock
|
7
|
+
InstalledFiles
|
8
|
+
_yardoc
|
9
|
+
coverage
|
10
|
+
doc/
|
11
|
+
lib/bundler/man
|
12
|
+
pkg
|
13
|
+
rdoc
|
14
|
+
spec/reports
|
15
|
+
test/tmp
|
16
|
+
test/version_tmp
|
17
|
+
tmp
|
18
|
+
*.bundle
|
19
|
+
*.so
|
20
|
+
*.o
|
21
|
+
*.a
|
22
|
+
mkmf.log
|
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2015 Theo Li <bbtfrr@gmail.com>
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,114 @@
|
|
1
|
+
# EvilProxy
|
2
|
+
|
3
|
+
A ruby http proxy to do :imp: things.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
gem 'evil-proxy'
|
10
|
+
|
11
|
+
And then execute:
|
12
|
+
|
13
|
+
$ bundle
|
14
|
+
|
15
|
+
Or install it yourself as:
|
16
|
+
|
17
|
+
$ gem install evil-proxy
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
|
21
|
+
#### Basic usage: hooks
|
22
|
+
|
23
|
+
```ruby
|
24
|
+
require 'evil-proxy'
|
25
|
+
|
26
|
+
# EvilProxy::HTTPProxyServer is a subclass of Webrick::HTTPProxyServer;
|
27
|
+
# it takes the same parameters.
|
28
|
+
proxy = EvilProxy::HTTPProxyServer.new Port: 8080
|
29
|
+
|
30
|
+
proxy.before_request do |req|
|
31
|
+
# Do evil things
|
32
|
+
# Note that, different from Webrick::HTTPProxyServer,
|
33
|
+
# `req.body` is writable.
|
34
|
+
end
|
35
|
+
|
36
|
+
proxy.before_response do |req, res|
|
37
|
+
# Here `res.body` is also writable.
|
38
|
+
end
|
39
|
+
|
40
|
+
trap "INT" do proxy.shutdown end
|
41
|
+
trap "TERM" do proxy.shutdown end
|
42
|
+
|
43
|
+
proxy.start
|
44
|
+
```
|
45
|
+
|
46
|
+
Available hooks including `when_initialize`, `when_start`, `when_shutdown`,
|
47
|
+
`before_request`, `before_response`, `(before|after)_(get|head|post|options|connect)`.
|
48
|
+
|
49
|
+
#### Plugin: store
|
50
|
+
|
51
|
+
If you want to save the network traffic, you can use `store` plugin,
|
52
|
+
network traffic will be saved in `store.yml`.
|
53
|
+
```ruby
|
54
|
+
require 'evil-proxy'
|
55
|
+
require 'evil-proxy/store'
|
56
|
+
|
57
|
+
proxy = EvilProxy::HTTPProxyServer.new Port: 8080
|
58
|
+
|
59
|
+
proxy.store_filter do |req, res|
|
60
|
+
# Optional, if you don't set `store_filter`, evil-proxy
|
61
|
+
# will save all the network traffic.
|
62
|
+
res.unparsed_uri =~ /www.google.com/
|
63
|
+
end
|
64
|
+
|
65
|
+
...
|
66
|
+
```
|
67
|
+
|
68
|
+
#### Plugin: async
|
69
|
+
Start the proxy server asnychronously, which means start server in a background thread;
|
70
|
+
with it, you can check the `store` when runing the proxy server.
|
71
|
+
```ruby
|
72
|
+
require 'evil-proxy'
|
73
|
+
require 'evil-proxy/async'
|
74
|
+
require 'evil-proxy/store'
|
75
|
+
require 'yaml'
|
76
|
+
|
77
|
+
proxy = EvilProxy::HTTPProxyServer.new Port: 8080
|
78
|
+
|
79
|
+
proxy.start
|
80
|
+
|
81
|
+
loop do
|
82
|
+
# Do something with `proxy.store`
|
83
|
+
puts proxy.store.to_yaml
|
84
|
+
proxy.clean_store # if needed
|
85
|
+
sleep 10
|
86
|
+
end
|
87
|
+
|
88
|
+
...
|
89
|
+
```
|
90
|
+
|
91
|
+
#### Plugin: selenium
|
92
|
+
Use `proxy.selenium_proxy` to create a instance of `Selenium::WebDriver::Proxy`.
|
93
|
+
|
94
|
+
```ruby
|
95
|
+
require 'evil-proxy'
|
96
|
+
require 'evil-proxy/selenium'
|
97
|
+
require 'selenium/webdriver'
|
98
|
+
|
99
|
+
proxy = EvilProxy::HTTPProxyServer.new Port: 8080
|
100
|
+
proxy.start
|
101
|
+
|
102
|
+
driver = Selenium::WebDriver.for :chrome, proxy: proxy.selenium_proxy
|
103
|
+
|
104
|
+
...
|
105
|
+
```
|
106
|
+
|
107
|
+
|
108
|
+
## Contributing
|
109
|
+
|
110
|
+
1. Fork it ( https://github.com/bbtfr/evil-proxy/fork )
|
111
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
112
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
113
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
114
|
+
5. Create a new Pull Request
|
data/Rakefile
ADDED
data/evil-proxy.gemspec
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'evil-proxy/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "evil-proxy"
|
8
|
+
spec.version = EvilProxy::VERSION
|
9
|
+
spec.authors = ["Theo"]
|
10
|
+
spec.email = ["bbtfrr@gmail.com"]
|
11
|
+
spec.summary = %q{A ruby http proxy to do EVIL things.}
|
12
|
+
spec.description = %q{A ruby http proxy to do EVIL things.}
|
13
|
+
spec.homepage = "https://github.com/bbtfr/evil-proxy"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_development_dependency "bundler", "~> 1.6"
|
22
|
+
spec.add_development_dependency "rake"
|
23
|
+
end
|
data/lib/evil-proxy.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
EvilProxy::HTTPProxyServer.class_eval do
|
2
|
+
attr_reader :thread
|
3
|
+
alias_method :original_start, :start
|
4
|
+
alias_method :original_shutdown, :shutdown
|
5
|
+
|
6
|
+
def start
|
7
|
+
@thread = Thread.new do
|
8
|
+
self.original_start
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def shutdown
|
13
|
+
@thread.exit
|
14
|
+
end
|
15
|
+
|
16
|
+
def join
|
17
|
+
@thread.join
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
require 'webrick'
|
2
|
+
require 'webrick/httpproxy'
|
3
|
+
|
4
|
+
class EvilProxy::HTTPProxyServer < WEBrick::HTTPProxyServer
|
5
|
+
VALID_CALBACKS = Array.new
|
6
|
+
DEFAULT_CALLBACKS = Hash.new
|
7
|
+
|
8
|
+
def initialize *args
|
9
|
+
initialize_callbacks
|
10
|
+
fire :when_initialize, *args
|
11
|
+
super
|
12
|
+
end
|
13
|
+
|
14
|
+
def start
|
15
|
+
begin
|
16
|
+
fire :when_start
|
17
|
+
super
|
18
|
+
ensure
|
19
|
+
fire :when_shutdown
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def fire key, *args
|
24
|
+
return unless @callbacks[key]
|
25
|
+
@callbacks[key].each do |callback|
|
26
|
+
instance_exec *args, &callback
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def proxy_service req, res
|
31
|
+
fire :before_request, req
|
32
|
+
super
|
33
|
+
fire :before_response, req, res
|
34
|
+
end
|
35
|
+
|
36
|
+
VALID_CALBACKS << :when_initialize
|
37
|
+
VALID_CALBACKS << :when_start
|
38
|
+
VALID_CALBACKS << :when_shutdown
|
39
|
+
VALID_CALBACKS << :before_request
|
40
|
+
VALID_CALBACKS << :before_response
|
41
|
+
|
42
|
+
%w(GET HEAD POST OPTIONS CONNECT).each do |method|
|
43
|
+
do_method = "do_#{method}".to_sym
|
44
|
+
do_method_without_callbacks = "#{do_method}_without_callbacks".to_sym
|
45
|
+
before_method = "before_#{method.downcase}".to_sym
|
46
|
+
after_method = "after_#{method.downcase}".to_sym
|
47
|
+
|
48
|
+
VALID_CALBACKS << before_method
|
49
|
+
VALID_CALBACKS << after_method
|
50
|
+
|
51
|
+
alias_method do_method_without_callbacks, do_method
|
52
|
+
define_method do_method do |req, res|
|
53
|
+
fire before_method, req
|
54
|
+
send do_method_without_callbacks, req, res
|
55
|
+
fire after_method, req, res
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
VALID_CALBACKS.each do |callback|
|
60
|
+
define_method callback do |&block|
|
61
|
+
@callbacks[callback] ||= []
|
62
|
+
@callbacks[callback] << block
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
private
|
67
|
+
def initialize_callbacks
|
68
|
+
@callbacks = Hash.new
|
69
|
+
DEFAULT_CALLBACKS.each do |key, callbacks|
|
70
|
+
@callbacks[key] = callbacks.clone
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
class << self
|
75
|
+
VALID_CALBACKS.each do |callback|
|
76
|
+
define_method callback do |&block|
|
77
|
+
DEFAULT_CALLBACKS[callback] ||= []
|
78
|
+
DEFAULT_CALLBACKS[callback] << block
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'evil-proxy/async'
|
2
|
+
|
3
|
+
EvilProxy::HTTPProxyServer.class_eval do
|
4
|
+
def selenium_proxy *protocols
|
5
|
+
require 'selenium-webdriver' unless defined?(Selenium)
|
6
|
+
|
7
|
+
protocols.push :http if protocols.empty?
|
8
|
+
unless (protocols - [:http, :ssl, :ftp]).empty?
|
9
|
+
raise "Invalid protocol specified. Must be one of: :http, :ssl, or :ftp."
|
10
|
+
end
|
11
|
+
|
12
|
+
host = @config[:BindAddress] || "127.0.0.1"
|
13
|
+
port = @config[:Port]
|
14
|
+
|
15
|
+
proxy_mapping = Hash.new
|
16
|
+
protocols.each do |proto| proxy_mapping[proto] = "#{host}:#{port}" end
|
17
|
+
Selenium::WebDriver::Proxy.new(proxy_mapping)
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
3
|
+
EvilProxy::HTTPProxyServer.class_eval do
|
4
|
+
attr_reader :store
|
5
|
+
|
6
|
+
when_initialize do
|
7
|
+
clean_store
|
8
|
+
end
|
9
|
+
|
10
|
+
when_shutdown do
|
11
|
+
dump_store
|
12
|
+
end
|
13
|
+
|
14
|
+
before_response do |req, res|
|
15
|
+
@store << [ req, res ] if match_store_filter req, res
|
16
|
+
end
|
17
|
+
|
18
|
+
def store_filter &block
|
19
|
+
@store_filter = block
|
20
|
+
end
|
21
|
+
|
22
|
+
def match_store_filter req, res
|
23
|
+
return true unless @store_filter
|
24
|
+
instance_exec req, res, &@store_filter
|
25
|
+
end
|
26
|
+
|
27
|
+
def clean_store
|
28
|
+
@store = []
|
29
|
+
end
|
30
|
+
|
31
|
+
def dump_store filename = "store.yml"
|
32
|
+
previous_store = YAML.load(File.read(filename)) || [] rescue []
|
33
|
+
File.open filename, "w" do |file|
|
34
|
+
file.puts YAML.dump(previous_store + store_as_params)
|
35
|
+
end
|
36
|
+
clean_store
|
37
|
+
end
|
38
|
+
|
39
|
+
def store_as_params
|
40
|
+
@store.map do |req, res|
|
41
|
+
Hash.new.tap do |params|
|
42
|
+
params["request"] = Hash.new.tap do |request|
|
43
|
+
request["method"] = req.request_method
|
44
|
+
request["url"] = req.unparsed_uri
|
45
|
+
request["headers"] = Hash.new.tap do |headers|
|
46
|
+
req.header.each do |key, value|
|
47
|
+
headers[key] = value.join(",")
|
48
|
+
end
|
49
|
+
end
|
50
|
+
request["body"] = req.body if req.body
|
51
|
+
request["time"] = req.request_time
|
52
|
+
end
|
53
|
+
params["response"] = Hash.new.tap do |response|
|
54
|
+
response["headers"] = res.header
|
55
|
+
response["body"] = res.body if req.body
|
56
|
+
response["status"] = res.status
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
metadata
ADDED
@@ -0,0 +1,85 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: evil-proxy
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.2
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Theo
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-08-05 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.6'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.6'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
description: A ruby http proxy to do EVIL things.
|
42
|
+
email:
|
43
|
+
- bbtfrr@gmail.com
|
44
|
+
executables: []
|
45
|
+
extensions: []
|
46
|
+
extra_rdoc_files: []
|
47
|
+
files:
|
48
|
+
- ".gitignore"
|
49
|
+
- Gemfile
|
50
|
+
- LICENSE.txt
|
51
|
+
- README.md
|
52
|
+
- Rakefile
|
53
|
+
- evil-proxy.gemspec
|
54
|
+
- lib/evil-proxy.rb
|
55
|
+
- lib/evil-proxy/async.rb
|
56
|
+
- lib/evil-proxy/httpproxy.rb
|
57
|
+
- lib/evil-proxy/httprequest.rb
|
58
|
+
- lib/evil-proxy/selenium.rb
|
59
|
+
- lib/evil-proxy/store.rb
|
60
|
+
- lib/evil-proxy/version.rb
|
61
|
+
homepage: https://github.com/bbtfr/evil-proxy
|
62
|
+
licenses:
|
63
|
+
- MIT
|
64
|
+
metadata: {}
|
65
|
+
post_install_message:
|
66
|
+
rdoc_options: []
|
67
|
+
require_paths:
|
68
|
+
- lib
|
69
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
70
|
+
requirements:
|
71
|
+
- - ">="
|
72
|
+
- !ruby/object:Gem::Version
|
73
|
+
version: '0'
|
74
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
75
|
+
requirements:
|
76
|
+
- - ">="
|
77
|
+
- !ruby/object:Gem::Version
|
78
|
+
version: '0'
|
79
|
+
requirements: []
|
80
|
+
rubyforge_project:
|
81
|
+
rubygems_version: 2.4.6
|
82
|
+
signing_key:
|
83
|
+
specification_version: 4
|
84
|
+
summary: A ruby http proxy to do EVIL things.
|
85
|
+
test_files: []
|