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

Add FbGetSCCMAdmins (plus other refactors) #1

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
Open
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
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@
[Bb]in/
[Oo]bj/
.DS_Store

*.idea
47 changes: 23 additions & 24 deletions MalSCCM/Args/ArgumentParser.cs
Original file line number Diff line number Diff line change
@@ -1,43 +1,42 @@
using System.Collections.Generic;
using System.Diagnostics;

namespace MalSCCM.Args
namespace MalSCCM.Args;

public static class ArgumentParser
{
public static class ArgumentParser
public static ArgumentParserResult Parse(IEnumerable<string> args)
{
public static ArgumentParserResult Parse(IEnumerable<string> args)
var arguments = new Dictionary<string, string>();
try
{
var arguments = new Dictionary<string, string>();
try
foreach (var argument in args)
{
foreach (var argument in args)
var idx = argument.IndexOf(':');
if (idx > 0)
{
arguments[argument.Substring(0, idx)] = argument.Substring(idx + 1);
}
else
{
var idx = argument.IndexOf(':');
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;
}
arguments[argument] = string.Empty;
}
}

return ArgumentParserResult.Success(arguments);
}
catch (System.Exception ex)
{
Debug.WriteLine(ex.Message);
return ArgumentParserResult.Failure();
}

return ArgumentParserResult.Success(arguments);
}
catch (System.Exception ex)
{
Debug.WriteLine(ex.Message);
return ArgumentParserResult.Failure();
}
}
}
}
29 changes: 14 additions & 15 deletions MalSCCM/Args/ArgumentParserResult.cs
Original file line number Diff line number Diff line change
@@ -1,23 +1,22 @@
using System.Collections.Generic;

namespace MalSCCM.Args
namespace MalSCCM.Args;

public class ArgumentParserResult
{
public class ArgumentParserResult
{
public bool ParsedOk { get; }
public Dictionary<string, string> Arguments { get; }
public bool ParsedOk { get; }
public Dictionary<string, string> Arguments { get; }

private ArgumentParserResult(bool parsedOk, Dictionary<string, string> arguments)
{
ParsedOk = parsedOk;
Arguments = arguments;
}
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 Success(Dictionary<string, string> arguments)
=> new ArgumentParserResult(true, arguments);

public static ArgumentParserResult Failure()
=> new ArgumentParserResult(false, null);
public static ArgumentParserResult Failure()
=> new ArgumentParserResult(false, null);

}
}
76 changes: 40 additions & 36 deletions MalSCCM/Args/CommandCollection.cs
Original file line number Diff line number Diff line change
@@ -1,48 +1,52 @@
using System;
using System.Collections.Generic;
using System.Linq;

using MalSCCM.Commands;

namespace MalSCCM.Args
namespace MalSCCM.Args;

public class CommandCollection
{
public class CommandCollection
{
private readonly Dictionary<string, Func<ICommand>> _availableCommands = new Dictionary<string, Func<ICommand>>();
private readonly List<ICommand> _availableCommands = new();

// 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.
// How To Add A New Command:
// - Create your command class in the Commands Folder
// - That class must implement the ICommand interface
// - Give the command a name
// - Put the code that does the work into the Execute() method

public CommandCollection()
public CommandCollection()
{
// instantiate each command dynamically

var self = typeof(CommandCollection).Assembly;

// loop through each type
foreach (var type in self.GetTypes())
{
_availableCommands.Add(Inspect.CommandName, () => new Inspect());
_availableCommands.Add(Group.CommandName, () => new Group());
_availableCommands.Add(App.CommandName, () => new App());
_availableCommands.Add(Checkin.CommandName, () => new Checkin());
_availableCommands.Add(Locate.CommandName, () => new Locate());

// ignore if they don't implement ICommand or if it's the interface itself
if (!typeof(ICommand).IsAssignableFrom(type) || type.Name.Equals("ICommand"))
continue;

// instantiate a new instance
var command = (ICommand)Activator.CreateInstance(type);
_availableCommands.Add(command);
}
}

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;
}
public bool ExecuteCommand(string commandName, Dictionary<string, string> arguments)
{
// find the correct command, case-insensitive
var command = _availableCommands.FirstOrDefault(c =>
c.CommandName.Equals(commandName, StringComparison.OrdinalIgnoreCase));

// return false if command is null (i.e. not found)
if (command is null)
return false;

// otherwise execute and return true
command.Execute(arguments);
return true;
}
}
91 changes: 48 additions & 43 deletions MalSCCM/Args/Info.cs
Original file line number Diff line number Diff line change
@@ -1,48 +1,53 @@
using System;

