smbRpc 0.0.4 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7f3353d8440dbac0b159a906b9ddbeb6a7514a8061576badb2553871238bfc05
4
- data.tar.gz: f2797f8e40083d8e93dfcd3751720a12c9e288dced2fb8cd754e1bb0b3b41091
3
+ metadata.gz: 300363413b5dcdb199df282c238b28340d5feb864c91f34d41624e3baa23c558
4
+ data.tar.gz: 3625981dfdca5e97929b3489eb678760e99e26f5766ca9c8e6aad07d1fc7f977
5
5
  SHA512:
6
- metadata.gz: 4ebd5d9e565a097ff1c36221155fdc0047653e6e219eef73a10f28ac38aef59d51ab2dc70fbe724d121f6445ec339faf2ed1b10c9d634c8a7e571aee0ffe737d
7
- data.tar.gz: 3b1a63cac8deadc5a81cd2173ff21914e9234db9fa02163c5a68967552cef11c9ba54caa847cfd76533c7bfec4e5d1b01a82ae89debdc765a963d49a8cd6a055
6
+ metadata.gz: 02043c408515bba0e8535bfe4d5cb5b11a50ce58dacf3cc6f2f6cf4fc4e8db0230787a7b5c98ece82974951998221b58740f92949fbf2c1d19e1a431a2515322
7
+ data.tar.gz: 956e2afdc2abd9bcb05ba98136c6ab11fb7ed83c20f68a4f4fd2047d02e6014db04c8dc3bc14b3828a51ed8395e480066fa88313df89fbd91bd5d996b171c254
data/README.md CHANGED
@@ -1,11 +1,26 @@
1
- his is a Windows RPC over SMB namepipe library modeled over the ruby_smb library.
2
- All function names and arguments were written to closely reflct the originals MS documented specifications.
1
+ This is a Windows RPC over SMB namepipe library modeled over the ruby_smb library.
2
+ All function names and arguments were written to closely reflct the originals MS documented specifications. So if you want to know how to use it, just read the respective MS name pipe protocol documentations, see what functions I have exposed, and read the respective function definition.
3
+ Example:
4
+ To look up names in LSA; MS-LSAD and MS-LSAT would tell you to call openPolicy then lookUpNames. If you look in the lsarpc folder you'll see both functions available. All you have to do is read the function definition in the file and decide what arguments you want to pass in.
5
+
6
+ lsarpc = SmbRpc::Lsarpc.new(ip:ip, user:user, pass:pass)
7
+
8
+ policy = lsarpc.openPolicy
9
+
10
+ p policy.lookupNames(name:"guest")
11
+
3
12
  Currently I have only exposed some functions to the following namepipes. I'll be adding more as I continue developing this project.
4
13
 
5
- epmapper
6
- samr
7
- srvsvc
8
- svcctl
9
- lsarpc
14
+ epmapper https://svn.nmap.org/nmap-exp/drazen/var/IDL/epmapper.idl?p=25000
15
+
16
+ samr [MS-SAMR]
17
+
18
+ srvsvc [MS-SRVS]
19
+
20
+ svcctl [MS-SCMR]
21
+
22
+ lsarpc [MS-LSAD] and [MS-LSAT]
23
+
24
+ winreg [MS-RRP]
10
25
 
11
26
  Comments and suggestions are welcome, please email to rubysmbrpc@gmail.com
