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.
- checksums.yaml +7 -0
- data/LICENSE +674 -0
- data/README.md +38 -0
- data/README.rdoc +19 -0
- data/examples/alpc_client.rb +15 -0
- data/examples/alpc_server.rb +14 -0
- data/examples/com_client.rb +19 -0
- data/examples/com_finder.rb +39 -0
- data/examples/create_instance.rb +15 -0
- data/examples/cstruct.rb +19 -0
- data/examples/find_com_client_calls.rb +16 -0
- data/examples/find_rpc_security_callback.rb +12 -0
- data/examples/rpc_finder.rb +117 -0
- data/examples/scan_exports.rb +5 -0
- data/examples/scan_imports.rb +5 -0
- data/examples/tinysdk.rb +17 -0
- data/lib/turborex.rb +21 -0
- data/lib/turborex/cstruct.rb +565 -0
- data/lib/turborex/cstruct/struct_helper.rb +7 -0
- data/lib/turborex/exception.rb +65 -0
- data/lib/turborex/fuzzer.rb +204 -0
- data/lib/turborex/fuzzer/containers.rb +115 -0
- data/lib/turborex/fuzzer/coverage.rb +67 -0
- data/lib/turborex/fuzzer/mutators.rb +25 -0
- data/lib/turborex/fuzzer/seed.rb +30 -0
- data/lib/turborex/monkey.rb +11 -0
- data/lib/turborex/msrpc.rb +14 -0
- data/lib/turborex/msrpc/decompiler.rb +244 -0
- data/lib/turborex/msrpc/midl.rb +747 -0
- data/lib/turborex/msrpc/ndrtype.rb +167 -0
- data/lib/turborex/msrpc/rpcbase.rb +777 -0
- data/lib/turborex/msrpc/rpcfinder.rb +1426 -0
- data/lib/turborex/msrpc/utils.rb +70 -0
- data/lib/turborex/pefile.rb +8 -0
- data/lib/turborex/pefile/pe.rb +61 -0
- data/lib/turborex/pefile/scanner.rb +82 -0
- data/lib/turborex/utils.rb +321 -0
- data/lib/turborex/windows.rb +402 -0
- data/lib/turborex/windows/alpc.rb +844 -0
- data/lib/turborex/windows/com.rb +266 -0
- data/lib/turborex/windows/com/client.rb +84 -0
- data/lib/turborex/windows/com/com_finder.rb +330 -0
- data/lib/turborex/windows/com/com_registry.rb +100 -0
- data/lib/turborex/windows/com/interface.rb +522 -0
- data/lib/turborex/windows/com/utils.rb +210 -0
- data/lib/turborex/windows/constants.rb +82 -0
- data/lib/turborex/windows/process.rb +56 -0
- data/lib/turborex/windows/security.rb +12 -0
- data/lib/turborex/windows/security/ace.rb +76 -0
- data/lib/turborex/windows/security/acl.rb +25 -0
- data/lib/turborex/windows/security/security_descriptor.rb +118 -0
- data/lib/turborex/windows/tinysdk.rb +89 -0
- data/lib/turborex/windows/utils.rb +138 -0
- data/resources/headers/alpc/ntdef.h +72 -0
- data/resources/headers/alpc/ntlpcapi.h +1014 -0
- data/resources/headers/rpc/common.h +162 -0
- data/resources/headers/rpc/guiddef.h +191 -0
- data/resources/headers/rpc/internal_ndrtypes.h +262 -0
- data/resources/headers/rpc/rpc.h +10 -0
- data/resources/headers/rpc/rpcdce.h +266 -0
- data/resources/headers/rpc/rpcdcep.h +187 -0
- data/resources/headers/rpc/rpcndr.h +39 -0
- data/resources/headers/rpc/v4_x64/rpcinternals.h +154 -0
- data/resources/headers/rpc/wintype.h +517 -0
- data/resources/headers/tinysdk/tinysdk.h +5 -0
- data/resources/headers/tinysdk/tinysdk/comdef.h +645 -0
- data/resources/headers/tinysdk/tinysdk/dbghelp.h +118 -0
- data/resources/headers/tinysdk/tinysdk/guiddef.h +194 -0
- data/resources/headers/tinysdk/tinysdk/memoryapi.h +12 -0
- data/resources/headers/tinysdk/tinysdk/poppack.h +12 -0
- data/resources/headers/tinysdk/tinysdk/pshpack4.h +13 -0
- data/resources/headers/tinysdk/tinysdk/winnt.h +1059 -0
- data/resources/headers/tinysdk/tinysdk/wintype.h +326 -0
- metadata +290 -0
@@ -0,0 +1,210 @@
|
|
1
|
+
module TurboRex
|
2
|
+
class Windows < Metasm::WinOS
|
3
|
+
module COM
|
4
|
+
module Utils
|
5
|
+
def self.marshal_interface(object, mshctx=MSHCTX_DIFFERENTMACHINE, mshlflags=MSHLFLAGS_NORMAL)
|
6
|
+
iid = object.iid
|
7
|
+
_iid = "{#{iid}}"
|
8
|
+
pstr_iid = Win32API.alloc_c_ary('OLECHAR', _iid.chars.push(0).map{|c|c.ord})
|
9
|
+
iid = Win32API.alloc_c_struct('CLSID')
|
10
|
+
Win32API.clsidfromstring(pstr_iid, iid)
|
11
|
+
|
12
|
+
istream = create_istream
|
13
|
+
hr = Win32API.comarshalinterface(istream.this, iid, object.this, mshctx, 0, mshlflags)
|
14
|
+
return false unless TinySDK.nt_success?(hr)
|
15
|
+
istream
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.marshal_interface_to_string(object, mshctx=MSHCTX_DIFFERENTMACHINE, mshlflags=MSHLFLAGS_NORMAL)
|
19
|
+
# https://thrysoee.dk/InsideCOM+/ch15c.htm
|
20
|
+
istream = marshal_interface(object, mshctx, mshlflags)
|
21
|
+
return false unless istream
|
22
|
+
phglobal = Win32API.alloc_c_ptr('HGLOBAL')
|
23
|
+
size = Win32API.alloc_c_ptr('ULONG')
|
24
|
+
|
25
|
+
iid = object.iid
|
26
|
+
_iid = "{#{iid}}"
|
27
|
+
pstr_iid = Win32API.alloc_c_ary('OLECHAR', _iid.chars.push(0).map{|c|c.ord})
|
28
|
+
iid = Win32API.alloc_c_struct('CLSID')
|
29
|
+
Win32API.clsidfromstring(pstr_iid, iid)
|
30
|
+
|
31
|
+
hr = Win32API.cogetmarshalsizemax(size, iid, object.this, mshctx, 0, mshlflags)
|
32
|
+
return false unless TinySDK.nt_success?(hr)
|
33
|
+
|
34
|
+
Win32API.gethglobalfromstream(istream.this, phglobal)
|
35
|
+
addr = Win32API.globallock(phglobal[0])
|
36
|
+
|
37
|
+
objref = Win32API.memory_read(addr, size[0])
|
38
|
+
Win32API.globalunlock(phglobal[0])
|
39
|
+
istream.Release
|
40
|
+
|
41
|
+
objref
|
42
|
+
end
|
43
|
+
|
44
|
+
def self.unmarshal_interface(stream, riid, interface=nil)
|
45
|
+
riid =~ /\{.+\}/ ? _iid = riid : _iid = "{#{riid}}"
|
46
|
+
|
47
|
+
pstr_iid = Win32API.alloc_c_ary('OLECHAR', _iid.chars.push(0).map{|c|c.ord})
|
48
|
+
iid = Win32API.alloc_c_struct('CLSID')
|
49
|
+
ppv = Win32API.alloc_c_ptr('PVOID')
|
50
|
+
Win32API.clsidfromstring(pstr_iid, iid)
|
51
|
+
|
52
|
+
hr = Win32API.counmarshalinterface(stream.this, iid, ppv)
|
53
|
+
raise hr.to_s unless TinySDK.nt_success?(hr)
|
54
|
+
|
55
|
+
pthis = ppv[0]
|
56
|
+
return pthis unless interface
|
57
|
+
|
58
|
+
interface.this = pthis
|
59
|
+
interface
|
60
|
+
end
|
61
|
+
|
62
|
+
def self.unmarshal_interface_from_string(objref, riid, interface=nil)
|
63
|
+
istream = create_istream
|
64
|
+
return false unless istream
|
65
|
+
|
66
|
+
buf = Win32API.alloc_c_ary('BYTE', objref.bytesize)
|
67
|
+
buf.str = objref
|
68
|
+
hr = istream.Write(buf, objref.bytesize, 0)
|
69
|
+
return false unless TinySDK.nt_success?(hr)
|
70
|
+
|
71
|
+
# WTF? Why dlibMove won't work?
|
72
|
+
# dlibMove = Win32API.alloc_c_struct('LARGE_INTEGER')
|
73
|
+
# dlibMove.QuadPart = 0
|
74
|
+
# istream.Seek(dlibMove, 0, 0)
|
75
|
+
|
76
|
+
istream.Seek(0, 0, 0)
|
77
|
+
|
78
|
+
phglobal = Win32API.alloc_c_ptr('HGLOBAL')
|
79
|
+
Win32API.gethglobalfromstream(istream.this, phglobal)
|
80
|
+
addr = Win32API.globallock(phglobal[0])
|
81
|
+
objref = Win32API.memory_read(addr, 292)
|
82
|
+
|
83
|
+
unmarshal_interface(istream, riid, interface)
|
84
|
+
end
|
85
|
+
|
86
|
+
def self.create_istream
|
87
|
+
ppstm = Win32API.alloc_c_ptr('LPSTREAM')
|
88
|
+
hr = Win32API.createstreamonhglobal(0, 1, ppstm)
|
89
|
+
return false unless TinySDK.nt_success?(hr)
|
90
|
+
istream = Interface::IStream.new
|
91
|
+
istream.this = ppstm[0]
|
92
|
+
istream
|
93
|
+
end
|
94
|
+
|
95
|
+
def self.create_istorage(name, mode=STGM_SHARE_EXCLUSIVE|STGM_CREATE|STGM_READWRITE)
|
96
|
+
wname = Win32API.alloc_c_ary('WCHAR', name.chars.map{|c|c.unpack('C').first}.push(0))
|
97
|
+
ppstgOpen = Win32API.alloc_c_ptr('LPSTORAGE')
|
98
|
+
hr = Win32API.stgcreatedocfile(wname, mode, 0, ppstgOpen)
|
99
|
+
return false unless TinySDK.nt_success?(hr)
|
100
|
+
istorage = Interface::IStorage.new
|
101
|
+
istorage.this = ppstgOpen[0]
|
102
|
+
istorage
|
103
|
+
end
|
104
|
+
|
105
|
+
def self.clsid_to_raw(clsid)
|
106
|
+
pstr_clsid = INTERNAL_APIPROXY.alloc_c_ary('OLECHAR', "{#{clsid}}".chars.push(0).map{|c|c.ord})
|
107
|
+
pclsid = INTERNAL_APIPROXY.alloc_c_ptr('CLSID')
|
108
|
+
return unless INTERNAL_APIPROXY.clsidfromstring(pstr_clsid, pclsid).nil?
|
109
|
+
pclsid
|
110
|
+
end
|
111
|
+
|
112
|
+
def self.dll_get_class_object(rclsid, dll, interface=Interface::IClassFactory.new)
|
113
|
+
_api_proxy = TurboRex::Windows::COM::INTERNAL_APIPROXY.dup
|
114
|
+
_api_proxy.new_api_c <<-EOS, dll
|
115
|
+
HRESULT DllGetClassObject(
|
116
|
+
REFCLSID rclsid,
|
117
|
+
REFIID riid,
|
118
|
+
LPVOID *ppv
|
119
|
+
);
|
120
|
+
EOS
|
121
|
+
|
122
|
+
rclsid = clsid_to_raw(rclsid)
|
123
|
+
riid = clsid_to_raw(interface.iid)
|
124
|
+
ppv = _api_proxy.alloc_c_ptr('PVOID')
|
125
|
+
|
126
|
+
unless hr = _api_proxy.dllgetclassobject(rclsid, riid, ppv)
|
127
|
+
interface.this = ppv[0]
|
128
|
+
return interface
|
129
|
+
end
|
130
|
+
|
131
|
+
raise "Failed to call DllGetClassObject(): #{TinySDK.format_hex_ntstatus(hr, hex_str: true)}"
|
132
|
+
end
|
133
|
+
|
134
|
+
def get_disptbl_count(proxy_file_info)
|
135
|
+
pcif_stub_vtbl_list = to_ptr(@memory.get_page(proxy_file_info.pStubVtblList, @ptr_len))
|
136
|
+
if_stub_vtbl = TurboRex::Windows::COM::INTERNAL_APIPROXY.alloc_c_struct('CInterfaceStubVtbl')
|
137
|
+
if_stub_vtbl.str = @memory.get_page(pcif_stub_vtbl_list, if_stub_vtbl.sizeof)
|
138
|
+
return if_stub_vtbl.header.DispatchTableCount
|
139
|
+
end
|
140
|
+
|
141
|
+
def get_proxy_file_info(iid)
|
142
|
+
# TODO: Replace to call CoGetPSClsid()
|
143
|
+
require 'win32/registry'
|
144
|
+
Win32::Registry::HKEY_CLASSES_ROOT.open("Interface\\{#{iid}}") do |reg|
|
145
|
+
psclsid32_key = reg.open('ProxyStubClsid32')
|
146
|
+
ps_clsid = psclsid32_key.read('').last
|
147
|
+
psclsid32_key.close
|
148
|
+
|
149
|
+
Win32::Registry::HKEY_CLASSES_ROOT.open("CLSID\\#{ps_clsid}") do |reg_clsid|
|
150
|
+
inproc32_key = reg_clsid.open('InprocServer32')
|
151
|
+
dll_path = inproc32_key.read_s_expand('')
|
152
|
+
inproc32_key.close
|
153
|
+
return internal_get_proxyfile(dll_path, ps_clsid.delete('{}'))
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
# Note: The interface stub should be standard.
|
159
|
+
def get_pid_by_std_objref(interface)
|
160
|
+
objref = TurboRex::Windows::Win32API.decode_c_struct('OBJREF', interface.marshal_to_string)
|
161
|
+
objref.u_standard.std.ipid.Data2
|
162
|
+
end
|
163
|
+
|
164
|
+
def internal_get_proxyfile(path, clsid)
|
165
|
+
_api_proxy = TurboRex::Windows::COM::INTERNAL_APIPROXY.dup
|
166
|
+
_api_proxy.new_api_c <<-EOS, path
|
167
|
+
void RPC_ENTRY GetProxyDllInfo( const ProxyFileInfo*** pInfo, const CLSID ** pId );
|
168
|
+
HRESULT DllGetClassObject(
|
169
|
+
REFCLSID rclsid,
|
170
|
+
REFIID riid,
|
171
|
+
LPVOID *ppv
|
172
|
+
);
|
173
|
+
EOS
|
174
|
+
|
175
|
+
begin
|
176
|
+
ppproxy_fileinfo = _api_proxy.alloc_c_ptr('PVOID')
|
177
|
+
proxy_file_info = _api_proxy.alloc_c_struct('ProxyFileInfo')
|
178
|
+
ppclsid = _api_proxy.alloc_c_ptr('PVOID')
|
179
|
+
_api_proxy.getproxydllinfo(ppproxy_fileinfo, ppclsid)
|
180
|
+
pproxy_file_info = to_ptr(@memory.get_page(to_ptr(ppproxy_fileinfo.str), @ptr_len))
|
181
|
+
proxy_file_info.str = @memory.get_page(pproxy_file_info, proxy_file_info.sizeof)
|
182
|
+
rescue NoMethodError # GetProxyDllInfo() is not exported
|
183
|
+
ipsfactory = Interface::IPSFactoryBuffer.new
|
184
|
+
Utils.dll_get_class_object(clsid, path, ipsfactory)
|
185
|
+
cstd_psfactory = _api_proxy.alloc_c_struct('CStdPSFactoryBuffer')
|
186
|
+
cstd_psfactory.str = @memory.get_page(ipsfactory.this, cstd_psfactory.sizeof)
|
187
|
+
|
188
|
+
pproxy_file_info = to_ptr(@memory.get_page(cstd_psfactory.pProxyFileList, @ptr_len))
|
189
|
+
proxy_file_info = _api_proxy.alloc_c_struct('ProxyFileInfo')
|
190
|
+
proxy_file_info.str = @memory.get_page(pproxy_file_info, proxy_file_info.sizeof)
|
191
|
+
ipsfactory.Release
|
192
|
+
end
|
193
|
+
|
194
|
+
proxy_file_info
|
195
|
+
end
|
196
|
+
|
197
|
+
def to_ptr(raw)
|
198
|
+
format = case @ptr_len
|
199
|
+
when 8
|
200
|
+
'Q'
|
201
|
+
when 4
|
202
|
+
'L'
|
203
|
+
end
|
204
|
+
|
205
|
+
raw.unpack(format).first
|
206
|
+
end
|
207
|
+
end
|
208
|
+
end
|
209
|
+
end
|
210
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module TurboRex
|
4
|
+
class Windows < Metasm::WinOS
|
5
|
+
module Constants
|
6
|
+
# Impersonation Level
|
7
|
+
SecurityAnonymous = 0
|
8
|
+
SecurityIdentification = 1
|
9
|
+
SecurityImpersonation = 2
|
10
|
+
SecurityDelegation = 3
|
11
|
+
|
12
|
+
# Security Descriptor Control
|
13
|
+
SE_OWNER_DEFAULTED = 0x0001
|
14
|
+
SE_GROUP_DEFAULTED = 0x0002
|
15
|
+
SE_DACL_PRESENT = 0x0004
|
16
|
+
SE_DACL_DEFAULTED = 0x0008
|
17
|
+
SE_SACL_PRESENT = 0x0010
|
18
|
+
SE_SACL_DEFAULTED = 0x0020
|
19
|
+
SE_DACL_AUTO_INHERIT_REQ = 0x0100
|
20
|
+
SE_SACL_AUTO_INHERIT_REQ = 0x0200
|
21
|
+
SE_DACL_AUTO_INHERITED = 0x0400
|
22
|
+
SE_SACL_AUTO_INHERITED = 0x0800
|
23
|
+
SE_DACL_PROTECTED = 0x1000
|
24
|
+
SE_SACL_PROTECTED = 0x2000
|
25
|
+
SE_RM_CONTROL_VALID = 0x4000
|
26
|
+
SE_SELF_RELATIVE = 0x8000
|
27
|
+
|
28
|
+
## ACE Type
|
29
|
+
ACCESS_MIN_MS_ACE_TYPE = 0x0
|
30
|
+
ACCESS_ALLOWED_ACE_TYPE = 0x0
|
31
|
+
ACCESS_DENIED_ACE_TYPE = 0x1
|
32
|
+
SYSTEM_AUDIT_ACE_TYPE = 0x2
|
33
|
+
SYSTEM_ALARM_ACE_TYPE = 0x3
|
34
|
+
ACCESS_MAX_MS_V2_ACE_TYPE = 0x3
|
35
|
+
|
36
|
+
ACCESS_ALLOWED_COMPOUND_ACE_TYPE = 0x4
|
37
|
+
ACCESS_MAX_MS_V3_ACE_TYPE = 0x4
|
38
|
+
|
39
|
+
ACCESS_MIN_MS_OBJECT_ACE_TYPE = 0x5
|
40
|
+
ACCESS_ALLOWED_OBJECT_ACE_TYPE = 0x5
|
41
|
+
ACCESS_DENIED_OBJECT_ACE_TYPE = 0x6
|
42
|
+
SYSTEM_AUDIT_OBJECT_ACE_TYPE = 0x7
|
43
|
+
SYSTEM_ALARM_OBJECT_ACE_TYPE = 0x8
|
44
|
+
ACCESS_MAX_MS_OBJECT_ACE_TYPE = 0x8
|
45
|
+
|
46
|
+
ACCESS_MAX_MS_V4_ACE_TYPE = 0x8
|
47
|
+
ACCESS_MAX_MS_ACE_TYPE = 0x8
|
48
|
+
|
49
|
+
ACCESS_ALLOWED_CALLBACK_ACE_TYPE = 0x9
|
50
|
+
ACCESS_DENIED_CALLBACK_ACE_TYPE = 0xA
|
51
|
+
ACCESS_ALLOWED_CALLBACK_OBJECT_ACE_TYPE = 0xB
|
52
|
+
ACCESS_DENIED_CALLBACK_OBJECT_ACE_TYPE = 0xC
|
53
|
+
SYSTEM_AUDIT_CALLBACK_ACE_TYPE = 0xD
|
54
|
+
SYSTEM_ALARM_CALLBACK_ACE_TYPE = 0xE
|
55
|
+
SYSTEM_AUDIT_CALLBACK_OBJECT_ACE_TYPE = 0xF
|
56
|
+
SYSTEM_ALARM_CALLBACK_OBJECT_ACE_TYPE = 0x10
|
57
|
+
|
58
|
+
SYSTEM_MANDATORY_LABEL_ACE_TYPE = 0x11
|
59
|
+
SYSTEM_RESOURCE_ATTRIBUTE_ACE_TYPE = 0x12
|
60
|
+
SYSTEM_SCOPED_POLICY_ID_ACE_TYPE = 0x13
|
61
|
+
SYSTEM_PROCESS_TRUST_LABEL_ACE_TYPE = 0x14
|
62
|
+
SYSTEM_ACCESS_FILTER_ACE_TYPE = 0x15
|
63
|
+
ACCESS_MAX_MS_V5_ACE_TYPE = 0x15
|
64
|
+
|
65
|
+
# ACE Flag
|
66
|
+
OBJECT_INHERIT_ACE = 0x1
|
67
|
+
CONTAINER_INHERIT_ACE = 0x2
|
68
|
+
NO_PROPAGATE_INHERIT_ACE = 0x4
|
69
|
+
INHERIT_ONLY_ACE = 0x8
|
70
|
+
INHERITED_ACE = 0x10
|
71
|
+
VALID_INHERIT_FLAGS = 0x1F
|
72
|
+
CRITICAL_ACE_FLAG = 0x20
|
73
|
+
SUCCESSFUL_ACCESS_ACE_FLAG = 0x40
|
74
|
+
FAILED_ACCESS_ACE_FLAG = 0x80
|
75
|
+
TRUST_PROTECTED_FILTER_ACE_FLAG = 0x40
|
76
|
+
|
77
|
+
|
78
|
+
# UnOfficial
|
79
|
+
MAX_BUCKETS_NUM = 0x17
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module TurboRex
|
4
|
+
class Windows < Metasm::WinOS
|
5
|
+
class Process < Metasm::WinOS::Process
|
6
|
+
def disassembler
|
7
|
+
return @disassembler if @disassembler
|
8
|
+
case self.cpusz
|
9
|
+
when 32
|
10
|
+
@disassembler = Metasm::Shellcode.decode(self.memory, Metasm::Ia32.new).disassembler
|
11
|
+
when 64
|
12
|
+
@disassembler = Metasm::Shellcode.decode(self.memory, Metasm::X86_64.new).disassembler
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def load_symbol_table(libname)
|
17
|
+
initialize_sym_handler
|
18
|
+
unless lib = modules.find { |m| m.path =~ Regexp.new(libname, true) }
|
19
|
+
return false
|
20
|
+
end
|
21
|
+
|
22
|
+
if Win32API.symloadmoduleex(self.handle, 0, libname, 0, lib.addr, lib.size, 0, 0) == 0 &&
|
23
|
+
Win32API.getlasterror != 0
|
24
|
+
return false
|
25
|
+
end
|
26
|
+
|
27
|
+
# module_info = Win32API.alloc_c_struct('IMAGEHLP_MODULE64')
|
28
|
+
# module_info.SizeOfStruct = module_info.sizeof
|
29
|
+
# unless Win32API.symgetmoduleinfo64(self.handle, lib.addr, module_info) == 1
|
30
|
+
# return false
|
31
|
+
# end
|
32
|
+
|
33
|
+
true
|
34
|
+
end
|
35
|
+
|
36
|
+
def close_handle
|
37
|
+
Metasm::WinAPI.closehandle(handle)
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
def initialize_sym_handler
|
43
|
+
return true if @sym_handler_initialized
|
44
|
+
Win32API.syminitialize(self.handle, 0, false)
|
45
|
+
Win32API.symsetoptions(Win32API.symgetoptions |
|
46
|
+
Win32API::SYMOPT_DEFERRED_LOADS |
|
47
|
+
Win32API::SYMOPT_NO_PROMPTS # | Win32API::SYMOPT_DEBUG
|
48
|
+
)
|
49
|
+
sympath = ENV.fetch('_NT_SYMBOL_PATH') { 'srv*C:\\symbols*https://msdl.microsoft.com/download/symbols;' }
|
50
|
+
Win32API.symsetsearchpath(self.handle, sympath.dup)
|
51
|
+
|
52
|
+
@sym_handler_initialized = true
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
warn "\033[33m[-]Warning: This module doesn't currently work on non-Windows os.\033[0m" unless OS.windows?
|
2
|
+
module TurboRex
|
3
|
+
class Windows < Metasm::WinOS
|
4
|
+
module Security
|
5
|
+
include TurboRex::Windows::Constants
|
6
|
+
|
7
|
+
require 'turborex/windows/security/ace.rb'
|
8
|
+
require 'turborex/windows/security/acl.rb'
|
9
|
+
require 'turborex/windows/security/security_descriptor.rb'
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
module TurboRex
|
2
|
+
class Windows < Metasm::WinOS
|
3
|
+
module Security
|
4
|
+
class ACE
|
5
|
+
attr_reader :type
|
6
|
+
attr_reader :flags
|
7
|
+
|
8
|
+
def initialize(type, flags)
|
9
|
+
@type = type
|
10
|
+
@flags = flags
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.from_raw(raw)
|
14
|
+
ace_header = TurboRex::Windows::Win32API.decode_c_struct('ACE_HEADER', raw)
|
15
|
+
sid_offset = ace_header.sizeof + 4
|
16
|
+
type = ace_header.AceType
|
17
|
+
flags = ace_header.AceFlags
|
18
|
+
mask = raw[ace_header.sizeof, 4].unpack('V').first
|
19
|
+
|
20
|
+
sid = TurboRex::Windows::Win32API.decode_c_struct('SID', raw, sid_offset)
|
21
|
+
ppszsid = TurboRex::Windows::Win32API.alloc_c_ptr('LPSTR')
|
22
|
+
if TurboRex::Windows::Win32API.convertsidtostringsida(sid, ppszsid) == 0
|
23
|
+
raise "Unable to call ConvertSidToStringSidA. GetLastError returns: #{TurboRex::Windows::Win32API.getlasterror}"
|
24
|
+
end
|
25
|
+
sz_sid = TurboRex::Windows::Win32API.memory_read_strz(ppszsid[0])
|
26
|
+
|
27
|
+
case type
|
28
|
+
when TurboRex::Windows::Constants::ACCESS_DENIED_ACE_TYPE
|
29
|
+
AccessDeniedACE.new(mask, sz_sid, flags)
|
30
|
+
when TurboRex::Windows::Constants::ACCESS_ALLOWED_ACE_TYPE
|
31
|
+
AccessAllowedACE.new(mask, sz_sid, flags)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
class AccessAllowedACE < ACE
|
37
|
+
attr_reader :mask
|
38
|
+
attr_reader :sid
|
39
|
+
attr_reader :short
|
40
|
+
|
41
|
+
def initialize(mask, sid, flags, type=TurboRex::Windows::Constants::ACCESS_ALLOWED_ACE_TYPE)
|
42
|
+
@mask = mask
|
43
|
+
@sid = sid
|
44
|
+
@short = :allowed
|
45
|
+
super(type, flags)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
class AccessDeniedACE < ACE
|
50
|
+
attr_reader :mask
|
51
|
+
attr_reader :sid
|
52
|
+
attr_reader :short
|
53
|
+
|
54
|
+
def initialize(mask, sid, flags, type=TurboRex::Windows::Constants::ACCESS_DENIED_ACE_TYPE)
|
55
|
+
@mask = mask
|
56
|
+
@sid = sid
|
57
|
+
@short = :denied
|
58
|
+
super(type, flags)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
class SystemAuditAce < ACE
|
63
|
+
attr_reader :mask
|
64
|
+
attr_reader :sid
|
65
|
+
attr_reader :short
|
66
|
+
|
67
|
+
def initialize(mask, sid, flags, type=TurboRex::Windows::Constants::SYSTEM_AUDIT_ACE_TYPE)
|
68
|
+
@mask = mask
|
69
|
+
@sid = sid
|
70
|
+
@short = :audit
|
71
|
+
super(type, flags)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'turborex/windows/security/ace.rb'
|
2
|
+
|
3
|
+
module TurboRex
|
4
|
+
class Windows < Metasm::WinOS
|
5
|
+
module Security
|
6
|
+
class ACL
|
7
|
+
class DACL < ACL
|
8
|
+
attr_reader :revision
|
9
|
+
attr_reader :count
|
10
|
+
attr_reader :ace_list
|
11
|
+
|
12
|
+
def initialize(revision, count, ace_list=[])
|
13
|
+
@revision = revision
|
14
|
+
@count = count
|
15
|
+
@ace_list = ace_list.freeze
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.from_raw(raw)
|
19
|
+
raise NotImplementedError
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|