public void SimpleFile()
        {
            byte[] randomData = new byte[65 * 4096];
            _random.NextBytes(randomData);

            using (TempFile tmpFile = new TempFile())
            {
                // Create a file
                File.WriteAllBytes(tmpFile.File.FullName, randomData);

                // Discover it via the NTFS lib
                char    driveLetter = tmpFile.File.FullName[0];
                RawDisk disk        = new RawDisk(driveLetter);

                NTFSDiskProvider provider = new NTFSDiskProvider(disk);

                NTFSWrapper ntfsWrapper = new NTFSWrapper(provider, 0);

                NtfsDirectory ntfsDir  = NTFSHelpers.OpenDir(ntfsWrapper, tmpFile.File.DirectoryName);
                NtfsFile      ntfsFile = NTFSHelpers.OpenFile(ntfsDir, tmpFile.File.Name);

                Assert.IsNotNull(ntfsFile);

                // Read it
                using (Stream actualStream = File.OpenRead(tmpFile.File.FullName))
                    using (Stream ntfsStream = ntfsFile.OpenRead())
                    {
                        bool equal = StreamUtils.CompareStreams(actualStream, ntfsStream);

                        Assert.IsTrue(equal);
                    }
            }
        }
Example #2
0
        public IActionResult Get([FromQuery] string id)
        {
            var req = id;

            if (Regex.IsMatch(id, @"^([a-zA-Z]\:)\/") || Regex.IsMatch(id, @"^([a-zA-Z]\:)\\"))
            {
                id = id;
            }
            else
            {
                //id = @"\\" + (id.Replace("/", "\\"));
                id = @"\\" + (id.Replace(@"/", @"\"));
            }
            var    file   = new NtfsFile(id);
            var    result = new vmNtfsFile(file, appConfiguration.ApiRootUrl, req);
            string json   = JsonConvert.SerializeObject(result, Formatting.Indented);

            json = json.Replace(@"\\", @"\");
            return(new ContentResult
            {
                Content = json,
                ContentType = "application/json",
                StatusCode = 200
            });
        }
Example #3
0
        public static NtfsFile OpenFile(NtfsDirectory dir, string file)
        {
            NtfsFile currFile = dir.ListFiles(false).SingleOrDefault(s => s.Name.Equals(file, StringComparison.InvariantCultureIgnoreCase));

            Debug.Assert(currFile != null);

            return(currFile);
        }
        public void SparseFile()
        {
            byte[] randomData = new byte[35 * 4096];
            _random.NextBytes(randomData);

            // Clear the 16 * 4096 -> 32 * 4096 range
            Array.Clear(randomData, 16 * 4096, 16 * 4096);

            using (TempFile tmpFile = new TempFile())
            {
                // Create a file
                File.WriteAllBytes(tmpFile.File.FullName, randomData);

                using (FilesystemDeviceWrapper wrapper = Win32.GetFileWrapper(tmpFile.File.FullName))
                {
                    wrapper.FileSystemSetSparseFile(true);
                    wrapper.FileSystemSetZeroData(16 * 4096, 16 * 4096);

                    FILE_ALLOCATED_RANGE_BUFFER[] rangesData = wrapper.FileSystemQueryAllocatedRanges(0, randomData.Length);

                    // We should have 2 ranges on non-zero data
                    Assert.AreEqual(2, rangesData.Length);
                }

                // Discover it via the NTFS lib
                char    driveLetter = tmpFile.File.FullName[0];
                RawDisk disk        = new RawDisk(driveLetter);

                NTFSDiskProvider provider = new NTFSDiskProvider(disk);

                NTFSWrapper ntfsWrapper = new NTFSWrapper(provider, 0);

                NtfsDirectory ntfsDir  = NTFSHelpers.OpenDir(ntfsWrapper, tmpFile.File.DirectoryName);
                NtfsFile      ntfsFile = NTFSHelpers.OpenFile(ntfsDir, tmpFile.File.Name);

                Assert.IsNotNull(ntfsFile);
                Assert.IsTrue(tmpFile.File.Attributes.HasFlag(FileAttributes.SparseFile));
                AttributeData attributeData = ntfsFile.MFTRecord.Attributes.OfType <AttributeData>().Single();
                Assert.IsTrue(attributeData.DataFragments.Length > 1);
                Assert.IsTrue(attributeData.DataFragments.Any(s => s.IsSparseFragment));

                // Read it
                using (Stream actualStream = File.OpenRead(tmpFile.File.FullName))
                    using (Stream ntfsStream = ntfsFile.OpenRead())
                    {
                        bool equal = StreamUtils.CompareStreams(actualStream, ntfsStream);

                        Assert.IsTrue(equal);
                    }
            }
        }
        public void CompressedFile()
        {
            using (TempFile tmpFile = new TempFile())
            {
                // Create a file
                // Write file data
                using (FileStream fs = File.OpenWrite(tmpFile.File.FullName))
                {
                    byte[] data = Encoding.ASCII.GetBytes("The white bunny jumps over the brown dog in a carparking lot");

                    for (int i = 0; i < 20000; i++)
                    {
                        fs.Write(data, 0, data.Length);
                    }
                }

                using (FilesystemDeviceWrapper wrapper = Win32.GetFileWrapper(tmpFile.File.FullName))
                {
                    wrapper.FileSystemSetCompression(COMPRESSION_FORMAT.LZNT1);
                }

                // Discover it via the NTFS lib
                char    driveLetter = tmpFile.File.FullName[0];
                RawDisk disk        = new RawDisk(driveLetter);

                NTFSDiskProvider provider = new NTFSDiskProvider(disk);

                NTFSWrapper ntfsWrapper = new NTFSWrapper(provider, 0);

                NtfsDirectory ntfsDir  = NTFSHelpers.OpenDir(ntfsWrapper, tmpFile.File.DirectoryName);
                NtfsFile      ntfsFile = NTFSHelpers.OpenFile(ntfsDir, tmpFile.File.Name);

                Assert.IsNotNull(ntfsFile);
                Assert.IsTrue(tmpFile.File.Attributes.HasFlag(FileAttributes.Compressed));
                AttributeData attributeData = ntfsFile.MFTRecord.Attributes.OfType <AttributeData>().Single();
                Assert.IsTrue(attributeData.DataFragments.Any(s => s.IsCompressed));

                // Read it
                using (Stream actualStream = File.OpenRead(tmpFile.File.FullName))
                    using (Stream ntfsStream = ntfsFile.OpenRead())
                    {
                        bool equal = StreamUtils.CompareStreams(actualStream, ntfsStream);

                        Assert.IsTrue(equal);
                    }
            }
        }
Example #6
0
        private static string GetDirectory(NtfsFile file)
        {
            StringBuilder result = new StringBuilder();

            result.Insert(0, "\\");

            NtfsDirectory dir = file.Parent;

            while (dir.Name != ".")
            {
                result.Insert(0, $"{Path.DirectorySeparatorChar}{dir.Name}");
                dir = dir.Parent;
            }

            result.Insert(0, ":");

            return(result.ToString());
        }
Example #7
0
        //CONSTRUCTOR
        public vmNtfsFile(NtfsFile dir, string apiRoot, string reqPath)
        {
            Name      = dir.Name;
            FullPath  = dir.FullPath;
            Exists    = dir.Exists;
            Created   = dir.Created;
            LastWrite = dir.LastWrite;
            FileLink  = new Uri(apiRoot + "File?id=" + reqPath);
            ScanTime  = DateTime.Now;
            //ScanUser = user;
            InheritanceEnabled = dir.InheritanceEnabled;
            Owner = dir.Owner;

            AccessControl = new List <vmNtfsAccessRule>();

            foreach (var ar in dir.AccessControlList)
            {
                AccessControl.Add(new vmNtfsAccessRule(ar));
            }
        }
Example #8
0
        private static bool FileMatchesPattern(NtfsFile file, string[] searchPatterns)
        {
            string filename = file.Name;

            if (filename.FirstOrDefault() == '$')
            {
                return(false);
            }

            if (ignoreFiles.Contains(filename))
            {
                return(false);
            }

            if (searchPatterns.Contains("*"))
            {
                return(true);
            }

            string extension = Path.GetExtension(filename);

            foreach (string pattern in searchPatterns)
            {
                if (pattern.Contains("."))
                {
                    if (extension.Contains(pattern))
                    {
                        return(true);
                    }
                }
                else
                {
                    if (filename.Contains(pattern))
                    {
                        return(true);
                    }
                }
            }

            return(false);
        }
Example #9
0
        private byte[] GetFileBytes(NtfsFile file)
        {
            byte[] result = new byte[] { };
            // If we made it this far, attempt to read the bytes
            using (MemoryStream ms = new MemoryStream((int)this.Length))
            {
                using (Stream ntfsStream = file.OpenRead())
                {
                    int    read;
                    byte[] buffer = new byte[16 * 1024];

                    while ((read = ntfsStream.Read(buffer, 0, buffer.Length)) > 0)
                    {
                        ms.Write(buffer, 0, read);
                        CancellationHelper.ThrowIfCancelled();
                    }
                    buffer = null;
                }
                result = ms.ToArray();
            }
            return(result);
        }
Example #10
0
        public void AlternateDatastreamFile()
        {
            Random rand = new Random();

            byte[][] data = new byte[11][];
            for (int i = 0; i < 11; i++)
            {
                data[i] = new byte[1024 * 1024];
                rand.NextBytes(data[i]);
            }

            using (TempFile tmpFile = new TempFile())
            {
                // Make file
                File.WriteAllBytes(tmpFile.File.FullName, data[10]);

                for (int i = 0; i < 10; i++)
                {
                    using (SafeFileHandle fileHandle = Win32.CreateFile(tmpFile.File.FullName + ":alternate" + i + ":$DATA"))
                        using (FileStream fs = new FileStream(fileHandle, FileAccess.ReadWrite))
                        {
                            fs.Write(data[i], 0, data[i].Length);
                        }
                }

                // Discover file in NTFSLib
                char    driveLetter = tmpFile.File.DirectoryName[0];
                RawDisk disk        = new RawDisk(driveLetter);

                NTFSDiskProvider provider = new NTFSDiskProvider(disk);

                NTFSWrapper ntfsWrapper = new NTFSWrapper(provider, 0);

                NtfsDirectory ntfsDir  = NTFSHelpers.OpenDir(ntfsWrapper, tmpFile.File.DirectoryName);
                NtfsFile      ntfsFile = NTFSHelpers.OpenFile(ntfsDir, tmpFile.File.Name);

                // Check streams
                string[] streams = ntfsWrapper.ListDatastreams(ntfsFile.MFTRecord);

                Assert.AreEqual(11, streams.Length);
                Assert.AreEqual(1, streams.Count(s => s == string.Empty));

                for (int i = 0; i < 10; i++)
                {
                    Assert.AreEqual(1, streams.Count(s => s == "alternate" + i));
                }

                // Check data
                using (Stream memStream = new MemoryStream(data[10]))
                    using (Stream fileStream = ntfsWrapper.OpenFileRecord(ntfsFile.MFTRecord))
                    {
                        StreamUtils.CompareStreams(memStream, fileStream);
                    }

                for (int i = 0; i < 10; i++)
                {
                    using (Stream memStream = new MemoryStream(data[i]))
                        using (Stream fileStream = ntfsWrapper.OpenFileRecord(ntfsFile.MFTRecord, "alternate" + i))
                        {
                            StreamUtils.CompareStreams(memStream, fileStream);
                        }
                }
            }
        }
Example #11
0
        public void PopulateFileProperties(FileEnumeratorParameters parameters, char driveLetter, NtfsFile ntfsFile)
        {
            if (parameters == null)
            {
                return;
            }
            if (ntfsFile == null)
            {
                return;
            }

            CancellationHelper.SetCancellationToken(parameters.CancelToken);
            CancellationHelper.ThrowIfCancelled();

            MFTNumber      = ntfsFile.MFTRecord.MFTNumber;
            SequenceNumber = ntfsFile.MFTRecord.SequenceNumber;

            DriveLetter = driveLetter;
            FileName    = ntfsFile.Name;

            MftTimeAccessed    = ntfsFile.TimeAccessed;
            MftTimeCreation    = ntfsFile.TimeCreation;
            MftTimeModified    = ntfsFile.TimeModified;
            MftTimeMftModified = ntfsFile.TimeMftModified;

            DirectoryLocation = GetDirectory(ntfsFile);
            Extension         = Path.GetExtension(FileName);
            FullPath          = Path.Combine(DriveLetter.ToString() + DirectoryLocation, FileName);

            this.Length = ntfsFile.AllocatedSize;

            CancellationHelper.ThrowIfCancelled();

            if (this.Length != 0)
            {
                // Some entries in the MFT are greater than int.MaxValue !! That or the size is corrupt. Either way, we handle that here.
                if (this.Length >= (int.MaxValue - 1))
                {
                    using (Stream ntfsStream = ntfsFile.OpenRead())
                    {
                        this.Sha256Hash = GetSha256Hash_BigFile(ntfsStream);
                        this.Length     = ntfsStream.Length;
                    }

                    this.PeData = PeDataObject.TryGetPeDataObject(FileName, parameters.OnlineCertValidation);
                    CancellationHelper.ThrowIfCancelled();
                    this.Authenticode = AuthenticodeData.TryGetAuthenticodeData(FileName);
                    CancellationHelper.ThrowIfCancelled();
                }
                else
                {
                    byte[] fileBytes = GetFileBytes(ntfsFile);

                    CancellationHelper.ThrowIfCancelled();

                    this.PeData = PeDataObject.TryGetPeDataObject(fileBytes, parameters.OnlineCertValidation);
                    if (IsPeDataPopulated)
                    {
                        this.Sha256Hash = PeData.SHA256Hash;
                    }
                    else
                    {
                        this.Sha256Hash = GetSha256Hash(fileBytes);
                    }

                    CancellationHelper.ThrowIfCancelled();

                    if (parameters.CalculateEntropy)
                    {
                        this.Entropy = EntropyHelper.CalculateFileEntropy(fileBytes);
                        CancellationHelper.ThrowIfCancelled();
                    }

                    this.Authenticode = AuthenticodeData.TryGetAuthenticodeData(fileBytes);

                    CancellationHelper.ThrowIfCancelled();

                    if (!string.IsNullOrWhiteSpace(parameters.YaraRulesFilePath) && File.Exists(parameters.YaraRulesFilePath))
                    {
                        this.YaraRulesMatched = YaraRules.Scan(fileBytes, parameters.YaraRulesFilePath);
                        CancellationHelper.ThrowIfCancelled();
                    }

                    fileBytes = null;
                }
            }

            PopulateFileInfoProperties(FullPath);

            CancellationHelper.ThrowIfCancelled();

            this.Attributes = new Attributes(FullPath);

            CancellationHelper.ThrowIfCancelled();

            PopulateShellFileInfo(FullPath);

            CancellationHelper.ThrowIfCancelled();
        }