turborex 0.1.1

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 (74) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +674 -0
  3. data/README.md +38 -0
  4. data/README.rdoc +19 -0
  5. data/examples/alpc_client.rb +15 -0
  6. data/examples/alpc_server.rb +14 -0
  7. data/examples/com_client.rb +19 -0
  8. data/examples/com_finder.rb +39 -0
  9. data/examples/create_instance.rb +15 -0
  10. data/examples/cstruct.rb +19 -0
  11. data/examples/find_com_client_calls.rb +16 -0
  12. data/examples/find_rpc_security_callback.rb +12 -0
  13. data/examples/rpc_finder.rb +117 -0
  14. data/examples/scan_exports.rb +5 -0
  15. data/examples/scan_imports.rb +5 -0
  16. data/examples/tinysdk.rb +17 -0
  17. data/lib/turborex.rb +21 -0
  18. data/lib/turborex/cstruct.rb +565 -0
  19. data/lib/turborex/cstruct/struct_helper.rb +7 -0
  20. data/lib/turborex/exception.rb +65 -0
  21. data/lib/turborex/fuzzer.rb +204 -0
  22. data/lib/turborex/fuzzer/containers.rb +115 -0
  23. data/lib/turborex/fuzzer/coverage.rb +67 -0
  24. data/lib/turborex/fuzzer/mutators.rb +25 -0
  25. data/lib/turborex/fuzzer/seed.rb +30 -0
  26. data/lib/turborex/monkey.rb +11 -0
  27. data/lib/turborex/msrpc.rb +14 -0
  28. data/lib/turborex/msrpc/decompiler.rb +244 -0
  29. data/lib/turborex/msrpc/midl.rb +747 -0
  30. data/lib/turborex/msrpc/ndrtype.rb +167 -0
  31. data/lib/turborex/msrpc/rpcbase.rb +777 -0
  32. data/lib/turborex/msrpc/rpcfinder.rb +1426 -0
  33. data/lib/turborex/msrpc/utils.rb +70 -0
  34. data/lib/turborex/pefile.rb +8 -0
  35. data/lib/turborex/pefile/pe.rb +61 -0
  36. data/lib/turborex/pefile/scanner.rb +82 -0
  37. data/lib/turborex/utils.rb +321 -0
  38. data/lib/turborex/windows.rb +402 -0
  39. data/lib/turborex/windows/alpc.rb +844 -0
  40. data/lib/turborex/windows/com.rb +266 -0
  41. data/lib/turborex/windows/com/client.rb +84 -0
  42. data/lib/turborex/windows/com/com_finder.rb +330 -0
  43. data/lib/turborex/windows/com/com_registry.rb +100 -0
  44. data/lib/turborex/windows/com/interface.rb +522 -0
  45. data/lib/turborex/windows/com/utils.rb +210 -0
  46. data/lib/turborex/windows/constants.rb +82 -0
  47. data/lib/turborex/windows/process.rb +56 -0
  48. data/lib/turborex/windows/security.rb +12 -0
  49. data/lib/turborex/windows/security/ace.rb +76 -0
  50. data/lib/turborex/windows/security/acl.rb +25 -0
  51. data/lib/turborex/windows/security/security_descriptor.rb +118 -0
  52. data/lib/turborex/windows/tinysdk.rb +89 -0
  53. data/lib/turborex/windows/utils.rb +138 -0
  54. data/resources/headers/alpc/ntdef.h +72 -0
  55. data/resources/headers/alpc/ntlpcapi.h +1014 -0
  56. data/resources/headers/rpc/common.h +162 -0
  57. data/resources/headers/rpc/guiddef.h +191 -0
  58. data/resources/headers/rpc/internal_ndrtypes.h +262 -0
  59. data/resources/headers/rpc/rpc.h +10 -0
  60. data/resources/headers/rpc/rpcdce.h +266 -0
  61. data/resources/headers/rpc/rpcdcep.h +187 -0
  62. data/resources/headers/rpc/rpcndr.h +39 -0
  63. data/resources/headers/rpc/v4_x64/rpcinternals.h +154 -0
  64. data/resources/headers/rpc/wintype.h +517 -0
  65. data/resources/headers/tinysdk/tinysdk.h +5 -0
  66. data/resources/headers/tinysdk/tinysdk/comdef.h +645 -0
  67. data/resources/headers/tinysdk/tinysdk/dbghelp.h +118 -0
  68. data/resources/headers/tinysdk/tinysdk/guiddef.h +194 -0
  69. data/resources/headers/tinysdk/tinysdk/memoryapi.h +12 -0
  70. data/resources/headers/tinysdk/tinysdk/poppack.h +12 -0
  71. data/resources/headers/tinysdk/tinysdk/pshpack4.h +13 -0
  72. data/resources/headers/tinysdk/tinysdk/winnt.h +1059 -0
  73. data/resources/headers/tinysdk/tinysdk/wintype.h +326 -0
  74. metadata +290 -0
