ClickOnce hash failures when using code contract rewriter - validation

I am creating a ClickOnce deployment.
Now, I am using CodeContracts rewriter, which means that the application manifest is generated before CodeContracts modifies my assembly.
Therefore, I update the application manifest file with an up-to-date hash and file size. Here's the algorithm to compute the hash:
public static string ComputeHash(FileInfo info)
{
SHA1CryptoServiceProvider sha1 = new SHA1CryptoServiceProvider();
byte[] hashBytes = sha1.ComputeHash(info.OpenRead());
return Convert.ToBase64String(hashBytes);
}
I then save the manifest. I then update the ClickOnce deployment manifest (.application) which has a hash and size for the application manifest using the same hash computation routine.
After this, I run a test program which tells me that all the hashes and file sizes match those of the real files on disk.
Yet when I run the ClickOnce deployment it always complains that the hash verification failed for the main .exe file (which is the only dependent assembly in the application manifest that needs changing).
Note that if I do not change the hashes and sizes myself, the ClickOnce also fails because the information is even more palpably wrong (the file size is different, not just the hash).
Is there anyway I can see why the hash validation is failing when I think it is valid?
Or better still, is there a way I can generate manifests after the code contracts rewriter has finished hacking my executables?
Thanks

Have you tried Mage to update and resign your manifests? Look at the Update (-u) and the Sign (-s) commands.

Related

How to get hash of the compiled source files in dotnet core?

I have a .net core 5.0 solution. I would like to ensure that the files were not modified between the source code check out and a compilation step on a build machine. I don't want to re-invent a wheel but couldn't find an existing solution. There's a suggestion to use sha256 here (see the last two paragraphs). I thought of something like this:
MSBuild compilation task
Compiling solution
Generating source code sha256 signatures
# The output may look like this
sources.sha256
/src/app1/foo.cs sha1
/src/app2/bar.cs sha1
I could then run a final sha1 on the sources.sha256. Lastly and quite importantly, I can repeat the same process on different independently-maintained machines, to ensure the same output and make supply chain attack more difficult to execute.
I've looked into checksumalgorithm compiler option, but not sure I can use it, as it would embed sha256 into a PDB file, and I am unsure if a generated PDB file will be identical between the build which will happen on different machines and platforms.
What's the best way to run source code integrity check during a build of C# .net core solution?

Can I run a command before the setup.msi?

I have a desktop application and its installer project produces two files in the Release folder: let's call them setup.exe and setup.msi.
In the post build event I sign the setup.msi with a self signed certificate. Then my final installation batch is composed of three steps
Adding user store certificate with a start.cmd (or start.exe)
Running the setup.exe. Notice that the important thing is that it shows a user account control for a verified author with my name and surname.
Removing (with a stop.cmd or stop.exe) the certificate at point 1 for security reasons/best practices since it is self signed
Now I'm perfectly fine with this solution, I only wished to include the commands 1 and 3 inside the setup.exe if it was possible in a standard way.
What I have tried to do is to define the start.exe and stop.exe as custom actions. In that case I only have the two files setup.exe and setup.msi but unfortunately I get an unkown publisher. I guess it is obviously because the custom actions go inside the .msi and not in the setup.exe. But I'm not an expert of installer projects so someone might suggest a better and standard solution.
Alternative approach
Is that something that I could much more easily do by switching to Inno Setup and maybe as suggested in this comment?
References
How do I create a self-signed certificate for code signing on
Windows? - Original Answer
Answer about certmgr.msc - Will a self signed code-signing
certificate get rid of “Unknown Publisher” warnings?
Sign tools downloadable from github
Updated answer
Sorry, I've tested my original answer below and it is "wrong" in a sense:
actually I get a single click installer but then the Windows operating system anticipates the user account control before such single click installer and it shows an unknown publisher, which defeats the purpose of point 1 (and 3).
So, short, updated answer: it is impossible(*) to do that in a standard single-click exe, like the ones produced by the SFX module mention below.
(Note *): though it is doable by compiling a custom C# code and by adding files to the Resources.resx, for example _7zr.exe, etc... like in this example:
using System.IO;
using System.Diagnostics;
namespace selfextractinstaller
{
class Program
{
static void Main(string[] args)
{
string file_path_7zr = #"_7zr.exe";
using (FileStream fs = new FileStream(file_path_7zr, FileMode.Create))
{
byte[] pgm_bytes = Properties.Resources._7zr;
fs.Write(pgm_bytes, 0, (int)pgm_bytes.Length);
}
string file_path_config = #"config.txt";
using (StreamWriter sw = new StreamWriter(file_path_config, false))
{
sw.Write(Properties.Resources.config);
}
string file_path_7zSD = #"_7zSD.sfx";
using (FileStream fs = new FileStream(file_path_7zSD, FileMode.Create))
{
byte[] pgm_bytes = Properties.Resources._7zSD;
fs.Write(pgm_bytes, 0, (int)pgm_bytes.Length);
}
Process.Start(file_path_7zr, "b");
}
}
}
A similar code can be actually used as a self extracting installer that is not elevated and does not require the UAC!
Further Readings
How does Windows decide whether to display the UAC prompt?
How do I add a manifest to an executable using mt.exe?
Original answer
In absence of other answers, I'll proceed with a SFX module for installers, by packaging all the three .exe at points 1-3 (plus an install_all.bat running them in sequence) into a self extracting installer, that will automatically extract all the needed files (certificate included) and finally run the install_all.bat

