rex-encoder 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. checksums.yaml +7 -0
  2. checksums.yaml.gz.sig +1 -0
  3. data.tar.gz.sig +0 -0
  4. data/.gitignore +9 -0
  5. data/.rspec +2 -0
  6. data/.travis.yml +5 -0
  7. data/CODE_OF_CONDUCT.md +49 -0
  8. data/Gemfile +4 -0
  9. data/README.md +32 -0
  10. data/Rakefile +6 -0
  11. data/bin/console +14 -0
  12. data/bin/setup +8 -0
  13. data/lib/rex/encoder.rb +15 -0
  14. data/lib/rex/encoder/alpha2.rb +31 -0
  15. data/lib/rex/encoder/alpha2/alpha_mixed.rb +129 -0
  16. data/lib/rex/encoder/alpha2/alpha_upper.rb +138 -0
  17. data/lib/rex/encoder/alpha2/generic.rb +90 -0
  18. data/lib/rex/encoder/alpha2/unicode_mixed.rb +116 -0
  19. data/lib/rex/encoder/alpha2/unicode_upper.rb +123 -0
  20. data/lib/rex/encoder/bloxor/bloxor.rb +327 -0
  21. data/lib/rex/encoder/ndr.rb +90 -0
  22. data/lib/rex/encoder/nonalpha.rb +61 -0
  23. data/lib/rex/encoder/nonupper.rb +64 -0
  24. data/lib/rex/encoder/version.rb +5 -0
  25. data/lib/rex/encoder/xdr.rb +108 -0
  26. data/lib/rex/encoder/xor.rb +69 -0
  27. data/lib/rex/encoder/xor/dword.rb +13 -0
  28. data/lib/rex/encoder/xor/dword_additive.rb +13 -0
  29. data/lib/rex/encoding/xor.rb +20 -0
  30. data/lib/rex/encoding/xor/byte.rb +15 -0
  31. data/lib/rex/encoding/xor/dword.rb +21 -0
  32. data/lib/rex/encoding/xor/dword_additive.rb +92 -0
  33. data/lib/rex/encoding/xor/exceptions.rb +17 -0
  34. data/lib/rex/encoding/xor/generic.rb +146 -0
  35. data/lib/rex/encoding/xor/qword.rb +15 -0
  36. data/lib/rex/encoding/xor/word.rb +21 -0
  37. data/lib/rex/poly.rb +134 -0
  38. data/lib/rex/poly/block.rb +480 -0
  39. data/lib/rex/poly/machine.rb +13 -0
  40. data/lib/rex/poly/machine/machine.rb +830 -0
  41. data/lib/rex/poly/machine/x86.rb +509 -0
  42. data/lib/rex/poly/register.rb +101 -0
  43. data/lib/rex/poly/register/x86.rb +41 -0
  44. data/rex-encoder.gemspec +31 -0
  45. metadata +248 -0
  46. metadata.gz.sig +0 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: a1449e0625dd065a353bae94c84d45fd1203d8c2
