rex-encoder 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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