Skip to content

Commit

Permalink
Merge pull request #469 from FortyNorthSecurity/flags_and_compress
Browse files Browse the repository at this point in the history
Added flag options, help menu, and compression
  • Loading branch information
mattgrandy authored Apr 9, 2020
2 parents 89406ff + e873d6e commit 3fa91d8
Show file tree
Hide file tree
Showing 5 changed files with 238 additions and 52 deletions.
21 changes: 21 additions & 0 deletions CS/EyeWitness/EyeWitness.csproj
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\packages\Costura.Fody.4.1.0\build\Costura.Fody.props" Condition="Exists('..\packages\Costura.Fody.4.1.0\build\Costura.Fody.props')" />
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
Expand All @@ -12,6 +13,8 @@
<FileAlignment>512</FileAlignment>
<Deterministic>true</Deterministic>
<TargetFrameworkProfile />
<NuGetPackageImportStamp>
</NuGetPackageImportStamp>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
Expand All @@ -38,10 +41,19 @@
<StartupObject>EyeWitness.Program</StartupObject>
</PropertyGroup>
<ItemGroup>
<Reference Include="CommandLine, Version=2.7.82.0, Culture=neutral, PublicKeyToken=5a870481e358d379, processorArchitecture=MSIL">
<HintPath>..\packages\CommandLineParser.2.7.82\lib\net45\CommandLine.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Costura, Version=4.1.0.0, Culture=neutral, PublicKeyToken=9919ef960d84173d, processorArchitecture=MSIL">
<HintPath>..\packages\Costura.Fody.4.1.0\lib\net40\Costura.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Activities" />
<Reference Include="System.Core" />
<Reference Include="System.Drawing" />
<Reference Include="System.IO.Compression" />
<Reference Include="System.IO.Compression.FileSystem" />
<Reference Include="System.Net" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml.Linq" />
Expand All @@ -57,6 +69,15 @@
</ItemGroup>
<ItemGroup>
<None Include="app.config" />
<None Include="packages.config" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="..\packages\Fody.6.0.0\build\Fody.targets" Condition="Exists('..\packages\Fody.6.0.0\build\Fody.targets')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\packages\Fody.6.0.0\build\Fody.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Fody.6.0.0\build\Fody.targets'))" />
<Error Condition="!Exists('..\packages\Costura.Fody.4.1.0\build\Costura.Fody.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Costura.Fody.4.1.0\build\Costura.Fody.props'))" />
</Target>
</Project>
3 changes: 3 additions & 0 deletions CS/EyeWitness/FodyWeavers.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd">
<Costura />
</Weavers>
111 changes: 111 additions & 0 deletions CS/EyeWitness/FodyWeavers.xsd
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<!-- This file was generated by Fody. Manual changes to this file will be lost when your project is rebuilt. -->
<xs:element name="Weavers">
<xs:complexType>
<xs:all>
<xs:element name="Costura" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:all>
<xs:element minOccurs="0" maxOccurs="1" name="ExcludeAssemblies" type="xs:string">
<xs:annotation>
<xs:documentation>A list of assembly names to exclude from the default action of "embed all Copy Local references", delimited with line breaks</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element minOccurs="0" maxOccurs="1" name="IncludeAssemblies" type="xs:string">
<xs:annotation>
<xs:documentation>A list of assembly names to include from the default action of "embed all Copy Local references", delimited with line breaks.</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element minOccurs="0" maxOccurs="1" name="Unmanaged32Assemblies" type="xs:string">
<xs:annotation>
<xs:documentation>A list of unmanaged 32 bit assembly names to include, delimited with line breaks.</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element minOccurs="0" maxOccurs="1" name="Unmanaged64Assemblies" type="xs:string">
<xs:annotation>
<xs:documentation>A list of unmanaged 64 bit assembly names to include, delimited with line breaks.</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element minOccurs="0" maxOccurs="1" name="PreloadOrder" type="xs:string">
<xs:annotation>
<xs:documentation>The order of preloaded assemblies, delimited with line breaks.</xs:documentation>
</xs:annotation>
</xs:element>
</xs:all>
<xs:attribute name="CreateTemporaryAssemblies" type="xs:boolean">
<xs:annotation>
<xs:documentation>This will copy embedded files to disk before loading them into memory. This is helpful for some scenarios that expected an assembly to be loaded from a physical file.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="IncludeDebugSymbols" type="xs:boolean">
<xs:annotation>
<xs:documentation>Controls if .pdbs for reference assemblies are also embedded.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="DisableCompression" type="xs:boolean">
<xs:annotation>
<xs:documentation>Embedded assemblies are compressed by default, and uncompressed when they are loaded. You can turn compression off with this option.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="DisableCleanup" type="xs:boolean">
<xs:annotation>
<xs:documentation>As part of Costura, embedded assemblies are no longer included as part of the build. This cleanup can be turned off.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="LoadAtModuleInit" type="xs:boolean">
<xs:annotation>
<xs:documentation>Costura by default will load as part of the module initialization. This flag disables that behavior. Make sure you call CosturaUtility.Initialize() somewhere in your code.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="IgnoreSatelliteAssemblies" type="xs:boolean">
<xs:annotation>
<xs:documentation>Costura will by default use assemblies with a name like 'resources.dll' as a satellite resource and prepend the output path. This flag disables that behavior.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="ExcludeAssemblies" type="xs:string">
<xs:annotation>
<xs:documentation>A list of assembly names to exclude from the default action of "embed all Copy Local references", delimited with |</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="IncludeAssemblies" type="xs:string">
<xs:annotation>
<xs:documentation>A list of assembly names to include from the default action of "embed all Copy Local references", delimited with |.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="Unmanaged32Assemblies" type="xs:string">
<xs:annotation>
<xs:documentation>A list of unmanaged 32 bit assembly names to include, delimited with |.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="Unmanaged64Assemblies" type="xs:string">
<xs:annotation>
<xs:documentation>A list of unmanaged 64 bit assembly names to include, delimited with |.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="PreloadOrder" type="xs:string">
<xs:annotation>
<xs:documentation>The order of preloaded assemblies, delimited with |.</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
</xs:element>
</xs:all>
<xs:attribute name="VerifyAssembly" type="xs:boolean">
<xs:annotation>
<xs:documentation>'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="VerifyIgnoreCodes" type="xs:string">
<xs:annotation>
<xs:documentation>A comma-separated list of error codes that can be safely ignored in assembly verification.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="GenerateXsd" type="xs:boolean">
<xs:annotation>
<xs:documentation>'false' to turn off automatic generation of the XML Schema file.</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
</xs:element>
</xs:schema>
149 changes: 97 additions & 52 deletions CS/EyeWitness/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Linq;
using CommandLine;
using CommandLine.Text;
using System.IO.Compression;

namespace EyeWitness
{
Expand All @@ -23,6 +26,37 @@ class Program
//private static SemaphoreSlim _pool = new SemaphoreSlim(2);
private static SemaphoreSlim _Sourcepool = new SemaphoreSlim(10);

public class Options
{
public static Options Instance { get; set; }

// Command line options
[Option('v', "verbose", Required = false, HelpText = "Set output to verbose")]
public bool Verbose { get; set; }

[Option('f', "file", Required = true, HelpText = "Specify a new-line separated file of URLs", Default = null)]
public string File { get; set; }

[Option('d', "delay", Required = false, HelpText = "Specify a delay to use before cancelling a single URL request", Default = 30)]
public int Delay { get; set; }

[Option('c', "compress", Required = false, HelpText = "Compress output directory", Default = false)]
public bool Compress { get; set; }
}

static void DisplayHelp<T>(ParserResult<T> result, IEnumerable<Error> errs)
{
var helpText = HelpText.AutoBuild(result, h =>
{
h.AdditionalNewLineAfterOption = false;
h.Heading = "EyeWitness C# Version 1.0"; //change header
h.Copyright = ""; //change copyright text
return HelpText.DefaultParsingErrorsHandler(result, h);
}, e => e);
Console.WriteLine(helpText);
System.Environment.Exit(1);
}


// The main program will handle determining where the output is saved to, it's not the requirement of the object
// the object will look up the location where everything should be saved and write to there accordingly
Expand Down Expand Up @@ -111,19 +145,17 @@ static void DictMaker()
private static async Task ScreenshotSender(WitnessedServer obj, int timeDelay)
{
//Cancel after 30s
var cts = new CancellationTokenSource(30000);
cts.CancelAfter(30000);
var cts = new CancellationTokenSource(timeDelay);
cts.CancelAfter(timeDelay);
try
{
//Keep it syncronous for this slow version
//Allow the thread to exit somewhat cleanly before exiting the semaphore
_pool.WaitOne(40000);

Console.WriteLine("Grabbing screenshot for: " + obj.remoteSystem);
//obj.RunWithTimeout(TimeSpan.FromMilliseconds(timeDelay));
var task = await obj.RunWithTimeoutCancellation(cts.Token);



_pool.Release();
}
catch (OperationCanceledException)
Expand All @@ -139,6 +171,7 @@ private static async Task ScreenshotSender(WitnessedServer obj, int timeDelay)
private static async Task SourceSender(WitnessedServer obj)
{
//Cancel after 10s
//This cancellation time isn't as important as the screenshot one so we can hard code it
var cts = new CancellationTokenSource(10000);
cts.CancelAfter(10000);

Expand Down Expand Up @@ -234,67 +267,63 @@ public static void Writer(WitnessedServer[] urlArray, string[] allUrlArray)
reportHtml += "</table>"; //close out the category table
Cronkite.FinalReporter(reportHtml, pages, allUrlArray.GetLength(0), witnessDir);
}

}

static void Main(string[] args)
{
Console.WriteLine("[+] Firing up EyeWitness...");
DirMaker();
DictMaker();
Console.WriteLine("[+] Firing up EyeWitness...\n");
string[] allUrls = null;
int delay = 30000;
var watch = new System.Diagnostics.Stopwatch();
watch.Start();


// Read in URLs
//Account for 2 arguments - the first is the file of URLs the second is the timeout
if (args.Length == 2)
//Parse arguments passed
var parser = new Parser(with =>
{
try
{
allUrls = System.IO.File.ReadAllLines(args[0]);
delay = Int32.Parse(args[1]);
}
catch (FileNotFoundException)
{
Console.WriteLine("\n[*] ERROR: The file containing the URLS to scan does not exist!");
Console.WriteLine("[*] ERROR: Please make sure you've provided the correct filepath and try again.");
return;
}
catch
{
Console.WriteLine("Invalid int for timeout, using the default of 30 seconds");
delay = 30000; //Set the delay to default to 10s
}
}
else if (args.Length == 1)
{
try
{
allUrls = System.IO.File.ReadAllLines(args[0]);
Console.WriteLine("Using the default timeout of 10 seconds");
}
catch (Exception e)
with.CaseInsensitiveEnumValues = true;
with.CaseSensitive = false;
with.HelpWriter = null;
});

var parserResult = parser.ParseArguments<Options>(args);
parserResult.WithParsed<Options>(o =>
{
Console.WriteLine("Error when running. Error thrown: \n" + e);
}
}
else
{
Console.WriteLine("\n[*] ERROR: Please specify a URL file to use\n");
Console.WriteLine("\n\n[++] Usage: EyeWitness.exe c:\\Path\\To\\URLs.txt [Timeout] (ex. 10000 = 10 seconds)");
Console.WriteLine("[++] EyeWitness.exe c:\\users\\test\\urls.txt");
Console.WriteLine("[++] EyeWitness.exe c:\\users\\test\\urls.txt 20000");
System.Environment.Exit(1);
}
if (o.Delay != 30)
{
Console.WriteLine("[+] Using a custom timeout of " + o.Delay + " seconds per URL thread");
delay = o.Delay * 1000;
}
else
{
Console.WriteLine("[+] Using the default timeout of 30 seconds per URL thread");
}
if (o.Compress)
{
Console.WriteLine("[+] Compressing files afterwards\n");
}
try
{
allUrls = System.IO.File.ReadAllLines(o.File);
}
catch (FileNotFoundException)
{
Console.WriteLine("[-] ERROR: The file containing the URLS to scan does not exist!");
Console.WriteLine("[-] ERROR: Please make sure you've provided the correct filepath and try again.");
System.Environment.Exit(1);
}
Options.Instance = o;
})
.WithNotParsed(errs => DisplayHelp(parserResult, errs));

DirMaker();
DictMaker();
var options = Options.Instance;

// build an array containing all the web server objects
WitnessedServer[] serverArray = new WitnessedServer[allUrls.Length];

// Build an array containing the objects so we can easily loop over them
Console.WriteLine("[+] Using a delay of: " + delay + " (in milliseconds)");

//WitnessedServer.SetFeatureBrowserEmulation(); // enable HTML5

List<Task> SourceTaskList = new List<Task>();
Expand Down Expand Up @@ -343,6 +372,22 @@ static void Main(string[] args)
Thread.Sleep(1000);
watch.Stop();
Console.WriteLine("Execution time: " + watch.ElapsedMilliseconds/1000 + " Seconds");
if (options.Compress)
{
Console.WriteLine("Compressing output directory...");
try
{
string ZipFileName = witnessDir + ".zip";
ZipFile.CreateFromDirectory(witnessDir, ZipFileName, CompressionLevel.Optimal, false);
Directory.Delete(witnessDir, true);
}
catch (Exception ex)
{
Console.WriteLine("[-] Error zipping file");
Console.WriteLine(ex);
}

}
Console.WriteLine("Finished! Exiting shortly...");
Thread.Sleep(5000);
return;
Expand Down
6 changes: 6 additions & 0 deletions CS/EyeWitness/packages.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="CommandLineParser" version="2.7.82" targetFramework="net45" />
<package id="Costura.Fody" version="4.1.0" targetFramework="net45" />
<package id="Fody" version="6.0.0" targetFramework="net45" developmentDependency="true" />
</packages>

0 comments on commit 3fa91d8

Please sign in to comment.