Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Code Refactor and Additional Functionality #19

Merged
merged 3 commits into from
Sep 13, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
91 changes: 40 additions & 51 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,57 +10,41 @@ SharpUp is licensed under the BSD 3-Clause license.

## Usage

C:\Temp>SharpUp.exe

=== SharpUp: Running Privilege Escalation Checks ===


=== Modifiable Services ===

Name : VulnSvc
DisplayName : VulnSvc
Description :
State : Stopped
StartMode : Auto
PathName : C:\Program Files\VulnSvc\VulnSvc.exe


=== Modifiable Service Binaries ===

Name : VulnSvc2
DisplayName : VulnSvc22
Description :
State : Stopped
StartMode : Auto
PathName : C:\VulnSvc2\VulnSvc2.exe


=== AlwaysInstallElevated Registry Keys ===



=== Modifiable Folders in %PATH% ===

Modifable %PATH% Folder : C:\Go\bin


=== Modifiable Registry Autoruns ===



=== *Special* User Privileges ===



=== Unattended Install Files ===



=== McAfee Sitelist.xml Files ===



[*] Completed Privesc Checks in 11 seconds
```
SharpUp.exe [audit] [check1] [check2]...

audit - Specifies whether or not to enable audit mode. If enabled, SharpUp will run vulenrability checks
regardless if the process is in high integrity or the user is in the local administrator's group.
If no checks are specified, audit will run all checks. Otherwise, each check following audit will
be ran.

check* - The individual vulnerability check to be ran. Must be one of the following:

- AlwaysInstallElevated
- CachedGPPPassword
- DomainGPPPassword
- HijackablePaths
- McAfeeSitelistFiles
- ModifiableServiceBinaries
- ModifiableServiceRegistryKeys
- ModifiableServices
- RegistryAutoLogons
- RegistryAutoruns
- TokenPrivileges
- UnattendedInstallFiles
- UnquotedServicePath


Examples:
SharpUp.exe audit
-> Runs all vulnerability checks regardless of integrity level or group membership.

SharpUp.exe HijackablePaths
-> Check only if there are modifiable paths in the user's %PATH% variable.

SharpUp.exe audit HijackablePaths
-> Check only for modifiable paths in the user's %PATH% regardless of integrity level or group membership.
```

## Compile Instructions