@@ -0,0 +1,44 @@
1
+ #!/usr/bin/ruby
2
+ require"smbRpc"
3
+
4
+ ip = "10.1.1.234"
5
+ port = 445
6
+ user = "admin"
7
+ pass = "superSecret"
8
+ key = "HKLM\\HARDWARE"
9
+
10
+ splitKey = key.split("\\")
11
+ rKey = splitKey[0].upcase
12
+ sKey = splitKey[1..-1].join("\\")
13
+
14
+ newKey = "BLA"
15
+ newValues = {
16
+ "sz" => [ WINREG_REG_VALUE_TYPE["REG_SZ"], "abcd\x00".bytes.pack("v*")],
17
+ "exp" => [ WINREG_REG_VALUE_TYPE["REG_EXPAND_SZ"], "System32\\Drivers\\ACPI.sys".bytes.pack("v*")],
18
+ "bin" => [ WINREG_REG_VALUE_TYPE["REG_BINARY"], "\x23\x56\xff\xde\xed\x56\x7c\x44"],
19
+ "dwle" => [ WINREG_REG_VALUE_TYPE["REG_DWORDLE"], "\x01\x00\x00\x00"],
20
+ "dwbe" => [ WINREG_REG_VALUE_TYPE["REG_DWORDBE"], "\x00\x00\x00\xff"],
21
+ "multi" => [ WINREG_REG_VALUE_TYPE["REG_MULTI_SZ"], "System32\x00Drivers\x00ACPI.sys\x00".bytes.pack("v*")],
22
+ "qw" => [ WINREG_REG_VALUE_TYPE["REG_QWORDLE"], [4096].pack("<q")]
23
+ }
24
+
25
+ rootKeys = {
26
+ "HKLM" => SmbRpc::Winreg.new(ip:ip, user:user, pass:pass).openLocalMachine,
27
+ "HKCU" => SmbRpc::Winreg.new(ip:ip, user:user, pass:pass).openCurrentUser,
28
+ "HKCR" => SmbRpc::Winreg.new(ip:ip, user:user, pass:pass).openClassesRoot,
29
+ "HKU" => SmbRpc::Winreg.new(ip:ip, user:user, pass:pass).openUsers,
30
+ "HKCC" => SmbRpc::Winreg.new(ip:ip, user:user, pass:pass).openCurrentConfig
31
+ }
32
+
33
+ winreg = rootKeys[rKey].baseRegOpenKey(subKey:sKey)
34
+
35
+ p WINREG_DISPOSITION.key(winreg.baseRegCreateKey(subKey:newKey).disposition) #can not create key imediately under HKLM/HKU
36
+
37
+ newValues.each do |k,v|
38
+ winreg.baseRegSetValue(valueName:k, type:v[0], data:v[1])
39
+ puts"%s\\%s => %s"%[key, k, v[1].inspect]
40
+ end
41
+
42
+ winreg.close
43
+
44
+
@@ -0,0 +1,40 @@
1
+ #!/usr/bin/ruby
2
+ require"smbRpc"
3
+
4
+ #regQuery.rb 10.1.1.245 admin seperSecret HkLm\\System\\CurrentControlset\\services\\ALG
5
+
6
+ ip = ARGV[0]
7
+ port = 445
8
+ user = ARGV[1]
9
+ pass = ARGV[2]
10
+ #key = "HkLm\\System\\CurrentControlset\\services\\ALG"
11
+ key = ARGV[3]
12
+ puts"reading: %s\n\n"%[key]
13
+
14
+ splitKey = key.split("\\")
15
+ rKey = splitKey[0].upcase
16
+ sKey = splitKey[1..-1].join("\\")
17
+
18
+ rootKeys = {
19
+ "HKLM" => SmbRpc::Winreg.new(ip:ip, user:user, pass:pass).openLocalMachine,
20
+ "HKCU" => SmbRpc::Winreg.new(ip:ip, user:user, pass:pass).openCurrentUser,
21
+ "HKCR" => SmbRpc::Winreg.new(ip:ip, user:user, pass:pass).openClassesRoot,
22
+ "HKU" => SmbRpc::Winreg.new(ip:ip, user:user, pass:pass).openUsers,
23
+ "HKCC" => SmbRpc::Winreg.new(ip:ip, user:user, pass:pass).openCurrentConfig
24
+ }
25
+
26
+ winreg = rootKeys[rKey].baseRegOpenKey(subKey:sKey)
27
+
28
+ keyInfo = winreg.baseRegQueryInfoKey
29
+ keyInfo[:numberOfSubkeys].times do |i| #enum keys if subkeys count > 0
30
+ p winreg.baseRegEnumKey(index:i)
31
+ end if keyInfo[:numberOfSubkeys] > 0
32
+
33
+ keyInfo[:numberOfValues].times do |i| #enum values if values count > 0
34
+ h = winreg.baseRegEnumValue(index:i)
35
+ puts"%s : %i : %s"%[h[:valueName], h[:type], winreg.baseRegQueryValue(valueName:h[:valueName]).inspect]
36
+ end if keyInfo[:numberOfValues] > 0
37
+
38
+ winreg.close
39
+
40
+
@@ -0,0 +1,26 @@
1
+ #!/usr/bin/ruby
2
+ require"smbRpc"
3
+
4
+ #regSave.rb 10.1.1.234 admin superSecret HkLm\\SAM C:\\sam
5
+ ip = ARGV[0]
6
+ port = 445
7
+ user = ARGV[1]
8
+ pass = ARGV[2]
9
+ key = ARGV[3]
10
+ file = ARGV[4]
11
+
12
+ splitKey = key.split("\\")
13
+ rKey = splitKey[0].upcase
14
+ sKey = splitKey[1..-1].join("\\")
15
+
16
+ rootKeys = {
17
+ "HKLM" => SmbRpc::Winreg.new(ip:ip, user:user, pass:pass).openLocalMachine,
18
+ "HKCU" => SmbRpc::Winreg.new(ip:ip, user:user, pass:pass).openCurrentUser,
19
+ "HKCR" => SmbRpc::Winreg.new(ip:ip, user:user, pass:pass).openClassesRoot,
20
+ "HKU" => SmbRpc::Winreg.new(ip:ip, user:user, pass:pass).openUsers,
21
+ "HKCC" => SmbRpc::Winreg.new(ip:ip, user:user, pass:pass).openCurrentConfig
22
+ }
23
+
24
+ winreg = rootKeys[rKey].baseRegOpenKey(subKey:sKey).baseRegSaveKey(file:file).close
25
+ puts"%s \nsaved to\n %s"%[key, file]
26
+
data/lib/smbRpc.rb CHANGED
@@ -3,7 +3,6 @@ require"ruby_smb"
3
3
  require"bindata"
4
4
  require"windows_error/win32"
5
5
  require"smbhash" #nice little library to make Lm/NTLM hash
6
- #require"windows_error/nt_status" #already loaded by ruby_smb
7
6
 
8
7
  #$:.unshift(File.expand_path('.',__dir__))
9
8
  require"smbRpc/rpc"
@@ -12,22 +11,6 @@ require"smbRpc/svcctl"
12
11
  require"smbRpc/lsarpc"
13
12
  require"smbRpc/epmapper"
14
13
  require"smbRpc/samr"
14
+ require"smbRpc/winreg"
15
15
  require"smbRpc/updateRuby_smb"
16
16
  require"smbRpc/updateString"
17
-
18
- #require"rpc_packet"
19
- #require"endpoints"
20
- #require"constants"
21
- #require"ndrep"
22
- #require"srvsvc_packet"
23
- #require"svcctl_packet"
24
-
25
- #require_relative"endpoints"
26
- #require_relative"constants"
27
- #require_relative"ndrep"
28
- #require_relative"rpc"
29
- #require_relative"rpc_packet"
30
- #require_relative"srvsvc"
31
- #require_relative"srvsvc_packet"
32
- #require_relative"svcctl"
33
- #require_relative"svcctl_packet"
@@ -25,6 +25,11 @@ module SmbRpc
25
25
  VER_MAJOR = 1
26
26
  VER_MINOR = 0
27
27
  end
28
+ module Winreg
29
+ UUID = '338CD001-2244-31F1-AAAA-900038001003'
30
+ VER_MAJOR = 1
31
+ VER_MINOR = 0
32
+ end
28
33
  end
29
34
  end
30
35
 
@@ -33,6 +38,6 @@ ENDPOINT = {
33
38
  "svcctl" => SmbRpc::Endpoint::Svcctl,
34
39
  "lsarpc" => SmbRpc::Endpoint::Lsarpc,
35
40
  "epmapper" => SmbRpc::Endpoint::Epmapper,
36
- "samr" => SmbRpc::Endpoint::Samr
41
+ "samr" => SmbRpc::Endpoint::Samr,
42
+ "winreg" => SmbRpc::Endpoint::Winreg
37
43
  }