Create an application that generates a DLL

Currently, I have an MFC C++ visual studio project that is built to a DLL. Let's call it the FinalDLL.
I need this FinalDLL to be configurable. So, I want a GUI such that the users can generate the FinalDLL based on the information the enter via GUI. Please consider that I don't want to make the sources available at any points.
I do not have a clear idea how to integrate these steps. The solution I came up with was to have something like a button in my GUI, so that when it is clicked, the FinalDLL gets generated based on the information entered via GUI. Is it possible to do something like that? Probably I need another DLL library, as the information entered via GUI can be calls to functions that are used inside the FinalDLL source.
The solution to this would be very complex and complicated, mainly due to the fact that you don't want to disclose the source code of the DLL.
Basically you need to compile those source files every time you want to generate the DLL, and without the user having access to them.
Firstly, this is also required for the users that you want your DLL-generator app distributed to.
Secondly, you'll need to store those files somewhere in the app, and in an encrypted form, so that hackers won't just look at you app binaries and extract the source code for the DLL.
As a prerequisite on the user side, he will need to have a compatible Visual Studio installation, which will be used to compile on the fly the source code files.
What the DLL-generator application will need to do is to compile on the fly those source code files along with the customised ones via the form that the application will present.
So what you will need to do (the list might not be exhaustive due to the complex requirements):
Gather all compiler/linker commands that Visual Studio executes when building your project
Store all source code files into your application, in an encrypted form. Now if you want to allow your application to decode the files then you need to either store the encryption key within the application, and obfuscate it so its not that easy to find, or have the app communicate with your server and ask for the encryption key via https (this is a more secure approach, however neither this is 100% bullet-proof, insistent/trained hackers can still peek into the memory used by your app)
After the user fills all DLL generating details, the app will need to decrypt the source code files, updated the ones affected by the customised parameters, and start the build process by using the commands gathered at step #1. The compiler/linker should allow reading from stdin, so you'll use pipes to write the source code contents to the compiler/linker stdin, and to obtain the compiled/linked objects from stdout.
As I said, the solution is not pretty, and the main problem will be having the users install a Visual Studio that comes with a compiler compatible with the one from your machine, otherwise the commands you gathered at step #1 will not work.

How can I profile Signed Assemblies with VS 2010 or VS 2013

