Thursday, June 27, 2013

The downfalls of C#

I have mixed feelings about C# as a programming language.

I feel as a programming language it is intuitive and full featured, but that is where it's positives end.  I really like developing in C#, but I feel it is really only good for Open Source Software (OSS), and I will tell you why.

Recently I was hired to do some integrations for 2 different customers each for a third party software that had no API or integration documentation.  The companies who produced the softwares mentioned basically refused to help. So where does that leave me?  Since they were both written in C#, I can still get what I need, and pretty easily also.  How you may ask ... ILSpy.  C# allows reflection on "compiled" code.  With ILSpy I was able to reverse engineer (for purposes of interoperability) and see their source code.  It even had the original variable names!  It had everything except code comments.  So with this ability, someone could look at, say ... their license mechanism and write a keygen or a software crack.  As a proof of concept, I will go over how it is could be done in one of the 2 softwares I was working with.  I will not disclose the actual software's name, any of its original source code or the end result keygen executable (because I did not write one) ... this is just an example of how it could be done.

So the first step is to open the the executable in ILSpy and start browsing around in the code.  After some digging I found the license methods in a supporting DLL file, a method called ReadLicenseFile(), and a method called DecryptString() which is used by ReadLicenseFile().  But there is a problem ... there is only the decrypt method .... no encrypt.  Well lucky for me most cryptography assumes decrypting is the private or secure part and so with a good understanding of the C# programming language and the fact that they embedded their entire 1024bit RSA key (both public and private keys) in their code I was able to produce a reverse of what they did.  Here is the code sans the RSA key:

public string EncryptString(string inputString, int dwKeySize, string xmlString) {
 RSACryptoServiceProvider rSACryptoServiceProvider = new RSACryptoServiceProvider(dwKeysize);
 string returnstr = "";
 int num = dwKeySize * 11 / 16 / 8 / 4 - 1;
 int num2 = inputString.Length / num;

 string tmpstr = "";
 for(int i = 0; i <= num2; i++) {
  if(inputString.Length < (num*i)+num) {
   tmpstr = inputString.Substring(num*i);
  } else {
   tmpstr = inputString.Substring(num*i, num);
  byte[] val = rSACryptoServiceProvider.Encrypt(Encoding.UTF32.GetBytes(tmpstr.ToCharArray()), true);
  returnstr += Convert.ToBase64String(val);
 return returnstr;

So by using this and reading through the license parsing code to determine what it expects to be in the unencrypted string, I can produce my own license file. This was a very simple example because their license mechanism was very simple.  When it comes to protecting your software from piracy this should be the most secure aspect and the hardest to reverse engineer part of your software.

So to conclude, I feel C# is a great programming language but if you are producing closed source software, DO NOT USE IT, AND SURE AS HELL DO NOT INCLUDE YOUR ENTIRE RSA KEY IN IT!!!!  To be fair there are some tools out there obfuscate the code to help prevent reflection, but these can actually introduce bugs into your software because they rewrite the code and re-compile it to a less readable version which is still not very secure.

To all closed source software companies using C#:  DON'T!

Sorry to all of the hackers out there for spilling the beans.

1 comment: