├── .gitattributes ├── .gitignore ├── ITLEFileSpec ├── ITLEFileSpec.csproj ├── ITleFileSpec.cs └── Properties │ └── AssemblyInfo.cs ├── LICENSE ├── README.md ├── TLEFile.Test ├── Properties │ └── AssemblyInfo.cs ├── TLEFile.Test.csproj └── TestMain.cs ├── TLEFileEZTools ├── EZTools.cs ├── Properties │ └── AssemblyInfo.cs └── TLEFileEZTools.csproj ├── TLEFileGenericCsv ├── GenericCsv.cs ├── Properties │ └── AssemblyInfo.cs └── TLEFileGenericCsv.csproj ├── TLEFileKAPE ├── KAPE.cs ├── Properties │ └── AssemblyInfo.cs └── TLEFileKAPE.csproj ├── TLEFileMicrosoft ├── Microsoft.cs ├── Properties │ └── AssemblyInfo.cs └── TLEFileMicrosoft.csproj ├── TLEFileMisc ├── Misc.cs ├── Properties │ └── AssemblyInfo.cs └── TLEFileMisc.csproj ├── TLEFilePlugins.sln ├── TLEFilePlugins.v3.ncrunchsolution ├── TLEFileTimelines ├── Properties │ └── AssemblyInfo.cs ├── TLEFileTimelines.csproj └── Timelines.cs └── TLEFileTzWorks ├── Properties └── AssemblyInfo.cs ├── TLEFileTzWorks.csproj └── TZWorks.cs /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | ## 4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore 5 | 6 | # User-specific files 7 | *.rsuser 8 | *.suo 9 | *.user 10 | *.userosscache 11 | *.sln.docstates 12 | 13 | # User-specific files (MonoDevelop/Xamarin Studio) 14 | *.userprefs 15 | 16 | # Build results 17 | [Dd]ebug/ 18 | [Dd]ebugPublic/ 19 | [Rr]elease/ 20 | [Rr]eleases/ 21 | x64/ 22 | x86/ 23 | [Aa][Rr][Mm]/ 24 | [Aa][Rr][Mm]64/ 25 | bld/ 26 | [Bb]in/ 27 | [Oo]bj/ 28 | [Ll]og/ 29 | 30 | # Visual Studio 2015/2017 cache/options directory 31 | .vs/ 32 | # Uncomment if you have tasks that create the project's static files in wwwroot 33 | #wwwroot/ 34 | 35 | # Visual Studio 2017 auto generated files 36 | Generated\ Files/ 37 | 38 | # MSTest test Results 39 | [Tt]est[Rr]esult*/ 40 | [Bb]uild[Ll]og.* 41 | 42 | # NUNIT 43 | *.VisualState.xml 44 | TestResult.xml 45 | 46 | # Build Results of an ATL Project 47 | [Dd]ebugPS/ 48 | [Rr]eleasePS/ 49 | dlldata.c 50 | 51 | # Benchmark Results 52 | BenchmarkDotNet.Artifacts/ 53 | 54 | # .NET Core 55 | project.lock.json 56 | project.fragment.lock.json 57 | artifacts/ 58 | 59 | # StyleCop 60 | StyleCopReport.xml 61 | 62 | # Files built by Visual Studio 63 | *_i.c 64 | *_p.c 65 | *_h.h 66 | *.ilk 67 | *.meta 68 | *.obj 69 | *.iobj 70 | *.pch 71 | *.pdb 72 | *.ipdb 73 | *.pgc 74 | *.pgd 75 | *.rsp 76 | *.sbr 77 | *.tlb 78 | *.tli 79 | *.tlh 80 | *.tmp 81 | *.tmp_proj 82 | *_wpftmp.csproj 83 | *.log 84 | *.vspscc 85 | *.vssscc 86 | .builds 87 | *.pidb 88 | *.svclog 89 | *.scc 90 | 91 | # Chutzpah Test files 92 | _Chutzpah* 93 | 94 | # Visual C++ cache files 95 | ipch/ 96 | *.aps 97 | *.ncb 98 | *.opendb 99 | *.opensdf 100 | *.sdf 101 | *.cachefile 102 | *.VC.db 103 | *.VC.VC.opendb 104 | 105 | # Visual Studio profiler 106 | *.psess 107 | *.vsp 108 | *.vspx 109 | *.sap 110 | 111 | # Visual Studio Trace Files 112 | *.e2e 113 | 114 | # TFS 2012 Local Workspace 115 | $tf/ 116 | 117 | # Guidance Automation Toolkit 118 | *.gpState 119 | 120 | # ReSharper is a .NET coding add-in 121 | _ReSharper*/ 122 | *.[Rr]e[Ss]harper 123 | *.DotSettings.user 124 | 125 | # JustCode is a .NET coding add-in 126 | .JustCode 127 | 128 | # TeamCity is a build add-in 129 | _TeamCity* 130 | 131 | # DotCover is a Code Coverage Tool 132 | *.dotCover 133 | 134 | # AxoCover is a Code Coverage Tool 135 | .axoCover/* 136 | !.axoCover/settings.json 137 | 138 | # Visual Studio code coverage results 139 | *.coverage 140 | *.coveragexml 141 | 142 | # NCrunch 143 | _NCrunch_* 144 | .*crunch*.local.xml 145 | nCrunchTemp_* 146 | 147 | # MightyMoose 148 | *.mm.* 149 | AutoTest.Net/ 150 | 151 | # Web workbench (sass) 152 | .sass-cache/ 153 | 154 | # Installshield output folder 155 | [Ee]xpress/ 156 | 157 | # DocProject is a documentation generator add-in 158 | DocProject/buildhelp/ 159 | DocProject/Help/*.HxT 160 | DocProject/Help/*.HxC 161 | DocProject/Help/*.hhc 162 | DocProject/Help/*.hhk 163 | DocProject/Help/*.hhp 164 | DocProject/Help/Html2 165 | DocProject/Help/html 166 | 167 | # Click-Once directory 168 | publish/ 169 | 170 | # Publish Web Output 171 | *.[Pp]ublish.xml 172 | *.azurePubxml 173 | # Note: Comment the next line if you want to checkin your web deploy settings, 174 | # but database connection strings (with potential passwords) will be unencrypted 175 | *.pubxml 176 | *.publishproj 177 | 178 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 179 | # checkin your Azure Web App publish settings, but sensitive information contained 180 | # in these scripts will be unencrypted 181 | PublishScripts/ 182 | 183 | # NuGet Packages 184 | *.nupkg 185 | # The packages folder can be ignored because of Package Restore 186 | **/[Pp]ackages/* 187 | # except build/, which is used as an MSBuild target. 188 | !**/[Pp]ackages/build/ 189 | # Uncomment if necessary however generally it will be regenerated when needed 190 | #!**/[Pp]ackages/repositories.config 191 | # NuGet v3's project.json files produces more ignorable files 192 | *.nuget.props 193 | *.nuget.targets 194 | 195 | # Microsoft Azure Build Output 196 | csx/ 197 | *.build.csdef 198 | 199 | # Microsoft Azure Emulator 200 | ecf/ 201 | rcf/ 202 | 203 | # Windows Store app package directories and files 204 | AppPackages/ 205 | BundleArtifacts/ 206 | Package.StoreAssociation.xml 207 | _pkginfo.txt 208 | *.appx 209 | 210 | # Visual Studio cache files 211 | # files ending in .cache can be ignored 212 | *.[Cc]ache 213 | # but keep track of directories ending in .cache 214 | !?*.[Cc]ache/ 215 | 216 | # Others 217 | ClientBin/ 218 | ~$* 219 | *~ 220 | *.dbmdl 221 | *.dbproj.schemaview 222 | *.jfm 223 | *.pfx 224 | *.publishsettings 225 | orleans.codegen.cs 226 | 227 | # Including strong name files can present a security risk 228 | # (https://github.com/github/gitignore/pull/2483#issue-259490424) 229 | #*.snk 230 | 231 | # Since there are multiple workflows, uncomment next line to ignore bower_components 232 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 233 | #bower_components/ 234 | 235 | # RIA/Silverlight projects 236 | Generated_Code/ 237 | 238 | # Backup & report files from converting an old project file 239 | # to a newer Visual Studio version. Backup files are not needed, 240 | # because we have git ;-) 241 | _UpgradeReport_Files/ 242 | Backup*/ 243 | UpgradeLog*.XML 244 | UpgradeLog*.htm 245 | ServiceFabricBackup/ 246 | *.rptproj.bak 247 | 248 | # SQL Server files 249 | *.mdf 250 | *.ldf 251 | *.ndf 252 | 253 | # Business Intelligence projects 254 | *.rdl.data 255 | *.bim.layout 256 | *.bim_*.settings 257 | *.rptproj.rsuser 258 | *- Backup*.rdl 259 | 260 | # Microsoft Fakes 261 | FakesAssemblies/ 262 | 263 | # GhostDoc plugin setting file 264 | *.GhostDoc.xml 265 | 266 | # Node.js Tools for Visual Studio 267 | .ntvs_analysis.dat 268 | node_modules/ 269 | 270 | # Visual Studio 6 build log 271 | *.plg 272 | 273 | # Visual Studio 6 workspace options file 274 | *.opt 275 | 276 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 277 | *.vbw 278 | 279 | # Visual Studio LightSwitch build output 280 | **/*.HTMLClient/GeneratedArtifacts 281 | **/*.DesktopClient/GeneratedArtifacts 282 | **/*.DesktopClient/ModelManifest.xml 283 | **/*.Server/GeneratedArtifacts 284 | **/*.Server/ModelManifest.xml 285 | _Pvt_Extensions 286 | 287 | # Paket dependency manager 288 | .paket/paket.exe 289 | paket-files/ 290 | 291 | # FAKE - F# Make 292 | .fake/ 293 | 294 | # JetBrains Rider 295 | .idea/ 296 | *.sln.iml 297 | 298 | # CodeRush personal settings 299 | .cr/personal 300 | 301 | # Python Tools for Visual Studio (PTVS) 302 | __pycache__/ 303 | *.pyc 304 | 305 | # Cake - Uncomment if you are using it 306 | # tools/** 307 | # !tools/packages.config 308 | 309 | # Tabs Studio 310 | *.tss 311 | 312 | # Telerik's JustMock configuration file 313 | *.jmconfig 314 | 315 | # BizTalk build output 316 | *.btp.cs 317 | *.btm.cs 318 | *.odx.cs 319 | *.xsd.cs 320 | 321 | # OpenCover UI analysis results 322 | OpenCover/ 323 | 324 | # Azure Stream Analytics local run output 325 | ASALocalRun/ 326 | 327 | # MSBuild Binary and Structured Log 328 | *.binlog 329 | 330 | # NVidia Nsight GPU debugger configuration file 331 | *.nvuser 332 | 333 | # MFractors (Xamarin productivity tool) working folder 334 | .mfractor/ 335 | 336 | # Local History for Visual Studio 337 | .localhistory/ 338 | 339 | # BeatPulse healthcheck temp database 340 | healthchecksdb -------------------------------------------------------------------------------- /ITLEFileSpec/ITLEFileSpec.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | netstandard2.0 4 | ITLEFileSpec 5 | ITLEFileSpec 6 | Eric Zimmerman 7 | 10 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /ITLEFileSpec/ITleFileSpec.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.ComponentModel; 3 | 4 | namespace ITLEFileSpec 5 | { 6 | /// 7 | /// Note that it is also critical to override ToString and concatenate all fields in your class! This is used when 8 | /// searching across each supported file type. 9 | /// 10 | /// It is also useful to use DateTime vs DateTimeOffset so TLE filtering works better 11 | /// 12 | /// 13 | /// See BootOut for fully commented example and others in CoreFileTypes for common patterns 14 | /// 15 | /// 16 | public interface IFileSpec 17 | { 18 | /// 19 | /// Who wrote this amazing plugin (this would be you) 20 | /// 21 | string Author { get; } 22 | 23 | /// 24 | /// A brief summary of what this file is, what generates it, version info, etc. 25 | /// 26 | string FileDescription { get; } 27 | 28 | 29 | /// 30 | /// This should be the exact headers this type expects to process. These values are compared to what is in a file being 31 | /// loaded. 32 | /// 33 | /// Case insensitive 34 | /// 35 | /// 36 | HashSet ExpectedHeaders { get; } 37 | 38 | /// 39 | /// This should be a BindingList where records from the data source are loaded into 40 | /// 41 | IBindingList DataList { get; } 42 | 43 | /// 44 | /// This will be populated with previously tagged lines (when session files are used). This allows for 're-tagging' 45 | /// previously tagged rows. 46 | /// 47 | List TaggedLines { get; } 48 | 49 | /// 50 | /// This must be unique across all plugins! 51 | /// 52 | string InternalGuid { get; } 53 | 54 | /// 55 | /// When a matching ExpectedHeader is found, this will be called, passing the full path to the file. 56 | /// 57 | /// This function should load the data in whatever way it deems necessary, adding each row to DataList 58 | /// 59 | /// 60 | /// 61 | void ProcessFile(string filename); 62 | } 63 | 64 | /// 65 | /// Note that it is also critical to override ToString and concatenate all fields in your class! This is used when 66 | /// searching across each supported file type. 67 | /// 68 | /// It is also useful to use DateTime vs DateTimeOffset so TLE filtering works better 69 | /// 70 | /// 71 | /// See BootOut for fully commented example and others in CoreFileTypes for common patterns 72 | /// 73 | /// 74 | public interface IFileSpecData 75 | { 76 | int Line { get; set; } 77 | bool Tag { get; set; } 78 | } 79 | } -------------------------------------------------------------------------------- /ITLEFileSpec/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.InteropServices; 2 | 3 | // Setting ComVisible to false makes the types in this assembly not visible 4 | // to COM components. If you need to access a type in this assembly from 5 | // COM, set the ComVisible attribute to true on that type. 6 | [assembly: ComVisible(false)] 7 | 8 | // The following GUID is for the ID of the typelib if this project is exposed to COM 9 | [assembly: Guid("b405ee7d-7ede-4812-88b4-7297dd35dfbb")] 10 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Eric Zimmerman 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # TLEFilePlugins 2 | Plugins for parsing CSV files in Timeline Explorer. This project allows for anyone to add more supported files (i,e. they get a Line #/tag column, layout support, searching, etc.) 3 | 4 | I will maintain a reference to CSVHelper in TLE proper, so you do not need to worry about moving around that dll or any files it needs, just your plugins for file support. 5 | 6 | Layouts, pinned columns, etc all rely on a call to **Plugin.GetType().FullName**, so name your classes according to the examples. 7 | 8 | For a complete example, see TLEFileMFTECmd, Boot* classes at the link below. 9 | 10 | https://github.com/EricZimmerman/TLEFilePlugins/blob/master/TLEFileEZTools/EZTools.cs#L12 11 | 12 | For more advanced uses of CSVHelper, look at things like **AnalyzeMFT** or **Supertimeline** plugins. 13 | -------------------------------------------------------------------------------- /TLEFile.Test/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.InteropServices; 2 | 3 | // Setting ComVisible to false makes the types in this assembly not visible 4 | // to COM components. If you need to access a type in this assembly from 5 | // COM, set the ComVisible attribute to true on that type. 6 | [assembly: ComVisible(false)] 7 | 8 | // The following GUID is for the ID of the typelib if this project is exposed to COM 9 | [assembly: Guid("6a9f9e57-170a-4959-8768-0c0ebbddcbe8")] 10 | -------------------------------------------------------------------------------- /TLEFile.Test/TLEFile.Test.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | net6.0;net462 4 | TLEFile.Test 5 | TLEFile.Test 6 | Eric Zimmerman 7 | 10 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /TLEFile.Test/TestMain.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Diagnostics; 3 | using NUnit.Framework; 4 | using Serilog; 5 | using TLEFileEZTools; 6 | using TLEFileMisc; 7 | using TLEFileTimelines; 8 | using TLEFileGenericCsv; 9 | 10 | namespace TLEFile.Test 11 | { 12 | public class TestMain 13 | { 14 | 15 | [Test] 16 | public void EzTools_Evtx() 17 | { 18 | var t = new TLEFileEZTools.EvtxECmd(); 19 | t.ProcessFile(@"C:\temp\foo.csv"); 20 | 21 | //20210202154458_EvtxECmd_Output.csv 22 | 23 | } 24 | 25 | [Test] 26 | public void EzTools_SbeCmd() 27 | { 28 | var t = new TLEFileEZTools.SbeCmd(); 29 | t.ProcessFile(@"C:\temp\testdata\M__Forensics_TrainingImages_AliHadi_Challenge5_tout_E_Users_Joker_AppData_Local_Microsoft_Windows_UsrClass.dat.csv"); 30 | 31 | Debug.WriteLine(t.DataList.Count); 32 | 33 | //20210202154458_EvtxECmd_Output.csv 34 | 35 | } 36 | 37 | 38 | 39 | [Test] 40 | public void EzTools_Evtx2() 41 | { 42 | var t = new TLEFileEZTools.SbeCmd(); 43 | t.ProcessFile(@"C:\Users\eric\Desktop\2021-07-21115457_ShellBagsExplorerExport.csv"); 44 | 45 | } 46 | 47 | 48 | [Test] 49 | public void EzTools_Evtx3() 50 | { 51 | var t = new TLEFileEZTools.EvtxECmd(); 52 | t.ProcessFile(@"C:\temp\20210202155341_EvtxECmd_Output.csv"); 53 | 54 | } 55 | 56 | [Test] 57 | public void EzTools_Evtx4() 58 | { 59 | var t = new TLEFileEZTools.EvtxECmd(); 60 | t.ProcessFile(@"C:\temp\Large_RecordNumber-EventRecordId.csv"); 61 | 62 | } 63 | 64 | 65 | [Test] 66 | public void EzTools_KapeTL() 67 | { 68 | var t = new TLEFileTimelines.KapeMiniTimeline(); 69 | t.ProcessFile(@"C:\Temp\minitimeline.csv"); 70 | 71 | } 72 | 73 | [Test] 74 | public void HyabMin() 75 | { 76 | var t = new HayabusaMinimal(); 77 | t.ProcessFile(@"C:\temp\hayabusa__minimal.csv"); 78 | 79 | } 80 | 81 | [Test] 82 | public void HyabStd() 83 | { 84 | var t = new HayabusaStandard(); 85 | t.ProcessFile(@"C:\temp\hayabusa_standard.csv"); 86 | 87 | } 88 | 89 | [Test] 90 | public void HyabVer() 91 | { 92 | var t = new HayabusaVerbose(); 93 | t.ProcessFile(@"C:\temp\hayabusa-results\hayabusa-results.csv"); 94 | 95 | } 96 | 97 | [Test] 98 | public void HyabSuperVer() 99 | { 100 | var t = new HayabusaSuperVerbose(); 101 | t.ProcessFile(@"C:\temp\hayabusa_super_verbose.csv"); 102 | 103 | var t2 = new HayabusaSuperVerbose(); 104 | t2.ProcessFile(@"C:\temp\sample-hayabusa-results.csv"); 105 | 106 | 107 | 108 | } 109 | 110 | [Test] 111 | public void FTTest() 112 | { 113 | Log.Logger = new LoggerConfiguration() 114 | .WriteTo.Debug() 115 | .WriteTo.Console() 116 | 117 | .CreateLogger(); 118 | 119 | 120 | 121 | var t = new ForensicTimeline(); 122 | t.ProcessFile(@"C:\temp\20250416_235546_forensic_timeliner.csv"); 123 | Log.Information("Count: {C}",t.DataList.Count); 124 | 125 | } 126 | 127 | 128 | [Test] 129 | public void GenTest() 130 | { 131 | var t = new GenericCsv(); 132 | t.ProcessFile(@"C:\temp\20240904144034_SumECmd_DETAIL_DnsInfo_Output.csv"); 133 | 134 | 135 | } 136 | 137 | 138 | //PsortTimeline 139 | 140 | 141 | [Test] 142 | public void PsortTimelineTest() 143 | { 144 | 145 | Log.Logger = new LoggerConfiguration() 146 | .WriteTo.Debug() 147 | .WriteTo.Console() 148 | 149 | .CreateLogger(); 150 | 151 | Console.WriteLine(1); 152 | Debug.WriteLine("Test 1"); 153 | var t = new TLEFileTimelines.PsortTimeline(); 154 | t.ProcessFile(@"C:\temp\Testing-TLE-for-608\SmallTest.csv"); 155 | 156 | Console.WriteLine(2); 157 | t = new PsortTimeline(); 158 | t.ProcessFile(@"C:\temp\Testing-TLE-for-608\base-av-log2timeline.csv"); 159 | 160 | Console.WriteLine(3); 161 | t = new PsortTimeline(); 162 | t.ProcessFile(@"C:\temp\Testing-TLE-for-608\base-rd-01-log2timeline.csv"); 163 | 164 | 165 | 166 | } 167 | 168 | [Test] 169 | public void GenericTest() 170 | { 171 | var t = new TLEFileGenericCsv.GenericCsv(); 172 | t.ProcessFile(@"C:\temp\Test.csv"); 173 | 174 | } 175 | 176 | [Test] 177 | public void BrowserHistView() 178 | { 179 | var t = new J(); 180 | t.ProcessFile(@"C:\temp\20210928133849_MFTECmd_$J_Output.csv"); 181 | 182 | } 183 | 184 | 185 | } 186 | } 187 | -------------------------------------------------------------------------------- /TLEFileEZTools/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.InteropServices; 2 | 3 | // Setting ComVisible to false makes the types in this assembly not visible 4 | // to COM components. If you need to access a type in this assembly from 5 | // COM, set the ComVisible attribute to true on that type. 6 | [assembly: ComVisible(false)] 7 | 8 | // The following GUID is for the ID of the typelib if this project is exposed to COM 9 | [assembly: Guid("6caa82ce-3e8c-473c-b48b-e0bd857740d7")] 10 | -------------------------------------------------------------------------------- /TLEFileEZTools/TLEFileEZTools.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | netstandard2.0 4 | TLEFilesCore 5 | TLEFilesCore 6 | Eric Zimmerman 7 | 10 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /TLEFileGenericCsv/GenericCsv.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Dynamic; 5 | using System.Globalization; 6 | using System.IO; 7 | using CsvHelper; 8 | using CsvHelper.Configuration; 9 | using ITLEFileSpec; 10 | using Serilog; 11 | 12 | namespace TLEFileGenericCsv 13 | { 14 | public class GenericCsv : IFileSpec 15 | { 16 | public GenericCsv() 17 | { 18 | TaggedLines = new List(); 19 | 20 | DataList = new BindingList(); 21 | 22 | ExpectedHeaders = new HashSet(StringComparer.OrdinalIgnoreCase); 23 | } 24 | 25 | public string Author => "Eric Zimmerman"; 26 | public string FileDescription => "Generic CSV/TSV plugin. Adds Tag and Line number columns when loading the file"; 27 | public HashSet ExpectedHeaders { get; } 28 | 29 | public IBindingList DataList { get; private set; } 30 | public List TaggedLines { get; set; } 31 | public string InternalGuid => "40dd7405-16cf-4612-a480-9a050d0a9952"; 32 | 33 | 34 | 35 | private ExpandoObject ConvertToDynamic(IDictionary fastDynamicObject) { 36 | if (fastDynamicObject == null) return null; 37 | IDictionary result = new ExpandoObject(); 38 | foreach (var item in fastDynamicObject) 39 | result.Add(item.Key, item.Value); 40 | return (ExpandoObject)result; 41 | } 42 | 43 | 44 | public void ProcessFile(string filename) 45 | { 46 | 47 | 48 | var tempList = new List(); 49 | 50 | using var fileReader = File.Open(filename, FileMode.Open, FileAccess.Read); 51 | using var ff = new StreamReader(fileReader); 52 | var config = new CsvConfiguration(CultureInfo.InvariantCulture) 53 | { 54 | // BadDataFound = null, 55 | 56 | BadDataFound = context => 57 | { 58 | Log.Warning("Bad data found in {Field}! Skipping. Raw data: {RawRecord}",context.Field, context.RawRecord); 59 | }, 60 | }; 61 | 62 | if (filename.ToUpperInvariant().EndsWith(".TSV")) 63 | { 64 | config = new CsvConfiguration(CultureInfo.InvariantCulture) 65 | { 66 | BadDataFound = null, 67 | Delimiter = "\t" 68 | }; 69 | } 70 | 71 | var csv = new CsvReader(ff, config); 72 | 73 | 74 | 75 | var ln = 1; 76 | while (csv.Read()) 77 | { 78 | if (csv.Parser.RawRecord.StartsWith("#TYPE")) 79 | { 80 | csv.Read(); 81 | } 82 | 83 | 84 | Log.Debug("Line # {Line}, Record: {RawRecord}",ln,csv.Context.Parser.RawRecord); 85 | 86 | var f = csv.GetRecord(); 87 | f.Line = ln; 88 | f.Tag = TaggedLines.Contains(ln); 89 | 90 | ExpandoObject f1= ConvertToDynamic(f); 91 | 92 | 93 | 94 | 95 | tempList.Add(f1); 96 | 97 | ln += 1; 98 | } 99 | 100 | // var records = csv.GetRecords().ToList(); 101 | 102 | 103 | 104 | DataList = new BindingList(tempList); 105 | } 106 | } 107 | } -------------------------------------------------------------------------------- /TLEFileGenericCsv/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.InteropServices; 2 | 3 | // Setting ComVisible to false makes the types in this assembly not visible 4 | // to COM components. If you need to access a type in this assembly from 5 | // COM, set the ComVisible attribute to true on that type. 6 | [assembly: ComVisible(false)] 7 | 8 | // The following GUID is for the ID of the typelib if this project is exposed to COM 9 | [assembly: Guid("fc0eb431-2893-41c4-b0ed-c4d2c4290ca4")] 10 | -------------------------------------------------------------------------------- /TLEFileGenericCsv/TLEFileGenericCsv.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | netstandard2.0 4 | TLEFileGenericCsv 5 | TLEFileGenericCsv 6 | Eric Zimmerman 7 | 10 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /TLEFileKAPE/KAPE.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Globalization; 5 | using System.IO; 6 | using CsvHelper; 7 | using CsvHelper.TypeConversion; 8 | using ITLEFileSpec; 9 | using Serilog; 10 | 11 | namespace TLEFileKAPE 12 | { 13 | public class KapeCopyLogData : IFileSpecData 14 | { 15 | public DateTime CopiedTimestamp { get; set; } 16 | public string SourceFile { get; set; } 17 | public string DestinationFile { get; set; } 18 | public long FileSize { get; set; } 19 | public string SourceFileSha1 { get; set; } 20 | public bool DeferredCopy { get; set; } 21 | 22 | public DateTime CreatedOnUtc { get; set; } 23 | public DateTime ModifiedOnUtc { get; set; } 24 | public DateTime LastAccessedOnUtc { get; set; } 25 | 26 | public TimeSpan CopyDuration { get; set; } 27 | 28 | public int Line { get; set; } 29 | 30 | public bool Tag { get; set; } 31 | 32 | public override string ToString() 33 | { 34 | return 35 | $"{CopiedTimestamp} {SourceFile} {DestinationFile} {FileSize} {SourceFileSha1} {DeferredCopy} {CreatedOnUtc} {ModifiedOnUtc} {LastAccessedOnUtc} {CopyDuration}"; 36 | } 37 | } 38 | 39 | public class KapeCopyLog : IFileSpec 40 | { 41 | public KapeCopyLog() 42 | { 43 | //Initialize collections here, one for TaggedLines TLE can add values to, and the collection that TLE will display 44 | TaggedLines = new List(); 45 | 46 | DataList = new BindingList(); 47 | 48 | ExpectedHeaders = new HashSet(StringComparer.OrdinalIgnoreCase) 49 | { 50 | "CopiedTimestamp,SourceFile,DestinationFile,FileSize,SourceFileSha1,DeferredCopy,CreatedOnUtc,ModifiedOnUtc,LastAccessedOnUtc,CopyDuration" 51 | }; 52 | } 53 | 54 | public string Author => "Eric Zimmerman"; 55 | public string FileDescription => "CSV generated from KAPE for copied files"; 56 | public HashSet ExpectedHeaders { get; } 57 | 58 | public IBindingList DataList { get; } 59 | public List TaggedLines { get; set; } 60 | 61 | public string InternalGuid => "11dd7405-16cf-4612-a480-9b050d0a9952"; 62 | 63 | public void ProcessFile(string filename) 64 | { 65 | DataList.Clear(); 66 | 67 | using var fileReader = File.OpenText(filename); 68 | var csv = new CsvReader(fileReader, CultureInfo.InvariantCulture); 69 | 70 | 71 | var o = new TypeConverterOptions 72 | { 73 | DateTimeStyle = DateTimeStyles.AssumeUniversal & DateTimeStyles.AdjustToUniversal 74 | }; 75 | csv.Context.TypeConverterOptionsCache.AddOptions(o); 76 | 77 | 78 | var foo = csv.Context.AutoMap(); 79 | 80 | foo.Map(t => t.Line).Ignore(); 81 | foo.Map(t => t.Tag).Ignore(); 82 | 83 | csv.Context.RegisterClassMap(foo); 84 | 85 | 86 | 87 | var records = csv.GetRecords(); 88 | 89 | var ln = 1; 90 | foreach (var record in records) 91 | { 92 | Log.Debug("Line # {Line}, Record: {RawRecord}",ln,csv.Context.Parser.RawRecord); 93 | record.Line = ln; 94 | 95 | record.Tag = TaggedLines.Contains(ln); 96 | 97 | DataList.Add(record); 98 | 99 | ln += 1; 100 | } 101 | } 102 | } 103 | 104 | public class KapeSkipLogData : IFileSpecData 105 | { 106 | public string SourceFile { get; set; } 107 | public string SourceFileSha1 { get; set; } 108 | public string Reason { get; set; } 109 | 110 | public int Line { get; set; } 111 | 112 | public bool Tag { get; set; } 113 | 114 | public override string ToString() 115 | { 116 | return $"{SourceFile} {SourceFileSha1} {Reason}"; 117 | } 118 | } 119 | 120 | 121 | public class KapeSkipLog : IFileSpec 122 | { 123 | public KapeSkipLog() 124 | { 125 | //Initialize collections here, one for TaggedLines TLE can add values to, and the collection that TLE will display 126 | TaggedLines = new List(); 127 | 128 | DataList = new BindingList(); 129 | 130 | ExpectedHeaders = new HashSet(StringComparer.OrdinalIgnoreCase) 131 | { 132 | "SourceFile,SourceFileSha1,Reason" 133 | }; 134 | } 135 | 136 | public string Author => "Eric Zimmerman"; 137 | public string FileDescription => "CSV generated from KAPE for skipped files"; 138 | public HashSet ExpectedHeaders { get; } 139 | 140 | public IBindingList DataList { get; } 141 | public List TaggedLines { get; set; } 142 | 143 | public string InternalGuid => "40dd7405-16cf-4612-b220-9a050d0a9952"; 144 | 145 | public void ProcessFile(string filename) 146 | { 147 | DataList.Clear(); 148 | 149 | using var fileReader = File.OpenText(filename); 150 | var csv = new CsvReader(fileReader, CultureInfo.InvariantCulture); 151 | 152 | 153 | var o = new TypeConverterOptions 154 | { 155 | DateTimeStyle = DateTimeStyles.AssumeUniversal & DateTimeStyles.AdjustToUniversal 156 | }; 157 | csv.Context.TypeConverterOptionsCache.AddOptions(o); 158 | 159 | 160 | var foo = csv.Context.AutoMap(); 161 | 162 | foo.Map(t => t.Line).Ignore(); 163 | foo.Map(t => t.Tag).Ignore(); 164 | 165 | csv.Context.RegisterClassMap(foo); 166 | 167 | 168 | 169 | var records = csv.GetRecords(); 170 | 171 | var ln = 1; 172 | foreach (var record in records) 173 | { 174 | Log.Debug("Line # {Line}, Record: {RawRecord}",ln,csv.Context.Parser.RawRecord); 175 | record.Line = ln; 176 | 177 | record.Tag = TaggedLines.Contains(ln); 178 | 179 | DataList.Add(record); 180 | 181 | ln += 1; 182 | } 183 | } 184 | } 185 | 186 | 187 | public class KapeTriageData : IFileSpecData 188 | { 189 | public DateTime DateTimeUTC { get; set; } 190 | 191 | public string EventTimeSource { get; set; } 192 | public string Hostname { get; set; } 193 | public string HostIPAddress { get; set; } 194 | public string UserID { get; set; } 195 | 196 | public string Assessment { get; set; } 197 | public string EventType { get; set; } 198 | public string EventDetails { get; set; } 199 | public string SDIPAddress { get; set; } 200 | 201 | public string ExaminerComments { get; set; } 202 | public string MD5 { get; set; } 203 | public string EventAddedBy { get; set; } 204 | public DateTime DateAdded { get; set; } 205 | public string RawEvent { get; set; } 206 | 207 | public int Line { get; set; } 208 | public bool Tag { get; set; } 209 | 210 | public override string ToString() 211 | { 212 | return 213 | $"{DateTimeUTC} {EventTimeSource} {Hostname} {HostIPAddress} {UserID} {Assessment} {EventType} {EventDetails} {SDIPAddress} {ExaminerComments} {MD5} {EventAddedBy} {DateAdded} {RawEvent}"; 214 | } 215 | } 216 | 217 | 218 | public class KapeTriage : IFileSpec 219 | { 220 | public KapeTriage() 221 | { 222 | //Initialize collections here, one for TaggedLines TLE can add values to, and the collection that TLE will display 223 | TaggedLines = new List(); 224 | 225 | DataList = new BindingList(); 226 | 227 | ExpectedHeaders = new HashSet(StringComparer.OrdinalIgnoreCase) 228 | { 229 | "\"datetimeutc\",\"eventtimesource\",\"hostname\",\"hostipaddress\",\"userid\",\"assessment\",\"eventtype\",\"eventdetails\",\"sdipaddress\",\"examinercomments\",\"md5\",\"eventaddedby\",\"dateadded\",\"rawevent\"" 230 | }; 231 | } 232 | 233 | public string Author => "Eric Zimmerman"; 234 | public string FileDescription => "CSV generated from KAPE triage package"; 235 | public HashSet ExpectedHeaders { get; } 236 | 237 | public IBindingList DataList { get; } 238 | public List TaggedLines { get; set; } 239 | 240 | public string InternalGuid => "40dd7405-16cf-4612-a480-9a050d0a2222"; 241 | 242 | public void ProcessFile(string filename) 243 | { 244 | DataList.Clear(); 245 | 246 | using var fileReader = File.OpenText(filename); 247 | var csv = new CsvReader(fileReader, CultureInfo.InvariantCulture); 248 | 249 | 250 | var o = new TypeConverterOptions 251 | { 252 | DateTimeStyle = DateTimeStyles.AssumeUniversal & DateTimeStyles.AdjustToUniversal 253 | }; 254 | csv.Context.TypeConverterOptionsCache.AddOptions(o); 255 | 256 | var foo = csv.Context.AutoMap(); 257 | 258 | foo.Map(t => t.Line).Ignore(); 259 | foo.Map(t => t.Tag).Ignore(); 260 | 261 | csv.Context.RegisterClassMap(foo); 262 | 263 | 264 | var records = csv.GetRecords(); 265 | 266 | var ln = 1; 267 | foreach (var record in records) 268 | { 269 | Log.Debug("Line # {Line}, Record: {RawRecord}",ln,csv.Context.Parser.RawRecord); 270 | record.Line = ln; 271 | 272 | record.Tag = TaggedLines.Contains(ln); 273 | 274 | DataList.Add(record); 275 | 276 | ln += 1; 277 | } 278 | } 279 | } 280 | } -------------------------------------------------------------------------------- /TLEFileKAPE/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.InteropServices; 2 | 3 | // Setting ComVisible to false makes the types in this assembly not visible 4 | // to COM components. If you need to access a type in this assembly from 5 | // COM, set the ComVisible attribute to true on that type. 6 | [assembly: ComVisible(false)] 7 | 8 | // The following GUID is for the ID of the typelib if this project is exposed to COM 9 | [assembly: Guid("4af4ae97-649b-4a8f-aa77-c72f5826d848")] 10 | -------------------------------------------------------------------------------- /TLEFileKAPE/TLEFileKAPE.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | netstandard2.0 4 | TLEFileKAPE 5 | TLEFileKAPE 6 | Eric Zimmerman 7 | 10 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /TLEFileMicrosoft/Microsoft.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Globalization; 5 | using System.IO; 6 | using System.Text; 7 | using CsvHelper; 8 | using CsvHelper.Configuration; 9 | using CsvHelper.TypeConversion; 10 | using ITLEFileSpec; 11 | using Serilog; 12 | 13 | namespace TLEFileMicrosoft 14 | { 15 | public class SigcheckData : IFileSpecData 16 | { 17 | public string Path { get; set; } 18 | public bool Verified { get; set; } 19 | public DateTime Timestamp { get; set; } 20 | 21 | public string Publisher { get; set; } 22 | public string Company { get; set; } 23 | public string Description { get; set; } 24 | public string Product { get; set; } 25 | public string ProductVersion { get; set; } 26 | public string FileVersion { get; set; } 27 | public string MachineType { get; set; } 28 | public string MD5 { get; set; } 29 | public string SHA1 { get; set; } 30 | public string PESHA1 { get; set; } 31 | public string PESHA256 { get; set; } 32 | public string SHA256 { get; set; } 33 | public string IMP { get; set; } 34 | public string VTDetection { get; set; } 35 | public string VTLink { get; set; } 36 | 37 | public int Line { get; set; } 38 | 39 | public bool Tag { get; set; } 40 | 41 | public override string ToString() 42 | { 43 | return 44 | $"{Path} {Verified} {Timestamp} {Publisher} {Company} {Description} {Product} {ProductVersion} {FileVersion} {MachineType} {MD5} {SHA1} {PESHA1} {PESHA256} {SHA256} {IMP} {VTDetection} {VTLink}"; 45 | } 46 | } 47 | 48 | 49 | public class Sigcheck : IFileSpec 50 | { 51 | public Sigcheck() 52 | { 53 | //Initialize collections here, one for TaggedLines TLE can add values to, and the collection that TLE will display 54 | TaggedLines = new List(); 55 | 56 | DataList = new BindingList(); 57 | 58 | ExpectedHeaders = new HashSet(StringComparer.OrdinalIgnoreCase) 59 | { 60 | "path,verified,date,publisher,company,description,product,product version,file version,machine type,md5,sha1,pesha1,pesha256,sha256,imp,vt detection,vt link" 61 | }; 62 | } 63 | 64 | public string Author => "Eric Zimmerman"; 65 | public string FileDescription => "CSV generated from SysInternals Sigcheck"; 66 | public HashSet ExpectedHeaders { get; } 67 | 68 | public IBindingList DataList { get; } 69 | public List TaggedLines { get; set; } 70 | 71 | public string InternalGuid => "40dd7405-16cf-4612-a221-9a050d0a9952"; 72 | 73 | public void ProcessFile(string filename) 74 | { 75 | DataList.Clear(); 76 | 77 | using var fileReader = new StreamReader(filename, CodePagesEncodingProvider.Instance.GetEncoding(1252)); 78 | var config = new CsvConfiguration(CultureInfo.InvariantCulture) 79 | { 80 | BadDataFound = null, 81 | }; 82 | 83 | var csv = new CsvReader(fileReader, config); 84 | 85 | var o = new TypeConverterOptions 86 | { 87 | DateTimeStyle = DateTimeStyles.AssumeUniversal & DateTimeStyles.AdjustToUniversal 88 | }; 89 | csv.Context.TypeConverterOptionsCache.AddOptions(o); 90 | 91 | var foo = csv.Context.AutoMap(); 92 | 93 | foo.Map(t => t.Line).Ignore(); 94 | foo.Map(t => t.Tag).Ignore(); 95 | 96 | foo.Map(t => t.Verified).Convert(t => t.Row.GetField("Verified") == "Signed"); 97 | 98 | foo.Map(t => t.Timestamp).Name("Date"); 99 | foo.Map(t => t.ProductVersion).Name("Product Version"); 100 | foo.Map(t => t.FileVersion).Name("File Version"); 101 | foo.Map(t => t.MachineType).Name("Machine Type"); 102 | foo.Map(t => t.VTDetection).Name("VT detection"); 103 | foo.Map(t => t.VTLink).Name("VT link"); 104 | 105 | csv.Context.RegisterClassMap(foo); 106 | 107 | 108 | 109 | var records = csv.GetRecords(); 110 | 111 | var ln = 1; 112 | foreach (var sc in records) 113 | { 114 | Log.Debug("Line # {Line}, Record: {RawRecord}",ln,csv.Context.Parser.RawRecord); 115 | 116 | sc.Line = ln; 117 | sc.Tag = TaggedLines.Contains(ln); 118 | DataList.Add(sc); 119 | ln += 1; 120 | } 121 | } 122 | } 123 | 124 | public class SigcheckTroyData : IFileSpecData 125 | { 126 | public string Path { get; set; } 127 | public bool Verified { get; set; } 128 | public DateTime Timestamp { get; set; } 129 | 130 | public string Publisher { get; set; } 131 | public string Company { get; set; } 132 | public string Description { get; set; } 133 | public string Product { get; set; } 134 | public string ProductVersion { get; set; } 135 | public string FileVersion { get; set; } 136 | public string MachineType { get; set; } 137 | public string BinaryVersion { get; set; } 138 | public string OriginalName { get; set; } 139 | public string InternalName { get; set; } 140 | public string Copyright { get; set; } 141 | public string Comments { get; set; } 142 | public string Entropy { get; set; } 143 | public string MD5 { get; set; } 144 | public string SHA1 { get; set; } 145 | public string PESHA1 { get; set; } 146 | public string PESHA256 { get; set; } 147 | public string SHA256 { get; set; } 148 | public string IMP { get; set; } 149 | 150 | 151 | public int Line { get; set; } 152 | 153 | public bool Tag { get; set; } 154 | 155 | public override string ToString() 156 | { 157 | return 158 | $"{Path} {Verified} {Timestamp} {Publisher} {Company} {Description} {Product} {ProductVersion} {FileVersion} {MachineType} {BinaryVersion} {OriginalName} {InternalName} {Copyright} {Comments} {Entropy} {MD5} {SHA1} {PESHA1} {PESHA256} {SHA256} {IMP}"; 159 | } 160 | } 161 | 162 | 163 | public class SigcheckTroy : IFileSpec 164 | { 165 | public SigcheckTroy() 166 | { 167 | //Initialize collections here, one for TaggedLines TLE can add values to, and the collection that TLE will display 168 | TaggedLines = new List(); 169 | 170 | DataList = new BindingList(); 171 | 172 | ExpectedHeaders = new HashSet(StringComparer.OrdinalIgnoreCase) 173 | { 174 | "path,verified,date,publisher,company,description,product,product version,file version,machine type,binary version,original name,internal name,copyright,comments,entropy,md5,sha1,pesha1,pesha256,sha256,imp" 175 | }; 176 | } 177 | 178 | public string Author => "Eric Zimmerman"; 179 | public string FileDescription => "CSV generated from customized Sigcheck"; 180 | public HashSet ExpectedHeaders { get; } 181 | 182 | public IBindingList DataList { get; } 183 | public List TaggedLines { get; set; } 184 | 185 | public string InternalGuid => "40dd7405-16cf-4612-a480-1a010d0a1912"; 186 | 187 | public void ProcessFile(string filename) 188 | { 189 | DataList.Clear(); 190 | 191 | using var fileReader = new StreamReader(filename, CodePagesEncodingProvider.Instance.GetEncoding(1252)); 192 | var config = new CsvConfiguration(CultureInfo.InvariantCulture) 193 | { 194 | BadDataFound = null, 195 | }; 196 | 197 | var csv = new CsvReader(fileReader, config); 198 | 199 | 200 | 201 | var o = new TypeConverterOptions 202 | { 203 | DateTimeStyle = DateTimeStyles.AssumeUniversal & DateTimeStyles.AdjustToUniversal 204 | }; 205 | csv.Context.TypeConverterOptionsCache.AddOptions(o); 206 | 207 | var foo = csv.Context.AutoMap(); 208 | 209 | //path,verified,date,publisher,company,description,product,product version,file version,machine type,binary version,original name,internal name,copyright,comments,entropy,md5,sha1,pesha1,pesha256,sha256,imp 210 | 211 | foo.Map(t => t.Line).Ignore(); 212 | foo.Map(t => t.Tag).Ignore(); 213 | 214 | foo.Map(t => t.Verified).Convert(t => t.Row.GetField("Verified") == "Signed"); 215 | 216 | foo.Map(t => t.Timestamp).Name("Date"); 217 | foo.Map(t => t.ProductVersion).Name("Product Version"); 218 | foo.Map(t => t.FileVersion).Name("File Version"); 219 | foo.Map(t => t.MachineType).Name("Machine Type"); 220 | foo.Map(t => t.BinaryVersion).Name("Binary Version"); 221 | foo.Map(t => t.OriginalName).Name("Original Name"); 222 | foo.Map(t => t.InternalName).Name("Internal Name"); 223 | 224 | 225 | csv.Context.RegisterClassMap(foo); 226 | 227 | 228 | 229 | var records = csv.GetRecords(); 230 | 231 | var ln = 1; 232 | foreach (var sc in records) 233 | { 234 | Log.Debug("Line # {Line}, Record: {RawRecord}",ln,csv.Context.Parser.RawRecord); 235 | 236 | sc.Line = ln; 237 | sc.Tag = TaggedLines.Contains(ln); 238 | DataList.Add(sc); 239 | ln += 1; 240 | } 241 | } 242 | } 243 | 244 | public class AutorunsData : IFileSpecData 245 | { 246 | public DateTime? Time { get; set; } 247 | public string EntryLocation { get; set; } 248 | public string Entry { get; set; } 249 | public bool Enabled { get; set; } 250 | public string Category { get; set; } 251 | public string Description { get; set; } 252 | public string Signer { get; set; } 253 | public string Company { get; set; } 254 | public string Version { get; set; } 255 | public string ImagePath { get; set; } 256 | public string LaunchString { get; set; } 257 | public string MD5 { get; set; } 258 | public string SHA1 { get; set; } 259 | public string PESHA1 { get; set; } 260 | public string SHA256 { get; set; } 261 | public string PESHA256 { get; set; } 262 | public string Imp { get; set; } 263 | public string PSComputerName { get; set; } 264 | public string RunspaceId { get; set; } 265 | public string PSShowComputerName { get; set; } 266 | 267 | public int Line { get; set; } 268 | public bool Tag { get; set; } 269 | 270 | public override string ToString() 271 | { 272 | return 273 | $"{Time} {EntryLocation} {Entry} {Category} {Description} {Signer} {Company} {Version} {ImagePath} {LaunchString} {MD5} {SHA1} {SHA256} {PESHA1} {PESHA256} {PSComputerName} {RunspaceId} {PSShowComputerName} "; 274 | } 275 | } 276 | 277 | 278 | public class Autoruns : IFileSpec 279 | { 280 | public Autoruns() 281 | { 282 | //Initialize collections here, one for TaggedLines TLE can add values to, and the collection that TLE will display 283 | TaggedLines = new List(); 284 | 285 | DataList = new BindingList(); 286 | 287 | ExpectedHeaders = new HashSet(StringComparer.OrdinalIgnoreCase) 288 | { 289 | "\"time\",\"entry location\",\"entry\",\"enabled\",\"category\",\"profile\",\"description\",\"signer\",\"company\",\"image path\",\"version\",\"launch string\",\"md5\",\"sha-1\",\"pesha-1\",\"pesha-256\",\"sha-256\",\"imp\",\"pscomputername\",\"runspaceid\",\"psshowcomputername\"" 290 | }; 291 | } 292 | 293 | public string Author => "Eric Zimmerman"; 294 | public string FileDescription => "CSV generated from SysInternals Autoruns"; 295 | public HashSet ExpectedHeaders { get; } 296 | 297 | public IBindingList DataList { get; } 298 | public List TaggedLines { get; set; } 299 | 300 | public string InternalGuid => "42dd2304-16cf-4612-a480-9a050d0a9952"; 301 | 302 | public void ProcessFile(string filename) 303 | { 304 | DataList.Clear(); 305 | 306 | using var fileReader = File.OpenText(filename); 307 | var csv = new CsvReader(fileReader, CultureInfo.InvariantCulture); 308 | 309 | var foo = csv.Context.AutoMap(); 310 | 311 | //"Time","Entry Location","Entry","Enabled","Category","Profile","Description","Signer","Company", 312 | //"Image Path","Version","Launch String","MD5","SHA-1","PESHA-1","PESHA-256","SHA-256","IMP", 313 | //"PSComputerName","RunspaceId","PSShowComputerName" 314 | 315 | foo.Map(t => t.Line).Ignore(); 316 | foo.Map(t => t.Tag).Ignore(); 317 | 318 | foo.Map(t => t.EntryLocation).Name("Entry Location"); 319 | foo.Map(t => t.Enabled).Convert(t => t.Row[3] == "enabled"); 320 | foo.Map(t => t.ImagePath).Name("Image Path"); 321 | foo.Map(t => t.LaunchString).Name("Launch String"); 322 | foo.Map(t => t.SHA1).Name("SHA-1"); 323 | foo.Map(t => t.PESHA1).Name("PESHA-1"); 324 | foo.Map(t => t.SHA256).Name("SHA-256"); 325 | foo.Map(t => t.PESHA256).Name("PESHA-256"); 326 | foo.Map(t => t.Imp).Name("IMP"); 327 | 328 | csv.Context.RegisterClassMap(foo); 329 | 330 | 331 | 332 | var records = csv.GetRecords(); 333 | 334 | var ln = 1; 335 | foreach (var autorunsEntry in records) 336 | { 337 | Log.Debug("Line # {Line}, Record: {RawRecord}",ln,csv.Context.Parser.RawRecord); 338 | 339 | autorunsEntry.Line = ln; 340 | autorunsEntry.Tag = TaggedLines.Contains(ln); 341 | DataList.Add(autorunsEntry); 342 | ln += 1; 343 | } 344 | } 345 | } 346 | 347 | public class MsftMftData : IFileSpecData 348 | { 349 | public long SegmentNumber { get; set; } 350 | public bool InUse { get; set; } 351 | public int ReferenceCount { get; set; } 352 | public bool IsDirectory { get; set; } 353 | public bool IsStream { get; set; } 354 | public string FileName { get; set; } 355 | public long? FileSize { get; set; } 356 | public string Extension { get; set; } 357 | public DateTime? CreationTime0x10 { get; set; } 358 | public DateTime? LastModificationTime0x10 { get; set; } 359 | public DateTime? LastChangeTime0x10 { get; set; } 360 | public DateTime? LastAccessTime0x10 { get; set; } 361 | public DateTime? LastModificationTime0x30 { get; set; } 362 | public DateTime? CreationTime0x30 { get; set; } 363 | public DateTime? LastChangeTime0x30 { get; set; } 364 | public DateTime? LastAccessTime0x30 { get; set; } 365 | public string Path { get; set; } 366 | public int ParentFRS { get; set; } 367 | public int? OwnerID { get; set; } 368 | public int? SecurityID { get; set; } 369 | public bool HasEA { get; set; } 370 | public bool IsReadOnly { get; set; } 371 | public bool IsHidden { get; set; } 372 | public bool IsSystem { get; set; } 373 | public bool IsArchive { get; set; } 374 | public bool IsNormal { get; set; } 375 | public bool IsTemporary { get; set; } 376 | public bool IsSparse { get; set; } 377 | public bool IsReparsePoint { get; set; } 378 | public bool IsCompressed { get; set; } 379 | public bool IsOffline { get; set; } 380 | public bool IsNotContentIndexed { get; set; } 381 | public bool IsEncrypted { get; set; } 382 | public bool IsIntegrityStream { get; set; } 383 | public bool IsVirtual { get; set; } 384 | public bool IsNoScrubData { get; set; } 385 | public bool IsEA { get; set; } 386 | public string LoggedUtilityStream { get; set; } 387 | public int SequenceNumber { get; set; } 388 | public string ParseErrorMsg { get; set; } 389 | 390 | public int Line { get; set; } 391 | 392 | public bool Tag { get; set; } 393 | 394 | 395 | public override string ToString() 396 | { 397 | return 398 | $"{SegmentNumber} {InUse} {ReferenceCount} {IsDirectory} {IsStream} {FileName} {FileSize} {Extension} {CreationTime0x10} {LastModificationTime0x10} {LastChangeTime0x10} {LastAccessTime0x10} {CreationTime0x30} {LastModificationTime0x30} {LastChangeTime0x30} {LastAccessTime0x30} {Path} {ParentFRS} {OwnerID} {SecurityID}" + 399 | $" {HasEA} {IsHidden} {IsSystem} {IsArchive} {IsNormal} {IsTemporary} {IsSparse} {IsReparsePoint} {IsCompressed} {IsOffline} {IsNotContentIndexed} {IsEncrypted} {IsIntegrityStream} {IsVirtual} {IsNoScrubData} {IsEA} {IsReadOnly} {LoggedUtilityStream} {SequenceNumber} {ParseErrorMsg}"; 400 | } 401 | } 402 | 403 | 404 | public class MsftMft : IFileSpec 405 | { 406 | public MsftMft() 407 | { 408 | //Initialize collections here, one for TaggedLines TLE can add values to, and the collection that TLE will display 409 | TaggedLines = new List(); 410 | 411 | DataList = new BindingList(); 412 | 413 | ExpectedHeaders = new HashSet(StringComparer.OrdinalIgnoreCase) 414 | { 415 | "segmentnumber inuse referencecount isdirectory isstream filename filesize extension creationtime0x10 lastmodificationtime0x10 lastchangetime0x10 lastaccesstime0x10 lastmodificationtime0x30 creationtime0x30 lastchangetime0x30 lastaccesstime0x30 path parentfrs ownerid securityid hasea isreadonly ishidden issystem isarchive isnormal istemporary issparse isreparsepoint iscompressed isoffline isnotcontentindexed isencrypted isintegritystream isvirtual isnoscrubdata isea loggedutilitystream sequencenumber parseerrormsg" 416 | }; 417 | } 418 | 419 | public string Author => "Eric Zimmerman"; 420 | public string FileDescription => "CSV generated from internal Microsoft tool"; 421 | public HashSet ExpectedHeaders { get; } 422 | 423 | public IBindingList DataList { get; } 424 | public List TaggedLines { get; set; } 425 | 426 | public string InternalGuid => "40dd7405-16cf-4612-c580-9a050d0c1252"; 427 | 428 | public void ProcessFile(string filename) 429 | { 430 | DataList.Clear(); 431 | 432 | using var fileReader = File.OpenText(filename); 433 | var csv = new CsvReader(fileReader, CultureInfo.InvariantCulture); 434 | 435 | 436 | 437 | var foo = csv.Context.AutoMap(); 438 | 439 | var o = new TypeConverterOptions 440 | { 441 | DateTimeStyle = DateTimeStyles.AssumeUniversal & DateTimeStyles.AdjustToUniversal 442 | }; 443 | 444 | csv.Context.TypeConverterOptionsCache.AddOptions(o); 445 | 446 | foo.Map(t => t.Line).Ignore(); 447 | foo.Map(t => t.Tag).Ignore(); 448 | 449 | foo.Map(m => m.CreationTime0x10).Convert(row => 450 | DateTime.Parse(row.Row.GetField("CreationTime0x10").Replace("Z", ""))); 451 | foo.Map(m => m.CreationTime0x30).Convert(row => 452 | DateTime.Parse(row.Row.GetField("CreationTime0x30").Replace("Z", ""))); 453 | foo.Map(m => m.LastModificationTime0x10).Convert(row => 454 | DateTime.Parse(row.Row.GetField("LastModificationTime0x10").Replace("Z", ""))); 455 | foo.Map(m => m.LastModificationTime0x30).Convert(row => 456 | DateTime.Parse(row.Row.GetField("LastModificationTime0x30").Replace("Z", ""))); 457 | foo.Map(m => m.LastChangeTime0x10).Convert(row => 458 | DateTime.Parse(row.Row.GetField("LastChangeTime0x10").Replace("Z", ""))); 459 | foo.Map(m => m.LastChangeTime0x30).Convert(row => 460 | DateTime.Parse(row.Row.GetField("LastChangeTime0x30").Replace("Z", ""))); 461 | foo.Map(m => m.LastAccessTime0x10).Convert(row => 462 | DateTime.Parse(row.Row.GetField("LastAccessTime0x10").Replace("Z", ""))); 463 | foo.Map(m => m.LastAccessTime0x30).Convert(row => 464 | DateTime.Parse(row.Row.GetField("LastAccessTime0x30").Replace("Z", ""))); 465 | 466 | 467 | csv.Context.RegisterClassMap(foo); 468 | 469 | 470 | 471 | var records = csv.GetRecords(); 472 | 473 | var ln = 1; 474 | foreach (var record in records) 475 | { 476 | Log.Debug("Line # {Line}, Record: {RawRecord}",ln,csv.Context.Parser.RawRecord); 477 | record.Line = ln; 478 | record.Tag = TaggedLines.Contains(ln); 479 | DataList.Add(record); 480 | 481 | ln += 1; 482 | } 483 | } 484 | } 485 | } -------------------------------------------------------------------------------- /TLEFileMicrosoft/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.InteropServices; 2 | 3 | // Setting ComVisible to false makes the types in this assembly not visible 4 | // to COM components. If you need to access a type in this assembly from 5 | // COM, set the ComVisible attribute to true on that type. 6 | [assembly: ComVisible(false)] 7 | 8 | // The following GUID is for the ID of the typelib if this project is exposed to COM 9 | [assembly: Guid("496a603a-7a88-490f-bec8-97967746aff8")] 10 | -------------------------------------------------------------------------------- /TLEFileMicrosoft/TLEFileMicrosoft.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | netstandard2.0 4 | TLEFileMicrosoft 5 | TLEFileMicrosoft 6 | Eric Zimmerman 7 | 10 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /TLEFileMisc/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.InteropServices; 2 | 3 | // Setting ComVisible to false makes the types in this assembly not visible 4 | // to COM components. If you need to access a type in this assembly from 5 | // COM, set the ComVisible attribute to true on that type. 6 | [assembly: ComVisible(false)] 7 | 8 | // The following GUID is for the ID of the typelib if this project is exposed to COM 9 | [assembly: Guid("efbb6815-a8ec-40d5-83ff-5d73db540116")] 10 | -------------------------------------------------------------------------------- /TLEFileMisc/TLEFileMisc.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | netstandard2.0 4 | TLEFileMisc 5 | TLEFileMisc 6 | Eric Zimmerman 7 | 10 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /TLEFilePlugins.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.30804.86 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ITLEFileSpec", "ITLEFileSpec\ITLEFileSpec.csproj", "{B405EE7D-7EDE-4812-88B4-7297DD35DFBB}" 7 | EndProject 8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TLEFileEZTools", "TLEFileEZTools\TLEFileEZTools.csproj", "{6CAA82CE-3E8C-473C-B48B-E0BD857740D7}" 9 | EndProject 10 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TLEFileGenericCsv", "TLEFileGenericCsv\TLEFileGenericCsv.csproj", "{FC0EB431-2893-41C4-B0ED-C4D2C4290CA4}" 11 | EndProject 12 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TLEFileTimelines", "TLEFileTimelines\TLEFileTimelines.csproj", "{8983B700-AFE0-480A-BABE-D8DD5A760404}" 13 | EndProject 14 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TLEFileMicrosoft", "TLEFileMicrosoft\TLEFileMicrosoft.csproj", "{496A603A-7A88-490F-BEC8-97967746AFF8}" 15 | EndProject 16 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TLEFileKAPE", "TLEFileKAPE\TLEFileKAPE.csproj", "{4AF4AE97-649B-4A8F-AA77-C72F5826D848}" 17 | EndProject 18 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TLEFileTzWorks", "TLEFileTzWorks\TLEFileTzWorks.csproj", "{3F975021-89C4-4E63-B342-DCCA4AF5F1BC}" 19 | EndProject 20 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TLEFileMisc", "TLEFileMisc\TLEFileMisc.csproj", "{EFBB6815-A8EC-40D5-83FF-5D73DB540116}" 21 | EndProject 22 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TLEFile.Test", "TLEFile.Test\TLEFile.Test.csproj", "{6A9F9E57-170A-4959-8768-0C0EBBDDCBE8}" 23 | EndProject 24 | Global 25 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 26 | Debug|Any CPU = Debug|Any CPU 27 | Release|Any CPU = Release|Any CPU 28 | EndGlobalSection 29 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 30 | {B405EE7D-7EDE-4812-88B4-7297DD35DFBB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 31 | {B405EE7D-7EDE-4812-88B4-7297DD35DFBB}.Debug|Any CPU.Build.0 = Debug|Any CPU 32 | {B405EE7D-7EDE-4812-88B4-7297DD35DFBB}.Release|Any CPU.ActiveCfg = Release|Any CPU 33 | {B405EE7D-7EDE-4812-88B4-7297DD35DFBB}.Release|Any CPU.Build.0 = Release|Any CPU 34 | {6CAA82CE-3E8C-473C-B48B-E0BD857740D7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 35 | {6CAA82CE-3E8C-473C-B48B-E0BD857740D7}.Debug|Any CPU.Build.0 = Debug|Any CPU 36 | {6CAA82CE-3E8C-473C-B48B-E0BD857740D7}.Release|Any CPU.ActiveCfg = Release|Any CPU 37 | {6CAA82CE-3E8C-473C-B48B-E0BD857740D7}.Release|Any CPU.Build.0 = Release|Any CPU 38 | {FC0EB431-2893-41C4-B0ED-C4D2C4290CA4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 39 | {FC0EB431-2893-41C4-B0ED-C4D2C4290CA4}.Debug|Any CPU.Build.0 = Debug|Any CPU 40 | {FC0EB431-2893-41C4-B0ED-C4D2C4290CA4}.Release|Any CPU.ActiveCfg = Release|Any CPU 41 | {FC0EB431-2893-41C4-B0ED-C4D2C4290CA4}.Release|Any CPU.Build.0 = Release|Any CPU 42 | {8983B700-AFE0-480A-BABE-D8DD5A760404}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 43 | {8983B700-AFE0-480A-BABE-D8DD5A760404}.Debug|Any CPU.Build.0 = Debug|Any CPU 44 | {8983B700-AFE0-480A-BABE-D8DD5A760404}.Release|Any CPU.ActiveCfg = Release|Any CPU 45 | {8983B700-AFE0-480A-BABE-D8DD5A760404}.Release|Any CPU.Build.0 = Release|Any CPU 46 | {496A603A-7A88-490F-BEC8-97967746AFF8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 47 | {496A603A-7A88-490F-BEC8-97967746AFF8}.Debug|Any CPU.Build.0 = Debug|Any CPU 48 | {496A603A-7A88-490F-BEC8-97967746AFF8}.Release|Any CPU.ActiveCfg = Release|Any CPU 49 | {496A603A-7A88-490F-BEC8-97967746AFF8}.Release|Any CPU.Build.0 = Release|Any CPU 50 | {4AF4AE97-649B-4A8F-AA77-C72F5826D848}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 51 | {4AF4AE97-649B-4A8F-AA77-C72F5826D848}.Debug|Any CPU.Build.0 = Debug|Any CPU 52 | {4AF4AE97-649B-4A8F-AA77-C72F5826D848}.Release|Any CPU.ActiveCfg = Release|Any CPU 53 | {4AF4AE97-649B-4A8F-AA77-C72F5826D848}.Release|Any CPU.Build.0 = Release|Any CPU 54 | {3F975021-89C4-4E63-B342-DCCA4AF5F1BC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 55 | {3F975021-89C4-4E63-B342-DCCA4AF5F1BC}.Debug|Any CPU.Build.0 = Debug|Any CPU 56 | {3F975021-89C4-4E63-B342-DCCA4AF5F1BC}.Release|Any CPU.ActiveCfg = Release|Any CPU 57 | {3F975021-89C4-4E63-B342-DCCA4AF5F1BC}.Release|Any CPU.Build.0 = Release|Any CPU 58 | {EFBB6815-A8EC-40D5-83FF-5D73DB540116}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 59 | {EFBB6815-A8EC-40D5-83FF-5D73DB540116}.Debug|Any CPU.Build.0 = Debug|Any CPU 60 | {EFBB6815-A8EC-40D5-83FF-5D73DB540116}.Release|Any CPU.ActiveCfg = Release|Any CPU 61 | {EFBB6815-A8EC-40D5-83FF-5D73DB540116}.Release|Any CPU.Build.0 = Release|Any CPU 62 | {6A9F9E57-170A-4959-8768-0C0EBBDDCBE8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 63 | {6A9F9E57-170A-4959-8768-0C0EBBDDCBE8}.Debug|Any CPU.Build.0 = Debug|Any CPU 64 | {6A9F9E57-170A-4959-8768-0C0EBBDDCBE8}.Release|Any CPU.ActiveCfg = Release|Any CPU 65 | {6A9F9E57-170A-4959-8768-0C0EBBDDCBE8}.Release|Any CPU.Build.0 = Release|Any CPU 66 | EndGlobalSection 67 | GlobalSection(SolutionProperties) = preSolution 68 | HideSolutionNode = FALSE 69 | EndGlobalSection 70 | GlobalSection(ExtensibilityGlobals) = postSolution 71 | SolutionGuid = {1AA0AF61-B998-4A64-8045-09D79B9DCDD3} 72 | EndGlobalSection 73 | EndGlobal 74 | -------------------------------------------------------------------------------- /TLEFilePlugins.v3.ncrunchsolution: -------------------------------------------------------------------------------- 1 |  2 | 3 | True 4 | True 5 | 6 | -------------------------------------------------------------------------------- /TLEFileTimelines/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.InteropServices; 2 | 3 | // Setting ComVisible to false makes the types in this assembly not visible 4 | // to COM components. If you need to access a type in this assembly from 5 | // COM, set the ComVisible attribute to true on that type. 6 | [assembly: ComVisible(false)] 7 | 8 | // The following GUID is for the ID of the typelib if this project is exposed to COM 9 | [assembly: Guid("8983b700-afe0-480a-babe-d8dd5a760404")] 10 | -------------------------------------------------------------------------------- /TLEFileTimelines/TLEFileTimelines.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | netstandard2.0 4 | TLEFileTimelines 5 | TLEFileTimelines 6 | Eric Zimmerman 7 | 10 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /TLEFileTimelines/Timelines.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Globalization; 5 | using System.IO; 6 | using System.Linq; 7 | using CsvHelper; 8 | using CsvHelper.Configuration; 9 | using CsvHelper.TypeConversion; 10 | using ITLEFileSpec; 11 | using Serilog; 12 | 13 | namespace TLEFileTimelines 14 | { 15 | public class ForensicTimelineData : IFileSpecData 16 | { 17 | public DateTime DateTime { get; set; } 18 | public string TimestampInfo { get; set; } 19 | public string ArtifactName { get; set; } 20 | public string Tool { get; set; } 21 | public string Description { get; set; } 22 | public string DataDetails { get; set; } 23 | public string DataPath { get; set; } 24 | public string FileExtension { get; set; } 25 | public string EvidencePath { get; set; } 26 | public string EventId { get; set; } 27 | public string User { get; set; } 28 | public string Computer { get; set; } 29 | public long? FileSize { get; set; } 30 | public string IPAddress { get; set; } 31 | public string SourceAddress { get; set; } 32 | public string DestinationAddress { get; set; } 33 | public string SHA1 { get; set; } 34 | public string Count { get; set; } 35 | public string RawData { get; set; } 36 | 37 | public int Line { get; set; } 38 | public bool Tag { get; set; } 39 | public string Color { get; set; } 40 | 41 | public override string ToString() 42 | { 43 | return $"{DateTime} {TimestampInfo} {ArtifactName} {Tool} {Description} {DataDetails} {DataPath} {FileExtension} {EvidencePath} {EventId} {User} {Computer} {FileSize} {IPAddress} {SourceAddress} {DestinationAddress} {SHA1} {Count} {RawData}"; 44 | } 45 | } 46 | 47 | public class ForensicTimeline : IFileSpec 48 | { 49 | 50 | public ForensicTimeline() 51 | { 52 | TaggedLines = new List(); 53 | 54 | DataList = new BindingList(); 55 | 56 | ExpectedHeaders = new HashSet(StringComparer.OrdinalIgnoreCase) 57 | { 58 | "DateTime,TimestampInfo,ArtifactName,Tool,Description,DataDetails,DataPath,FileExtension,EventId,User,Computer,FileSize,IPAddress,SourceAddress,DestinationAddress,SHA1,Count,EvidencePath,RawData" 59 | }; 60 | 61 | } 62 | 63 | public string Author => "Brad Roughan (@acquiredsecurity)"; 64 | public string FileDescription => "CSV generated for ForensicTimeliner"; 65 | public HashSet ExpectedHeaders { get; } 66 | public IBindingList DataList { get; } 67 | public List TaggedLines { get; set; } 68 | public string InternalGuid => "40ef1341-42af-4612-a480-9a021e2a3353"; 69 | 70 | public void ProcessFile(string filename) 71 | { 72 | var ln = 1; 73 | using var fileReader = File.OpenText(filename); 74 | var csv = new CsvReader(fileReader, CultureInfo.InvariantCulture); 75 | 76 | try 77 | { 78 | DataList.Clear(); 79 | var o = new TypeConverterOptions 80 | { 81 | DateTimeStyle = DateTimeStyles.AssumeUniversal & DateTimeStyles.AdjustToUniversal 82 | }; 83 | csv.Context.TypeConverterOptionsCache.AddOptions(o); 84 | 85 | var foo = csv.Context.AutoMap(); 86 | 87 | // Ignore internal fields 88 | foo.Map(t => t.Line).Ignore(); 89 | foo.Map(t => t.Tag).Ignore(); 90 | foo.Map(t => t.Color).Ignore(); 91 | 92 | csv.Context.RegisterClassMap(foo); 93 | 94 | var records = csv.GetRecords(); 95 | 96 | foreach (var record in records) 97 | { 98 | Log.Debug("Line # {Line}, Record: {RawRecord}", ln, csv.Context.Parser.RawRecord); 99 | 100 | record.Line = ln; 101 | record.Tag = TaggedLines.Contains(ln); 102 | 103 | // SIMPLE COLOR LOGIC 104 | if (record.ArtifactName != null) 105 | { 106 | if (record.ArtifactName.Contains("LNK") || 107 | record.ArtifactName.Contains("JumpLists") || 108 | record.ArtifactName.Contains("WindowsTimelineActivity") || 109 | record.ArtifactName.Contains("Shellbags")) 110 | { 111 | record.Color = "FileFolderOpening"; 112 | } 113 | else if (record.ArtifactName.Contains("FileDeletion")) 114 | { 115 | record.Color = "DeletedData"; 116 | } 117 | else if (record.ArtifactName.Contains("AppCompatCache") || 118 | record.ArtifactName.Contains("Prefetch") || 119 | record.ArtifactName.Contains("Amcache") || 120 | record.ArtifactName.Contains("MFT") || 121 | record.ArtifactName.Contains("Registry")) 122 | { 123 | record.Color = "Execution"; 124 | } 125 | else if (record.ArtifactName.Contains("Web History")) 126 | { 127 | record.Color = "WebHistory"; 128 | } 129 | else if (record.ArtifactName.Contains("Event Logs")) 130 | { 131 | record.Color = "LogFile"; 132 | } 133 | } 134 | 135 | 136 | DataList.Add(record); 137 | ln++; 138 | } 139 | } 140 | catch (Exception e) 141 | { 142 | throw new Exception( 143 | $"Error loading data on line '{ln}': {e.Message}. Line: {csv.Context.Parser.RawRecord}", e); 144 | } 145 | } 146 | } 147 | 148 | public class PsortTimelineData : IFileSpecData 149 | { 150 | public PsortTimelineData(int line, string timestamp, string timestampDescription, string source, string sourceLong, string message, string parser, string displayName, string tagInfo) 151 | { 152 | Line = line; 153 | TimestampDescription = timestampDescription; 154 | Source = source; 155 | SourceLong = sourceLong; 156 | Message = message; 157 | Parser = parser; 158 | DisplayName = displayName; 159 | TagInfo = tagInfo; 160 | 161 | try 162 | { 163 | //Timestamp = DateTime.ParseExact($"{date} {time}", "MM/dd/yyyy HH:mm:ss", CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal).ToUniversalTime(); 164 | Timestamp = DateTime.Parse(timestamp, CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal).ToUniversalTime(); 165 | } 166 | catch (Exception) 167 | { 168 | Timestamp = DateTime.MinValue; 169 | } 170 | 171 | TimestampDescription = timestampDescription; 172 | Source = source; 173 | SourceLong = sourceLong; 174 | Message = message; 175 | Parser = parser; 176 | DisplayName = displayName; 177 | TagInfo = tagInfo; 178 | 179 | if (sourceLong == null) 180 | { 181 | return; 182 | } 183 | 184 | if (sourceLong.Contains("RECYCLE") || 185 | sourceLong.Contains("DELETED") || 186 | sourceLong.Contains("Deleted Registry") || 187 | sourceLong.Contains("$Recycle.Bin")) 188 | { 189 | Color = "DeletedData"; 190 | } 191 | 192 | if (sourceLong.Contains("Expiration Time") || 193 | sourceLong.Contains("Cookie") || 194 | sourceLong.Contains("Visited") || 195 | sourceLong.Contains("URL") && source.Contains("FILE") == false || 196 | sourceLong.Contains("Flash Cookie") || 197 | sourceLong.Contains("LSO") && source.Contains("REG") == false || 198 | sourceLong.ToLowerInvariant().Contains("http://") || 199 | sourceLong.ToLowerInvariant().Contains("https://") || 200 | sourceLong.Contains("Location:") || 201 | sourceLong.Contains("time(s) [HTTP") || 202 | sourceLong.Contains("Last Visited Time") || 203 | source.StartsWith("WEBHIST")) 204 | { 205 | Color = "WebHistory"; 206 | } 207 | 208 | 209 | if (sourceLong.Contains("lnk/shell_items") || 210 | source.Contains("File entry shell item") || 211 | sourceLong.Contains("BagMRU") || 212 | sourceLong.Contains("ShellNoRoam/Bags")) 213 | { 214 | Color = "FolderOpening"; 215 | } 216 | 217 | if (sourceLong.Contains("visited file://") || 218 | sourceLong.Contains("CreateDate") || 219 | sourceLong.Contains("URL:file://") || 220 | sourceLong.Contains("File Opened") || 221 | sourceLong.Contains("Folder opened") || 222 | sourceLong.Contains("Shortcut LNK") || 223 | sourceLong.Contains("RecentDocs key") || 224 | sourceLong.Contains("Link target:") || 225 | sourceLong.Contains("File attribute flags") || 226 | sourceLong.Contains("Birth droid volume identifier:") || 227 | sourceLong.Contains("UserAssist entry") || 228 | sourceLong.ToLowerInvariant().EndsWith(".lnk") || 229 | sourceLong.Contains("Recently opened file") || 230 | sourceLong.Contains("file of extension") || 231 | sourceLong.Contains("Recently") && source.Contains("Firefox") == false || 232 | sourceLong.EndsWith("LNK") || 233 | sourceLong.Contains("file://") && source.Contains("Firefox") == false || 234 | sourceLong.Contains("RecentDocs")) 235 | { 236 | Color = "FileOpening"; 237 | } 238 | 239 | if (sourceLong.Contains("MountPoints2") || 240 | sourceLong.Contains("volume mounted") || 241 | sourceLong.Contains("USB") || 242 | sourceLong.Contains("/USB/Vid_") || 243 | sourceLong.Contains("Enum/USBSTOR/Disk") || 244 | sourceLong.Contains("RemovableMedia") || 245 | sourceLong.Contains("STORAGE/RemovableMedia") || 246 | sourceLong.Contains("drive mounted") || 247 | sourceLong.Contains("Drive last mounted") || 248 | sourceLong.Contains("SetupAPI Log")) 249 | { 250 | Color = "Device|USBUsage"; 251 | } 252 | 253 | if (sourceLong.Contains("EVT") || 254 | sourceLong.Contains("XP Firewall Log") || 255 | sourceLong.Contains("Event Level:") || 256 | source.StartsWith("EVT") 257 | ) 258 | { 259 | Color = "LogFile"; 260 | } 261 | 262 | if (sourceLong.Contains("Prefetch {") || 263 | sourceLong.Contains("AppCompatCache") || 264 | sourceLong.Contains(@"\Software\Sysinternals") || 265 | sourceLong.Contains("typed the following cmd") || 266 | sourceLong.Contains("CMD typed") || 267 | sourceLong.Contains("Last run") || 268 | sourceLong.Contains("RunMRU") || 269 | sourceLong.Contains("MUICache") || 270 | sourceLong.Contains("UserAssist key") || 271 | sourceLong.Contains("Time of Launch") || 272 | sourceLong.Contains("Prefetch") || 273 | sourceLong.Contains("SHIMCACHE") || 274 | sourceLong.Contains("Scheduled") || 275 | sourceLong.ToLowerInvariant().EndsWith(".pf") || 276 | sourceLong.Contains("was run") || 277 | sourceLong.Contains("UEME_") || 278 | sourceLong.StartsWith("[PROCESS]") 279 | ) 280 | { 281 | Color = "Execution"; 282 | } 283 | } 284 | 285 | 286 | public DateTime Timestamp { get; } 287 | public string TimestampDescription { get; } 288 | public string Source { get; } 289 | public string SourceLong { get; } 290 | public string Message { get; } 291 | public string Parser { get; } 292 | public string DisplayName { get; } 293 | public string TagInfo { get; } 294 | 295 | public string Color { get; set; } 296 | 297 | public int Line { get; set; } 298 | public bool Tag { get; set; } 299 | 300 | public override string ToString() 301 | { 302 | return 303 | $"{Timestamp} {TimestampDescription} {Source} {SourceLong} {Message} {Parser} {DisplayName} {TagInfo}"; 304 | } 305 | } 306 | 307 | 308 | 309 | 310 | 311 | public class PsortTimeline : IFileSpec 312 | { 313 | public PsortTimeline() 314 | { 315 | TaggedLines = new List(); 316 | 317 | DataList = new BindingList(); 318 | 319 | ExpectedHeaders = new HashSet(StringComparer.OrdinalIgnoreCase) 320 | { 321 | "datetime,timestamp_desc,source,source_long,message,parser,display_name,tag" 322 | }; 323 | } 324 | 325 | public string Author => "Eric Zimmerman"; 326 | public string FileDescription => "CSV generated from Plaso in psort format"; 327 | public HashSet ExpectedHeaders { get; } 328 | 329 | public IBindingList DataList { get; } 330 | public List TaggedLines { get; set; } 331 | 332 | public string InternalGuid => "40ee3432-12eb-4612-a480-9a021e2a3353"; 333 | 334 | public void ProcessFile(string filename) 335 | { 336 | DataList.Clear(); 337 | 338 | using var fileReader = File.OpenText(filename); 339 | var config = new CsvConfiguration(CultureInfo.InvariantCulture) 340 | { 341 | BadDataFound = context => 342 | { 343 | Log.Warning("Bad data found in {Field}! Skipping. Raw data: {RawRecord}", context.Field, context.RawRecord); 344 | }, 345 | MissingFieldFound = null, 346 | Mode = CsvMode.Escape 347 | }; 348 | 349 | 350 | var csv = new CsvReader(fileReader, config); 351 | 352 | 353 | var foo = csv.Context.AutoMap(); 354 | 355 | foo.Map(t => t.Line).Ignore(); 356 | foo.Map(t => t.Tag).Ignore(); 357 | foo.Map(t => t.Color).Ignore(); 358 | foo.Map(t => t.Timestamp).Name("datetime"); 359 | foo.Map(t => t.TimestampDescription).Name("timestamp_desc"); 360 | foo.Map(t => t.Source).Name("source"); 361 | foo.Map(t => t.SourceLong).Name("source_long"); 362 | foo.Map(t => t.Message).Name("message"); 363 | foo.Map(t => t.Parser).Name("parser"); 364 | foo.Map(t => t.DisplayName).Name("display_name"); 365 | foo.Map(t => t.TagInfo).Name("tag"); 366 | 367 | 368 | var o = new TypeConverterOptions 369 | { 370 | DateTimeStyle = DateTimeStyles.AssumeUniversal & DateTimeStyles.AdjustToUniversal 371 | }; 372 | csv.Context.TypeConverterOptionsCache.AddOptions(o); 373 | 374 | csv.Context.RegisterClassMap(foo); 375 | 376 | csv.Read(); 377 | csv.ReadHeader(); 378 | 379 | 380 | 381 | var ln = 1; 382 | 383 | try 384 | { 385 | while (csv.Read()) 386 | { 387 | Log.Debug("Line # {Line}, Record: {RawRecord}", ln, csv.Context.Parser.RawRecord); 388 | 389 | // "datetime,timestamp_desc,source,source_long,message,parser,display_name,tag" 390 | // var dt = csv.GetField("date"); 391 | // 392 | // if (dt.StartsWith("Processing")) 393 | // { 394 | // break; 395 | // } 396 | 397 | var dt = csv.GetField("datetime"); 398 | var tsD = csv.GetField("timestamp_desc"); 399 | var source = csv.GetField("source"); 400 | var sourceLong = csv.GetField("source_long"); 401 | var message = csv.GetField("message"); 402 | var parser = csv.GetField("parser"); 403 | var displayName = csv.GetField("display_name"); 404 | var tag = csv.GetField("tag"); 405 | 406 | 407 | var psd = new PsortTimelineData(ln, dt, tsD, source, sourceLong, message, parser, displayName, tag); 408 | psd.Tag = TaggedLines.Contains(ln); 409 | DataList.Add(psd); 410 | ln += 1; 411 | } 412 | } 413 | catch (Exception e) 414 | { 415 | throw new Exception( 416 | $"Error loading data on line '{ln}': {e.Message}. Line: {csv.Context.Parser.RawRecord}", e); 417 | } 418 | } 419 | } 420 | 421 | 422 | //3333333333333333333333333333333333333333 423 | 424 | 425 | public class SuperTimelineData : IFileSpecData 426 | { 427 | public SuperTimelineData(int line, string date, string time, string tz, string macb, string sourceName, 428 | string sourceDesc, 429 | string type, string userName, string hostName, string shortDesc, string longDesc, string version, string 430 | fileName, int inode, string notes, string format, string extra) 431 | { 432 | Line = line; 433 | 434 | try 435 | { 436 | Timestamp = DateTime.ParseExact($"{date} {time}", "MM/dd/yyyy HH:mm:ss", CultureInfo.InvariantCulture, 437 | DateTimeStyles.AssumeUniversal).ToUniversalTime(); 438 | } 439 | catch (Exception) 440 | { 441 | Timestamp = DateTime.MinValue; 442 | } 443 | 444 | 445 | TimeZone = tz; 446 | var macbLower = macb.ToLowerInvariant(); 447 | 448 | var hasM = macbLower.Contains("m") ? 1 : 0; 449 | var hasA = macbLower.Contains("a") ? 2 : 0; 450 | var hasC = macbLower.Contains("c") ? 4 : 0; 451 | var hasB = macbLower.Contains("b") ? 8 : 0; 452 | 453 | 454 | Macb = macbLower; //tst.ToString(); 455 | 456 | SourceName = sourceName; 457 | SourceDescription = sourceDesc; 458 | Type = type; 459 | Username = userName; 460 | HostName = hostName; 461 | ShortDescription = shortDesc; 462 | LongDescription = longDesc; 463 | Version = version; 464 | FileName = fileName; 465 | Inode = inode; 466 | Notes = notes; 467 | Format = format; 468 | Extra = extra; 469 | 470 | if (longDesc == null) 471 | { 472 | return; 473 | } 474 | 475 | if (longDesc.Contains("RECYCLE") || 476 | longDesc.Contains("DELETED") || 477 | longDesc.Contains("Deleted Registry") || 478 | longDesc.Contains("$Recycle.Bin")) 479 | { 480 | Color = "DeletedData"; 481 | } 482 | 483 | if (longDesc.Contains("Expiration Time") || 484 | longDesc.Contains("Cookie") || 485 | longDesc.Contains("Visited") || 486 | longDesc.Contains("URL") && sourceName.Contains("FILE") == false || 487 | longDesc.Contains("Flash Cookie") || 488 | longDesc.Contains("LSO") && sourceName.Contains("REG") == false || 489 | longDesc.ToLowerInvariant().Contains("http://") || 490 | longDesc.ToLowerInvariant().Contains("https://") || 491 | longDesc.Contains("Location:") || 492 | longDesc.Contains("time(s) [HTTP") || 493 | longDesc.Contains("Last Visited Time") || 494 | sourceName.StartsWith("WEBHIST")) 495 | { 496 | Color = "WebHistory"; 497 | } 498 | 499 | 500 | if (longDesc.Contains("lnk/shell_items") || 501 | sourceDesc.Contains("File entry shell item") || 502 | longDesc.Contains("BagMRU") || 503 | longDesc.Contains("ShellNoRoam/Bags")) 504 | { 505 | Color = "FolderOpening"; 506 | } 507 | 508 | if (longDesc.Contains("visited file://") || 509 | longDesc.Contains("CreateDate") || 510 | longDesc.Contains("URL:file://") || 511 | longDesc.Contains("File Opened") || 512 | longDesc.Contains("Folder opened") || 513 | longDesc.Contains("Shortcut LNK") || 514 | longDesc.Contains("RecentDocs key") || 515 | longDesc.Contains("Link target:") || 516 | longDesc.Contains("File attribute flags") || 517 | longDesc.Contains("Birth droid volume identifier:") || 518 | longDesc.Contains("UserAssist entry") || 519 | longDesc.ToLowerInvariant().EndsWith(".lnk") || 520 | longDesc.Contains("Recently opened file") || 521 | longDesc.Contains("file of extension") || 522 | longDesc.Contains("Recently") && sourceDesc.Contains("Firefox") == false || 523 | longDesc.EndsWith("LNK") || 524 | longDesc.Contains("file://") && sourceDesc.Contains("Firefox") == false || 525 | longDesc.Contains("RecentDocs")) 526 | { 527 | Color = "FileOpening"; 528 | } 529 | 530 | if (longDesc.Contains("MountPoints2") || 531 | longDesc.Contains("volume mounted") || 532 | longDesc.Contains("USB") || 533 | longDesc.Contains("/USB/Vid_") || 534 | longDesc.Contains("Enum/USBSTOR/Disk") || 535 | longDesc.Contains("RemovableMedia") || 536 | longDesc.Contains("STORAGE/RemovableMedia") || 537 | longDesc.Contains("drive mounted") || 538 | longDesc.Contains("Drive last mounted") || 539 | longDesc.Contains("SetupAPI Log")) 540 | { 541 | Color = "Device|USBUsage"; 542 | } 543 | 544 | if (longDesc.Contains("EVT") || 545 | longDesc.Contains("XP Firewall Log") || 546 | longDesc.Contains("Event Level:") || 547 | sourceName.StartsWith("EVT") 548 | ) 549 | { 550 | Color = "LogFile"; 551 | } 552 | 553 | if (longDesc.Contains("Prefetch {") || 554 | longDesc.Contains("AppCompatCache") || 555 | longDesc.Contains(@"\Software\Sysinternals") || 556 | longDesc.Contains("typed the following cmd") || 557 | longDesc.Contains("CMD typed") || 558 | longDesc.Contains("Last run") || 559 | longDesc.Contains("RunMRU") || 560 | longDesc.Contains("MUICache") || 561 | longDesc.Contains("UserAssist key") || 562 | longDesc.Contains("Time of Launch") || 563 | longDesc.Contains("Prefetch") || 564 | longDesc.Contains("SHIMCACHE") || 565 | longDesc.Contains("Scheduled") || 566 | longDesc.ToLowerInvariant().EndsWith(".pf") || 567 | longDesc.Contains("was run") || 568 | longDesc.Contains("UEME_") || 569 | longDesc.StartsWith("[PROCESS]") 570 | ) 571 | { 572 | Color = "Execution"; 573 | } 574 | } 575 | 576 | public DateTime Timestamp { get; } 577 | public string TimeZone { get; } 578 | public string Macb { get; } 579 | public string SourceName { get; } 580 | public string SourceDescription { get; } 581 | public string Type { get; } 582 | public string Username { get; } 583 | public string HostName { get; } 584 | public string ShortDescription { get; } 585 | public string LongDescription { get; } 586 | public string Version { get; } 587 | public string FileName { get; } 588 | public int Inode { get; } 589 | public string Notes { get; } 590 | public string Format { get; } 591 | public string Extra { get; } 592 | 593 | public string Color { get; set; } 594 | 595 | public int Line { get; set; } 596 | public bool Tag { get; set; } 597 | 598 | public override string ToString() 599 | { 600 | return 601 | $"{Timestamp} {TimeZone} {Macb} {SourceName} {ShortDescription} {SourceDescription} {Type} {Username} {HostName} {ShortDescription} {LongDescription} {Version} {FileName} {Inode} {Notes} {Format} {Extra}"; 602 | } 603 | } 604 | 605 | public class SuperTimeline : IFileSpec 606 | { 607 | public SuperTimeline() 608 | { 609 | TaggedLines = new List(); 610 | 611 | DataList = new BindingList(); 612 | 613 | ExpectedHeaders = new HashSet(StringComparer.OrdinalIgnoreCase) 614 | { 615 | "date,time,timezone,macb,source,sourcetype,type,user,host,short,desc,version,filename,inode,notes,format,extra" 616 | }; 617 | } 618 | 619 | public string Author => "Eric Zimmerman"; 620 | public string FileDescription => "CSV generated from Plaso in L2TCsv format"; 621 | public HashSet ExpectedHeaders { get; } 622 | 623 | public IBindingList DataList { get; } 624 | public List TaggedLines { get; set; } 625 | 626 | public string InternalGuid => "40dd7405-16cf-4612-a480-9a021e2a3353"; 627 | 628 | public void ProcessFile(string filename) 629 | { 630 | DataList.Clear(); 631 | 632 | using var fileReader = File.OpenText(filename); 633 | var config = new CsvConfiguration(CultureInfo.InvariantCulture) 634 | { 635 | BadDataFound = null, 636 | MissingFieldFound = null 637 | }; 638 | 639 | 640 | var csv = new CsvReader(fileReader, config); 641 | 642 | 643 | var foo = csv.Context.AutoMap(); 644 | 645 | foo.Map(t => t.Line).Ignore(); 646 | foo.Map(t => t.Tag).Ignore(); 647 | foo.Map(t => t.Color).Ignore(); 648 | foo.Map(t => t.Timestamp).Name("date"); 649 | foo.Map(t => t.TimeZone).Name("timezone"); 650 | foo.Map(t => t.Macb).Name("macb"); 651 | foo.Map(t => t.SourceName).Name("source"); 652 | foo.Map(t => t.ShortDescription).Name("sourcetype"); 653 | foo.Map(t => t.Timestamp).Name("sourcetype"); 654 | foo.Map(t => t.Type).Name("type"); 655 | foo.Map(t => t.Username).Name("user"); 656 | foo.Map(t => t.HostName).Name("host"); 657 | foo.Map(t => t.ShortDescription).Name("short"); 658 | foo.Map(t => t.LongDescription).Name("desc"); 659 | foo.Map(t => t.Version).Name("version"); 660 | foo.Map(t => t.FileName).Name("filename"); 661 | foo.Map(t => t.Inode).Name("inode"); 662 | foo.Map(t => t.Notes).Name("notes"); 663 | foo.Map(t => t.Format).Name("format"); 664 | foo.Map(t => t.Extra).Name("extra"); 665 | 666 | var o = new TypeConverterOptions 667 | { 668 | DateTimeStyle = DateTimeStyles.AssumeUniversal & DateTimeStyles.AdjustToUniversal 669 | }; 670 | csv.Context.TypeConverterOptionsCache.AddOptions(o); 671 | 672 | csv.Context.RegisterClassMap(foo); 673 | 674 | csv.Read(); 675 | csv.ReadHeader(); 676 | 677 | 678 | 679 | var ln = 1; 680 | 681 | try 682 | { 683 | while (csv.Read()) 684 | { 685 | Log.Debug("Line # {Line}, Record: {RawRecord}", ln, csv.Context.Parser.RawRecord); 686 | 687 | //"date,time,timezone,macb,source,sourcetype,type,user,host,short,desc,version,filename,inode,notes,format,extra": 688 | var dt = csv.GetField("date"); 689 | 690 | if (dt.StartsWith("Processing")) 691 | { 692 | break; 693 | } 694 | 695 | var time = csv.GetField("time"); 696 | var tz = csv.GetField("timezone"); 697 | var macb = csv.GetField("MACB"); 698 | var sourceName = csv.GetField("source"); 699 | var sourceDesc = csv.GetField("sourcetype"); 700 | var type = csv.GetField("type"); 701 | var username = csv.GetField("user"); 702 | var hostname = csv.GetField("host"); 703 | var shortDesc = csv.GetField("short"); 704 | var longDesc = csv.GetField("desc"); 705 | var version = csv.GetField("version"); 706 | var filename1 = csv.GetField("filename"); 707 | var inodeRaw = csv.GetField("inode"); 708 | var notes = csv.GetField("notes"); 709 | var format = csv.GetField("format"); 710 | var extra = csv.GetField("extra"); 711 | 712 | int.TryParse(inodeRaw, out var inode); 713 | 714 | var lfe = new SuperTimelineData(ln, dt, time, tz, macb, sourceName, sourceDesc, type, 715 | username, hostname, shortDesc, longDesc, version, filename1, inode, notes, format, 716 | extra); 717 | lfe.Tag = TaggedLines.Contains(ln); 718 | DataList.Add(lfe); 719 | ln += 1; 720 | } 721 | } 722 | catch (Exception e) 723 | { 724 | throw new Exception( 725 | $"Error loading data on line '{ln}': {e.Message}. Line: {csv.Context.Parser.RawRecord}", e); 726 | } 727 | } 728 | } 729 | 730 | public class MacTimeData : IFileSpecData 731 | { 732 | [Flags] 733 | public enum TimestampType 734 | { 735 | Modified = 0x1, 736 | Accessed = 0x2, 737 | Changed = 0x4, 738 | Born = 0x8 739 | } 740 | 741 | public MacTimeData() 742 | { 743 | } 744 | 745 | public MacTimeData(int line, DateTime? timestamp, long fileSize, string macb, string permissions, 746 | string uid, 747 | string gid, 748 | string meta, string filename) 749 | { 750 | //Mon Apr 02 2012 00:46:02,1938,m...,r/rrwxrwxrwx,0,0,51206-128-4,"C:/Users/nromanoff/AppData/LocalLow/Microsoft/CryptnetUrlCache/Content/F4B372709D6C2AD766C34D274501DC76_516445E2D2E0044FF0510B085B354A0C" 751 | 752 | Line = line; 753 | 754 | Timestamp = timestamp; 755 | 756 | FileSize = fileSize; 757 | 758 | Macb = macb; //tst.ToString(); 759 | Permissions = permissions; 760 | UId = uid; 761 | GId = gid; 762 | Meta = meta; 763 | FileName = filename.TrimStart('"').TrimEnd('"'); 764 | } 765 | 766 | public DateTime? Timestamp { get; set; } 767 | 768 | 769 | public long FileSize { get; set; } 770 | public string Macb { get; set; } 771 | public string Permissions { get; set; } 772 | public string UId { get; set; } 773 | public string GId { get; set; } 774 | public string Meta { get; set; } 775 | public string FileName { get; set; } 776 | 777 | 778 | public string Color { get; set; } 779 | 780 | public int Line { get; set; } 781 | public bool Tag { get; set; } 782 | 783 | public override string ToString() 784 | { 785 | return $"{Timestamp} {Macb} {Permissions} {UId} {GId} {Meta} {FileName} {FileSize}"; 786 | } 787 | 788 | 789 | public void UpdateColor() 790 | { 791 | if ( 792 | FileName.Contains("$Recycle.Bin")) 793 | { 794 | Color = "DeletedData"; 795 | } 796 | 797 | if (FileName.StartsWith("[IEHISTORY]")) 798 | { 799 | Color = "WebHistory"; 800 | } 801 | 802 | 803 | if (FileName.ToLowerInvariant().Contains(".lnk")) 804 | { 805 | Color = "FileOpening"; 806 | } 807 | 808 | if (FileName.StartsWith("[SHIMCACHE]") || 809 | FileName.ToLowerInvariant().EndsWith(".pf") || 810 | FileName.StartsWith(@"[USER ASSIST]") || 811 | FileName.StartsWith("[PROCESS]")) 812 | { 813 | Color = "Execution"; 814 | } 815 | } 816 | } 817 | 818 | public class MacTime : IFileSpec 819 | { 820 | public MacTime() 821 | { 822 | TaggedLines = new List(); 823 | 824 | DataList = new BindingList(); 825 | 826 | ExpectedHeaders = new HashSet(StringComparer.OrdinalIgnoreCase) 827 | { 828 | "date,size,type,mode,uid,gid,meta,file name" 829 | }; 830 | } 831 | 832 | public string Author => "Eric Zimmerman"; 833 | public string FileDescription => "CSV generated from bodyfile and mactime"; 834 | public HashSet ExpectedHeaders { get; } 835 | 836 | public IBindingList DataList { get; } 837 | public List TaggedLines { get; set; } 838 | 839 | public string InternalGuid => "30877d57-540d-4460-bc4e-859fee4b0aac"; 840 | 841 | public void ProcessFile(string filename) 842 | { 843 | DataList.Clear(); 844 | 845 | using var fileReader = File.OpenText(filename); 846 | var csv = new CsvReader(fileReader, CultureInfo.InvariantCulture); 847 | 848 | var foo = csv.Context.AutoMap(); 849 | 850 | var o = new TypeConverterOptions 851 | { 852 | DateTimeStyle = DateTimeStyles.AssumeUniversal & DateTimeStyles.AdjustToUniversal & 853 | DateTimeStyles.AdjustToUniversal 854 | }; 855 | csv.Context.TypeConverterOptionsCache.AddOptions(o); 856 | 857 | foo.Map(t => t.Line).Ignore(); 858 | foo.Map(t => t.Tag).Ignore(); 859 | foo.Map(t => t.Color).Ignore(); 860 | // 861 | foo.Map(t => t.Timestamp).Name("Date"); 862 | foo.Map(m => m.Timestamp).Convert(row => 863 | DateTime.TryParse(row.Row.Context.Parser.Record[0], CultureInfo.InvariantCulture, 864 | DateTimeStyles.AssumeUniversal, out var outDate) 865 | ? outDate.ToUniversalTime() 866 | : new DateTime?()); 867 | foo.Map(m => m.Timestamp).TypeConverterOption.DateTimeStyles(DateTimeStyles.AssumeUniversal); 868 | 869 | foo.Map(t => t.FileSize).Name("Size"); 870 | foo.Map(t => t.Macb).Name("Type"); 871 | foo.Map(t => t.Permissions).Name("Mode"); 872 | foo.Map(t => t.UId).Name("UID"); 873 | foo.Map(t => t.GId).Name("GID"); 874 | foo.Map(t => t.Meta).Name("Meta"); 875 | foo.Map(t => t.FileName).Name("File Name"); 876 | 877 | csv.Context.RegisterClassMap(foo); 878 | 879 | csv.Read(); 880 | csv.ReadHeader(); 881 | 882 | 883 | 884 | var ln = 1; 885 | while (csv.Read()) 886 | { 887 | Log.Debug("Line # {Line}, Record: {RawRecord}", ln, csv.Context.Parser.RawRecord); 888 | 889 | var f = csv.GetRecord(); 890 | f.Line = ln; 891 | f.Tag = TaggedLines.Contains(ln); 892 | if (f.Timestamp != null && f.Timestamp?.Year == 1) 893 | { 894 | f.Timestamp = null; 895 | } 896 | 897 | f.UpdateColor(); 898 | 899 | DataList.Add(f); 900 | 901 | ln += 1; 902 | } 903 | } 904 | } 905 | 906 | 907 | 908 | public class KapeMiniTimelineData : IFileSpecData 909 | { 910 | public DateTime Timestamp { get; set; } 911 | 912 | public string DataType { get; set; } 913 | public string ComputerName { get; set; } 914 | public string UserSource { get; set; } 915 | public string Message { get; set; } 916 | 917 | 918 | public int Line { get; set; } 919 | public bool Tag { get; set; } 920 | 921 | public override string ToString() 922 | { 923 | return $"{Timestamp} {DataType} {ComputerName} {UserSource} {Message}"; 924 | } 925 | 926 | } 927 | 928 | public class KapeMiniTimeline : IFileSpec 929 | { 930 | public KapeMiniTimeline() 931 | { 932 | TaggedLines = new List(); 933 | 934 | DataList = new BindingList(); 935 | 936 | ExpectedHeaders = new HashSet(StringComparer.OrdinalIgnoreCase) 937 | { 938 | "Time,Type,ComputerName,User/Source,Message" 939 | }; 940 | } 941 | 942 | public string Author => "Eric Zimmerman"; 943 | public string FileDescription => "CSV generated from KAPE Mini timeline module"; 944 | public HashSet ExpectedHeaders { get; } 945 | 946 | public IBindingList DataList { get; } 947 | public List TaggedLines { get; set; } 948 | 949 | public string InternalGuid => "12855d57-540d-4460-bc4e-859fee4b0aac"; 950 | 951 | public void ProcessFile(string filename) 952 | { 953 | DataList.Clear(); 954 | 955 | using var fileReader = File.OpenText(filename); 956 | var csvO = new CsvConfiguration(CultureInfo.InvariantCulture) 957 | { 958 | 959 | }; 960 | 961 | var csv = new CsvReader(fileReader, csvO); 962 | 963 | 964 | 965 | var foo = csv.Context.AutoMap(); 966 | 967 | var o = new TypeConverterOptions 968 | { 969 | DateTimeStyle = DateTimeStyles.AssumeUniversal & DateTimeStyles.AdjustToUniversal & 970 | DateTimeStyles.AdjustToUniversal 971 | }; 972 | csv.Context.TypeConverterOptionsCache.AddOptions(o); 973 | 974 | foo.Map(t => t.Line).Ignore(); 975 | foo.Map(t => t.Tag).Ignore(); 976 | 977 | foo.Map(t => t.Timestamp).Name("Time"); 978 | foo.Map(t => t.DataType).Name("Type"); 979 | 980 | foo.Map(m => m.Timestamp).TypeConverterOption.DateTimeStyles(DateTimeStyles.AssumeUniversal); 981 | 982 | foo.Map(t => t.UserSource).Name("User/Source"); 983 | 984 | csv.Context.RegisterClassMap(foo); 985 | 986 | csv.Read(); 987 | csv.ReadHeader(); 988 | 989 | var ln = 1; 990 | while (csv.Read()) 991 | { 992 | Log.Debug("Line # {Line}, Record: {RawRecord}", ln, csv.Context.Parser.RawRecord); 993 | 994 | var testStr = csv.GetField(0); 995 | 996 | if (DateTime.TryParse(testStr, out var s) == false) 997 | { 998 | Log.Warning("Bad data found! Skipping. Raw data: {RawRecord}", csv.Context.Parser.RawRecord); 999 | continue; 1000 | } 1001 | 1002 | var f = csv.GetRecord(); 1003 | f.Line = ln; 1004 | f.Tag = TaggedLines.Contains(ln); 1005 | 1006 | 1007 | DataList.Add(f); 1008 | 1009 | ln += 1; 1010 | } 1011 | } 1012 | } 1013 | } -------------------------------------------------------------------------------- /TLEFileTzWorks/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.InteropServices; 2 | 3 | // Setting ComVisible to false makes the types in this assembly not visible 4 | // to COM components. If you need to access a type in this assembly from 5 | // COM, set the ComVisible attribute to true on that type. 6 | [assembly: ComVisible(false)] 7 | 8 | // The following GUID is for the ID of the typelib if this project is exposed to COM 9 | [assembly: Guid("3f975021-89c4-4e63-b342-dcca4af5f1bc")] 10 | -------------------------------------------------------------------------------- /TLEFileTzWorks/TLEFileTzWorks.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | netstandard2.0 4 | TLEFileTzWorks 5 | TLEFileTzWorks 6 | Eric Zimmerman 7 | 10 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /TLEFileTzWorks/TZWorks.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Globalization; 5 | using System.IO; 6 | using CsvHelper; 7 | using CsvHelper.Configuration; 8 | using CsvHelper.TypeConversion; 9 | using ITLEFileSpec; 10 | using Serilog; 11 | using ServiceStack; 12 | 13 | namespace TLEFileTzWorks 14 | { 15 | public class PeScanOutData : IFileSpecData 16 | { 17 | public DateTime? CompiledTime { get; set; } 18 | public DateTime CreatedTime { get; set; } 19 | public DateTime AccessedTime { get; set; } 20 | public DateTime ModifiedTime { get; set; } 21 | 22 | public int Size { get; set; } 23 | public string FileType { get; set; } 24 | public string CPU { get; set; } 25 | 26 | public float Linker { get; set; } 27 | public string CodeSize { get; set; } 28 | public string InitData { get; set; } 29 | public string UInitData { get; set; } 30 | public string ImageVer { get; set; } 31 | public string SubsysVer { get; set; } 32 | public string MinimumOS { get; set; } 33 | 34 | public int EntryOva { get; set; } 35 | 36 | public int EntryFAddress { get; set; } 37 | public ulong ImageBase { get; set; } 38 | public bool Signed { get; set; } 39 | public bool CheckSum { get; set; } 40 | 41 | public string MD5 { get; set; } 42 | public string Company { get; set; } 43 | public string FilePath { get; set; } 44 | 45 | public int Rating { get; set; } 46 | public string Notes { get; set; } 47 | public string PeId { get; set; } 48 | public string SymbolFile { get; set; } 49 | 50 | public int Line { get; set; } 51 | public bool Tag { get; set; } 52 | 53 | public override string ToString() 54 | { 55 | return 56 | $"{CompiledTime} {CreatedTime} {AccessedTime} {ModifiedTime} {Size} {FileType} {CPU} {Linker} {CodeSize} {InitData} {UInitData} {ImageVer} {SubsysVer} {MinimumOS} {EntryOva} {EntryFAddress} {ImageBase} {Signed} {CheckSum} {MD5} {Company} {FilePath} {Rating} {Notes} {PeId} {SymbolFile}"; 57 | } 58 | } 59 | 60 | 61 | public class PeScan : IFileSpec 62 | { 63 | public PeScan() 64 | { 65 | //Initialize collections here, one for TaggedLines TLE can add values to, and the collection that TLE will display 66 | TaggedLines = new List(); 67 | 68 | DataList = new BindingList(); 69 | 70 | ExpectedHeaders = new HashSet(StringComparer.OrdinalIgnoreCase) 71 | { 72 | "compiled,time-UTC,created,time-UTC,access,time-UTC,modify,time-UTC,size,type,cpu,linker,code size,init data,uninit data,image ver,subsys ver,min OS,entry rva,entryfaddr,imagebase,cert,chksum,md5,company,file,rating,notes,PEiD,symbol file" 73 | }; 74 | } 75 | 76 | public string Author => "Eric Zimmerman"; 77 | public string FileDescription => "CSV generated from pescan"; 78 | public HashSet ExpectedHeaders { get; } 79 | 80 | public IBindingList DataList { get; } 81 | public List TaggedLines { get; set; } 82 | 83 | public string InternalGuid => "30877d57-540d-4460-bc4e-859fee4b0bbc"; 84 | 85 | public void ProcessFile(string filename) 86 | { 87 | DataList.Clear(); 88 | 89 | using var fileReader = File.OpenText(filename); 90 | var config = new CsvConfiguration(CultureInfo.InvariantCulture) 91 | { 92 | BadDataFound = null, 93 | }; 94 | 95 | var csv = new CsvReader(fileReader, config); 96 | 97 | 98 | var o = new TypeConverterOptions 99 | { 100 | DateTimeStyle = DateTimeStyles.AssumeUniversal & DateTimeStyles.AdjustToUniversal 101 | }; 102 | csv.Context.TypeConverterOptionsCache.AddOptions(o); 103 | 104 | 105 | csv.Read(); 106 | 107 | if (csv.Context.Parser.RawRecord.StartsWith("pescan - ")) 108 | { 109 | //dumb ass non-csv, so skip it 110 | csv.Read(); 111 | csv.Read(); 112 | csv.Read(); 113 | csv.Read(); 114 | } 115 | 116 | 117 | 118 | csv.ReadHeader(); 119 | 120 | 121 | 122 | var ln11 = 1; 123 | while (csv.Read()) 124 | { 125 | Log.Debug("Line # {Line}, Record: {Record}",ln11,csv.Context.Parser.RawRecord); 126 | 127 | var compiled = csv.GetField(0); 128 | var compTime = csv.GetField(1); 129 | var created = csv.GetField(2); 130 | var createdTime = csv.GetField(3); 131 | var accessd = csv.GetField(4); 132 | var accessedTime = csv.GetField(5); 133 | var modified = csv.GetField(6); 134 | var modTime = csv.GetField(7); 135 | var size = csv.GetField(8); 136 | var fileType = csv.GetField(9); 137 | var cpu = csv.GetField(10); 138 | var linker = csv.GetField(11); 139 | var codeSize = csv.GetField(12); 140 | var initData = csv.GetField(13); 141 | var uinitData = csv.GetField(14); 142 | var imageVer = csv.GetField(15); 143 | var subsysVer = csv.GetField(16); 144 | var minOs = csv.GetField(17); 145 | var entryRva = csv.GetField(18); 146 | var entryfAddr = csv.GetField(19); 147 | var imagebase = csv.GetField(20); 148 | var cert = csv.GetField(21); 149 | var checksum = csv.GetField(22); 150 | var md5 = csv.GetField(23); 151 | var company = csv.GetField(24); 152 | var file = csv.GetField(25); 153 | var rating = csv.GetField(26); 154 | var notes = csv.GetField(27); 155 | var peid = csv.GetField(28); 156 | var symbolFile = csv.GetField(29); 157 | 158 | var pe = new PeScanOutData {Line = ln11}; 159 | pe.Tag = TaggedLines.Contains(ln11); 160 | if (compiled.Length > 0) 161 | { 162 | pe.CompiledTime = DateTime.Parse($"{compiled} {compTime}", CultureInfo.InvariantCulture, 163 | DateTimeStyles.AssumeUniversal) 164 | .ToUniversalTime(); 165 | } 166 | 167 | pe.CreatedTime = DateTime.Parse($"{created} {createdTime}", CultureInfo.InvariantCulture, 168 | DateTimeStyles.AssumeUniversal) 169 | .ToUniversalTime(); 170 | pe.AccessedTime = DateTime.Parse($"{accessd} {accessedTime}", CultureInfo.InvariantCulture, 171 | DateTimeStyles.AssumeUniversal) 172 | .ToUniversalTime(); 173 | pe.ModifiedTime = DateTime 174 | .Parse($"{modified} {modTime}", null, DateTimeStyles.AssumeUniversal) 175 | .ToUniversalTime(); 176 | 177 | pe.Size = int.Parse(size); 178 | pe.FileType = fileType; 179 | pe.CPU = cpu; 180 | if (linker.Length > 0) 181 | { 182 | pe.Linker = float.Parse(linker); 183 | } 184 | 185 | pe.CodeSize = codeSize; 186 | pe.InitData = initData; 187 | pe.UInitData = uinitData; 188 | pe.ImageVer = imageVer; 189 | pe.SubsysVer = subsysVer; 190 | pe.SymbolFile = symbolFile; 191 | pe.PeId = peid; 192 | 193 | pe.MinimumOS = minOs; 194 | if (entryRva.Length > 0) 195 | { 196 | pe.EntryOva = int.Parse(entryRva); 197 | } 198 | 199 | if (entryfAddr.Length > 0) 200 | { 201 | pe.EntryFAddress = int.Parse(entryfAddr); 202 | } 203 | 204 | if (imagebase.Length > 0) 205 | { 206 | pe.ImageBase = ulong.Parse(imagebase); 207 | } 208 | 209 | pe.Signed = cert.Equals("yes"); 210 | pe.CheckSum = checksum.Equals("yes"); 211 | pe.MD5 = md5; 212 | pe.Company = company; 213 | pe.FilePath = file; 214 | pe.Rating = int.Parse(rating); 215 | pe.Notes = notes; 216 | 217 | DataList.Add(pe); 218 | ln11 += 1; 219 | } 220 | } 221 | } 222 | 223 | public class WispOutData : IFileSpecData 224 | { 225 | public ulong? MftEntry { get; set; } 226 | public ulong? MftSequence { get; set; } 227 | public ulong ParentEntry { get; set; } 228 | public ulong ParentSequence { get; set; } 229 | public string EntryType { get; set; } 230 | public DateTime? AccessedTime { get; set; } 231 | public DateTime? ModifiedTime { get; set; } 232 | public DateTime? CreatedTime { get; set; } 233 | public DateTime? RecordChangedTime { get; set; } 234 | public string FileType { get; set; } 235 | public ulong SizeReserved { get; set; } 236 | public ulong SizeUsed { get; set; } 237 | public string Flags { get; set; } 238 | public string Name { get; set; } 239 | public string Comment { get; set; } 240 | 241 | 242 | public int Line { get; set; } 243 | public bool Tag { get; set; } 244 | 245 | public override string ToString() 246 | { 247 | return 248 | $"{MftEntry} {MftSequence} {ParentEntry} {ParentSequence} {EntryType} {AccessedTime} {ModifiedTime} {CreatedTime} {RecordChangedTime} {FileType} {SizeReserved} {SizeUsed} {Flags} {Name} {Comment}"; 249 | } 250 | } 251 | 252 | public class Wisp : IFileSpec 253 | { 254 | public Wisp() 255 | { 256 | //Initialize collections here, one for TaggedLines TLE can add values to, and the collection that TLE will display 257 | TaggedLines = new List(); 258 | 259 | DataList = new BindingList(); 260 | 261 | ExpectedHeaders = new HashSet(StringComparer.OrdinalIgnoreCase) 262 | { 263 | "mft entry,mft seq,parent mft,seqnum,type,file mdate,time-UTC,file adate,time-UTC,mftdate,time-UTC,file cdate,time-UTC,dir/file,size resv,size used,flags,name,slack comment" 264 | }; 265 | } 266 | 267 | public string Author => "Eric Zimmerman"; 268 | public string FileDescription => "CSV generated from Wisp"; 269 | public HashSet ExpectedHeaders { get; } 270 | 271 | public IBindingList DataList { get; } 272 | public List TaggedLines { get; set; } 273 | 274 | public string InternalGuid => "30877d57-120e-4460-bc4e-859fee4b0aac"; 275 | 276 | public void ProcessFile(string filename) 277 | { 278 | DataList.Clear(); 279 | 280 | int rawFlag; 281 | using var fileReader = File.OpenText(filename); 282 | var csv = new CsvReader(fileReader, CultureInfo.InvariantCulture); 283 | 284 | 285 | var o = new TypeConverterOptions 286 | { 287 | DateTimeStyle = DateTimeStyles.AssumeUniversal & DateTimeStyles.AdjustToUniversal 288 | }; 289 | csv.Context.TypeConverterOptionsCache.AddOptions(o); 290 | 291 | csv.Read(); 292 | 293 | if (csv.Context.Parser.RawRecord.StartsWith("wisp - ")) 294 | { 295 | //dumb ass non-csv, so skip it 296 | csv.Read(); 297 | csv.Read(); 298 | csv.Read(); 299 | csv.Read(); 300 | } 301 | 302 | csv.ReadHeader(); 303 | 304 | 305 | var ln11 = 1; 306 | while (csv.Read()) 307 | { 308 | Log.Debug("Line # {Line}, Record: {RawRecord}",ln11,csv.Context.Parser.RawRecord); 309 | 310 | var mftEntry = csv.GetField(0); 311 | var mftSeq = csv.GetField(1); 312 | var parentMftEntry = csv.GetField(2); 313 | var parentMftSeq = csv.GetField(3); 314 | var entryType = csv.GetField(4); 315 | var modified = csv.GetField(5); 316 | var modTime = csv.GetField(6); 317 | var accessd = csv.GetField(7); 318 | var accessedTime = csv.GetField(8); 319 | var recordChanged = csv.GetField(9); 320 | var recordChangedTime = csv.GetField(10); 321 | var created = csv.GetField(11); 322 | var createTime = csv.GetField(12); 323 | 324 | var fileType = csv.GetField(13); 325 | var sizeRes = csv.GetField(14); 326 | var sizeAct = csv.GetField(15); 327 | var flags = csv.GetField(16); 328 | var name = csv.GetField(17); 329 | var comment = csv.GetField(18); 330 | 331 | 332 | var wi = new WispOutData 333 | { 334 | Line = ln11 335 | }; 336 | 337 | wi.Tag = TaggedLines.Contains(ln11); 338 | 339 | if (created.IsNullOrEmpty() == false) 340 | { 341 | wi.CreatedTime = DateTime.Parse($"{created} {createTime}", CultureInfo.InvariantCulture, 342 | DateTimeStyles.AssumeUniversal) 343 | .ToUniversalTime(); 344 | } 345 | 346 | if (recordChanged.IsNullOrEmpty() == false) 347 | { 348 | wi.RecordChangedTime = DateTime.Parse($"{recordChanged} {recordChangedTime}", 349 | CultureInfo.InvariantCulture, 350 | DateTimeStyles.AssumeUniversal) 351 | .ToUniversalTime(); 352 | } 353 | 354 | if (accessd.IsNullOrEmpty() == false) 355 | { 356 | wi.AccessedTime = DateTime.Parse($"{accessd} {accessedTime}", CultureInfo.InvariantCulture, 357 | DateTimeStyles.AssumeUniversal) 358 | .ToUniversalTime(); 359 | } 360 | 361 | if (modified.IsNullOrEmpty() == false) 362 | { 363 | wi.ModifiedTime = DateTime 364 | .Parse($"{modified} {modTime}", null, DateTimeStyles.AssumeUniversal) 365 | .ToUniversalTime(); 366 | } 367 | 368 | if (mftEntry.Length > 0) 369 | { 370 | wi.MftEntry = ulong.Parse(mftEntry); 371 | } 372 | 373 | if (mftSeq.Length > 0) 374 | { 375 | wi.MftSequence = ulong.Parse(mftSeq); 376 | } 377 | 378 | if (parentMftEntry.Length > 0) 379 | { 380 | wi.ParentEntry = ulong.Parse(parentMftEntry); 381 | } 382 | 383 | if (parentMftSeq.Length > 0) 384 | { 385 | wi.ParentSequence = ulong.Parse(parentMftSeq); 386 | } 387 | 388 | wi.EntryType = entryType; 389 | if (fileType == "dir") 390 | { 391 | wi.FileType = "Directory"; 392 | } 393 | else 394 | { 395 | wi.FileType = "File"; 396 | } 397 | 398 | 399 | if (sizeAct.Length > 0) 400 | { 401 | wi.SizeUsed = ulong.Parse(sizeAct); 402 | } 403 | 404 | if (sizeRes.Length > 0) 405 | { 406 | wi.SizeReserved = ulong.Parse(sizeRes); 407 | } 408 | 409 | if (flags.Length > 0) 410 | { 411 | var rawNum = flags.Replace("0x", ""); 412 | 413 | 414 | var valOk = int.TryParse(rawNum, NumberStyles.HexNumber, CultureInfo.InvariantCulture, 415 | out rawFlag); 416 | 417 | if (valOk) 418 | { 419 | wi.Flags = ((FileFlag) rawFlag).ToString().Replace(", ", " | "); 420 | } 421 | } 422 | 423 | wi.Name = name; 424 | wi.Comment = comment; 425 | 426 | 427 | DataList.Add(wi); 428 | ln11 += 1; 429 | } 430 | } 431 | } 432 | 433 | [Flags] 434 | public enum FileFlag 435 | { 436 | ReadOnly = 0x01, 437 | Hidden = 0x02, 438 | System = 0x04, 439 | VolumeLabel = 0x08, 440 | Directory = 0x010, 441 | Archive = 0x020, 442 | Device = 0x040, 443 | Normal = 0x080, 444 | Temporary = 0x0100, 445 | SparseFile = 0x0200, 446 | ReparsePoint = 0x0400, 447 | Compressed = 0x0800, 448 | Offline = 0x01000, 449 | NotContentIndexed = 0x02000, 450 | Encrypted = 0x04000, 451 | IntegrityStream = 0x08000, 452 | Virtual = 0x010000, 453 | NoScrubData = 0x020000, 454 | HasEa = 0x040000, 455 | IsDirectory = 0x10000000, 456 | IsIndexView = 0x20000000 457 | } 458 | } --------------------------------------------------------------------------------