Skip to content

Commit 3e1efbf

Browse files
author
staaldraad
committed
Merge pull request #1 from Meatballs1/pr2107
Refactor to common post module
2 parents d3903aa + 051ef0b commit 3e1efbf

File tree

4 files changed

+276
-272
lines changed

4 files changed

+276
-272
lines changed

lib/msf/core/post/windows/netapi.rb

+154
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
# -*- coding: binary -*-
2+
module Msf
3+
class Post
4+
module Windows
5+
6+
module NetAPI
7+
8+
MAX_PREFERRED_LENGTH = -1
9+
SV_TYPE_ALL = 0xFFFFFFFF
10+
SV_TYPE_DOMAIN_ENUM = 0x80000000
11+
SV_TYPE_DOMAIN_BAKCTRL = 10
12+
SV_TYPE_DOMAIN_CTRL = 4
13+
14+
def UnicodeByteStringToAscii(str)
15+
length = (str.index "\0\0\0") + 1
16+
Rex::Text.to_ascii(str[0..length])
17+
end
18+
19+
def netapi_buffer_free(ptr)
20+
# Free the buffer
21+
ret = client.railgun.netapi32.NetApiBufferFree(ptr)
22+
vprint_error("Unable to free buffer, Error Code: #{ret['return']}") unless ret['return'] == 0
23+
end
24+
25+
def net_server_enum(server_type=SV_TYPE_ALL, domain=nil)
26+
result = client.railgun.netapi32.NetServerEnum(
27+
nil, # servername
28+
100, # level (100/101)
29+
4, # bufptr
30+
MAX_PREFERRED_LENGTH, # prefmaxlen
31+
4, # entries read
32+
4, # total entries
33+
server_type, # server_type
34+
domain, # domain
35+
nil # resume handle
36+
)
37+
38+
case result['return']
39+
when 5
40+
vprint_error("Access Denied when trying to enum hosts.")
41+
return nil
42+
when 6118
43+
vprint_error("No Browser servers found.")
44+
return nil
45+
when 50
46+
vprint_error("Request not supported.")
47+
return nil
48+
when 2184
49+
vprint_error("Service not installed.")
50+
return nil
51+
when 0
52+
vprint_status("Success.")
53+
when 87
54+
vprint_error ("Invalid parameter.")
55+
return nil
56+
else
57+
if result['return'] != 234
58+
vprint_status("Unaccounted for error code: #{result['return']}")
59+
return nil
60+
end
61+
end
62+
63+
hosts = read_server_structs(result['bufptr'], result['totalentries'])
64+
65+
netapi_buffer_free(result['bufptr'])
66+
67+
return hosts
68+
end
69+
70+
def read_server_structs(start_ptr, count)
71+
base = 0
72+
struct_size = 8
73+
hosts = []
74+
mem = client.railgun.memread(start_ptr, struct_size*count)
75+
76+
0.upto(count-1) do |i|
77+
x = {}
78+
x[:version]= mem[(base + 0),4].unpack("V*")[0]
79+
nameptr = mem[(base + 4),4].unpack("V*")[0]
80+
x[:name] = UnicodeByteStringToAscii(client.railgun.memread(nameptr, 255))
81+
hosts << x
82+
base += struct_size
83+
end
84+
85+
return hosts
86+
end
87+
88+
def getSessions(hostname, username)
89+
result = client.railgun.netapi32.NetSessionEnum(
90+
hostname,
91+
nil,
92+
username,
93+
10,
94+
4,
95+
MAX_PREFERRED_LENGTH,
96+
4,
97+
4,
98+
nil
99+
)
100+
101+
case result['return']
102+
when 5
103+
vprint_error("#{hostname} Access denied...")
104+
return nil
105+
when 53
106+
vprint_error("Host not found or did not respond: #{hostname}")
107+
return nil
108+
when 123
109+
vprint_error("Invalid host: #{hostname}")
110+
return nil
111+
when 0
112+
vprint_status("#{hostname} Session identified")
113+
when 2221 #username not found
114+
return nil
115+
else
116+
if result['return'] != 234
117+
vprint_error("Unaccounted for error code: #{result['return']}")
118+
return nil
119+
end
120+
end
121+
122+
sessions = read_session_structs(result['bufptr'], result['totalentries'], hostname)
123+
124+
netapi_buffer_free(result['bufptr'])
125+
126+
return sessions
127+
end
128+
129+
def read_session_structs(start_ptr, count, hostname)
130+
base = 0
131+
struct_size = 16
132+
sessions = []
133+
mem = client.railgun.memread(start_ptr, struct_size*count)
134+
135+
0.upto(count-1) do |i|
136+
sess = {}
137+
cnameptr = mem[(base + 0),4].unpack("V*")[0]
138+
usernameptr = mem[(base + 4),4].unpack("V*")[0]
139+
sess[:usetime] = mem[(base + 8),4].unpack("V*")[0]
140+
sess[:idletime] = mem[(base + 12),4].unpack("V*")[0]
141+
sess[:cname] = UnicodeByteStringToAscii(client.railgun.memread(cnameptr,255))
142+
sess[:username] = UnicodeByteStringToAscii(client.railgun.memread(usernameptr,255))
143+
sess[:hostname] = hostname
144+
sessions << sess
145+
base = base + struct_size
146+
end
147+
148+
return sessions
149+
end
150+
151+
end # NetAPI
152+
end # Windows
153+
end # Post
154+
end # Msf

lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_netapi32.rb

+16
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,22 @@ def self.create_dll(dll_path = 'netapi32')
5555
["PDWORD","totalentries","out"]
5656
])
5757

58+
dll.add_function('NetSessionEnum', 'DWORD',[
59+
['PWCHAR','servername','in'],
60+
['PWCHAR','UncClientName','in'],
61+
['PWCHAR','username','in'],
62+
['DWORD','level','in'],
63+
['PDWORD','bufptr','out'],
64+
['DWORD','prefmaxlen','in'],
65+
['PDWORD','entriesread','out'],
66+
['PDWORD','totalentries','out'],
67+
['PDWORD','resume_handle','inout']
68+
])
69+
70+
dll.add_function('NetApiBufferFree', 'DWORD', [
71+
['LPVOID','buffer','in']
72+
])
73+
5874
return dll
5975
end
6076

0 commit comments

Comments
 (0)