4
+ data.tar.gz: 23ee448ad20fcf27e45b7afaf7ff290390ebc7b6
5
+ SHA512:
6
+ metadata.gz: aafa688f874e573dfddd9419bf5d2da7bbfdcef327ce4cb26365027a99337f92b44a5405359f364b167596329c0e7d48c23392cd2de27b56822a70d21b0c7fe5
7
+ data.tar.gz: 075779953f26c537005a89e409164278a0d19097fde40c853182a8359a9a0d057843debeeb998d67d2222a99b5a1c5ce9bc46bbbba1118843e24a5e8c18ccb98
@@ -0,0 +1 @@
1
+ c �`a��������u䡆 .�z �!@�o)'�0 �N�Q ��������{ٝ���)ķ��[���5�o$+�=�ō�C:Z���E��Q�>W7���#!ȩ���
Binary file
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
@@ -0,0 +1,5 @@
1
+ sudo: false
2
+ language: ruby
3
+ rvm:
4
+ - 2.3.1
5
+ before_install: gem install bundler -v 1.12.5
@@ -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 DMaloney@rapid7.com. 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 rex-encoder.gemspec
4
+ gemspec
@@ -0,0 +1,32 @@
1
+ # Rex::Encoder
2
+
3
+ This library provides the basis for all of the polymorphic encoders that Metasploit uses for payload encoding.
4
+ Encoders are used to try and create a version of a payload that is free of bad characters as defined by the exploit.
5
+
6
+ ## Installation
7
+
8
+ Add this line to your application's Gemfile:
9
+
10
+ ```ruby
11
+ gem 'rex-encoder'
12
+ ```
13
+
14
+ And then execute:
15
+
16
+ $ bundle
17
+
18
+ Or install it yourself as:
19
+
20
+ $ gem install rex-encoder
21
+
22
+
23
+ ## Development
24
+
25
+ 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.
26
+
27
+ 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).
28
+
29
+ ## Contributing
30
+
31
+ Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/rex-encoder. 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.
32
+
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "rex/encoder"
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
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,15 @@
1
+ require "rex/encoder/version"
2
+ require 'rex/arch'
3
+ require 'rex/poly'
4
+ require 'rex/encoding/xor'
5
+ require 'rex/encoder/alpha2'
6
+ require 'rex/encoder/xor'
7
+ require 'rex/encoder/ndr'
8
+ require 'rex/encoder/nonalpha'
9
+ require 'rex/encoder/nonupper'
10
+ require 'rex/encoder/xdr'
11
+ module Rex
12
+ module Encoder
13
+ # Your code goes here...
14
+ end
15
+ end
@@ -0,0 +1,31 @@
1
+ # -*- coding: binary -*-
2
+
3
+ #
4
+ # ________________________________________________________________________________
5
+ #
6
+ # ,sSSs,,s, ,sSSSs, ALPHA 2: Zero-tolerance. (build 07)
7
+ # SS" Y$P" SY" ,SY
8
+ # iS' dY ,sS" Unicode-proof uppercase alphanumeric shellcode encoding.
9
+ # YS, dSb ,sY" Copyright (C) 2003, 2004 by Berend-Jan Wever.
10
+ # `"YSS'"S' 'SSSSSSSP <skylined@edup.tudelft.nl>
11
+ # ________________________________________________________________________________
12
+ #
13
+
14
+ #
15
+ # make sure the namespace is created
16
+ #
17
+
18
+ module Rex
19
+ module Encoder
20
+ module Alpha2
21
+ end end end
22
+
23
+ #
24
+ # include the Alpha2 encodings
25
+ #
26
+
27
+ require 'rex/encoder/alpha2/generic'
28
+ require 'rex/encoder/alpha2/alpha_mixed'
29
+ require 'rex/encoder/alpha2/alpha_upper'
30
+ require 'rex/encoder/alpha2/unicode_mixed'
31
+ require 'rex/encoder/alpha2/unicode_upper'
@@ -0,0 +1,129 @@
1
+ # -*- coding: binary -*-
2
+
3
+ require 'rex/encoder/alpha2/generic'
4
+
5
+ module Rex
6
+ module Encoder
7
+ module Alpha2
8
+
9
+ class AlphaMixed < Generic
10
+
11
+ # Generates the decoder stub prefix
12
+ #
13
+ # @param [String] reg the register pointing to the encoded payload
14
+ # @param [Fixnum] offset the offset to reach the encoded payload
15
+ # @param [Array] modified_registers accounts the registers modified by the stub
16
+ # @return [String] the alpha mixed decoder stub prefix
17
+ def self.gen_decoder_prefix(reg, offset, modified_registers = [])
18
+ if offset > 32
19
+ raise 'Critical: Offset is greater than 32'
20
+ end
21
+
22
+ mod_registers = []
23
+ nop_regs = []
24
+ mod_regs = []
25
+ edx_regs = []
26
+
27
+ # use inc ebx as a nop here so we still pad correctly
28
+ if offset <= 16
29
+ nop = 'C' * offset
30
+ nop_regs.push(Rex::Arch::X86::EBX) unless nop.empty?
31
+
32
+ mod = 'I' * (16 - offset) + nop + '7QZ' # dec ecx,,, push ecx, pop edx
33
+ mod_regs.push(Rex::Arch::X86::ECX) unless offset == 16
34
+ mod_regs.concat(nop_regs)
35
+ mod_regs.push(Rex::Arch::X86::EDX)
36
+
37
+ edxmod = 'J' * (17 - offset)
38
+ edx_regs.push(Rex::Arch::X86::EDX) unless edxmod.empty?
39
+ else
40
+ mod = 'A' * (offset - 16)
41
+ mod_regs.push(Rex::Arch::X86::ECX) unless mod.empty?
42
+
43
+ nop = 'C' * (16 - mod.length)
44
+ nop_regs.push(Rex::Arch::X86::EBX) unless nop.empty?
45
+
46
+ mod << nop + '7QZ'
47
+ mod_regs.concat(nop_regs)
48
+ mod_regs.push(Rex::Arch::X86::EDX)
49
+
50
+ edxmod = 'B' * (17 - (offset - 16))
51
+ edx_regs.push(Rex::Arch::X86::EDX) unless edxmod.empty?
52
+ end
53
+
54
+ regprefix = {
55
+ 'EAX' => 'PY' + mod, # push eax, pop ecx
56
+ 'ECX' => 'I' + mod, # dec ecx
57
+ 'EDX' => edxmod + nop + '7RY', # dec edx,,, push edx, pop ecx
58
+ 'EBX' => 'SY' + mod, # push ebx, pop ecx
59
+ 'ESP' => 'TY' + mod, # push esp, pop ecx
60
+ 'EBP' => 'UY' + mod, # push ebp, pop ecx
61
+ 'ESI' => 'VY' + mod, # push esi, pop ecx
62
+ 'EDI' => 'WY' + mod, # push edi, pop ecx
63
+ }
64
+
65
+ reg.upcase!
66
+
67
+ unless regprefix.keys.include?(reg)
68
+ raise ArgumentError.new('Invalid register name')
69
+ end
70
+
71
+ case reg
72
+ when 'EDX'
73
+ mod_registers.concat(edx_regs)
74
+ mod_registers.concat(nop_regs)
75
+ mod_registers.push(Rex::Arch::X86::ECX)
76
+ else
77
+ mod_registers.push(Rex::Arch::X86::ECX)
78
+ mod_registers.concat(mod_regs)
79
+ end
80
+
81
+ mod_registers.uniq!
82
+ modified_registers.concat(mod_registers)
83
+
84
+ return regprefix[reg]
85
+ end
86
+
87
+ # Generates the decoder stub
88
+ #
89
+ # @param [String] reg the register pointing to the encoded payload
90
+ # @param [Fixnum] offset the offset to reach the encoded payload
91
+ # @param [Array] modified_registers accounts the registers modified by the stub
92
+ # @return [String] the alpha mixed decoder stub
93
+ def self.gen_decoder(reg, offset, modified_registers = [])
94
+ mod_registers = []
95
+
96
+ decoder =
97
+ gen_decoder_prefix(reg, offset, mod_registers) +
98
+ "jA" + # push 0x41
99
+ "X" + # pop eax
100
+ "P" + # push eax
101
+ "0A0" + # xor byte [ecx+30], al
102
+ "A" + # inc ecx <---
103
+ "kAAQ" + # imul eax, [ecx+42], 51 -> 10 |
104
+ "2AB" + # xor al, [ecx + 42] |
105
+ "2BB" + # xor al, [edx + 42] |
106
+ "0BB" + # xor [edx + 42], al |
107
+ "A" + # inc ecx |
108
+ "B" + # inc edx |
109
+ "X" + # pop eax |
110
+ "P" + # push eax |
111
+ "8AB" + # cmp [ecx + 42], al |
112
+ "uJ" + # jnz short -------------------------
113
+ "I" # first encoded char, fixes the above J
114
+
115
+ mod_registers.concat(
116
+ [
117
+ Rex::Arch::X86::ESP,
118
+ Rex::Arch::X86::EAX,
119
+ Rex::Arch::X86::ECX,
120
+ Rex::Arch::X86::EDX
121
+ ])
122
+
123
+ mod_registers.uniq!
124
+ modified_registers.concat(mod_registers)
125
+
126
+ decoder
127
+ end
128
+
129
+ end end end end
@@ -0,0 +1,138 @@
1
+ # -*- coding: binary -*-
2
+
3
+ require 'rex/encoder/alpha2/generic'
4
+
5
+ module Rex
6
+ module Encoder
7
+ module Alpha2
8
+
9
+ class AlphaUpper < Generic
10
+ def self.default_accepted_chars ; ('B' .. 'Z').to_a + ('0' .. '9').to_a ; end
11
+
12
+ # Generates the decoder stub prefix
13
+ #
14
+ # @param [String] reg the register pointing to the encoded payload
15
+ # @param [Fixnum] offset the offset to reach the encoded payload
16
+ # @param [Array] modified_registers accounts the registers modified by the stub
17
+ # @return [String] the alpha upper decoder stub prefix
18
+ def self.gen_decoder_prefix(reg, offset, modified_registers = [])
19
+ if offset > 20
20
+ raise 'Critical: Offset is greater than 20'
21
+ end
22
+
23
+ mod_registers = []
24
+ nop_regs = []
25
+ mod_regs = []
26
+ edx_regs = []
27
+
28
+ # use inc ebx as a nop here so we still pad correctly
29
+ if (offset <= 10)
30
+ nop = 'C' * offset
31
+ nop_regs.push(Rex::Arch::X86::EBX) unless nop.empty?
32
+
33
+ mod = 'I' * (10 - offset) + nop + 'QZ' # dec ecx,,, push ecx, pop edx
34
+ mod_regs.push(Rex::Arch::X86::ECX) unless offset == 10
35
+ mod_regs.concat(nop_regs)
36
+ mod_regs.push(Rex::Arch::X86::EDX)
37
+
38
+ edxmod = 'J' * (11 - offset)
39
+ edx_regs.push(Rex::Arch::X86::EDX) unless edxmod.empty?
40
+ else
41
+ mod = 'A' * (offset - 10)
42
+ mod_regs.push(Rex::Arch::X86::ECX) unless mod.empty?
43
+
44
+ nop = 'C' * (10 - mod.length)
45
+ nop_regs.push(Rex::Arch::X86::EBX) unless nop.empty?
46
+
47
+ mod << nop + 'QZ'
48
+ mod_regs.concat(nop_regs)
49
+ mod_regs.push(Rex::Arch::X86::EDX)
50
+
51
+ edxmod = 'B' * (11 - (offset - 10))
52
+ edx_regs.push(Rex::Arch::X86::EDX) unless edxmod.empty?
53
+ end
54
+ regprefix = {
55
+ 'EAX' => 'PY' + mod, # push eax, pop ecx
56
+ 'ECX' => 'I' + mod, # dec ecx
57
+ 'EDX' => edxmod + nop + 'RY', # mod edx,,, push edx, pop ecx
58
+ 'EBX' => 'SY' + mod, # push ebx, pop ecx
59
+ 'ESP' => 'TY' + mod, # push esp, pop ecx
60
+ 'EBP' => 'UY' + mod, # push ebp, pop ecx
61
+ 'ESI' => 'VY' + mod, # push esi, pop ecx
62
+ 'EDI' => 'WY' + mod, # push edi, pop ecx
63
+ }
64
+
65
+ reg.upcase!
66
+ unless regprefix.keys.include?(reg)
67
+ raise ArgumentError.new("Invalid register name")
68
+ end
69
+
70
+ case reg
71
+ when 'EDX'
72
+ mod_registers.concat(edx_regs)
73
+ mod_registers.concat(nop_regs)
74
+ mod_registers.push(Rex::Arch::X86::ECX)
75
+ else
76
+ mod_registers.push(Rex::Arch::X86::ECX)
77
+ mod_registers.concat(mod_regs)
78
+ end
79
+
80
+ mod_registers.uniq!
81
+ modified_registers.concat(mod_registers)
82
+
83
+ return regprefix[reg]
84
+ end
85
+
86
+ # Generates the decoder stub
87
+ #
88
+ # @param [String] reg the register pointing to the encoded payload
89
+ # @param [Fixnum] offset the offset to reach the encoded payload
90
+ # @param [Array] modified_registers accounts the registers modified by the stub
91
+ # @return [String] the alpha upper decoder stub
92
+ def self.gen_decoder(reg, offset, modified_registers = [])
93
+ mod_registers = []
94
+
95
+ decoder =
96
+ gen_decoder_prefix(reg, offset, mod_registers) +
97
+ "V" + # push esi
98
+ "T" + # push esp
99
+ "X" + # pop eax
100
+ "30" + # xor esi, [eax]
101
+ "V" + # push esi
102
+ "X" + # pop eax
103
+ "4A" + # xor al, 41
104
+ "P" + # push eax
105
+ "0A3" + # xor [ecx+33], al
106
+ "H" + # dec eax
107
+ "H" + # dec eax
108
+ "0A0" + # xor [ecx+30], al
109
+ "0AB" + # xor [ecx+42], al
110
+ "A" + # inc ecx <---------------
111
+ "A" + # inc ecx |
112
+ "B" + # inc edx |
113
+ "TAAQ" + # imul eax, [ecx+41], 10 * |
114
+ "2AB" + # xor al [ecx+42] |
115
+ "2BB" + # xor al, [edx+42] |
116
+ "0BB" + # xor [edx+42], al |
117
+ "X" + # pop eax |
118
+ "P" + # push eax |
119
+ "8AC" + # cmp [ecx+43], al |
120
+ "JJ" + # jnz * --------------------
121
+ "I" # first encoded char, fixes the above J
122
+
123
+ mod_registers.concat(
124
+ [
125
+ Rex::Arch::X86::ESP,
126
+ Rex::Arch::X86::EAX,
127
+ Rex::Arch::X86::ESI,
128
+ Rex::Arch::X86::ECX,
129
+ Rex::Arch::X86::EDX
130
+ ])
131
+
132
+ mod_registers.uniq!
133
+ modified_registers.concat(mod_registers)
134
+
135
+ return decoder
136
+ end
137
+
138
+ end end end end