-
Notifications
You must be signed in to change notification settings - Fork 4
/
sharpshares.cs
303 lines (275 loc) · 10.8 KB
/
sharpshares.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
//Taken from here and modified: https://github.com/djhohnstein/SharpShares
using System;
using System.Collections.Generic;
using System.DirectoryServices;
using System.DirectoryServices.ActiveDirectory;
using System.IO;
using System.Linq;
using System.Net;
using System.Runtime.InteropServices;
using System.Security.Principal;
using System.Text;
using System.Threading;
namespace SharpShares
{
class Program
{
private static Object thisLock = new Object();
public static Semaphore MaxThreads { get; set; }
[DllImport("Netapi32.dll", SetLastError = true)]
public static extern int NetWkstaGetInfo(string servername, int level, out IntPtr bufptr);
[DllImport("Netapi32.dll", SetLastError = true)]
static extern int NetApiBufferFree(IntPtr Buffer);
[DllImport("Netapi32.dll", CharSet = CharSet.Unicode)]
private static extern int NetShareEnum(
StringBuilder ServerName,
int level,
ref IntPtr bufPtr,
uint prefmaxlen,
ref int entriesread,
ref int totalentries,
ref int resume_handle
);
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct WKSTA_INFO_100
{
public int platform_id;
public string computer_name;
public string lan_group;
public int ver_major;
public int ver_minor;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct SHARE_INFO_0
{
public string shi0_netname;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct SHARE_INFO_1
{
public string shi1_netname;
public uint shi1_type;
public string shi1_remark;
public SHARE_INFO_1(string sharename, uint sharetype, string remark)
{
this.shi1_netname = sharename;
this.shi1_type = sharetype;
this.shi1_remark = remark;
}
public override string ToString()
{
return shi1_netname;
}
}
const uint MAX_PREFERRED_LENGTH = 0xFFFFFFFF;
const int NERR_Success = 0;
private enum NetError : uint
{
NERR_Success = 0,
NERR_BASE = 2100,
NERR_UnknownDevDir = (NERR_BASE + 16),
NERR_DuplicateShare = (NERR_BASE + 18),
NERR_BufTooSmall = (NERR_BASE + 23),
}
private enum SHARE_TYPE : uint
{
STYPE_DISKTREE = 0,
STYPE_PRINTQ = 1,
STYPE_DEVICE = 2,
STYPE_IPC = 3,
STYPE_SPECIAL = 0x80000000,
}
public static SHARE_INFO_1[] EnumNetShares(string Server)
{
List<SHARE_INFO_1> ShareInfos = new List<SHARE_INFO_1>();
int entriesread = 0;
int totalentries = 0;
int resume_handle = 0;
int nStructSize = Marshal.SizeOf(typeof(SHARE_INFO_1));
IntPtr bufPtr = IntPtr.Zero;
StringBuilder server = new StringBuilder(Server);
int ret = NetShareEnum(server, 1, ref bufPtr, MAX_PREFERRED_LENGTH, ref entriesread, ref totalentries, ref resume_handle);
if (ret == NERR_Success)
{
IntPtr currentPtr = bufPtr;
for (int i = 0; i < entriesread; i++)
{
SHARE_INFO_1 shi1 = (SHARE_INFO_1)Marshal.PtrToStructure(currentPtr, typeof(SHARE_INFO_1));
ShareInfos.Add(shi1);
currentPtr += nStructSize;
}
NetApiBufferFree(bufPtr);
return ShareInfos.ToArray();
}
else
{
ShareInfos.Add(new SHARE_INFO_1("ERROR=" + ret.ToString(), 10, string.Empty));
return ShareInfos.ToArray();
}
}
public static List<DomainController> GetDomainControllers()
{
List<DomainController> domainControllers = new List<DomainController>();
try
{
Domain domain = Domain.GetCurrentDomain();
foreach (DomainController dc in domain.DomainControllers)
{
domainControllers.Add(dc);
}
}
catch { }
return domainControllers;
}
public static void GetComputerAddresses(List<string> computers)
{
foreach (string computer in computers)
{
try
{
IPAddress[] ips = System.Net.Dns.GetHostAddresses(computer);
foreach (IPAddress ip in ips)
{
if (!ip.ToString().Contains(":"))
{
Console.WriteLine("{0}: {1}", computer, ip);
}
}
}
catch(Exception ex)
{
//Console.WriteLine("[X] ERROR: {0}", ex.Message);
}
}
}
public static List<string> GetComputers()
{
List<string> computerNames = new List<string>();
List<DomainController> dcs = GetDomainControllers();
if (dcs.Count > 0)
{
try
{
Domain domain = Domain.GetCurrentDomain();
//domain.
string currentUser = WindowsIdentity.GetCurrent().Name.Split('\\')[1];
using (DirectoryEntry entry = new DirectoryEntry(String.Format("LDAP://{0}", dcs[0])))
{
using (DirectorySearcher mySearcher = new DirectorySearcher(entry))
{
mySearcher.Filter = ("(objectClass=computer)");
// No size limit, reads all objects
mySearcher.SizeLimit = 0;
// Read data in pages of 250 objects. Make sure this value is below the limit configured in your AD domain (if there is a limit)
mySearcher.PageSize = 250;
// Let searcher know which properties are going to be used, and only load those
mySearcher.PropertiesToLoad.Add("name");
foreach (SearchResult resEnt in mySearcher.FindAll())
{
// Note: Properties can contain multiple values.
if (resEnt.Properties["name"].Count > 0)
{
string computerName = (string)resEnt.Properties["name"][0];
computerNames.Add(computerName);
}
}
}
}
}
catch { }
}
else
{
Console.WriteLine("ERROR: Could not get a list of Domain Controllers.");
}
return computerNames;
}
public static void GetComputerShares(string computer)
{
string[] errors = { "ERROR=53", "ERROR=5" };
SHARE_INFO_1[] computerShares = EnumNetShares(computer);
if (computerShares.Length > 0)
{
List<string> readableShares = new List<string>();
List<string> unauthorizedShares = new List<string>();
foreach (SHARE_INFO_1 share in computerShares)
{
try
{
string path = String.Format("\\\\{0}\\{1}", computer, share.shi1_netname);
var files = System.IO.Directory.GetFiles(path);
readableShares.Add(share.shi1_netname);
}
catch
{
if (!errors.Contains(share.shi1_netname))
{
unauthorizedShares.Add(share.shi1_netname);
}
}
}
if (readableShares.Count > 0)
{
string output = "";
foreach (string share in readableShares)
{
output += string.Format("\\\\{0}\\{1}\r\n", computer, share);
}
lock(thisLock)
{
File.AppendAllText(@"shares.txt", output);
}
}
}
}
public static void GetAllShares(List<string> computers)
{
List<Thread> runningThreads = new List<Thread>();
foreach(string computer in computers)
{
Thread t = new Thread(() => GetComputerShares(computer));
t.Start();
runningThreads.Add(t);
}
foreach(Thread t in runningThreads)
{
t.Join();
}
}
static void GetComputerVersions(List<string> computers)
{
String output = "";
foreach(string computer in computers)
{
output += String.Format("Computer: {0}\r\n", computer);
string serverName = String.Format("\\\\{0}", computer);
IntPtr buffer;
var ret = NetWkstaGetInfo(serverName, 100, out buffer);
var strut_size = Marshal.SizeOf(typeof(WKSTA_INFO_100));
if (ret == NERR_Success)
{
var info = (WKSTA_INFO_100)Marshal.PtrToStructure(buffer, typeof(WKSTA_INFO_100));
if (!string.IsNullOrEmpty(info.computer_name))
{
output += String.Format("\t{0}\r\n", info.computer_name);
output += String.Format("\t{0}\r\n", info.platform_id);
output += String.Format("\t{0}\r\n",info.ver_major);
output += String.Format("\t{0}\r\n",info.ver_minor);
output += String.Format("\t{0}\r\n",info.lan_group);
}
}
}
System.IO.File.WriteAllLines(@"systeminfo.txt", computers);
}
static void Main(string[] args)
{
var computers = GetComputers();
System.IO.File.WriteAllLines(@"systems.txt", computers);
Console.WriteLine("[*] Parsed {0} computer objects.", computers.Count);
ThreadPool.SetMaxThreads(100, 100);
//GetComputerAddresses(computers);
GetAllShares(computers);
// GetComputerVersions(computers);
}
}
}