lightning-bolt 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 5060bc86fb45cd3a522f7c9455190e163a04ee07
4
+ data.tar.gz: 8783ec8f5e707d382f7513dd21552e5271e2b74f
5
+ SHA512:
6
+ metadata.gz: f6ae02a3485c19d772433a777d097a204cef9f1fb6489b27b94b0e8b5f19119d30fdda3b80675d9e1be78ddc1972cf95ca690e2cdabc8ce921b5c834e3d9217d
7
+ data.tar.gz: a92775bd3e4ab16b48a1c263cddd45440e5bf6e62647f3c950406704370d92d3f1e5f57246f3ce58c697132332c6d5f5e4df730a703eb51f4f7bac5da69fc6b0
data/.gitignore ADDED
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
@@ -0,0 +1,49 @@
1
+ # Contributor Code of Conduct
2
+
3
+ As contributors and maintainers of this project, and in the interest of
4
+ fostering an open and welcoming community, we pledge to respect all people who
5
+ contribute through reporting issues, posting feature requests, updating
6
+ documentation, submitting pull requests or patches, and other activities.
7
+
8
+ We are committed to making participation in this project a harassment-free
9
+ experience for everyone, regardless of level of experience, gender, gender
10
+ identity and expression, sexual orientation, disability, personal appearance,
11
+ body size, race, ethnicity, age, religion, or nationality.
12
+
13
+ Examples of unacceptable behavior by participants include:
14
+
15
+ * The use of sexualized language or imagery
16
+ * Personal attacks
17
+ * Trolling or insulting/derogatory comments
18
+ * Public or private harassment
19
+ * Publishing other's private information, such as physical or electronic
20
+ addresses, without explicit permission
21
+ * Other unethical or unprofessional conduct
22
+
23
+ Project maintainers have the right and responsibility to remove, edit, or
24
+ reject comments, commits, code, wiki edits, issues, and other contributions
25
+ that are not aligned to this Code of Conduct, or to ban temporarily or
26
+ permanently any contributor for other behaviors that they deem inappropriate,
27
+ threatening, offensive, or harmful.
28
+
29
+ By adopting this Code of Conduct, project maintainers commit themselves to
30
+ fairly and consistently applying these principles to every aspect of managing
31
+ this project. Project maintainers who do not follow or enforce the Code of
32
+ Conduct may be permanently removed from the project team.
33
+
34
+ This code of conduct applies both within project spaces and in public spaces
35
+ when an individual is representing the project or its community.
36
+
37
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be
38
+ reported by contacting a project maintainer at TODO: Write your email address. All
39
+ complaints will be reviewed and investigated and will result in a response that
40
+ is deemed necessary and appropriate to the circumstances. Maintainers are
41
+ obligated to maintain confidentiality with regard to the reporter of an
42
+ incident.
43
+
44
+ This Code of Conduct is adapted from the [Contributor Covenant][homepage],
45
+ version 1.3.0, available at
46
+ [http://contributor-covenant.org/version/1/3/0/][version]
47
+
48
+ [homepage]: http://contributor-covenant.org
49
+ [version]: http://contributor-covenant.org/version/1/3/0/
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in lightning-bolt.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2016 TODO: Write your name
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,41 @@
1
+ # Lightning::Bolt
2
+
3
+ Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/lightning/bolt`. To experiment with that code, run `bin/console` for an interactive prompt.
4
+
5
+ TODO: Delete this and the text above, and describe your gem
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ ```ruby
12
+ gem 'lightning-bolt'
13
+ ```
14
+
15
+ And then execute:
16
+
17
+ $ bundle
18
+
19
+ Or install it yourself as:
20
+
21
+ $ gem install lightning-bolt
22
+
23
+ ## Usage
24
+
25
+ TODO: Write usage instructions here
26
+
27
+ ## Development
28
+
29
+ After checking out the repo, run `bin/setup` to install dependencies. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
30
+
31
+ 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).
32
+
33
+ ## Contributing
34
+
35
+ Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/lightning-bolt. 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.
36
+
37
+
38
+ ## License
39
+
40
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
41
+
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+ task :default => :spec
data/bin/lightningbolt ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require_relative '../lib/lightning/bolt/cli'
@@ -0,0 +1,63 @@
1
+ require 'thor'
2
+ require 'yaml'
3
+ require_relative "codex"
4
+ module Lightning
5
+ module Bolt
6
+ class Storm < Thor
7
+ include Thor::Actions
8
+ desc "strike payload.yml", "Run Lightning Bolt"
9
+ def strike(schematics)
10
+
11
+ puts battle.report('english')
12
+ end
13
+ desc "thunder", "Install Lightning Bolt"
14
+ option :install
15
+ option :name
16
+ def thunder()
17
+ install('payload.yml')
18
+ end
19
+ private
20
+ def install(template_file)
21
+ install_path = options[:install] ? options[:install] : '.'
22
+ filename = options[:name] ? options[:name] : template_file
23
+ template = File.read(File.join(File.dirname(__FILE__),'templates',template_file))
24
+ success = false
25
+ msg = ''
26
+ file = File.join(install_path, filename)
27
+ if File.exists?(file)
28
+ warn "[skip] `#{filename}' already exists"
29
+ if yes?("Would you like to overwrite the existing file?")
30
+ msg = "#{filename} has been overwritten"
31
+ success=true
32
+ end
33
+ elsif File.exists?(file.downcase)
34
+ warn "[skip] `#{filename.downcase}' exists, which could conflict with `#{filename}'"
35
+ if yes?("Would you like to overwrite the existing file?")
36
+ msg = "#{filename} has been overwritten"
37
+ success=true
38
+ end
39
+ elsif !File.exists?(File.dirname(file))
40
+ warn "[skip] directory `#{File.dirname(file)}' does not exist"
41
+ if yes?("Would you like to make the directory?")
42
+ FileUtils.mkdir_p(install_path)
43
+ msg = "The directory #{install_path} was created"
44
+ success=true
45
+ end
46
+ else
47
+ msg = "There were no issues with the installation"
48
+ success=true
49
+ end
50
+
51
+ if success
52
+ puts "[add] writing `#{filename}'"
53
+ File.open(file, "w") { |f| f.write(template) }
54
+ puts "#{msg}"
55
+ puts "[done] Lightning Bolt was successfully installed. Stay safe."
56
+ else
57
+ puts "[error] Lightning Bolt was not successfully installed."
58
+ end
59
+ end
60
+ end
61
+ Storm.start(ARGV)
62
+ end
63
+ end
@@ -0,0 +1,308 @@
1
+ require_relative "./cypher"
2
+ require_relative "./fuzzer"
3
+ require 'yaml'
4
+ require 'json'
5
+
6
+ module Lightning
7
+ module Bolt
8
+ class Codex
9
+ def initialize(bookstore, theorems, reports, memory)
10
+ @cypher = Lightning::Bolt::Cypher.new(bookstore)
11
+ @fuzzer = Lightning::Bolt::Fuzzer.new('UTF-8')
12
+ @keys = YAML.load_file("#{File.dirname(__FILE__)}/keys.yml")
13
+ @passable = true
14
+ @unique = false
15
+ @theorems = theorems
16
+ @reports = reports
17
+ @memory = memory
18
+ end
19
+
20
+ def signal(passable, unique, name)
21
+ @passable = passable.eql?(nil) ? true : passable
22
+ @unique = unique.eql?(nil) ? false : unique
23
+ path = nil
24
+ @theorems.each do | theorem |
25
+ if theorem["name"].eql?(name)
26
+ path = theorem["path"]
27
+ end
28
+ end
29
+ if path
30
+ path = decrypt(path)
31
+ path = rotar(path, @keys["keys"]["escapable"]) ? escapable(path) : path
32
+ return path
33
+ else
34
+ return ""
35
+ end
36
+ end
37
+
38
+ private
39
+
40
+ def decrypt(rule)
41
+ rule = rotar(rule, @keys["keys"]["reference"]) ? references(rule) : rule
42
+ rule = rotar(rule, @keys["keys"]["data"]) ? datum(rule) : rule
43
+ rule = rotar(rule, @keys["keys"]["group"]) ? group(rule) : rule
44
+ rule = rotar(rule, @keys["keys"]["set"]) ? set(rule) : rule
45
+ #rule = rotar(rule, @keys["keys"]["not"]) ? exclude(rule) : rule
46
+ rule = rotar(rule, @keys["keys"]["or"]) ? either(rule) : rule
47
+ rule = rotar(rule, @keys["keys"]["and"]) ? concat(rule) : rule
48
+ rule = rotar(rule, @keys["keys"]["exist"]) ? exist(rule) : rule
49
+ rule = rotar(rule, @keys["keys"]["repeat"]) ? repeat(rule) : rule
50
+ rule = rotar(rule, @keys["keys"]["escapable"]) ? escapable(rule) : rule
51
+ #rule = rotar(rule, @keys["keys"]["remember"]) ? remember(rule) : rule
52
+ return rule
53
+ end
54
+
55
+ def rotar(rule, expr)
56
+ return (rule.scan(Regexp.new(expr)).size > 0)
57
+ end
58
+
59
+ def references(rule)
60
+ vars = rule.scan(Regexp.new(@keys["keys"]["reference"]))
61
+ lock = false
62
+ vars.each do | var |
63
+ scan = radar(var)
64
+ if scan.eql?("")
65
+ lock = true
66
+ else
67
+ rule = rule.gsub(var, radar(var))
68
+ end
69
+ end
70
+ if lock
71
+ return rule
72
+ else
73
+ return decrypt(rule)
74
+ end
75
+ end
76
+
77
+ def radar(map)
78
+ rule = ""
79
+ if @passable
80
+ @theorems.each do | theorem |
81
+ if theorem["path"].eql?(map)
82
+ rule = theorem["rule"]
83
+ end
84
+ end
85
+ else
86
+ rule = @theorems[@fuzzer.random_number(0, @theorems.size)]
87
+ end
88
+ return rule
89
+ end
90
+
91
+ def datum(rule)
92
+ datum = rule.scan(Regexp.new(@keys["keys"]["data"]))
93
+ datum.each do | data |
94
+ if @passable
95
+ rule = rule.gsub(data, @cypher.arc(data))
96
+ else
97
+ rule = rule.gub(data, @fuzzer.launch(nil, 64, true))
98
+ end
99
+ end
100
+ return rule
101
+ end
102
+
103
+ def group(rule)
104
+ groups = rule.scan(Regexp.new(@keys["keys"]["group"]))
105
+ groups.each do | group |
106
+ group = group.join("")
107
+ rule = rule.gsub(group, decrypt(group[1..-2]))
108
+ end
109
+ return rule
110
+ end
111
+
112
+ def set(rule)
113
+ sets = rule.scan(Regexp.new(@keys["keys"]["set"]))
114
+ charset = []
115
+ if sets
116
+ sets.each do | set |
117
+ rangesets = set[0].scan(Regexp.new(@keys["keys"]["range"]))
118
+ subsets = set[0].scan(Regexp.new(@keys["keys"]["subsets"]))
119
+ if rangesets
120
+ rangesets.each do | rangeset |
121
+ subranges = []
122
+ subrangeset = rangeset[1..-2].split("..")
123
+ (subrangeset[0]..subrangeset[1]).each do | x |
124
+ subranges.push(x)
125
+ end
126
+ rule = rule.gsub(rangeset, subranges[@fuzzer.random_number(0,subranges.size)])
127
+ end
128
+ end
129
+ if subsets
130
+ subsets.each do | subset |
131
+ if subset
132
+ if @passable
133
+ charset += ruleset(subset[0])
134
+ else
135
+ charset += glyph
136
+ end
137
+ end
138
+ end
139
+ end
140
+ if charset.size > 0
141
+ char = charset[@fuzzer.random_number(0,charset.size)]
142
+ rule = rule.gsub(set[0], char)
143
+ end
144
+ end
145
+ end
146
+ return (rule)
147
+ end
148
+
149
+ def ruleset(subset)
150
+ charset = []
151
+ if subset
152
+ if subset.size == 3
153
+ set_range = subset.split("-")
154
+ if set_range.size == 2
155
+ min = set_range[0]
156
+ max = set_range[1]
157
+ range_set = []
158
+ (min..max).each do | range |
159
+ range_set.push(range)
160
+ end
161
+ charset += range_set
162
+ end
163
+ elsif subset.size == 2 && subset[0].eql?("\\")
164
+ charset.push(subset[1])
165
+ else
166
+ charset.push(subset)
167
+ end
168
+ end
169
+ return charset
170
+ end
171
+
172
+ def glyph()
173
+ range_set = []
174
+ min = rand(65)
175
+ max = rand(129)
176
+ (min..@fuzzer.random_number(min,max)).each do | range |
177
+ range_set.push(range.to_s(2).to_i(2))
178
+ end
179
+ return charsets
180
+ end
181
+
182
+ def either(rule)
183
+ if !@passable
184
+ rule = charflip(rule, "|", "&")
185
+ end
186
+ subrules = rule.split(Regexp.new(@keys["keys"]["or"]))
187
+ subrule = subrules[@fuzzer.random_number(0,subrules.length)]
188
+ rule = rule.gsub(rule, decrypt(subrule))
189
+ end
190
+
191
+ def concat(rule)
192
+ if !@passable
193
+ rule = charflip(rule, "&", "|")
194
+ end
195
+ combinator = ""
196
+ subrules = rule.split(Regexp.new(@keys["keys"]["and"]))
197
+ subrules.each do | subrule |
198
+ combinator += decrypt(subrule)
199
+ end
200
+ return rule.gsub(rule, combinator)
201
+ end
202
+
203
+ def charflip(str, a, b)
204
+ charset = str.split("")
205
+ charset.each_with_index do | set, index |
206
+ if set.eql?(a)
207
+ charset[index] = b
208
+ elsif set.eql?(b)
209
+ charset[index] = a
210
+ else
211
+ end
212
+ end
213
+ return charset.join("")
214
+ end
215
+
216
+ def exists(rule)
217
+ group_ranges = rule.match(Regexp.new(@keys["keys"]["group"] + @keys["keys"]["exist"]))
218
+ set_ranges = rule.match(Regexp.new(@keys["keys"]["set"] + @keys["keys"]["exist"]))
219
+ ranges = []
220
+ ranges += group_ranges.eql?(nil) ? [] : group_ranges[0..-1]
221
+ ranges += set_ranges.eql?(nil) ? [] : set_ranges[0..-1]
222
+ if ranges
223
+ ranges.each do | range |
224
+ range_set = range.match(Regexp.new(@keys["keys"]["exist"]))
225
+ if range_set
226
+ subrule = ""
227
+ if @fuzzer.random_number(0,1).eql(1)
228
+ subrule = rule[0..rule.size-2]
229
+ end
230
+ rule = rule.gsub(rule, decrypt(subrule))
231
+ end
232
+ end
233
+ end
234
+ return rule
235
+ end
236
+
237
+ def exclude(rule)
238
+ =begin
239
+ violated = true
240
+ rule = switch(rule)
241
+ while violated.eql?(true) do
242
+ violated = false
243
+ rule = decrypt(rule)
244
+ end
245
+ =end
246
+ return rule
247
+ end
248
+
249
+ def repeat(rule)
250
+ combinator = ""
251
+ min = max = 0
252
+ repeater = rule.scan(Regexp.new(@keys["keys"]["repeat"]))[0]
253
+ if repeater
254
+ rule = rule.gsub(repeater, "")
255
+ range = repeater.to_s[1..-2].split(":")
256
+ min = @passable ? range[0].to_i() : @fuzzer.random_number(0,min)
257
+ max = @passable ? range[1].to_i() : @fuzzer.random_number(min, rand(max + 9))
258
+ if min.eql?(max)
259
+ (0..max-1).each do | i |
260
+ combinator += decrypt(rule)
261
+ end
262
+ else
263
+ (0..min-1).each do | i |
264
+ combinator += decrypt(rule)
265
+ end
266
+ (min..max-min).each do | i |
267
+ combinator += decrypt(rule)
268
+ end
269
+ end
270
+ end
271
+ return rule.gsub(rule, combinator)
272
+ end
273
+
274
+ def escapable(rule)
275
+ escapes = rule.scan(Regexp.new(@keys["keys"]["escapable"]))
276
+ escapes.each do | escape |
277
+ if @passable
278
+ rule = rule.gsub(escape, escape[1..-1])
279
+ else
280
+ rule = rule.gsub(escape, @fuzzer.launch(nil, 1, false))
281
+ end
282
+ end
283
+ return decrypt(rule)
284
+ end
285
+
286
+ def remember(index)
287
+ return @memory[index]
288
+ end
289
+
290
+ def memorize(rule)
291
+ bank = rule.split("+:")
292
+ rule = decrypt(bank[0])
293
+ @memory[bank[1]] = rule
294
+ return rule
295
+ end
296
+
297
+ def unique?(rule)
298
+ @memories.each do | memory |
299
+ if memory.eql?(rule)
300
+ return false
301
+ end
302
+ end
303
+ return true
304
+ end
305
+
306
+ end
307
+ end
308
+ end
@@ -0,0 +1,85 @@
1
+ require 'securerandom'
2
+ module Lightning
3
+ module Bolt
4
+ class Cypher
5
+ def initialize(bookstore)
6
+ @bookstore = bookstore
7
+ @reports = []
8
+ bridge(@bookstore)
9
+ end
10
+
11
+ def bridge(dirname)
12
+ data = ''
13
+ Dir.foreach(dirname) do |dir|
14
+ path = dirname + '/' + dir
15
+ if File.directory?(path) then
16
+ if dir != '.' && dir != '..' then
17
+ data += bridge(path)
18
+ end
19
+ else
20
+ capture(path)
21
+ data += path
22
+ end
23
+ end
24
+ return data
25
+ end
26
+
27
+ def arc(pin)
28
+ value = ""
29
+ @reports.each do | report |
30
+ if report["key"].eql?(pin)
31
+ data = report["cypher"]
32
+ xrand = SecureRandom.random_number(data.size)
33
+ value = data[xrand]
34
+ end
35
+ end
36
+ return value
37
+ end
38
+
39
+ private
40
+
41
+ def span(data, path)
42
+ parts = []
43
+ if data.is_a?(Hash)
44
+ data.each do | key, value |
45
+ parts += span(data[key], "#{path}-#{key}")
46
+ end
47
+ else
48
+ parts.push({"key" => path, "cypher" => data})
49
+ end
50
+ return parts
51
+ end
52
+
53
+ def capture(data)
54
+ report = {}
55
+ key = "@:" + data.gsub(@bookstore, "").split(".")[0][1..-1].split("/").join("-")
56
+ ext = File.extname(data)
57
+ cypher = nil
58
+ if ext.match(/yma?l/)
59
+ begin
60
+ cypher = YAML.load_file(data)
61
+ rescue
62
+ end
63
+ elsif ext.match(/json/)
64
+ begin
65
+ cypher = JSON.parse(File.read(data))
66
+ rescue
67
+ end
68
+ elsif ext.match(/txt/)
69
+ begin
70
+ cypher = File.read(data).split("\r\n")
71
+ rescue
72
+ end
73
+ else
74
+ # the file type is not supported
75
+ end
76
+ @reports += span(cypher, key)
77
+ end
78
+
79
+ def srand(min, max)
80
+ return SecureRandom.random_number(max-min)+min
81
+ end
82
+
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,73 @@
1
+ encoding: "UTF-8"
2
+ #encodable:
3
+ #
4
+ non-encodable:
5
+ start: 55296
6
+ end: 57343
7
+ non-printable:
8
+ - code: 0
9
+ char: NUL
10
+ - code: 1
11
+ char: SOH
12
+ - code: 2
13
+ char: STX
14
+ - code: 3
15
+ char: ETX
16
+ - code: 4
17
+ char: EOT
18
+ - code: 5
19
+ char: ENQ
20
+ - code: 6
21
+ char: ACK
22
+ - code: 7
23
+ char: BEL
24
+ - code: 8
25
+ char: BS
26
+ - code: 9
27
+ char: TAB
28
+ - code: A
29
+ char: LF
30
+ - code: B
31
+ char: VT
32
+ - code: C
33
+ char: FF
34
+ - code: D
35
+ char: CR
36
+ - code: E
37
+ char: SO
38
+ - code: F
39
+ char: SI
40
+ - code: 10
41
+ char: DLE
42
+ - code: 11
43
+ char: DC1
44
+ - code: 12
45
+ char: DC2
46
+ - code: 13
47
+ char: DC3
48
+ - code: 14
49
+ char: DC4
50
+ - code: 15
51
+ char: NAK
52
+ - code: 16
53
+ char: SYN
54
+ - code: 17
55
+ char: ETB
56
+ - code: 18
57
+ char: CAN
58
+ - code: 19
59
+ char: EM
60
+ - code: 1A
61
+ char: SUB
62
+ - code: 1B
63
+ char: ESC
64
+ - code: 1C
65
+ char: FS
66
+ - code: 1D
67
+ char: GS
68
+ - code: 1E
69
+ char: RS
70
+ - code: 1F
71
+ char: US
72
+ - code: 7F
73
+ char: DEL