38
-
@@ -0,0 +1,27 @@
1
+ require"smbRpc/winreg/constants"
2
+ require"smbRpc/winreg/openLocalMachine"
3
+ require"smbRpc/winreg/baseRegOpenKey"
4
+ require"smbRpc/winreg/baseRegQueryValue"
5
+ require"smbRpc/winreg/baseRegCloseKey"
6
+ require"smbRpc/winreg/baseRegEnumKey"
7
+ require"smbRpc/winreg/baseRegQueryInfoKey"
8
+ require"smbRpc/winreg/baseRegEnumValue"
9
+ require"smbRpc/winreg/openClassesRoot"
10
+ require"smbRpc/winreg/openCurrentUser"
11
+ require"smbRpc/winreg/openUsers"
12
+ require"smbRpc/winreg/openCurrentConfig"
13
+ require"smbRpc/winreg/baseRegCreateKey"
14
+ require"smbRpc/winreg/baseRegSetValue"
15
+ require"smbRpc/winreg/baseRegDeleteValue"
16
+ require"smbRpc/winreg/baseRegDeleteKey"
17
+ require"smbRpc/winreg/baseRegSaveKey"
18
+
19
+ module SmbRpc
20
+ class Winreg < Rpc
21
+ def initialize(**argv)
22
+ super(argv)
23
+ self.connect
24
+ self.bind(pipe:"winreg")
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,50 @@
1
+
2
+ module SmbRpc
3
+ class Winreg < Rpc
4
+
5
+ class BaseRegCloseKeyReq < BinData::Record
6
+ endian :little
7
+ request :request
8
+ string :hKey, :length => 20
9
+ def initialize_instance
10
+ super
11
+ hKey.value = get_parameter(:handle)
12
+ request.pduHead.frag_length = self.num_bytes
13
+ request.opnum.value = 5 #BaseRegCloseKey
14
+ end
15
+ end
16
+
17
+ class BaseRegCloseKeyRes < BinData::Record
18
+ endian :little
19
+ request :request
20
+ string :hKey, :length => 20
21
+ uint32 :windowsError
22
+ end
23
+
24
+ def closeRootKey()
25
+ if !@rootKeyHandle.nil?
26
+ baseRegCloseKeyReq = BaseRegCloseKeyReq.new(handle:@rootKeyHandle)
27
+ baseRegCloseKeyRes = @file.ioctl_send_recv(baseRegCloseKeyReq).buffer
28
+ baseRegCloseKeyRes.raise_not_error_success("closeRootKey")
29
+ baseRegCloseKeyRes = BaseRegCloseKeyRes.read(baseRegCloseKeyRes)
30
+ @rootKeyHandle = nil
31
+ end
32
+ end
33
+
34
+ def closeSubKey()
35
+ if !@subKeyHandle.nil?
36
+ baseRegCloseKeyReq = BaseRegCloseKeyReq.new(handle:@subKeyHandle)
37
+ baseRegCloseKeyRes = @file.ioctl_send_recv(baseRegCloseKeyReq).buffer
38
+ baseRegCloseKeyRes.raise_not_error_success("closeSubKey")
39
+ baseRegCloseKeyRes = BaseRegCloseKeyRes.read(baseRegCloseKeyRes)
40
+ @subKeyHandle = nil
41
+ end
42
+ end
43
+
44
+ def close()
45
+ closeSubKey()
46
+ closeRootKey()
47
+ super
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,58 @@
1
+ module SmbRpc
2
+ class Winreg < Rpc
3
+ attr_reader :disposition
4
+
5
+ class BaseRegCreateKeyReq < BinData::Record
6
+ endian :little
7
+ request :request
8
+ string :hKey, :length => 20
9
+ rpc_unicode_string :lpSubKey
10
+ conformantandVaryingStrings :lpSubKeyNdr
11
+ rpc_unicode_string :lpClass
12
+ uint32 :dwOptions
13
+ uint32 :samDesired
14
+ uint32 :lpSecurityAttributes
15
+ uint32 :ref_id_lpdwDisposition, :initial_value => 1
16
+ uint32 :lpdwDisposition
17
+
18
+ def initialize_instance
19
+ super
20
+ hKey.value = get_parameter(:handle)
21
+ uniString = "#{get_parameter(:name)}\x00".bytes.pack("v*")
22
+ lpSubKey.len.value = uniString.bytesize
23
+ lpSubKey.maximumLength.value = uniString.bytesize
24
+ lpSubKeyNdr.str.value = uniString
25
+ lpClass.len.value = 0
26
+ lpClass.maximumLength.value = 0
27
+ lpClass.ref_id_buffer.value = 0
28
+ dwOptions.value = get_parameter(:options)
29
+ samDesired.value = get_parameter(:desired)
30
+ request.pduHead.frag_length = self.num_bytes
31
+ request.opnum.value = 6 #BaseRegCreateKey
32
+ end
33
+ end
34
+
35
+ class BaseRegCreateKeyRes < BinData::Record
36
+ endian :little
37
+ request :request
38
+ string :phkResult, :length => 20
39
+ uint32 :ref_id_lpdwDisposition
40
+ uint32 :lpdwDisposition
41
+ uint32 :windowsError
42
+ end
43
+
44
+ #https://msdn.microsoft.com/en-us/library/cc244922.aspx
45
+ #can not create remote key imediately under HKLM/HKU, will get ERROR_INVALID_PARAMETER
46
+ def baseRegCreateKey(subKey:, samDesired:WINREG_REGSAM["MAXIMUM_ALLOWED"], options:WINREG_OPTIONS["NONE"])
47
+ baseRegCreateKeyReq = BaseRegCreateKeyReq.new(handle:(@subKeyHandle || @rootKeyHandle), name:subKey, desired:samDesired, options:options)
48
+ baseRegCreateKeyRes = @file.ioctl_send_recv(baseRegCreateKeyReq).buffer
49
+ baseRegCreateKeyRes.raise_not_error_success("baseRegCreateKey")
50
+ baseRegCreateKeyRes = BaseRegCreateKeyRes.read(baseRegCreateKeyRes)
51
+ @disposition = baseRegCreateKeyRes.lpdwDisposition
52
+ @subKeyHandle = baseRegCreateKeyRes.phkResult
53
+ return self
54
+ end
55
+
56
+ end
57
+ end
58
+
@@ -0,0 +1,38 @@
1
+ module SmbRpc
2
+ class Winreg < Rpc
3
+
4
+ class BaseRegDeleteKeyReq < BinData::Record
5
+ endian :little
6
+ request :request
7
+ string :hKey, :length => 20
8
+ rpc_unicode_string :lpSubKey
9
+ conformantandVaryingStrings :lpSubKeyNdr
10
+
11
+ def initialize_instance
12
+ super
13
+ hKey.value = get_parameter(:handle)
14
+ uniString = "#{get_parameter(:subKey)}\x00".bytes.pack("v*")
15
+ lpSubKey.len.value = uniString.bytesize
16
+ lpSubKey.maximumLength.value = uniString.bytesize
17
+ lpSubKeyNdr.str.value = uniString
18
+ request.pduHead.frag_length = self.num_bytes
19
+ request.opnum.value = 7 #BaseRegDeleteKey
20
+ end
21
+ end
22
+
23
+ class BaseRegDeleteKeyRes < BinData::Record
24
+ endian :little
25
+ request :request
26
+ uint32 :windowsError
27
+ end
28
+
29
+ def baseRegDeleteKey(subKey:)
30
+ baseRegDeleteKeyReq = BaseRegDeleteKeyReq.new(handle:@subKeyHandle, subKey:subKey)
31
+ baseRegDeleteKeyRes = @file.ioctl_send_recv(baseRegDeleteKeyReq).buffer
32
+ baseRegDeleteKeyRes.raise_not_error_success("baseRegDeleteKey")
33
+ return self
34
+ end
35
+
36
+ end
37
+ end
38
+
@@ -0,0 +1,38 @@
1
+ module SmbRpc
2
+ class Winreg < Rpc
3
+
4
+ class BaseRegDeleteValueReq < BinData::Record
5
+ endian :little
6
+ request :request
7
+ string :hKey, :length => 20
8
+ rpc_unicode_string :lpValueName
9
+ conformantandVaryingStrings :lpValueNameNdr
10
+
11
+ def initialize_instance
12
+ super
13
+ hKey.value = get_parameter(:handle)
14
+ uniString = "#{get_parameter(:valueName)}\x00".bytes.pack("v*")
15
+ lpValueName.len.value = uniString.bytesize
16
+ lpValueName.maximumLength.value = uniString.bytesize
17
+ lpValueNameNdr.str.value = uniString
18
+ request.pduHead.frag_length = self.num_bytes
19
+ request.opnum.value = 8 #BaseRegDeleteValue
20
+ end
21
+ end
22
+
23
+ class BaseRegDeleteValueRes < BinData::Record
24
+ endian :little
25
+ request :request
26
+ uint32 :windowsError
27
+ end
28
+
29
+ def baseRegDeleteValue(valueName:)
30
+ baseRegDeleteValueReq = BaseRegDeleteValueReq.new(handle:(@subKeyHandle || @rootKeyHandle), valueName:valueName)
31
+ baseRegDeleteValueRes = @file.ioctl_send_recv(baseRegDeleteValueReq).buffer
32
+ baseRegDeleteValueRes.raise_not_error_success("baseRegDeleteValue")
33
+ return self
34
+ end
35
+
36
+ end
37
+ end
38
+
@@ -0,0 +1,53 @@
1
+ module SmbRpc
2
+ class Winreg < Rpc
3
+
4
+ class BaseRegEnumKeyReq < BinData::Record
5
+ endian :little
6
+ request :request
7
+ string :hKey, :length => 20
8
+
9
+ uint32 :dwIndex
10
+ rpc_unicode_string :lpNameIn
11
+ uint32 :ref_id_lpClassIn, :value => 1
12
+ rpc_unicode_string :lpClassIn
13
+ uint32 :lpftLastWriteTime
14
+
15
+ def initialize_instance
16
+ super
17
+ hKey.value = get_parameter(:handle)
18
+ dwIndex.value = get_parameter(:index)
19
+ lpNameIn.len.value = 0
20
+ lpNameIn.maximumLength.value = 0x1000
21
+ lpNameIn.ref_id_buffer.value = 0
22
+ lpClassIn.len.value = 0
23
+ lpClassIn.maximumLength.value = 0x1000
24
+ lpClassIn.ref_id_buffer.value = 0
25
+ request.pduHead.frag_length = self.num_bytes
26
+ request.opnum.value = 9 #BaseRegEnumKey
27
+ end
28
+ end
29
+
30
+ class BaseRegEnumKeyRes < BinData::Record
31
+ endian :little
32
+ request :request
33
+
34
+ rpc_unicode_string :lpNameOut
35
+ conformantandVaryingStrings :lpNameOutNdr
36
+ rpc_unicode_string :lplpClassOut
37
+ uint32 :lpftLastWriteTime
38
+
39
+ uint32 :windowsError
40
+ end
41
+
42
+ def baseRegEnumKey(index:)
43
+ baseRegEnumKeyReq = BaseRegEnumKeyReq.new(handle:(@subKeyHandle || @rootKeyHandle), index:index)
44
+ baseRegEnumKeyRes = @file.ioctl_send_recv(baseRegEnumKeyReq).buffer
45
+ baseRegEnumKeyRes.raise_not_error_success("baseRegEnumKey")
46
+ baseRegEnumKeyRes = BaseRegEnumKeyRes.read(baseRegEnumKeyRes)
47
+ out = baseRegEnumKeyRes.lpNameOutNdr.str.unpack("v*").pack("c*")
48
+ return out.chop if out[-1] == "\x00"
49
+ end
50
+
51
+ end
52
+ end
53
+
@@ -0,0 +1,57 @@
1
+ module SmbRpc
2
+ class Winreg < Rpc
3
+
4
+ class BaseRegEnumValueReq < BinData::Record
5
+ endian :little
6
+ request :request
7
+ string :hKey, :length => 20
8
+ uint32 :dwIndex
9
+ rpc_unicode_string :lpValueNameIn
10
+ conformantandVaryingStrings :lpValueNameInNdr
11
+ uint32 :ref_id_lpType, :value => 1
12
+ uint32 :lpType
13
+ uint32 :ref_id_lpData, :initial_value => 0
14
+ uint32 :ref_id_lpcbData, :initial_value => 0
15
+ uint32 :ref_id_lpcbLen, :initial_value => 0
16
+
17
+ def initialize_instance
18
+ super
19
+ hKey.value = get_parameter(:handle)
20
+ dwIndex.value = get_parameter(:index)
21
+ #https://support.microsoft.com/en-us/help/256986/windows-registry-information-for-advanced-users
22
+ maxValueNameLen = 0x100
23
+ lpValueNameIn.len.value = maxValueNameLen
24
+ lpValueNameIn.maximumLength.value = maxValueNameLen
25
+ lpValueNameInNdr.str = "\x00" * maxValueNameLen #this is so weird :_
26
+ request.pduHead.frag_length = self.num_bytes
27
+ request.opnum.value = 10 #BaseRegEnumValue
28
+ end
29
+ end
30
+
31
+ class BaseRegEnumValueRes < BinData::Record
32
+ endian :little
33
+ request :request
34
+ rpc_unicode_string :lpValueNameOut
35
+ conformantandVaryingStrings :lpValueNameOutNdr
36
+ uint32 :ref_id_lpType, :value => 1
37
+ uint32 :lpType
38
+ uint32 :lpData
39
+ uint32 :lpcbData
40
+ uint32 :lpcbLen
41
+ uint32 :windowsError
42
+ end
43
+
44
+ def baseRegEnumValue(index:)
45
+ baseRegEnumValueReq = BaseRegEnumValueReq.new(handle:(@subKeyHandle || @rootKeyHandle), index:index)
46
+ baseRegEnumValueRes = @file.ioctl_send_recv(baseRegEnumValueReq).buffer
47
+ baseRegEnumValueRes.raise_not_error_success("baseRegEnumValue")
48
+ baseRegEnumValueRes = BaseRegEnumValueRes.read(baseRegEnumValueRes)
49
+ valueName = baseRegEnumValueRes.lpValueNameOutNdr.str.unpack("v*").pack("c*").chop
50
+ return { :valueName => valueName,
51
+ :type => baseRegEnumValueRes.lpType.to_i
52
+ }
53
+ end
54
+
55
+ end
56
+ end
57
+
@@ -0,0 +1,47 @@
1
+ module SmbRpc
2
+ class Winreg < Rpc
3
+
4
+ attr_accessor :subKeyHandle
5
+
6
+ class BaseRegOpenKeyReq < BinData::Record
7
+ endian :little
8
+ request :request
9
+ string :hKey, :length => 20
10
+ rpc_unicode_string :lpSubKey
11
+ conformantandVaryingStrings :lpSubKeyNdr
12
+ uint32 :dwOptions
13
+ uint32 :samDesired
14
+
15
+ def initialize_instance
16
+ super
17
+ hKey.value = get_parameter(:handle)
18
+ uniString = "#{get_parameter(:subKey)}\x00".bytes.pack("v*")
19
+ lpSubKey.len.value = uniString.bytesize
20
+ lpSubKey.maximumLength.value = uniString.bytesize
21
+ lpSubKeyNdr.str.value = uniString
22
+ dwOptions.value = get_parameter(:options)
23
+ samDesired.value = get_parameter(:desired)
24
+ request.pduHead.frag_length = self.num_bytes
25
+ request.opnum.value = 15 #BaseRegOpenKey
26
+ end
27
+ end
28
+
29
+ class BaseRegOpenKeyRes < BinData::Record
30
+ endian :little
31
+ request :request
32
+ string :phkResult, :length => 20
33
+ uint32 :windowsError
34
+ end
35
+
36
+ def baseRegOpenKey(subKey:, samDesired:WINREG_REGSAM["MAXIMUM_ALLOWED"], options:WINREG_OPTIONS["NONE"])
37
+ baseRegOpenKeyReq = BaseRegOpenKeyReq.new(handle:@rootKeyHandle, subKey:subKey, desired:samDesired, options:options)
38
+ baseRegOpenKeyRes = @file.ioctl_send_recv(baseRegOpenKeyReq).buffer
39
+ baseRegOpenKeyRes.raise_not_error_success("baseRegOpenKey")
40
+ baseRegOpenKeyRes = BaseRegOpenKeyRes.read(baseRegOpenKeyRes)
41
+ @subKeyHandle = baseRegOpenKeyRes.phkResult
42
+ return self
43
+ end
44
+
45
+ end
46
+ end
47
+
@@ -0,0 +1,56 @@
1
+ module SmbRpc
2
+ class Winreg < Rpc
3
+
4
+ class BaseRegQueryInfoKeyReq < BinData::Record
5
+ endian :little
6
+ request :request
7
+ string :hKey, :length => 20
8
+ rpc_unicode_string :lpClassIn
9
+
10
+ def initialize_instance
11
+ super
12
+ hKey.value = get_parameter(:handle)
13
+ lpClassIn.len.value = 0
14
+ lpClassIn.maximumLength.value = 0x1000
15
+ lpClassIn.ref_id_buffer.value = 0
16
+ request.pduHead.frag_length = self.num_bytes
17
+ request.opnum.value = 16 #BaseRegQueryInfoKey
18
+ end
19
+ end
20
+
21
+ class BaseRegQueryInfoKeyRes < BinData::Record
22
+ endian :little
23
+ request :request
24
+ rpc_unicode_string :lpClassOut
25
+ conformantandVaryingStrings :lpClassOutNdr
26
+ uint32 :lpcSubKeys
27
+ uint32 :lpcbMaxSubKeyLen
28
+ uint32 :lpcbMaxClassLen
29
+ uint32 :lpcValues
30
+ uint32 :lpcbMaxValueNameLen
31
+ uint32 :lpcbMaxValueLen
32
+ uint32 :lpcbSecurityDescriptor
33
+ uint64 :lpftLastWriteTime
34
+ uint32 :windowsError
35
+ end
36
+
37
+ def baseRegQueryInfoKey
38
+ baseRegQueryInfoKeyReq = BaseRegQueryInfoKeyReq.new(handle:(@subKeyHandle || @rootKeyHandle))
39
+ baseRegQueryInfoKeyRes = @file.ioctl_send_recv(baseRegQueryInfoKeyReq).buffer
40
+ baseRegQueryInfoKeyRes.raise_not_error_success("baseRegQueryInfoKey")
41
+ baseRegQueryInfoKeyRes = BaseRegQueryInfoKeyRes.read(baseRegQueryInfoKeyRes)
42
+ k = baseRegQueryInfoKeyRes
43
+ return { :numberOfSubkeys => k.lpcSubKeys,
44
+ :maxSubkeySize => k.lpcbMaxSubKeyLen,
45
+ :maxClassSize => k.lpcbMaxClassLen,
46
+ :numberOfValues => k.lpcValues,
47
+ :maxValueNameSize => k.lpcbMaxValueNameLen,
48
+ :maxValueSize => k.lpcbMaxValueLen,
49
+ :securityDescriptorSize => k.lpcbSecurityDescriptor,
50
+ :lastWriteTime => k.lpftLastWriteTime
51
+ }
52
+ end
53
+
54
+ end
55
+ end
56
+
@@ -0,0 +1,81 @@
1
+ module SmbRpc
2
+ class Winreg < Rpc
3
+
4
+ class BaseRegQueryValueReq < BinData::Record
5
+ endian :little
6
+ request :request
7
+ string :hKey, :length => 20
8
+ rpc_unicode_string :lpValueName
9
+ conformantandVaryingStrings :lpValueNameNdr
10
+ uint32 :ref_id_lpType, :value => 1
11
+ uint32 :lpType
12
+ uint32 :ref_id_lpData, :initial_value => 1
13
+ conformantandVaryingStringsAscii :lpData
14
+ uint32 :ref_id_lpcbData, :initial_value => 1
15
+ uint32 :lpcbData
16
+ uint32 :ref_id_lpcbLen, :initial_value => 1
17
+ uint32 :lpcbLen
18
+
19
+ def initialize_instance
20
+ super
21
+
22
+ hKey.value = get_parameter(:handle)
23
+ uniString = "#{get_parameter(:vName)}\x00".bytes.pack("v*")
24
+ lpValueName.len.value = uniString.bytesize
25
+ lpValueName.maximumLength.value = uniString.bytesize
26
+ lpValueNameNdr.str.value = uniString
27
+ lpType.value = get_parameter(:type)
28
+ lpData.str = ""
29
+ lpData.max_count.value = 0x1000
30
+
31
+ lpcbData.value = 0x1000
32
+ request.pduHead.frag_length = self.num_bytes
33
+ request.opnum.value = 17 #BaseRegQueryValue
34
+ end
35
+ end
36
+
37
+ class BaseRegQueryValueRes < BinData::Record
38
+ endian :little
39
+ request :request
40
+ uint32 :ref_id_lpType
41
+ uint32 :lpType
42
+ uint32 :ref_id_lpData
43
+ conformantandVaryingStringsAscii :lpData
44
+ uint32 :ref_id_lpcbData
45
+ uint32 :lpcbData
46
+ uint32 :ref_id_lpcbLen
47
+ uint32 :lpcbLen
48
+
49
+ uint32 :windowsError
50
+ end
51
+
52
+ def baseRegQueryValue(valueName:, type:WINREG_REG_VALUE_TYPE["UNDEF"])
53
+ baseRegQueryValueReq = BaseRegQueryValueReq.new(handle:(@subKeyHandle || @rootKeyHandle), vName:valueName, type:type)
54
+ baseRegQueryValueRes = @file.ioctl_send_recv(baseRegQueryValueReq).buffer
55
+ baseRegQueryValueRes.raise_not_error_success("baseRegQueryValue")
56
+ baseRegQueryValueRes = BaseRegQueryValueRes.read(baseRegQueryValueRes)
57
+ type = baseRegQueryValueRes.lpType
58
+ data = baseRegQueryValueRes.lpData.str
59
+ case type
60
+ when 0
61
+ return data
62
+ when 1
63
+ return data.unpack("v*").pack("c*").chop
64
+ when 2
65
+ return data.unpack("v*").pack("c*").chop
66
+ when 3
67
+ return data
68
+ when 4
69
+ return data.unpack("V")[0]
70
+ when 5
71
+ return data.unpack("N")[0]
72
+ when 7
73
+ return data.unpack("v*").pack("c*").split("\x00")
74
+ when 11
75
+ return data.unpack("Q<")[0]
76
+ end
77
+ end
78
+
79
+ end
80
+ end
81
+
@@ -0,0 +1,39 @@
1
+ module SmbRpc
2
+ class Winreg < Rpc
3
+
4
+ class BaseRegSaveKeyReq < BinData::Record
5
+ endian :little
6
+ request :request
7
+ string :hKey, :length => 20
8
+ rpc_unicode_string :lpFile
9
+ conformantandVaryingStrings :lpFileNdr
10
+ uint32 :pSecurityAttributes
11
+
12
+ def initialize_instance
13
+ super
14
+ hKey.value = get_parameter(:handle)
15
+ uniString = "#{get_parameter(:file)}\x00".bytes.pack("v*")
16
+ lpFile.len.value = uniString.bytesize
17
+ lpFile.maximumLength.value = uniString.bytesize
18
+ lpFileNdr.str.value = uniString
19
+ request.pduHead.frag_length = self.num_bytes
20
+ request.opnum.value = 20 #BaseRegSaveKey
21
+ end
22
+ end
23
+
24
+ class BaseRegSaveKeyRes < BinData::Record
25
+ endian :little
26
+ request :request
27
+ uint32 :windowsError
28
+ end
29
+
30
+ def baseRegSaveKey(file:)
31
+ baseRegSaveKeyReq = BaseRegSaveKeyReq.new(handle:(@subKeyHandle || @rootKeyHandle), file:file)
32
+ baseRegSaveKeyRes = @file.ioctl_send_recv(baseRegSaveKeyReq).buffer
33
+ baseRegSaveKeyRes.raise_not_error_success("baseRegSaveKey")
34
+ return self
35
+ end
36
+
37
+ end
38
+ end
39
+
@@ -0,0 +1,46 @@
1
+ module SmbRpc
2
+ class Winreg < Rpc
3
+
4
+ class BaseRegSetValueReq < BinData::Record
5
+ endian :little
6
+ request :request
7
+ string :hKey, :length => 20
8
+ rpc_unicode_string :lpValueName
9
+ conformantandVaryingStrings :lpValueNameNdr
10
+ uint32 :dwType
11
+ uint32 :maxCount, :value => lambda{ lpData.num_bytes }
12
+ string :lpData, :read_length => :maxCount
13
+ #pad to 4 bytes align per RPC spec
14
+ string :pad, :onlyif => lambda{ (maxCount.value % 4) > 0}, :length => lambda { (4 - (maxCount % 4)) % 4 }
15
+ uint32 :cbData, :value => :maxCount
16
+
17
+ def initialize_instance
18
+ super
19
+ hKey.value = get_parameter(:handle)
20
+ uniString = "#{get_parameter(:valueName)}\x00".bytes.pack("v*")
21
+ lpValueName.len.value = uniString.bytesize
22
+ lpValueName.maximumLength.value = uniString.bytesize
23
+ lpValueNameNdr.str.value = uniString
24
+ dwType.value = get_parameter(:type)
25
+ lpData.value = get_parameter(:data)
26
+ request.pduHead.frag_length = self.num_bytes
27
+ request.opnum.value = 22 #BaseRegSetValue
28
+ end
29
+ end
30
+
31
+ class BaseRegSetValueRes < BinData::Record
32
+ endian :little
33
+ request :request
34
+ uint32 :windowsError
35
+ end
36
+
37
+ def baseRegSetValue(valueName:, type:, data:)
38
+ baseRegSetValueReq = BaseRegSetValueReq.new(handle:(@subKeyHandle || @rootKeyHandle), valueName:valueName, type:type, data:data)
39
+ baseRegSetValueRes = @file.ioctl_send_recv(baseRegSetValueReq).buffer
40
+ baseRegSetValueRes.raise_not_error_success("baseRegSetValue")
41
+ return self
42
+ end
43
+
44
+ end
45
+ end
46
+
@@ -0,0 +1,33 @@
1
+ WINREG_REGSAM = {
2
+ "KEY_QUERY_VALUE" => 0x00000001,
3
+ "KEY_SET_VALUE" => 0x00000002,
4
+ "KEY_CREATE_SUB_KEY" => 0x00000004,
5
+ "KEY_ENUMERATE_SUB_KEYS" => 0x00000008,
6
+ "KEY_CREATE_LINK" => 0x00000020,
7
+ "KEY_WOW64_64KEY" => 0x00000100,
8
+ "KEY_WOW64_32KEY" => 0x00000200,
9
+ "MAXIMUM_ALLOWED" => 0x02000000
10
+ }
11
+
12
+ WINREG_OPTIONS = {
13
+ "NONE" => 0x00000000,
14
+ "REG_OPTION_BACKUP_RESTORE" => 0x00000004,
15
+ "REG_OPTION_OPEN_LINK" => 0x00000008,
16
+ "REG_OPTION_DONT_VIRTUALIZE" => 0x00000010
17
+ }
18
+
19
+ WINREG_REG_VALUE_TYPE = {
20
+ "UNDEF" => 0,
21
+ "REG_SZ" => 1,
22
+ "REG_EXPAND_SZ" => 2,
23
+ "REG_BINARY" => 3,
24
+ "REG_DWORDLE" => 4,
25
+ "REG_DWORDBE" => 5,
26
+ "REG_MULTI_SZ" => 7,
27
+ "REG_QWORDLE" => 11
28
+ }
29
+
30
+ WINREG_DISPOSITION = {
31
+ "REG_CREATED_NEW_KEY" => 0x00000001,
32
+ "REG_OPENED_EXISTING_KEY" => 0x00000002
33
+ }
@@ -0,0 +1,37 @@
1
+ module SmbRpc
2
+ class Winreg < Rpc
3
+
4
+ class OpenClassesRootReq < BinData::Record
5
+ endian :little
6
+ request :request
7
+ uint32 :serverName
8
+ uint32 :samDesired
9
+
10
+ def initialize_instance
11
+ super
12
+ samDesired.value = get_parameter(:access)
13
+
14
+ request.pduHead.frag_length = self.num_bytes
15
+ request.opnum.value = 0 #OpenClassesRoot
16
+ end
17
+ end
18
+
19
+ class OpenClassesRootRes < BinData::Record
20
+ endian :little
21
+ request :request
22
+ string :phKey, :length => 20
23
+ uint32 :windowsError
24
+ end
25
+
26
+ def openClassesRoot(samDesired:WINREG_REGSAM["MAXIMUM_ALLOWED"])
27
+ openClassesRootReq = OpenClassesRootReq.new(access:samDesired)
28
+ openClassesRootRes = @file.ioctl_send_recv(openClassesRootReq).buffer
29
+ openClassesRootRes.raise_not_error_success("openClassesRoot")
30
+ openClassesRootRes = OpenClassesRootRes.read(openClassesRootRes)
31
+ @rootKeyHandle = openClassesRootRes.phKey
32
+ return self
33
+ end
34
+
35
+ end
36
+ end
37
+
@@ -0,0 +1,37 @@
1
+ module SmbRpc
2
+ class Winreg < Rpc
3
+
4
+ class OpenCurrentConfigReq < BinData::Record
5
+ endian :little
6
+ request :request
7
+ uint32 :serverName
8
+ uint32 :samDesired
9
+
10
+ def initialize_instance
11
+ super
12
+ samDesired.value = get_parameter(:access)
13
+
14
+ request.pduHead.frag_length = self.num_bytes
15
+ request.opnum.value = 27 #OpenCurrentConfig
16
+ end
17
+ end
18
+
19
+ class OpenCurrentConfigRes < BinData::Record
20
+ endian :little
21
+ request :request
22
+ string :phKey, :length => 20
23
+ uint32 :windowsError
24
+ end
25
+
26
+ def openCurrentConfig(samDesired:WINREG_REGSAM["MAXIMUM_ALLOWED"])
27
+ openCurrentConfigReq = OpenCurrentConfigReq.new(access:samDesired)
28
+ openCurrentConfigRes = @file.ioctl_send_recv(openCurrentConfigReq).buffer
29
+ openCurrentConfigRes.raise_not_error_success("openCurrentConfig")
30
+ openCurrentConfigRes = OpenCurrentConfigRes.read(openCurrentConfigRes)
31
+ @rootKeyHandle = openCurrentConfigRes.phKey
32
+ return self
33
+ end
34
+
35
+ end
36
+ end
37
+
@@ -0,0 +1,37 @@
1
+ module SmbRpc
2
+ class Winreg < Rpc
3
+
4
+ class OpenCurrentUserReq < BinData::Record
5
+ endian :little
6
+ request :request
7
+ uint32 :serverName
8
+ uint32 :samDesired
9
+
10
+ def initialize_instance
11
+ super
12
+ samDesired.value = get_parameter(:access)
13
+
14
+ request.pduHead.frag_length = self.num_bytes
15
+ request.opnum.value = 1 #OpenCurrentUser
16
+ end
17
+ end
18
+
19
+ class OpenCurrentUserRes < BinData::Record
20
+ endian :little
21
+ request :request
22
+ string :phKey, :length => 20
23
+ uint32 :windowsError
24
+ end
25
+
26
+ def openCurrentUser(samDesired:WINREG_REGSAM["MAXIMUM_ALLOWED"])
27
+ openCurrentUserReq = OpenCurrentUserReq.new(access:samDesired)
28
+ openCurrentUserRes = @file.ioctl_send_recv(openCurrentUserReq).buffer
29
+ openCurrentUserRes.raise_not_error_success("openCurrentUser")
30
+ openCurrentUserRes = OpenCurrentUserRes.read(openCurrentUserRes)
31
+ @rootKeyHandle = openCurrentUserRes.phKey
32
+ return self
33
+ end
34
+
35
+ end
36
+ end
37
+
@@ -0,0 +1,37 @@
1
+ module SmbRpc
2
+ class Winreg < Rpc
3
+
4
+ class OpenLocalMachineReq < BinData::Record
5
+ endian :little
6
+ request :request
7
+ uint32 :serverName
8
+ uint32 :samDesired
9
+
10
+ def initialize_instance
11
+ super
12
+ samDesired.value = get_parameter(:access)
13
+
14
+ request.pduHead.frag_length = self.num_bytes
15
+ request.opnum.value = 2 #OpenLocalMachine
16
+ end
17
+ end
18
+
19
+ class OpenLocalMachineRes < BinData::Record
20
+ endian :little
21
+ request :request
22
+ string :phKey, :length => 20
23
+ uint32 :windowsError
24
+ end
25
+
26
+ def openLocalMachine(samDesired:WINREG_REGSAM["MAXIMUM_ALLOWED"])
27
+ openLocalMachineReq = OpenLocalMachineReq.new(access:samDesired)
28
+ openLocalMachineRes = @file.ioctl_send_recv(openLocalMachineReq).buffer
29
+ openLocalMachineRes.raise_not_error_success("openLocalMachine")
30
+ openLocalMachineRes = OpenLocalMachineRes.read(openLocalMachineRes)
31
+ @rootKeyHandle = openLocalMachineRes.phKey
32
+ return self
33
+ end
34
+
35
+ end
36
+ end
37
+
@@ -0,0 +1,37 @@
1
+ module SmbRpc
2
+ class Winreg < Rpc
3
+
4
+ class OpenUsersReq < BinData::Record
5
+ endian :little
6
+ request :request
7
+ uint32 :serverName
8
+ uint32 :samDesired
9
+
10
+ def initialize_instance
11
+ super
12
+ samDesired.value = get_parameter(:access)
13
+
14
+ request.pduHead.frag_length = self.num_bytes
15
+ request.opnum.value = 4 #OpenUsers
16
+ end
17
+ end
18
+
19
+ class OpenUsersRes < BinData::Record
20
+ endian :little
21
+ request :request
22
+ string :phKey, :length => 20
23
+ uint32 :windowsError
24
+ end
25
+
26
+ def openUsers(samDesired:WINREG_REGSAM["MAXIMUM_ALLOWED"])
27
+ openUsersReq = OpenUsersReq.new(access:samDesired)
28
+ openUsersRes = @file.ioctl_send_recv(openUsersReq).buffer
29
+ openUsersRes.raise_not_error_success("openUsers")
30
+ openUsersRes = OpenUsersRes.read(openUsersRes)
31
+ @rootKeyHandle = openUsersRes.phKey
32
+ return self
33
+ end
34
+
35
+ end
36
+ end
37
+
data/smbRpc.gemspec CHANGED
@@ -1,7 +1,7 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'smbRpc'
3
- s.version = '0.0.4'
4
- s.date = '2019-01-24'
3
+ s.version = '0.0.5'
4
+ s.date = '2019-02-09'
5
5
  s.summary = "Interface to various Windows RPC services over SMB namepipes"
