Skip to content

Commit 961155e

Browse files
authored
2.0 Update
Refactored code base Improved multithreaded file writing
1 parent b1f89e5 commit 961155e

File tree

5 files changed

+613
-500
lines changed

5 files changed

+613
-500
lines changed

SharpShares/Enums/Shares.cs

Lines changed: 306 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,306 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.IO;
4+
using System.Linq;
5+
using System.Security.AccessControl;
6+
using System.Security.Principal;
7+
using System.Runtime.InteropServices;
8+
using System.Text;
9+
using System.Threading;
10+
using System.Threading.Tasks;
11+
12+
13+
namespace SharpShares.Enums
14+
{
15+
class Shares
16+
{
17+
[DllImport("Netapi32.dll", SetLastError = true)]
18+
public static extern int NetWkstaGetInfo(string servername, int level, out IntPtr bufptr);
19+
20+
[DllImport("Netapi32.dll", SetLastError = true)]
21+
static extern int NetApiBufferFree(IntPtr Buffer);
22+
23+
[DllImport("Netapi32.dll", CharSet = CharSet.Unicode)]
24+
private static extern int NetShareEnum(
25+
StringBuilder ServerName,
26+
int level,
27+
ref IntPtr bufPtr,
28+
uint prefmaxlen,
29+
ref int entriesread,
30+
ref int totalentries,
31+
ref int resume_handle
32+
);
33+
34+
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
35+
public struct WKSTA_INFO_100
36+
{
37+
public int platform_id;
38+
public string computer_name;
39+
public string lan_group;
40+
public int ver_major;
41+
public int ver_minor;
42+
}
43+
44+
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
45+
public struct SHARE_INFO_0
46+
{
47+
public string shi0_netname;
48+
}
49+
50+
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
51+
public struct SHARE_INFO_1
52+
{
53+
public string shi1_netname;
54+
public uint shi1_type;
55+
public string shi1_remark;
56+
public SHARE_INFO_1(string sharename, uint sharetype, string remark)
57+
{
58+
this.shi1_netname = sharename;
59+
this.shi1_type = sharetype;
60+
this.shi1_remark = remark;
61+
}
62+
public override string ToString()
63+
{
64+
return shi1_netname;
65+
}
66+
}
67+
68+
const uint MAX_PREFERRED_LENGTH = 0xFFFFFFFF;
69+
const int NERR_Success = 0;
70+
71+
private enum NetError : uint
72+
{
73+
NERR_Success = 0,
74+
NERR_BASE = 2100,
75+
NERR_UnknownDevDir = (NERR_BASE + 16),
76+
NERR_DuplicateShare = (NERR_BASE + 18),
77+
NERR_BufTooSmall = (NERR_BASE + 23),
78+
}
79+
80+
private enum SHARE_TYPE : uint
81+
{
82+
STYPE_DISKTREE = 0,
83+
STYPE_PRINTQ = 1,
84+
STYPE_DEVICE = 2,
85+
STYPE_IPC = 3,
86+
STYPE_SPECIAL = 0x80000000,
87+
}
88+
89+
public static SHARE_INFO_1[] EnumNetShares(string Server)
90+
{
91+
List<SHARE_INFO_1> ShareInfos = new List<SHARE_INFO_1>();
92+
int entriesread = 0;
93+
int totalentries = 0;
94+
int resume_handle = 0;
95+
int nStructSize = Marshal.SizeOf(typeof(SHARE_INFO_1));
96+
IntPtr bufPtr = IntPtr.Zero;
97+
StringBuilder server = new StringBuilder(Server);
98+
int ret = NetShareEnum(server, 1, ref bufPtr, MAX_PREFERRED_LENGTH, ref entriesread, ref totalentries, ref resume_handle);
99+
if (ret == NERR_Success)
100+
{
101+
IntPtr currentPtr = bufPtr;
102+
for (int i = 0; i < entriesread; i++)
103+
{
104+
SHARE_INFO_1 shi1 = (SHARE_INFO_1)Marshal.PtrToStructure(currentPtr, typeof(SHARE_INFO_1));
105+
ShareInfos.Add(shi1);
106+
currentPtr += nStructSize;
107+
}
108+
NetApiBufferFree(bufPtr);
109+
return ShareInfos.ToArray();
110+
}
111+
else
112+
{
113+
ShareInfos.Add(new SHARE_INFO_1("ERROR=" + ret.ToString(), 10, string.Empty));
114+
return ShareInfos.ToArray();
115+
}
116+
}
117+
118+
public static void GetComputerShares(string computer, bool verbose, List<string> filter, bool stealth, string outfile)
119+
{
120+
//Error 53 - network path was not found
121+
//Error 5 - Access Denied
122+
string[] errors = { "ERROR=53", "ERROR=5" };
123+
SHARE_INFO_1[] computerShares = EnumNetShares(computer);
124+
if (computerShares.Length > 0)
125+
{
126+
List<string> readableShares = new List<string>();
127+
List<string> writeableShares = new List<string>();
128+
List<string> unauthorizedShares = new List<string>();
129+
// get current user's identity to compare against ACL of shares
130+
WindowsIdentity identity = WindowsIdentity.GetCurrent();
131+
string userSID = identity.User.Value;
132+
foreach (SHARE_INFO_1 share in computerShares)// <------------ go to next share -----------+
133+
{ // |
134+
if ((filter !=null) && (filter.Contains(share.shi1_netname.ToString().ToUpper()))) // |
135+
{ // |
136+
continue; // Skip the remainder of this iteration. --------------------------------+
137+
}
138+
//share.shi1_netname returns the error code when caught
139+
if (stealth && !errors.Contains(share.shi1_netname))
140+
{
141+
Console.WriteLine("[?] \\\\{0}\\{1}", computer, share.shi1_netname);
142+
continue; //do not perform access checks
143+
}
144+
try
145+
{
146+
string path = String.Format("\\\\{0}\\{1}", computer, share.shi1_netname);
147+
var files = Directory.GetFiles(path);
148+
readableShares.Add(share.shi1_netname);
149+
AuthorizationRuleCollection rules = Directory.GetAccessControl(path).GetAccessRules(true, true, typeof(System.Security.Principal.SecurityIdentifier));
150+
foreach (FileSystemAccessRule rule in rules)
151+
{
152+
//https://stackoverflow.com/questions/130617/how-do-you-check-for-permissions-to-write-to-a-directory-or-file
153+
// compare SID of group referenced in ACL to groups the current user is a member of
154+
if (rule.IdentityReference.ToString() == userSID || identity.Groups.Contains(rule.IdentityReference))
155+
{
156+
// plenty of other FileSystem Rights to look for
157+
// https://docs.microsoft.com/en-us/dotnet/api/system.security.accesscontrol.filesystemrights
158+
if ((//rule.FileSystemRights.HasFlag(FileSystemRights.CreateFiles) ||
159+
//rule.FileSystemRights.HasFlag(FileSystemRights.WriteAttributes) ||
160+
//rule.FileSystemRights.HasFlag(FileSystemRights.WriteData) ||
161+
//rule.FileSystemRights.HasFlag(FileSystemRights.WriteExtendedAttributes) ||
162+
//rule.FileSystemRights.HasFlag(FileSystemRights.CreateDirectories) ||
163+
rule.FileSystemRights.HasFlag(FileSystemRights.Write)) && rule.AccessControlType == AccessControlType.Allow)
164+
{
165+
writeableShares.Add(share.shi1_netname);
166+
break;
167+
}
168+
}
169+
}
170+
}
171+
catch
172+
{
173+
//share.shi1_netname returns the error code when caught
174+
if (!errors.Contains(share.shi1_netname))
175+
{
176+
unauthorizedShares.Add(share.shi1_netname);
177+
}
178+
}
179+
}
180+
if (readableShares.Count > 0)
181+
{
182+
foreach (string share in readableShares)
183+
{
184+
string output = String.Format("[r] \\\\{0}\\{1}", computer, share);
185+
if (!String.IsNullOrEmpty(outfile))
186+
{
187+
try
188+
{
189+
WriteToFileThreadSafe(output, outfile);
190+
/*
191+
using (StreamWriter sw = File.AppendText(outfile))
192+
{
193+
sw.WriteLine(output);
194+
}
195+
*/
196+
}
197+
catch (Exception ex)
198+
{
199+
Console.WriteLine("[!] Outfile Error: {0}", ex.Message);
200+
Environment.Exit(0);
201+
}
202+
}
203+
else
204+
{
205+
Console.WriteLine(output);
206+
}
207+
}
208+
}
209+
if (writeableShares.Count > 0)
210+
{
211+
foreach (string share in writeableShares)
212+
{
213+
string output = String.Format("[w] \\\\{0}\\{1}", computer, share);
214+
if (!String.IsNullOrEmpty(outfile))
215+
{
216+
try
217+
{
218+
WriteToFileThreadSafe(output, outfile);
219+
/*
220+
using (StreamWriter sw = File.AppendText(outfile))
221+
{
222+
sw.WriteLine(output);
223+
}
224+
*/
225+
}
226+
catch (Exception ex)
227+
{
228+
Console.WriteLine("[!] Outfile Error: {0}", ex.Message);
229+
Environment.Exit(0);
230+
}
231+
}
232+
else
233+
{
234+
Console.WriteLine(output);
235+
}
236+
}
237+
}
238+
if (verbose && unauthorizedShares.Count > 0)
239+
{
240+
foreach (string share in unauthorizedShares)
241+
{
242+
string output = String.Format("[-] \\\\{0}\\{1}", computer, share);
243+
if (!String.IsNullOrEmpty(outfile))
244+
{
245+
try
246+
{
247+
WriteToFileThreadSafe(output, outfile);
248+
/*
249+
using (StreamWriter sw = File.AppendText(outfile))
250+
{
251+
sw.WriteLine(output);
252+
}
253+
*/
254+
}
255+
catch (Exception ex)
256+
{
257+
Console.WriteLine("[!] Outfile Error: {0}", ex.Message);
258+
Environment.Exit(0);
259+
}
260+
}
261+
else
262+
{
263+
Console.WriteLine(output);
264+
}
265+
}
266+
}
267+
}
268+
}
269+
270+
public static ReaderWriterLockSlim _readWriteLock = new ReaderWriterLockSlim();
271+
272+
public static void WriteToFileThreadSafe(string text, string path)
273+
{
274+
// Set Status to Locked
275+
_readWriteLock.EnterWriteLock();
276+
try
277+
{
278+
// Append text to the file
279+
using (StreamWriter sw = File.AppendText(path))
280+
{
281+
sw.WriteLine(text);
282+
sw.Close();
283+
}
284+
}
285+
finally
286+
{
287+
// Release lock
288+
_readWriteLock.ExitWriteLock();
289+
}
290+
}
291+
public static void GetAllShares(List<string> computers, int threads, bool verbose, List<string> filter, bool stealth, string outfile)
292+
{
293+
Console.WriteLine("[+] Starting share enumeration against {0} hosts\n", computers.Count);
294+
//https://blog.danskingdom.com/limit-the-number-of-c-tasks-that-run-in-parallel/
295+
var threadList = new List<Action>();
296+
foreach (string computer in computers)
297+
{
298+
threadList.Add(() => GetComputerShares(computer, verbose, filter, stealth, outfile));
299+
}
300+
var options = new ParallelOptions { MaxDegreeOfParallelism = threads };
301+
Parallel.Invoke(options, threadList.ToArray());
302+
Console.WriteLine("[+] Finished Enumerating Shares");
303+
}
304+
305+
}
306+
}

0 commit comments

Comments
 (0)