I have a website that uses AjaxControlToolkit.dll and Log4Net.dll.
When I try to run the performance profiling tool in VS 2010 on it it gives me the following warning:
AjaxControlToolkit.dll is signed and instrumenting it will invalidate its signature. If you proceed without a post-instrument event to re-sign the binary it may not load correctly.
Now, if I choose the option to continue without re-signing, the profiling starts but the assembly doesn't load and gives an ASP.NET exception.
If you're doing this on a development machine, you can disable strong name verification altogether with sn -Vr *. If you do this, you don't have to resign anything. This approach can be a security risk, but if you are comfortable with it, it's easier than resigning.
Specifically, from MSDN, it says:
Registers assembly for verification skipping. Optionally, you can specify a comma-separated list of user names. If you specify infile, verification remains enabled, but the public key in infile is used in verification operations. Assembly can be specified in the form *, strongname to register all assemblies with the specified strong name. Strongname should be specified as the string of hexadecimal digits representing the tokenized form of the public key. See the -t and -T options to display the public key token.
And the security risk:
Caution: Use this option only during development. Adding an assembly to the skip verification list creates a security vulnerability. A malicious assembly could use the fully specified assembly name (assembly name, version, culture, and public key token) of the assembly added to the skip verification list to fake its identity. This would allow the malicious assembly to also skip verification.
ghusse linked to a blog post giving the answer. The answer is described there. As he points out, you have to use a post-instrument event on each signed assembly.
It's easiest to call sn.exe directly:
"C:\Program Files\Microsoft SDKs\Windows\v7.0A\bin\sn.exe" -R [pathOfDll] [pathOfSNK]
Note that [pathOfDll] is located in the directory obj\Debug associated to the project.
The answer is described here. You have to use a post-instrument event on each signed assembly.
I could not manage to make it work "as is" with my installation of VS 2010. I had to call this command line as a post-build event on each dll :
"C:\Program Files\Microsoft Visual Studio 10.0\VC\vcvarsall.bat" & sn -Ra [pathOfDll] [pathOfSNK]
Note that [pathOfDll] is located in the directory obj\Debug associated to the project.
The easiest way to get instrumentation work on signed binaries, which have not been re-signed, is to disable signature checks altogether. This is a machine wide setting that you can activate by registering an exception for the * pattern:
sn.exe -Vr *
This command must be executed from an elevated command prompt. You will find sn.exe in the SDK (in my case, I found it in C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin).
When you are finished with testing, you should unregister the exception:
sn.exe -Vu *
or else your machine could be vulnerable to malicious code, since assemblies will be trusted even if they have been tampered with.
See also Access denied running sn.exe on Windows 7.
The profiler probably changes the assembly and because it was previously signed.
Apparently you need to add a post-instrument action that re-signs the assembly.
This could be a problem because you do not have the sn file that was used to sign the 3rd party assemblies.
Might have taken the lazy learning-new-things-free way out here, but I ended up solving this by writing a powershell script to unsign all the projects in my solution -- worked just fine. As part of the script, I save the original csproj files so I can revert them after. (you could also just undo changes in source control).
http://pastebin.com/UbABvz7d
should be able to revert by calling it passing the -revert switch.

How do you verify that 2 copies of a VB 6 executable came from the same code base?