namespace MalSCCM.Args
namespace MalSCCM.Args;

public static class Info
{
public static class Info
public static void ShowLogo()
{
const string logo = """
__ __ _ ____ ____ ____ __ __
| \/ | __ _| / ___| / ___/ ___| \/ |
| |\/| |/ _` | \___ \| | | | | |\/| |
| | | | (_| | |___) | |__| |___| | | |
|_| |_|\__,_|_|____/ \____\____|_| |_|
Phil Keeble @ Nettitude Red Team

""";

Console.WriteLine(logo);
}

public static void ShowUsage()
{
public static void ShowLogo()
{
string logo = @" __ __ _ ____ ____ ____ __ __
| \/ | __ _| / ___| / ___/ ___| \/ |
| |\/| |/ _` | \___ \| | | | | |\/| |
| | | | (_| | |___) | |__| |___| | | |
|_| |_|\__,_|_|____/ \____\____|_| |_|
Phil Keeble @ Nettitude Red Team
";
Console.WriteLine(logo);
}

public static void ShowUsage()
{
string usage = @"Commands listed below have optional parameters in <>.

Attempt to find the SCCM management and primary servers:
MalSCCM.exe locate

Inspect the primary server to gather SCCM information:
MalSCCM.exe inspect </server:PrimarySiteHostname> </all /computers /deployments /groups /applications /forest /packages /primaryusers>

Create/Modify/Delete Groups to add targets in for deploying malicious apps. Groups can either be for devices or users:
MalSCCM.exe group /create /groupname:example /grouptype:[user|device] </server:PrimarySiteHostname>
MalSCCM.exe group /delete /groupname:example </server:PrimarySiteHostname>
MalSCCM.exe group /addhost /groupname:example /host:examplehost </server:PrimarySiteHostname>
MalSCCM.exe group /adduser /groupname:example /user:exampleuser </server:PrimarySiteHostname>

Create/Deploy/Delete malicious applications:
MalSCCM.exe app /create /name:appname /uncpath:""\\unc\path"" </server:PrimarySiteHostname>
MalSCCM.exe app /delete /name:appname </server:PrimarySiteHostname>
MalSCCM.exe app /deploy /name:appname /groupname:example /assignmentname:example2 </server:PrimarySiteHostname>
MalSCCM.exe app /deletedeploy /name:appname </server:PrimarySiteHostname>
MalSCCM.exe app /cleanup /name:appname </server:PrimarySiteHostname>

Force devices of a group to checkin within a couple minutes:
MalSCCM.exe checkin /groupname:example </server:PrimarySiteHostname>
";
Console.WriteLine(usage);
}
const string usage = """
Commands listed below have optional parameters in <>.

Attempt to find the SCCM management and primary servers:
MalSCCM.exe locate

Inspect the primary server to gather SCCM information:
MalSCCM.exe inspect </server:PrimarySiteHostname> </all /computers /deployments /groups /applications /forest /packages /primaryusers /admins>

Create/Modify/Delete Groups to add targets in for deploying malicious apps. Groups can either be for devices or users:
MalSCCM.exe group /create /groupname:example /grouptype:[user|device] </server:PrimarySiteHostname>
MalSCCM.exe group /delete /groupname:example </server:PrimarySiteHostname>
MalSCCM.exe group /addhost /groupname:example /host:examplehost </server:PrimarySiteHostname>
MalSCCM.exe group /adduser /groupname:example /user:exampleuser </server:PrimarySiteHostname>

Create/Deploy/Delete malicious applications:
MalSCCM.exe app /create /name:appname /uncpath:"\\unc\path" </server:PrimarySiteHostname>
MalSCCM.exe app /delete /name:appname </server:PrimarySiteHostname>
MalSCCM.exe app /deploy /name:appname /groupname:example /assignmentname:example2 </server:PrimarySiteHostname>
MalSCCM.exe app /deletedeploy /name:appname </server:PrimarySiteHostname>
MalSCCM.exe app /cleanup /name:appname </server:PrimarySiteHostname>

Force devices of a group to checkin within a couple minutes:
MalSCCM.exe checkin /groupname:example </server:PrimarySiteHostname>

""";

Console.WriteLine(usage);
}
}
}
Loading