@@ -0,0 +1,7 @@
1
+ module TurboRex
2
+ module CStruct
3
+ module Helper
4
+
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,65 @@
1
+ module TurboRex
2
+ module Exception
3
+
4
+ module ALPC
5
+ include Exception
6
+
7
+ class BufferTooSmall < RuntimeError
8
+ def to_s
9
+ "The length of Buffer is too small."
10
+ end
11
+ end
12
+
13
+ class TooManyRetries < RuntimeError
14
+ def to_s
15
+ "Too many retries."
16
+ end
17
+ end
18
+
19
+ class UnknownPayloadType < RuntimeError
20
+ def to_s
21
+ "The payload type is invalid."
22
+ end
23
+ end
24
+
25
+ class ReplyMessageMismatch < RuntimeError
26
+ def to_s
27
+ "An attempt was made to reply to an LPC message, but the thread specified by the client ID in the message was not waiting on that message."
28
+ end
29
+ end
30
+
31
+ class UnableToAcceptConnection < RuntimeError
32
+
33
+ end
34
+ end
35
+
36
+ module MSRPC
37
+ class InvalidParamDescriptor < StandardError
38
+ end
39
+
40
+ class InvalidTypeFormatString < StandardError
41
+
42
+ end
43
+
44
+ class UnknownSymbolName < StandardError
45
+
46
+ end
47
+ end
48
+
49
+ class UnknownError < StandardError
50
+ def to_s
51
+ "An unknown error occurred."
52
+ end
53
+ end
54
+
55
+ class NotNTSuccess < StandardError
56
+ def initialize(ntstatus='')
57
+ @message = "The return value isn't one of NT_SUCCESS: #{ntstatus}"
58
+ end
59
+
60
+ def to_s
61
+ @message
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,204 @@
1
+ require 'turborex/windows/com'
2
+ require 'turborex/fuzzer/containers'
3
+ require 'turborex/fuzzer/mutators'
4
+ require 'turborex/fuzzer/coverage'
5
+ require 'turborex/fuzzer/seed'
6
+
7
+ module TurboRex
8
+ module Fuzzer
9
+ class InputBase
10
+
11
+ end
12
+
13
+ class FuzzerBase
14
+
15
+ end
16
+
17
+ class COMFuzzer < FuzzerBase
18
+ class Config
19
+ attr_reader :target
20
+
21
+ def new_target(&block)
22
+ @target = Docile.dsl_eval(TargetBuilder.new, &block).build
23
+ end
24
+
25
+ def build
26
+ self
27
+ end
28
+ end
29
+
30
+ Target = Struct.new(:clsid, :interface, :method, :params, :context)
31
+ Parameter = Struct.new(:index, :container, :mutator, :fixed, :seed, :depends_on, :relationship)
32
+
33
+ class ParamBuilder
34
+ def initialize(index, args)
35
+ @args = args
36
+ @struct = Parameter.new
37
+ @struct.index = index
38
+ end
39
+
40
+ def container(c)
41
+ @struct.container = c
42
+ end
43
+
44
+ def seed(s, opts = {})
45
+
46
+ if s.is_a?(Array)
47
+ elsif s.is_a?(TurboRex::Fuzzer::Seed)
48
+ s = [s]
49
+ else
50
+ raise "Invalid seed type: #{s.class}"
51
+ end
52
+
53
+ @struct.seed = s
54
+
55
+ if opts[:depends_on] && opts[:relationship]
56
+ depends_arg = @args.find {|a| a.name == opts[:depends_on].to_s}
57
+ unless depends_arg
58
+ raise "No such parameter: #{opts[:depends_on]}"
59
+ end
60
+
61
+ @struct.depends_on = opts[:depends_on]
62
+ @struct.relationship = opts[:relationship]
63
+ end
64
+ end
65
+
66
+ def mutator(m)
67
+ @struct.mutator = m
68
+ end
69
+
70
+ def fixed(value)
71
+ @struct.fixed = value
72
+ end
73
+
74
+ def build
75
+ @struct
76
+ end
77
+ end
78
+
79
+ class TargetBuilder
80
+ def initialize
81
+ @params = []
82
+ end
83
+
84
+ def interface(iface)
85
+ @interface = iface
86
+ end
87
+
88
+ def clsid(clsid)
89
+ @clsid = clsid
90
+ end
91
+
92
+ def context(context)
93
+ @context = context
94
+ end
95
+
96
+ def method(name)
97
+ method = @interface.methods.find {|m| m.name == name.to_s}
98
+ raise "No such method #{name}" unless method
99
+
100
+ @method = method
101
+ end
102
+
103
+ def build
104
+ Target.new(@clsid, @interface, @method, @params, @context)
105
+ end
106
+
107
+ def method_missing(m, *args, &block)
108
+ if m.to_s.start_with?('param_')
109
+ name = m.to_s.split('param_')[-1]
110
+
111
+ index = @method.type.args.index {|a| a.name == name}
112
+ raise "No such parameter #{name}" unless index
113
+ arg = @method.type.args[index]
114
+ raise "The THIS pointer can't be specified." if index == 0
115
+ @params[index-1] = Docile.dsl_eval(ParamBuilder.new(index-1, @method.type.args), &block).build
116
+ else
117
+ super(m, *args, &block)
118
+ end
119
+ end
120
+ end
121
+
122
+ class Input < InputBase
123
+ def initialize(config)
124
+ configure = config.fuzzer_configure
125
+ target = configure.target
126
+ @clsid = target.clsid
127
+ @interface = target.interface
128
+ @method = target.method
129
+ @method_name = @method.name.to_sym
130
+
131
+ @client = TurboRex::Windows::COM::Client.new(@clsid)
132
+ @client.create_instance cls_context: target.context, interface: @interface
133
+ end
134
+
135
+ def feed(*args)
136
+ #raw_args = args.map {|a| a.buf}
137
+ #feed_raw(*raw_args)
138
+ @interface.send(@method_name, *args)
139
+ end
140
+
141
+ # def feed_raw(*args)
142
+ # @interface.send(@method_name, *args)
143
+ # end
144
+ end
145
+
146
+ attr_reader :input
147
+ attr_reader :config
148
+
149
+ def initialize(config)
150
+ @config = config
151
+ @input = Input.new(config)
152
+ @growth_medium = []
153
+
154
+ params = config.fuzzer_configure.target.params
155
+ params.each do |p|
156
+ if p.fixed
157
+ p.container.fixed = p.fixed
158
+ end
159
+
160
+ TurboRex::Fuzzer::SeedGroup.new()
161
+ @growth_medium << p.container
162
+ end
163
+
164
+ params.map {|p| p.seed }
165
+ end
166
+
167
+ def generate
168
+ @growth_medium.map {|c| c.padding }
169
+ end
170
+
171
+ end
172
+
173
+ class Config
174
+ attr_reader :mechanism
175
+ attr_reader :fuzzer_configure
176
+
177
+ def mechanism=(m)
178
+ raise "Should be one of these values: 'rpc', 'com'" unless [:com, :rpc].include?(m.to_sym)
179
+ @mechanism = m
180
+ end
181
+
182
+ def configure(&block)
183
+ case mechanism.to_sym
184
+ when :rpc
185
+ raise NotImplementedError
186
+ when :com
187
+ @fuzzer_configure = Docile.dsl_eval(COMFuzzer::Config.new, &block).build
188
+ end
189
+ end
190
+ end
191
+
192
+ def self.create_fuzzer(&block)
193
+ config = Config.new
194
+ yield(config)
195
+
196
+ case config.mechanism.to_sym
197
+ when :com
198
+ COMFuzzer.new(config)
199
+ when :rpc
200
+ #RPCFuzzer.new(config)
201
+ end
202
+ end
203
+ end
204
+ end
@@ -0,0 +1,115 @@
1
+ require 'turborex/windows'
2
+
3
+ module TurboRex
4
+ module Fuzzer
5
+ module Container
6
+ class ContainerBase
7
+ attr_reader :buf
8
+
9
+ def fixed=(v)
10
+ @fixed = true
11
+ set_data v
12
+ end
13
+
14
+ def mutate(mutator)
15
+ return @buf if @fixed
16
+ set_data mutator.mutate(@buf)
17
+ end
18
+ end
19
+
20
+ class BooleanContainer
21
+
22
+ end
23
+
24
+ class ByteContainer
25
+
26
+ end
27
+
28
+ class SmallContainer
29
+
30
+ end
31
+
32
+ class ShortContainer
33
+
34
+ end
35
+
36
+ class LongContainer
37
+
38
+ end
39
+
40
+ class HyperContainer
41
+
42
+ end
43
+
44
+ class FloatContainer
45
+
46
+ end
47
+
48
+ class DoubleContainer
49
+
50
+ end
51
+
52
+ class CharContainer
53
+
54
+ end
55
+
56
+ class WchartContainer
57
+
58
+ end
59
+
60
+ class OLESTRContainer < ContainerBase
61
+ def set_data(data)
62
+ wchar = TurboRex::Windows::Utils.multibyte_to_widechar(data)
63
+ @buf = TurboRex::Windows::Win32API.alloc_c_ary('WCHAR', @length / 2)
64
+ @buf.str = wchar
65
+ @buf
66
+ end
67
+ end
68
+
69
+ class BSTRContainer
70
+ def set_data(data)
71
+ if data.is_a? OLESTRContainer
72
+
73
+ else
74
+
75
+ end
76
+ end
77
+ end
78
+
79
+ class FixedSizeBufferContainer < ContainerBase
80
+ def initialize(size, opts = {})
81
+ @size = size
82
+ @offset = @opts[:offset]
83
+ @buf = TurboRex::Windows::Win32API.alloc_c_ary('BYTE', @size)
84
+ end
85
+
86
+ def set_data(data)
87
+ @offset ? @buf.str[@offset] = data : @buf.str = data
88
+ end
89
+ end
90
+
91
+ class VariantSizeBufferContainer < ContainerBase
92
+ def set_data(data)
93
+ @buf = TurboRex::Windows::Win32API.alloc_c_ary('BYTE', data.bytesize)
94
+ @buf.str = data
95
+ @buf
96
+ end
97
+ end
98
+
99
+ class StructureContainer < ContainerBase
100
+ def initialize(name, typedef=nil, opts = {})
101
+ if typedef
102
+ TurboRex::Windows::Win32API.parse_c(typedef)
103
+ end
104
+
105
+ @buf = TurboRex::Windows::Win32API.alloc_c_struct(name)
106
+ @member = opts[:member]
107
+ end
108
+
109
+ def set_data(data)
110
+ @member ? @buf.send("#{@member}=", data) : @buf.str = data
111
+ end
112
+ end
113
+ end
114
+ end
115
+ end
@@ -0,0 +1,67 @@
1
+ module TurboRex
2
+ module Fuzzer
3
+ class CoverageClient
4
+ def initialize(mapping_name, buf_size=65536)
5
+ setting_mapping(mapping_name, buf_size)
6
+ @virgin_bits = [0xFF] * buf_size
7
+ @view_size = buf_size
8
+ @bitmap_size = 0
9
+ end
10
+
11
+ def trace_bits
12
+ page = [0].pack('C')*@view_size
13
+ return if TurboRex::Windows::Win32API.readprocessmemory(-1, @buf, page, @view_size, 0) == 0
14
+ page
15
+ end
16
+
17
+ # def has_new_bits?(trace_bits=trace_bits, virgin_bits=@virgin_bits)
18
+ # ret = false
19
+ # trace_bits.bytes.to_a.each do |b, i|
20
+ # virgin_bit = virgin_bits[i]
21
+ # unless (b & virgin_bit).zero?
22
+ # unless ret
23
+ # if virgin_bit == 0xFF
24
+ # ret = true
25
+ # @bitmap_size += 1
26
+ # else
27
+ # ret = :new_hit
28
+ # end
29
+ # end
30
+
31
+ # virgin_byte = virgin_byte & ~b
32
+ # virgin_bits[i] = virgin_bit
33
+ # end
34
+ # end
35
+
36
+ # ret
37
+ # end
38
+
39
+ private
40
+
41
+ def setting_mapping(mapping_name, buf_size)
42
+ @mapping_name = mapping_name
43
+
44
+ @hmap = TurboRex::Windows::Win32API.openfilemappinga(
45
+ TurboRex::Windows::Win32API::FILE_MAP_ALL_ACCESS,
46
+ false,
47
+ mapping_name
48
+ )
49
+
50
+ raise "Error opening file mapping" unless @hmap
51
+
52
+ @buf = TurboRex::Windows::Win32API.mapviewoffile(
53
+ @hmap,
54
+ TurboRex::Windows::Win32API::FILE_MAP_ALL_ACCESS,
55
+ 0,
56
+ 0,
57
+ buf_size
58
+ )
59
+
60
+ unless @buf
61
+ TurboRex::Windows::Win32API.closehandle(@hmap)
62
+ raise "Error mapping view of file"
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end