Expand All @@ -77,3 +61,8 @@ SharpUp incorporates various code C# snippets and bits of PoCs found throughout
* [Rod Stephens' pattern for recursive file enumeration](http://csharphelper.com/blog/2015/06/find-files-that-match-multiple-patterns-in-c/)
* [SwDevMan81's snippet for enumerating current token privileges](https://stackoverflow.com/questions/4349743/setting-size-of-token-privileges-luid-and-attributes-array-returned-by-gettokeni)
* [Nikki Locke's code for querying service security descriptors](https://stackoverflow.com/questions/15771998/how-to-give-a-user-permission-to-start-and-stop-a-particular-service-using-c-sha/15796352#15796352)
* [Raika](https://github.com/Raikia) for providing example unquoted service path search code.
* [RemiEscourrou](https://github.com/RemiEscourrou) for contributing additional ACE checking code and example modifiable service registry key code.
* [Coder666](https://github.com/Coder666) for adding ACE filtering code to filter only ACEs with access allowed.
* [vysecurity](https://github.com/vysecurity) for providing Registry Auto Logon and Domain GPP Password example code.
* [djhohnstein](https://github.com/djhohnstein) for merging in several outdated PRs and refactoring the entire code base.
32 changes: 32 additions & 0 deletions SharpUp/Checks/AlwaysInstallElevated.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
using SharpUp.Classes;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using static SharpUp.Utilities.RegistryUtils;

namespace SharpUp.Checks
{
public class AlwaysInstallElevated : VulnerabilityCheck
{
private static string _regPath = "Software\\Policies\\Microsoft\\Windows\\Installer";
private static string _regName = "AlwaysInstallElevated";

public AlwaysInstallElevated()
{
_name = "Always Install Elevated";
string AlwaysInstallElevatedHKLM = GetRegValue("HKLM", _regPath, _regName);
string AlwaysInstallElevatedHKCU = GetRegValue("HKCU", _regPath, _regName);
if (!string.IsNullOrEmpty(AlwaysInstallElevatedHKCU))
{
_details.Add($"HKCU: {AlwaysInstallElevatedHKCU}");
_isVulnerable = true;
}
if (!string.IsNullOrEmpty(AlwaysInstallElevatedHKLM))
{
_details.Add($"HKLM: {AlwaysInstallElevatedHKLM}");
_isVulnerable = true;
}
}
}
}
53 changes: 53 additions & 0 deletions SharpUp/Checks/CachedGPPPassword.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
using SharpUp.Classes;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Xml;
using static SharpUp.Utilities.FileUtils;

namespace SharpUp.Checks
{
public class CachedGPPPassword : VulnerabilityCheck
{
private static string allUsers = System.Environment.GetEnvironmentVariable("ALLUSERSPROFILE");
public CachedGPPPassword()
{
_name = "Cached GPP Password";
try
{
if (!allUsers.Contains("ProgramData"))
{
// Before Windows Vista, the default value of AllUsersProfile was "C:\Documents and Settings\All Users"
// And after, "C:\ProgramData"
allUsers += "\\Application Data";
}
allUsers += "\\Microsoft\\Group Policy\\History"; // look only in the GPO cache folder

List<String> files = FindFiles(allUsers, "*.xml");

// files will contain all XML files
foreach (string file in files)
{
if (!(file.Contains("Groups.xml") || file.Contains("Services.xml")
|| file.Contains("Scheduledtasks.xml") || file.Contains("DataSources.xml")
|| file.Contains("Printers.xml") || file.Contains("Drives.xml"))
|| file.Contains("Registry.xml"))
{
continue; // uninteresting XML files, move to next
}
if (ParseGPPPasswordFromXml(file, out GPPPassword result))
{
_isVulnerable = true;
_details.Add(result.ToString());
}
}
}
catch (Exception ex)
{
_details.Add($"[X] Exception: {ex.Message}");
}
}
}
}
57 changes: 57 additions & 0 deletions SharpUp/Checks/DomainGPPPassword.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
using SharpUp.Classes;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using static SharpUp.Utilities.FileUtils;

namespace SharpUp.Checks
{
public class DomainGPPPassword : VulnerabilityCheck
{
private static string DNSDomain = System.Environment.GetEnvironmentVariable("USERDNSDOMAIN");
public DomainGPPPassword()
{
_name = "GPP Password in SYSVOL";
try
{
if (DNSDomain.Length > 1)
{
List<String> files = FindFiles("\\\\" + DNSDomain + "\\SYSVOL", "*.xml");

// files will contain
foreach (string file in files)
{
if (file.Contains("Registry.xml") ||
file.Contains("Groups.xml") ||
file.Contains("Services.xml") ||
file.Contains("ScheduledTasks.xml") ||
file.Contains("DataSources.xml") ||
file.Contains("Printers.xml") ||
file.Contains("Drives.xml"))
{
if (ParseGPPPasswordFromXml(file, out GPPPassword result))
{
_isVulnerable = true;
_details.Add(result.ToString());
}
}
}

}
else
{
_details.Add("Error: Machine is not a domain member or User is not a member of the domain.");
}



}
catch (Exception ex)
{
_details.Add(String.Format("[X] Exception: {0}", ex.Message));
}
}
}
}
35 changes: 35 additions & 0 deletions SharpUp/Checks/HijackablePaths.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
using SharpUp.Classes;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using static SharpUp.Utilities.RegistryUtils;
using static SharpUp.Utilities.FileUtils;

namespace SharpUp.Checks
{
public class HijackablePaths : VulnerabilityCheck
{
private static string _regPath = "SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment";
private static string _regName = "Path";
public HijackablePaths()
{
_name = "Modifiable Folders in %PATH%";
string path = GetRegValue("HKLM", _regPath, _regName);
if (string.IsNullOrEmpty(path))
{
_isVulnerable = false;
return;
}
string[] pathFolders = path.Split(';');
foreach (string folder in pathFolders)
{
if (CheckModifiableAccess(folder))
{
_isVulnerable = true;
_details.Add(folder);
}
}
}
}
}
35 changes: 35 additions & 0 deletions SharpUp/Checks/McAfeeSitelistFiles.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
using SharpUp.Classes;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using static SharpUp.Utilities.FileUtils;

namespace SharpUp.Checks
{
public class McAfeeSitelistFiles : VulnerabilityCheck
{
private static string _drive = System.Environment.GetEnvironmentVariable("SystemDrive");
private static string[] _searchLocations =
{
String.Format("{0}\\Program Files\\", _drive),
String.Format("{0}\\Program Files (x86)\\", _drive),
String.Format("{0}\\Documents and Settings\\", _drive),
String.Format("{0}\\Users\\", _drive)
};
public McAfeeSitelistFiles()
{
_name = "McAfee SiteList.xml Files";
foreach (string SearchLocation in _searchLocations)
{
List<string> files = FindFiles(SearchLocation, "SiteList.xml");

foreach (string file in files)
{
_isVulnerable = true;
_details.Add(file);
}
}
}
}
}
46 changes: 46 additions & 0 deletions SharpUp/Checks/ModifiableServiceBinaries.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
using SharpUp.Classes;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Management;
using System.Text;
using System.Text.RegularExpressions;
using static SharpUp.Utilities.FileUtils;

namespace SharpUp.Checks
{
public class ModifiableServiceBinaries : VulnerabilityCheck
{
public ModifiableServiceBinaries()
{
_name = "Modifiable Service Binaries";
try
{
// finds any service binaries that the current can modify
// TODO: or modify the parent folder

ManagementObjectSearcher wmiData = new ManagementObjectSearcher(@"root\cimv2", "SELECT * FROM win32_service");
ManagementObjectCollection data = wmiData.Get();

foreach (ManagementObject result in data)
{
if (result["PathName"] != null)
{
Match path = Regex.Match(result["PathName"].ToString(), @"^\W*([a-z]:\\.+?(\.exe|\.dll|\.sys))\W*", RegexOptions.IgnoreCase);
String binaryPath = path.Groups[1].ToString();

if (CheckModifiableAccess(binaryPath))
{
_isVulnerable = true;
_details.Add($"Service '{result["Name"]}' (State: {result["State"]}, StartMode: {result["StartMode"]}) : {result["PathName"]}");
}
}
}
}
catch (Exception ex)
{
_details.Add($"[X] Exception: {ex.Message}");
}
}
}
}
Loading