XSpear 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +11 -0
- data/.idea/XSpear.iml +17 -0
- data/.idea/encodings.xml +4 -0
- data/.idea/misc.xml +7 -0
- data/.idea/modules.xml +8 -0
- data/.idea/workspace.xml +470 -0
- data/.rspec +3 -0
- data/.travis.yml +7 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +21 -0
- data/README.md +218 -0
- data/Rakefile +6 -0
- data/XSpear-1.0.0.gem +0 -0
- data/XSpear.gemspec +45 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/exe/XSpear +75 -0
- data/lib/XSpear/XSpearRepoter.rb +72 -0
- data/lib/XSpear/banner.rb +14 -0
- data/lib/XSpear/log.rb +31 -0
- data/lib/XSpear/version.rb +3 -0
- data/lib/XSpear.rb +289 -0
- metadata +168 -0
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2019 hahwul
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,218 @@
|
|
1
|
+
# XSpear
|
2
|
+
XSpear is XSS Scanner on ruby gems
|
3
|
+
|
4
|
+
<img src="https://img.shields.io/static/v1.svg?label=lang&message=ruby&color=RED"> <img src="https://img.shields.io/github/languages/top/hahwul/XSpear.svg"> <img src="https://img.shields.io/static/v1.svg?label=version&message=1.0&color=purple"> <img src="https://img.shields.io/github/license/hahwul/XSpear.svg"> <a href="https://twitter.com/intent/follow?screen_name=hahwul"><img src="https://img.shields.io/static/v1.svg?label=follow&message=hahwul&color=black"></a>
|
5
|
+
|
6
|
+
## Key features
|
7
|
+
- Pattern matching based XSS scanning
|
8
|
+
- Dynamic test based XSS scanning (with Selenium)
|
9
|
+
- Testing request/response for XSS protection bypass and reflected params
|
10
|
+
- Enable XSpear in code with Gem library load
|
11
|
+
- Support output format `cli` `json`
|
12
|
+
- Support custom callback code to any test various attack vectors
|
13
|
+
|
14
|
+
## Installation
|
15
|
+
|
16
|
+
Add this line to your application's Gemfile:
|
17
|
+
|
18
|
+
```ruby
|
19
|
+
gem 'XSpear'
|
20
|
+
```
|
21
|
+
|
22
|
+
And then execute:
|
23
|
+
|
24
|
+
$ bundle
|
25
|
+
|
26
|
+
Or install it yourself as:
|
27
|
+
|
28
|
+
$ gem install XSpear
|
29
|
+
|
30
|
+
Or install it yourself as (local file):
|
31
|
+
|
32
|
+
$ gem install XSpear-0.1.0.gem
|
33
|
+
|
34
|
+
### Dependency gems
|
35
|
+
`colorize` `selenium-webdriver`<br>
|
36
|
+
If you configured it to install automatically in the Gem library, but it behaves abnormally, install it with the following command.
|
37
|
+
|
38
|
+
```
|
39
|
+
$ gem install colorize
|
40
|
+
$ gem install selenium-webdriver
|
41
|
+
```
|
42
|
+
|
43
|
+
## Usage on cli
|
44
|
+
|
45
|
+
```
|
46
|
+
Usage: xspear -u [target] -[options] [value]
|
47
|
+
[ e.g ]
|
48
|
+
$ xspear -u 'https://www.hahwul.com/?q=123' --cookie='role=admin'
|
49
|
+
|
50
|
+
[ Options ]
|
51
|
+
-u, --url=target_URL [required] Target Url
|
52
|
+
-d, --data=POST Body [optional] POST Method Body data
|
53
|
+
--headers=HEADERS [optional] Add HTTP Headers
|
54
|
+
--cookie=COOKIE [optional] Add Cookie
|
55
|
+
-l, --level=1~3 [optional] Custom scan level
|
56
|
+
+ Default value: 3
|
57
|
+
+ Level3
|
58
|
+
+ Level2
|
59
|
+
+ Level1:
|
60
|
+
-t, --threads=NUMBER [optional] thread , default: 10
|
61
|
+
-o, --output=FILENAME [optional] Save JSON Result
|
62
|
+
-v, --verbose=1~3 [optional] Show log depth
|
63
|
+
+ Default value: 2
|
64
|
+
+ v=1 : quite mode
|
65
|
+
+ v=2 : show scanning log
|
66
|
+
+ v=3 : show detail log(req/res)
|
67
|
+
-h, --help Prints this help
|
68
|
+
--update Update with online
|
69
|
+
|
70
|
+
```
|
71
|
+
|
72
|
+
### Case by Case
|
73
|
+
**Scanning XSS**
|
74
|
+
```
|
75
|
+
$ xspear -u "http://testphp.vulnweb.com/search.php?test=query" -d "searchFor=yy"
|
76
|
+
```
|
77
|
+
|
78
|
+
**json output**
|
79
|
+
```
|
80
|
+
$ xspear -u "http://testphp.vulnweb.com/search.php?test=query" -d "searchFor=yy" -o json -v 1
|
81
|
+
```
|
82
|
+
|
83
|
+
**detail log**
|
84
|
+
```
|
85
|
+
$ xspear -u "http://testphp.vulnweb.com/search.php?test=query" -d "searchFor=yy" -v 3
|
86
|
+
```
|
87
|
+
|
88
|
+
etc...
|
89
|
+
|
90
|
+
### Sample log
|
91
|
+
**Scanning XSS**
|
92
|
+
```
|
93
|
+
$ xspear -u "http://testphp.vulnweb.com/listproducts.php?cat=1"
|
94
|
+
[*] creating a test query.
|
95
|
+
[*] test query generation is complete. [50 query]
|
96
|
+
[*] starting test and analysis. [10 threads]
|
97
|
+
[I] [00:57:24] reflected XsPeaR>[param: searchFor][not filtered >]
|
98
|
+
[-] [00:57:24] not reflected XsPeaR>
|
99
|
+
[-] [00:57:24] not reflected <XsPeaR
|
100
|
+
[-] [00:57:24] not reflected XsPeaR"
|
101
|
+
[-] [00:57:24] not reflected rEfe6
|
102
|
+
...snip...
|
103
|
+
[-] [00:57:27] not reflected <script>alert(45)</script>
|
104
|
+
[H] [00:57:27] reflected <svg/onload=alert(45)>[param: searchFor][reflected XSS Code]
|
105
|
+
[-] [00:57:27] not reflected <svg/onload=alert(45)>
|
106
|
+
[*] finish scan. the report is being generated..
|
107
|
+
+----+------+-------------+------------------------------------------------------------+---------------------+
|
108
|
+
| [ XSpear report ] |
|
109
|
+
| 2019-07-17 00:57:23 +0900 ~ 2019-07-17 00:58:08 +0900 || Found 24 issues. |
|
110
|
+
| http://testphp.vulnweb.com/search.php?test=query |
|
111
|
+
+----+------+-------------+------------------------------------------------------------+---------------------+
|
112
|
+
| NO | TYPE | ISSUE | PAYLOAD | DESCRIPTION |
|
113
|
+
+----+------+-------------+------------------------------------------------------------+---------------------+
|
114
|
+
| 0 | INFO | FILERD RULE | searchFor=yyXsPeaR%3E | not filtered > |
|
115
|
+
| 1 | INFO | FILERD RULE | searchFor=yy%3CXsPeaR | not filtered < |
|
116
|
+
| 2 | INFO | FILERD RULE | searchFor=yyXsPeaR%22 | not filtered " |
|
117
|
+
| 3 | INFO | FILERD RULE | searchFor=yyXsPeaR%27 | not filtered ' |
|
118
|
+
| 4 | INFO | REFLECTED | searchFor=yyrEfe6 | reflected parameter |
|
119
|
+
| 5 | INFO | FILERD RULE | searchFor=yyXsPeaR%28 | not filtered ( |
|
120
|
+
| 6 | INFO | FILERD RULE | searchFor=yyXsPeaR%7C | not filtered | |
|
121
|
+
| 7 | INFO | FILERD RULE | searchFor=yyXsPeaR%3B | not filtered ; |
|
122
|
+
| 8 | INFO | FILERD RULE | searchFor=yyXsPeaR%29 | not filtered ) |
|
123
|
+
| 9 | INFO | FILERD RULE | searchFor=yyXsPeaR%60 | not filtered ` |
|
124
|
+
| 10 | INFO | FILERD RULE | searchFor=yyXsPeaR%5B | not filtered [ |
|
125
|
+
| 11 | INFO | FILERD RULE | searchFor=yyXsPeaR%7B | not filtered { |
|
126
|
+
| 12 | INFO | FILERD RULE | searchFor=yyXsPeaR%5D | not filtered ] |
|
127
|
+
| 13 | INFO | FILERD RULE | searchFor=yyXsPeaR%7D | not filtered } |
|
128
|
+
| 14 | INFO | FILERD RULE | searchFor=yyXsPeaR%3A | not filtered : |
|
129
|
+
| 15 | INFO | FILERD RULE | searchFor=yyXsPeaR. | not filtered . |
|
130
|
+
| 16 | INFO | FILERD RULE | searchFor=yyXsPeaR%2B | not filtered + |
|
131
|
+
| 17 | INFO | FILERD RULE | searchFor=yyXsPeaR%2C | not filtered , |
|
132
|
+
| 18 | INFO | FILERD RULE | searchFor=yyXsPeaR%3D | not filtered = |
|
133
|
+
| 19 | INFO | FILERD RULE | searchFor=yyXsPeaR- | not filtered - |
|
134
|
+
| 20 | HIGH | XSS | searchFor=yy%3Cimg%2Fsrc+onerror%3Dalert%2845%29%3E | reflected XSS Code |
|
135
|
+
| 21 | INFO | FILERD RULE | searchFor=yyXsPeaR%24 | not filtered $ |
|
136
|
+
| 22 | HIGH | XSS | searchFor=yy%22%3E%3Cscript%3Ealert%2845%29%3C%2Fscript%3E | reflected XSS Code |
|
137
|
+
| 23 | HIGH | XSS | searchFor=yy%3Csvg%2Fonload%3Dalert%2845%29%3E | reflected XSS Code |
|
138
|
+
+----+------+-------------+------------------------------------------------------------+---------------------+
|
139
|
+
```
|
140
|
+
|
141
|
+
**to JSON**
|
142
|
+
```
|
143
|
+
$ xspear -u "http://testphp.vulnweb.com/search.php?test=query" -d "searchFor=yy" -o json -v 1
|
144
|
+
{"starttime":"2019-07-17 01:02:13 +0900","endtime":"2019-07-17 01:02:59 +0900","issue_count":24,"issue_list":[{"id":0,"type":"INFO","issue":"FILERD RULE","payload":"searchFor=yy%3CXsPeaR","description":"not filtered \u001b[0;34;49m<\u001b[0m"},{"id":1,"type":"INFO","issue":"FILERD RULE","payload":"searchFor=yyXsPeaR%27","description":"not filtered \u001b[0;34;49m'\u001b[0m"},{"id":2,"type":"INFO","issue":"FILERD RULE","payload":"searchFor=yyXsPeaR%3E","description":"not filtered \u001b[0;34;49m>\u001b[0m"},{"id":3,"type":"INFO","issue":"REFLECTED","payload":"searchFor=yyrEfe6","description":"reflected parameter"},{"id":4,"type":"INFO","issue":"FILERD RULE","payload":"searchFor=yyXsPeaR%22","description":"not filtered \u001b[0;34;49m\"\u001b[0m"},{"id":5,"type":"INFO","issue":"FILERD RULE","payload":"searchFor=yyXsPeaR%60","description":"not filtered \u001b[0;34;49m`\u001b[0m"},{"id":6,"type":"INFO","issue":"FILERD RULE","payload":"searchFor=yyXsPeaR%3B","description":"not filtered \u001b[0;34;49m;\u001b[0m"},{"id":7,"type":"INFO","issue":"FILERD RULE","payload":"searchFor=yyXsPeaR%28","description":"not filtered \u001b[0;34;49m(\u001b[0m"},{"id":8,"type":"INFO","issue":"FILERD RULE","payload":"searchFor=yyXsPeaR%7C","description":"not filtered \u001b[0;34;49m|\u001b[0m"},{"id":9,"type":"INFO","issue":"FILERD RULE","payload":"searchFor=yyXsPeaR%29","description":"not filtered \u001b[0;34;49m)\u001b[0m"},{"id":10,"type":"INFO","issue":"FILERD RULE","payload":"searchFor=yyXsPeaR%7B","description":"not filtered \u001b[0;34;49m{\u001b[0m"},{"id":11,"type":"INFO","issue":"FILERD RULE","payload":"searchFor=yyXsPeaR%5B","description":"not filtered \u001b[0;34;49m[\u001b[0m"},{"id":12,"type":"INFO","issue":"FILERD RULE","payload":"searchFor=yyXsPeaR%5D","description":"not filtered \u001b[0;34;49m]\u001b[0m"},{"id":13,"type":"INFO","issue":"FILERD RULE","payload":"searchFor=yyXsPeaR%7D","description":"not filtered \u001b[0;34;49m}\u001b[0m"},{"id":14,"type":"INFO","issue":"FILERD RULE","payload":"searchFor=yyXsPeaR%3A","description":"not filtered \u001b[0;34;49m:\u001b[0m"},{"id":15,"type":"INFO","issue":"FILERD RULE","payload":"searchFor=yyXsPeaR%2B","description":"not filtered \u001b[0;34;49m+\u001b[0m"},{"id":16,"type":"INFO","issue":"FILERD RULE","payload":"searchFor=yyXsPeaR.","description":"not filtered \u001b[0;34;49m.\u001b[0m"},{"id":17,"type":"INFO","issue":"FILERD RULE","payload":"searchFor=yyXsPeaR-","description":"not filtered \u001b[0;34;49m-\u001b[0m"},{"id":18,"type":"INFO","issue":"FILERD RULE","payload":"searchFor=yyXsPeaR%2C","description":"not filtered \u001b[0;34;49m,\u001b[0m"},{"id":19,"type":"INFO","issue":"FILERD RULE","payload":"searchFor=yyXsPeaR%3D","description":"not filtered \u001b[0;34;49m=\u001b[0m"},{"id":20,"type":"HIGH","issue":"XSS","payload":"searchFor=yy%3Cimg%2Fsrc+onerror%3Dalert%2845%29%3E","description":"reflected \u001b[0;31;49mXSS Code\u001b[0m"},{"id":21,"type":"HIGH","issue":"XSS","payload":"searchFor=yy%3Csvg%2Fonload%3Dalert%2845%29%3E","description":"reflected \u001b[0;31;49mXSS Code\u001b[0m"},{"id":22,"type":"HIGH","issue":"XSS","payload":"searchFor=yy%22%3E%3Cscript%3Ealert%2845%29%3C%2Fscript%3E","description":"reflected \u001b[0;31;49mXSS Code\u001b[0m"},{"id":23,"type":"INFO","issue":"FILERD RULE","payload":"searchFor=yyXsPeaR%24","description":"not filtered \u001b[0;34;49m$\u001b[0m"}]}
|
145
|
+
```
|
146
|
+
|
147
|
+
## Usage on ruby code (gem library)
|
148
|
+
```ruby
|
149
|
+
require 'XSPear'
|
150
|
+
|
151
|
+
s = XspearScan.new "https://www.hahwul.com?target_url", "post_body=thisisbodydata", "CustomHeader: wow", 3, 10, "result.json", "3"
|
152
|
+
# s = XspearScan.new options.url, options.data, options.headers, options.level, options.thread.to_i, options.output, options.verbose
|
153
|
+
s.run
|
154
|
+
```
|
155
|
+
|
156
|
+
## Add Scanning Module
|
157
|
+
**1) Add `makeQueryPattern`**
|
158
|
+
```ruby
|
159
|
+
makeQueryPattern('type', 'query,', 'pattern', 'category', "description", "callback funcion")
|
160
|
+
# type: f(ilterd?) r(eflected?) x(ss?)
|
161
|
+
# category i(nfo) v(uln) l(ow) m(edium) h(igh)
|
162
|
+
|
163
|
+
# e.g
|
164
|
+
# makeQueryPattern('f', 'XsPeaR,', 'XsPeaR,', 'i', "not filtered "+",".blue, CallbackStringMatch)
|
165
|
+
```
|
166
|
+
|
167
|
+
**2) if other callback, write callback class override `ScanCallbackFunc`**
|
168
|
+
e.g
|
169
|
+
```ruby
|
170
|
+
class CallbackStringMatch < ScanCallbackFunc
|
171
|
+
def run
|
172
|
+
if @response.body.include? @query
|
173
|
+
[true, "reflected #{@query}"]
|
174
|
+
else
|
175
|
+
[false, "not reflected #{@query}"]
|
176
|
+
end
|
177
|
+
end
|
178
|
+
end
|
179
|
+
```
|
180
|
+
|
181
|
+
Parent class(ScanCallbackFunc)
|
182
|
+
```ruby
|
183
|
+
class ScanCallbackFunc()
|
184
|
+
def initialize(url, method, query, response)
|
185
|
+
@url = url
|
186
|
+
@method = method
|
187
|
+
@query = query
|
188
|
+
@response = response
|
189
|
+
# self.run
|
190
|
+
end
|
191
|
+
|
192
|
+
def run
|
193
|
+
# override
|
194
|
+
end
|
195
|
+
end
|
196
|
+
```
|
197
|
+
|
198
|
+
## Development
|
199
|
+
|
200
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
201
|
+
|
202
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
203
|
+
|
204
|
+
## Contributing
|
205
|
+
|
206
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/XSpear. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
|
207
|
+
|
208
|
+
## License
|
209
|
+
|
210
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
211
|
+
|
212
|
+
## Code of Conduct
|
213
|
+
|
214
|
+
Everyone interacting in the XSpear project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/[USERNAME]/XSpear/blob/master/CODE_OF_CONDUCT.md).
|
215
|
+
|
216
|
+
## ScreenShot
|
217
|
+
<img src="https://user-images.githubusercontent.com/13212227/61311070-8aacfc80-a830-11e9-9091-61d68e16d81a.png" width=100%>
|
218
|
+
<img src="https://user-images.githubusercontent.com/13212227/61311071-8b459300-a830-11e9-8e60-c08e984fdacb.png" width=100%>
|
data/Rakefile
ADDED
data/XSpear-1.0.0.gem
ADDED
Binary file
|
data/XSpear.gemspec
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
|
2
|
+
lib = File.expand_path("../lib", __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require "XSpear/version"
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "XSpear"
|
8
|
+
spec.version = XSpear::VERSION
|
9
|
+
spec.authors = ["hahwul"]
|
10
|
+
spec.email = ["hahwul@gmail.com"]
|
11
|
+
|
12
|
+
spec.summary = "Powerfull XSS Scanning and Parameter Analysis tool&gem"
|
13
|
+
spec.description = "XSpear is XSS Scanner on ruby gems"
|
14
|
+
spec.homepage = "https://github.com/hahwul/XSpear"
|
15
|
+
spec.license = "MIT"
|
16
|
+
|
17
|
+
# Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
|
18
|
+
# to allow pushing to a single host or delete this section to allow pushing to any host.
|
19
|
+
if spec.respond_to?(:metadata)
|
20
|
+
spec.metadata["homepage_uri"] = spec.homepage
|
21
|
+
spec.metadata["source_code_uri"] = "https://github.com/hahwul/XSpear"
|
22
|
+
spec.metadata["changelog_uri"] = "https://github.com/hahwul/XSpear"
|
23
|
+
else
|
24
|
+
raise "RubyGems 2.0 or newer is required to protect against " \
|
25
|
+
"public gem pushes."
|
26
|
+
end
|
27
|
+
|
28
|
+
# Specify which files should be added to the gem when it is released.
|
29
|
+
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
30
|
+
spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
|
31
|
+
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
32
|
+
end
|
33
|
+
spec.bindir = "exe"
|
34
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
35
|
+
spec.require_paths = ["lib"]
|
36
|
+
|
37
|
+
spec.add_runtime_dependency "colorize", "0.8.1"
|
38
|
+
spec.add_runtime_dependency "selenium-webdriver", "3.142.3"
|
39
|
+
|
40
|
+
spec.add_development_dependency "colorize", "0.8.1"
|
41
|
+
spec.add_development_dependency "selenium-webdriver", "3.142.3"
|
42
|
+
spec.add_development_dependency "bundler", "~> 2.0"
|
43
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
44
|
+
spec.add_development_dependency "rspec", "~> 3.0"
|
45
|
+
end
|
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "XSpear"
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require "pry"
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require "irb"
|
14
|
+
IRB.start(__FILE__)
|
data/bin/setup
ADDED
data/exe/XSpear
ADDED
@@ -0,0 +1,75 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "XSpear"
|
4
|
+
Options = Struct.new(:url, :data, :headers, :params, :thread, :verbose, :output)
|
5
|
+
class Parser
|
6
|
+
def self.parse(options)
|
7
|
+
args = Options.new('xspear')
|
8
|
+
if options.empty?
|
9
|
+
banner
|
10
|
+
puts 'please ' + "'-h'".yellow + ' option'
|
11
|
+
exit
|
12
|
+
end
|
13
|
+
opt_parser = OptionParser.new do |opts|
|
14
|
+
opts.banner = "Usage: xspear -u [target] -[options] [value]\n[ e.g ]\n$ ruby a.rb -u 'https://www.hahwul.com/?q=123' --cookie='role=admin'\n\n[ Options ]"
|
15
|
+
|
16
|
+
opts.on('-u', '--url=target_URL', '[required] Target Url') do |n|
|
17
|
+
args.url = n
|
18
|
+
end
|
19
|
+
|
20
|
+
opts.on('-d', '--data=POST Body', '[optional] POST Method Body data') do |n|
|
21
|
+
args.data = n
|
22
|
+
end
|
23
|
+
|
24
|
+
opts.on('--headers=HEADERS', '[optional] Add HTTP Headers') do |n|
|
25
|
+
args.headers = n
|
26
|
+
end
|
27
|
+
|
28
|
+
opts.on('--cookie=COOKIE', '[optional] Add Cookie') do |n|
|
29
|
+
args.headers = 'Cookie: ' + n
|
30
|
+
end
|
31
|
+
|
32
|
+
opts.on('-p', '--param=PARAM', '[optional] Test paramters') do |n|
|
33
|
+
args.params = n
|
34
|
+
end
|
35
|
+
|
36
|
+
opts.on('-t', '--threads=NUMBER', '[optional] thread , default: 10') do |n|
|
37
|
+
args.thread = n
|
38
|
+
end
|
39
|
+
|
40
|
+
opts.on('-o', '--output=FILENAME', '[optional] Save JSON Result') do |n|
|
41
|
+
args.output = n
|
42
|
+
end
|
43
|
+
|
44
|
+
opts.on('-v', '--verbose=1~3', '[optional] Show log depth',
|
45
|
+
' + Default value: 2',
|
46
|
+
' + v=1 : quite mode',
|
47
|
+
' + v=2 : show scanning log',
|
48
|
+
' + v=3 : show detail log(req/res)') do |n|
|
49
|
+
args.verbose = n
|
50
|
+
end
|
51
|
+
|
52
|
+
opts.on('-h', '--help', 'Prints this help') do
|
53
|
+
banner
|
54
|
+
puts opts
|
55
|
+
exit
|
56
|
+
end
|
57
|
+
|
58
|
+
opts.on('--update', 'Update with online') do
|
59
|
+
puts opts
|
60
|
+
exit
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
opt_parser.parse!(options)
|
65
|
+
args
|
66
|
+
end
|
67
|
+
end
|
68
|
+
options = Parser.parse ARGV
|
69
|
+
|
70
|
+
exit unless options.url
|
71
|
+
options.thread = 10 unless options.thread
|
72
|
+
options.verbose = 2 unless options.verbose
|
73
|
+
banner
|
74
|
+
s = XspearScan.new options.url, options.data, options.headers, options.params, options.thread.to_i, options.output, options.verbose
|
75
|
+
s.run
|
@@ -0,0 +1,72 @@
|
|
1
|
+
require 'terminal-table'
|
2
|
+
|
3
|
+
IssueStruct = Struct.new(:id, :type, :issue, :payload, :description)
|
4
|
+
class IssueStruct
|
5
|
+
def to_json(*a)
|
6
|
+
{:id => self.id, :type => self.type, :issue => self.issue, :payload => self.payload, :description => self.description}.to_json(*a)
|
7
|
+
end
|
8
|
+
|
9
|
+
|
10
|
+
def self.json_create(o)
|
11
|
+
new(o['id'], o['type'], o['issue'], o['payload'], o['description'])
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
class XspearRepoter
|
16
|
+
def initialize(url,starttime)
|
17
|
+
@url = url
|
18
|
+
@starttime = starttime
|
19
|
+
@endtime = nil
|
20
|
+
@issue = []
|
21
|
+
@query = []
|
22
|
+
# type : i,v,l,m,h
|
23
|
+
# param : paramter
|
24
|
+
# type :
|
25
|
+
# query :
|
26
|
+
# pattern
|
27
|
+
# desc
|
28
|
+
# category
|
29
|
+
# callback
|
30
|
+
end
|
31
|
+
|
32
|
+
def add_issue(type, issue, param, payload, pattern, description)
|
33
|
+
rtype = {"i"=>"INFO","v"=>"VULN","l"=>"LOW","m"=>"MIDUM","h"=>"HIGH"}
|
34
|
+
rissue = {"f"=>"FILERD RULE","r"=>"REFLECTED","x"=>"XSS","s"=>"STATIC ANALYSIS","d"=>"DYNAMIC ANALYSIS"}
|
35
|
+
@issue << [@issue.size, rtype[type], rissue[issue], param, pattern, description]
|
36
|
+
@query.push payload
|
37
|
+
end
|
38
|
+
|
39
|
+
def set_endtime
|
40
|
+
@endtime = Time.now
|
41
|
+
end
|
42
|
+
|
43
|
+
def to_json
|
44
|
+
buffer = []
|
45
|
+
@issue.each do |i|
|
46
|
+
tmp = IssueStruct.new(i[0],i[1],i[2],i[3],i[4])
|
47
|
+
buffer.push(tmp)
|
48
|
+
end
|
49
|
+
|
50
|
+
hash = {}
|
51
|
+
hash["starttime"]=@starttime
|
52
|
+
hash["endtime"]=@endtime
|
53
|
+
hash["issue_count"]=@issue.length
|
54
|
+
hash["issue_list"]=buffer
|
55
|
+
hash.to_json
|
56
|
+
end
|
57
|
+
|
58
|
+
def to_html; end
|
59
|
+
|
60
|
+
def to_cli
|
61
|
+
table = Terminal::Table.new
|
62
|
+
table.title = "[ XSpear report ]\n#{@url}\n#{@starttime} ~ #{@endtime} Found #{@issue.length} issues."
|
63
|
+
table.headings = ['NO','TYPE','ISSUE','PARAM','PAYLOAD','DESCRIPTION']
|
64
|
+
table.rows = @issue
|
65
|
+
#table.style = {:width => 80}
|
66
|
+
puts table
|
67
|
+
puts "< Raw Query >"
|
68
|
+
@query.each_with_index do |q, i|
|
69
|
+
puts "[#{i}] "+@url+"?"+q
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
def banner;
|
2
|
+
puts " ) (
|
3
|
+
( /( )\\ )
|
4
|
+
)\\())(()/( ( ) (
|
5
|
+
((_)\\ /(_))` ) ))\\ ( /( )(
|
6
|
+
__((_)(_)) /(/( /((_))(_))(()\\
|
7
|
+
\\ \\/ // __|((_)_\\ (_)) ((_)_ ((_)
|
8
|
+
> < \\__ \\| '_ \\)/ -_)/ _` || '_|
|
9
|
+
/_/\\_\\|___/| .__/ \\___|\\__,_||_| />
|
10
|
+
|_| \\ /<
|
11
|
+
{\\\\\\\\\\\\\\\\\\\\\\\\\\BYHAHWUL\\\\\\\\\\\\\\\\\\\\\\(0):::<======================-
|
12
|
+
/ \\<
|
13
|
+
\\>"
|
14
|
+
end
|
data/lib/XSpear/log.rb
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
def log(t, message)
|
2
|
+
# type, message
|
3
|
+
# + type: safe, info, matched, vuln
|
4
|
+
# + info: match percent
|
5
|
+
|
6
|
+
# = format
|
7
|
+
# detail
|
8
|
+
# [09:16:53][PARAM] Message / Matched 70%
|
9
|
+
# [09:16:54][XSS/INFO] Message / Matched 70%
|
10
|
+
|
11
|
+
# system message
|
12
|
+
# [+] start parameter analysis..
|
13
|
+
if @verbose.to_i > 1
|
14
|
+
time = Time.now
|
15
|
+
if t == 'd'
|
16
|
+
puts '[-]'.white + " [#{time.strftime('%H:%M:%S')}] #{message}"
|
17
|
+
elsif t == 's' # system message
|
18
|
+
puts '[*]'.green + " #{message}"
|
19
|
+
elsif t == 'i'
|
20
|
+
puts '[I]'.blue + " [#{time.strftime('%H:%M:%S')}] #{message}"
|
21
|
+
elsif t == 'v'
|
22
|
+
puts '[V]'.red + " [#{time.strftime('%H:%M:%S')}] #{message}"
|
23
|
+
elsif t == 'l'
|
24
|
+
puts '[L]'.blue + " [#{time.strftime('%H:%M:%S')}] #{message}"
|
25
|
+
elsif t == 'm'
|
26
|
+
puts '[M]'.yellow + " [#{time.strftime('%H:%M:%S')}] #{message}"
|
27
|
+
elsif t == 'h'
|
28
|
+
puts '[H]'.red + " [#{time.strftime('%H:%M:%S')}] #{message}"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|