I have a program under version control that has gone through multiple releases. A situation came up today where someone had somehow managed to point to an old copy of the program and thus was encountering bugs that have since been fixed. I'd like to go back and just delete all the old copies of the program (keeping them around is a company policy that dates from before version control was common and should no longer be necessary) but I need a way of verifying that I can generate the exact same executable that is better than saying "The old one came out of this commit so this one should be the same."
My initial thought was to simply MD5 hash the executable, store the hash file in source control, and be done with it but I've come up against a problem which I can't even parse.
It seems that every time the executable is generated (method: Open Project. File > Make X.exe) it hashes differently. I've noticed that Visual Basic messes with files every time the project is opened in seemingly random ways but I didn't think that would make it into the executable, nor do I have any evidence that that is indeed what's happening. To try to guard against that I tried generating the executable multiple times within the same IDE session and checking the hashes but they continued to be different every time.
So that's:
Generate Executable
Generate MD5 Checksum: md5sum X.exe > X.md5
Verify MD5 for current executable: md5sum -c X.md5
Generate New Executable
Verify MD5 for new executable: md5sum -c X.md5
Fail verification because computed checksum doesn't match.
I'm not understanding something about either MD5 or the way VB 6 is generating the executable but I'm also not married to the idea of using MD5. If there is a better way to verify that two executables are indeed the same then I'm all ears.
Thanks in advance for your help!
That's going to be nearly impossible. Read on for why.
The compiler will win this game, every time...
Compiling the same project twice in a row, even without making any changes to the source code or project settings, will always produce different executable files.
One of the reasons for this is that the PE (Portable Executable) format that Windows uses for EXE files includes a timestamp indicating the date and time the EXE was built, which is updated by the VB6 compiler whenever you build the project. Besides the "main" timestamp for the EXE as a whole, each resource directory in the EXE (where icons, bitmaps, strings, etc. are stored in the EXE) also has a timestamp, which the compiler also updates when it builds a new EXE. In addition to this, EXE files also have a checksum field that the compiler recalculates based on the EXE's raw binary content. Since the timestamps are updated to the current date/time, the checksum for the EXE will also change each time a project is recompiled.
But, but...I found this really cool EXE editing tool that can undo this compiler trickery!
There are EXE editing tools, such as PE Explorer, that claim to be able to adjust all the timestamps in an EXE file to a fixed time. At first glance you might think you could just set the timestamps in two copies of the EXE to the same date, and end up with equivalent files (assuming they were built from the same source code), but things are more complicated than that: the compiler is free to write out the resources (strings, icons, file version information, etc.) in a different order each time you compile the code, and you can't really prevent this from happening. Resources are stored as independent "chunks" of data that can be rearranged in the resulting EXE without affecting the run-time behavior of the program.
If that wasn't enough, the compiler might be building up the EXE file in an area of uninitialized memory, so certain parts of the EXE might contain bits and pieces of whatever was in memory at the time the compiler was running, creating even more differences.
As for MD5...
You are not misunderstanding MD5 hashing: MD5 will always produce the same hash given the same input. The problem here is that the input in this case (the EXE files) keep changing.
Conclusion: Source control is your friend
As for solving your current dilemma, I'll leave you with this: associating a particular EXE with a specific version of the source code is a more a matter of policy, which has to be enforced somehow, than anything else. Trying to figure out what EXE came from what version without any context is just not going to be reliable. You need to track this with the help of other tools. For example, ensuring that each build produces a different version number for your EXE's, and that that version can be easily paired with a specific revision/branch/tag/whatever in your version control system. To that end, a "free-for-all" situation where some developers use source control and others use "that copy of the source code from 1997 that I'm keeping in my network folder because it's my code and source control is for sissies anyway" won't help make this any easier. I would get everyone drinking the source control Kool-Aid and adhering to a standard policy for creating builds right away.
Whenever we build projects, our build server (we use Hudson) ensures that the compiled EXE version is updated to include the current build number (we use the Version Number Plugin and a custom build script to do this), and when we release a build, we create a tag in Subversion using the version number as the tag name. The build server archives release builds, so we can always get the specific EXE (and setup program) that was given to a customer. For internal testing, we can choose to pull an archived EXE from the build server, or just tell the build server to rebuild the EXE from the tag we created in Subversion.
We also never, ever, ever release any binaries to QA or to customers from any machine other than the build server. This prevents "works on my machine" bugs, and ensures that we are always compiling from a "known" copy of the source code (it only pulls and builds code that is in our Subversion repository), and that we can always associate a given binary with the exact version of the code that it was created from.
I know it has been a while, but since there is VB De-compiler app, you may consider bulk-decompiling vb6 apps, and then feeding decompilation results to an AI/statistical anomaly detection on the various code bases. Given the problem you face doesn't have an exact solution, it is unlikely the results will be 100% accurate, but as you feed more data, the detection should become more and more accurate

Resources