6
6
  s.description = "As describe in summary"
7
7
  s.authors = ["Rungsree Singholka"]
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: smbRpc
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.4
4
+ version: 0.0.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rungsree Singholka
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-01-24 00:00:00.000000000 Z
11
+ date: 2019-02-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ruby_smb
@@ -49,6 +49,9 @@ files:
49
49
  - examples/enumServices.rb
50
50
  - examples/enumSmbPipe.rb
51
51
  - examples/enumUsers.rb
52
+ - examples/regAdd.rb
53
+ - examples/regQuery.rb
54
+ - examples/regSave.rb
52
55
  - examples/serverGetInfo.rb
53
56
  - lib/smbRpc.rb
54
57
  - lib/smbRpc/epmapper.rb
@@ -123,6 +126,24 @@ files:
123
126
  - lib/smbRpc/updateString.rb
124
127
  - lib/smbRpc/updateString/raise_not_error_success.rb
125
128
  - lib/smbRpc/updateString/to_des_ecb_lm.rb
129
+ - lib/smbRpc/winreg.rb
130
+ - lib/smbRpc/winreg/baseRegCloseKey.rb
131
+ - lib/smbRpc/winreg/baseRegCreateKey.rb
132
+ - lib/smbRpc/winreg/baseRegDeleteKey.rb
133
+ - lib/smbRpc/winreg/baseRegDeleteValue.rb
134
+ - lib/smbRpc/winreg/baseRegEnumKey.rb
135
+ - lib/smbRpc/winreg/baseRegEnumValue.rb
136
+ - lib/smbRpc/winreg/baseRegOpenKey.rb
137
+ - lib/smbRpc/winreg/baseRegQueryInfoKey.rb
138
+ - lib/smbRpc/winreg/baseRegQueryValue.rb
139
+ - lib/smbRpc/winreg/baseRegSaveKey.rb
140
+ - lib/smbRpc/winreg/baseRegSetValue.rb
141
+ - lib/smbRpc/winreg/constants.rb
142
+ - lib/smbRpc/winreg/openClassesRoot.rb
143
+ - lib/smbRpc/winreg/openCurrentConfig.rb
144
+ - lib/smbRpc/winreg/openCurrentUser.rb
145
+ - lib/smbRpc/winreg/openLocalMachine.rb
146
+ - lib/smbRpc/winreg/openUsers.rb
126
147
  - smbRpc.gemspec
127
148
  homepage: https://github.com/smbRpc/smbRpc
128
149
  licenses: