Computers, Programming, Technology, Music, Literature

Archive for the ‘.Net’ Category

N Different Strategies to Automate OWASP ZAP – Cybersecurity WithTheBest – Oct 15 2017

leave a comment »

In this talk we will explore the many different ways of automating security testing with the OWASP Zed Attack Proxy and how it ties to an overall Software Security Initiative. Over the years, ZAP has made many advancements to its powerful APIs and introduced scripts to make security automation consumable for mortals. This talk is structured to demonstrate how ZAP’s API, and scripts could be integrated with Automated Testing frameworks beyond selenium, Continuous Integration and Continuous Delivery Pipelines beyond Jenkins, scanning authenticated parts of the application, options to manage the discovered vulnerabilities and so on with real world case studies and implementation challenges.





OWASP ZAP Development – Fixing the Can’t find bundle for base name lang.Messages error

leave a comment »


I have been generating the API files for OWASP ZAP DOT NET API since the inception. There is the core zaproxy project that has the class. And there is the extensions project, including the beta and alpha.


Now, when I tried to generate the ‘non-optional’, i.e., the core API files for .Net, everything would work fine, the API files would be generated as below.



OWASP ZAP is internationalized, so the source code comes with a bunch of resource bundles with supporting language files.

When you try to generate the API files for the extensions project, you get this wonderful error message.

Exception in thread "main" java.util.MissingResourceException: Can’t find bundle for base name lang.Messages, locale en at java.util.ResourceBundle.throwMissingResourceException( at java.util.ResourceBundle.getBundleImpl( at java.util.ResourceBundle.getBundle( at org.zaproxy.zap.extension.api.AbstractAPIGenerator.( at org.zaproxy.zap.extension.api.JavaAPIGenerator.( at org.zaproxy.zap.extension.ApiGenerator.main(



I have fixed this error message before when I was trying to generate the api files back in 2015. Running in debug mode and stepping through pointed out that the zaproxy core project had the resource files under a directory that was not available to the extensions project.

This error was gruesome.

In the end all I had to do was copy the contents of the workspaceowaspzap\zaproxy\src\lang directory to workspaceowaspzap\zap-extensions\bin\lang

That’s it. Do the same thing for the alpha, and beta extensions’ bin directory too.



Cheers. Try the OWASP ZAP DOT NET API available at

Written by gmaran23

March 22, 2017 at 1:46 am

Getting hackazon up and running on Wamp on Nov 2016

leave a comment »

Following the steps described here will most likely help in fixing the error messages and issues below:



Of all the vulnerable applications from the OWASP’s vulnerable web applications directory, Hackazon is up to date with the latest technology stack and customizable vulnerabilities. It’s is a great choice to learn and teach ethically hacking today’s web applications. As of today, although the project on GitHub reports an update nine months ago, the application still uses recent web technologies to that we can learn hacking like it is 2016. This article helps you set up hackazon on a windows machine.


Things to be downloaded before we get started:

1. Hackazon User guide

Download from

Direct Download Link


Alternative like to the Original Hackazon user guide (in case the link above goes dead) –


2. Wamp server


Here’s the story

I had a Wamp installed on Nov 2014 and I tried using the same Wamp server for hackazon deployment. After following the instructions on the user guide, and going to a browser, hitting the install page came up, and after you put the credentials for the MySQL user hackazon, and hit the Next Step button, the page would load the same page over and over again. So basically I was stuck at the first step of the wizard where you supply the administrator credentials. [Bug #5 filed at “Installation – unclickable buttons "next step" ”]

I tried everything in the Hackazon User Guide (here after referred to as the user guide) on a Kali linux machine, set up went smooth, just as described in the User Guide and the site was up and running in no time. It was happiness to see the second step of the installation page where you provide the MySQL database credentials.

Though I cant technically confirm if the older version of Wamp was the cause of bug # 5. My guess was may be to reinstall the Wamp to a recent version on a window machine and try the same steps as the user guide. And it indeed, helped me get over the bug # 5.

For Windows, the User Guide describes installation on Wamp 2.some version. However the current stable version available for release is Wamp 3.0.6 at the time of this writing. So something in MySQL changed, some things in Apache changed and hopefully this post will help you fill the gaps between the Hackazon User guide and the recent changes to the Wamp.


1. Download Wamp server


Please ensure your computer has the recent version of VC++ Runtime. If you want to install the VC++ runtime to the recent version, either have it done via Windows Update, or download it from the Microsoft website as recommended by the Wamp servers download page (as in the screenshot above). It is so important for Wamp to function properly that they have even updated their installation agreements during the installation wizard to reflect the installation and update of VC++ runtime. I had to download VC++ runtime for Visual Studio 2015 here at

Ok. Install Wamp. Pretty straight forward installation, go with the defaults.

This is the current Wamp installation on my computer right now.


2. Download Hackazon source code

Head over to the hackazon source code download page at github and download a zip of the hackazon source code.


Have them zip file contents extracted to c:\home\hackazon


3. Rename db.sample.php to dp.php

Head over to C:\home\hackazon\assets\config and rename the file db.sample.php to db.php


4. Create hackazon db and username in MySQL console

Open ‘MySQL console’ from the Wamp server system tray.


Press Enter on the ‘Enter password’ prompt if you did not create a MySQL root account password, which is the default during installation. Or if you had created a password for your MySQL installation, authenticate.


Enter the below query to create a database named hackazon.

create database hackazon;


Enter the below query to create a user named ‘hackazon’ and give it a password. In the screenshot below and in the query below, admin123!  is the password, feel free to choose your favorite.

The password you provide here is important as you would need it on the first step of the Hackazon Installation wizard.

GRANT ALL ON hackazon.* TO hackazon@’localhost’ IDENTIFIED BY ’admin123!’;


After this step, if you are curious, only if you are, head over to phpMyAdmin (from the Wamp Server system tray), login with your root server credentials, to see a database named hackazon, and a user named hackazon. Or just imagine, if the above two queries worked fine, a user name and a database named hackazon would have been created.


Do a restart by selecting Restart All Services from the Wamp server system tray menu.


5. Configuring or Verifying Apache’s default port

Open apache’s httpd.conf file. From Wamp Server System tray  -  Apache  – httpd.conf


Search for the word Listen, and ensure Apache listens on port 80. I tried changing it from the default settings and tried to configure Apache to run on 7070 port, and hackazon kept giving me 400 Invalid Referrer error message, I couldn’t find out why. So I reversed back to the default settings.

Tip: Let’s try to configure Apache on the default port 80.

If you have Skype or IIS, running on port 80, change them, at least for now to give hackazon a preference to run on apache’s port 80.


Also, search for ServerName and verify if Server localhost also says port 80. I honestly do not know what this for, read the description and figure out. For now, all we are trying to do is configure apache to run on port 80.


6. Configuring the hackazon website set up

Open apache’s httpd-vhosts.conf file. From Wamp Server System tray  – Apache  – httpd-vhosts.conf


Copy paste the below contents of the httpd-vhosts.conf file in to your httpd-vhosts.conf file.

# Virtual Hosts

<VirtualHost *:80>
ServerName localhost
DocumentRoot c:/wamp64/www
<Directory "c:/wamp64/www/">
Options +Indexes +Includes +FollowSymLinks +MultiViews
AllowOverride All
Require all granted
Allow from all


<VirtualHost *:80>
DocumentRoot "c:/home/hackazon/web"
<Directory "c:/home/hackazon/web/">
Options +Indexes +Includes +FollowSymLinks +MultiViews
AllowOverride All
Require all granted
Allow from all



Save the file. The vhost settings provided above is good enough to even access from another machine on the LAN.

7. Edit Windows hosts file to bind to loopback address

C:\Windows\System32\drivers\etc open hosts file with administrative privileges and add the below entries

8. Restart DNS service from wamp server tools (right click wamp server from system tray)


After Restarting DNS, Restart All Services from wamp server from system tray.

This is all is required to start hackazon installation wizard. For the first time you hit, you will automatically be redirected to the installation wizard.

9. Final tinkering

If you just go with this set up and continue with the Installation Wizard, on step 4 – the final step of the installation wizard will give you an error message as below:

Error 42S02: SQLSTATE[42S02]: Base table or view not found: 1146 Table ‘hackazon.tbl_product_options_values’ doesn’t exist”.

There is also a bug filed for it. [Bug #9 Database problem]


After digging and digging and executing the contents of the db.sql file at C:\home\hackazon\database manually at phpMyAdmin Sql console, it occurred that the default value given for the timestamp data type is not supported by MySQL anymore or you would need to turn off date zero validation for the query execution.


To fix, add the below line at the very top of the db.sql file in C:\home\hackazon\database and save the file.



Now, for one last time, Restart All Services from the Wamp server system tray.

10. Navigating through the Hackazon installation wizard

Open a browser and hit


You will be redirected to

Provide the admin123! password, that is the one we typed in the MySQL console. Hit Next Step.



Provide the same password under the Password field, and hit Next Step




Leave the defaults, hit Next Step


Leave the defaults, hit Install

In a couple of seconds, you should be automatically redirected to


Basically, that’s it. The hackazon user guide has more information on how to use the vulnerabilities configuration and other things that are specific to the hackazon application itself.


Just to do a walk through, hit, provide user name as admin and password as the password we entered in the MySql console admin123!

Navigate to Vulnerability Config, and choose account from the drop down. Or simply hit the url –


to see an error page as below:


To fix, click Wamp Server system tray icon  -  PHP   -   php.ini


Go to the very end of the php.ini file and comment out the zend_extension line by adding a semi colon ; in the front.

Save the file. Restart All Services.



If you want to access from another computer (let’s say ‘X’) on the same Local Area Network (LAN), Open drivers/etc/hosts file on computer X and add the ip address of the to point to

For every computer on the LAN, modify their windows hosts file to point to the Wamp servers ip address.

That’s how I set up hackazon and got it working. Do you have similar experiences?

Written by gmaran23

February 21, 2017 at 11:40 pm

Beefing Up Security In ASP.NET Part 2 Dot Net Bangalore 4th meet up on August 08 2015

leave a comment »

Written by gmaran23

August 10, 2015 at 7:14 pm

SSIS – An Effortless Two Step Approach to Protect Sensitive Information in Xml Configuration Files

leave a comment »


I wanted to grab some text regarding DPAPI and RSA Encryption providers for my talk Beefing up Security in ASP.NET Part 2. But I couldn’t find it handy, I had to download a pdf version of this below SSISCipherBoy support guide. Posting here for easy access.


SSIS – An Effortless Two Step Approach to Protect Sensitive Information in Xml Configuration Files


I. Introduction

II. Competitive approaches

III. Prerequisites

IV. Preparing your package for configuration

V. Step 1 – Using SSISCipherBoy.exe – Select and encrypt configuration entries

VI. Step 2 – Using SSISCipherBoy.exe – Prepare the package to decrypt information

VII. Deploying package with encrypted configuration to server – Using SSISCipherBoy.exe – Export/Import RSA key pair

VIII. Common errors and debugging options

IX. What now?

X. Glossary

a. Using SSISCipherBoy.exe – Processing multiple packages sharing same config

b. Using SSISCipherBoy.exe – Dump SSISCipherUtil.dll to GAC / local directory

c. Manually installing SSISCipherUtil.dll to GAC

d. Manually create a ScriptTask to decrypt information

e. What does the automatic Package Processor do?

f. How does the cipher algorithm work?

XI. References and further reading


Writing a tool or an article becomes best when it is a communal effort. While I conceived and developed the library and tool, I want to acknowledge a few people who contributed in various ways.

Balabhadra Pavan Kumar, Dheeraj Dhamija, Balakrishna Allidi for constantly proving feedback, improvement aspects, and for reviewing sections of the support guide.

Manohara Mahadevappa for putting up with me during early development cycles and suggesting a bit of user friendly features.

Narasimha A Prakash, Sriram Seshan for being good enough to support me whenever I approached them.

I. Introduction

One of the ways of saving configuration entries for SSIS packages is an Xml configuration file, probably because they are simple editable text files, portable, and so on. When developing ASP.Net or Windows applications, most of us are cautious enough to encrypt the sensitive information that is saved in their configuration files. Reasons? May be it is thought that ASP.Net applications may reside on a web server that is exposed to outside world and hence they might be susceptible to attacks of sorts, and when that happens, we would not want to expose sensitive information in plain text, so we encrypt them. And the .Net framework provides it as an out-of-the-box functionality. In the most common scenarios that we have known, SSIS packages run as scheduled jobs inside a server that is located far inside the corporate firewall with ports closed, just sitting there in a good hope that ‘I am not vulnerable to attacks, so I can just be here with an xml configuration file that has connections strings, besides others things, in plain text’. As protection comes with security applied in various layers, the kind of attitude to rely on good hope and on firewall may just not be enough. In the wake of recent attacks in high profile organizations, if by any miracle, someone infiltrates and steals the data, we don’t want to expose further information in plain text. Do we? The risk could even come from a new developer that accidentally performs some unwanted activities on data (by using the information in the xml configuration file saved as plain text) that is meant to be protected from accidental damage, both foreign and domestic. That is the motivation to write this library and executable to help us encrypt information in our SSIS xml configuration files and hence this article. The entire process is done in two simple steps. If you are an experienced developer, read the prerequisites section and proceed directly to section V and VI.

II. Competitive approaches

That said, there are best practices that you can adhere to, like protecting the configuration using Access Control Lists that are tied to your Active Directory efforts, storing configurations in a SQL server database somewhere. Below are two blog entries that talk about our present options.

  1. SSIS: Storing passwords
  2. SSIS: Encrypted Configurations
  3. BI xPress Secure Configuration Manager

While there are pros and cons for approaches, they might not suit your need due to restrictions of company’s policies. And most developers prefer to encrypt and decrypt using a custom script task. While this is a viable option, it is a lot of effort to write a separate encryption module and unit test it, and not all developers are expert programmers that care about strong cryptography and key management. Most of the times the symmetric key used for encryption/decryption is hardcoded in the script task and the package itself is protected by a password. The encryption algorithm that the proposed library (referred to as SSISCipherUtil.dll from now on) uses state-of-the-art methods of encrypting information that hands over the cryptographic key management to the Windows operating system itself. As a matter of fact the ASP.Net out of the box functionality supports encrypting configuration information using DPAPI and RSA. SSISCipherUtil.dll comes with those two options. DPAPI associates cryptographic key with the windows user accounts and RSA uses key containers. That’s just a one liner. More at msdn – DPAPI, RSA.

When you have an encrypted configuration that you would like to be ported across multiple servers, use RSA, export the key pair from one server as xml, import it another server, then destroy the key pair xml file. If the package just sits on one server use RSA or DPAPI.

III. Prerequisites

1. Windows XP or later workstations, Windows Server 2003 or later server operating systems.

2. SSISCipherUtil.dll requires .Net framework 2.0 or later – is the library that helps in encryption/decryption during package setup and at package runtime.

3. SSISCipherBoy.exe requires .Net framework 3.5 or later – is the tool that helps you encrypt/decrypt a configuration entry at design time.

4. Auto code generation functionality of SSISCipherBoy.exe of requires a computer with Business Intelligence Development Studio (BIDS) installation.

5. Requires Administrator Privileges. Run as administrator option if UAC is switched on.

6. Supports only String encryption/decryption. No other data types are allowed.

7. Supports only Package.Variables and Package.Connections collections.

8. Supported Package ProtectionLevel values are DontSaveSensitive, EncryptAllWithPassword, EncryptSensitiveWithPassword. EncryptAllWithUserKey, EncryptSensitiveWithUserKey are supported only when the user account that modifies the package is used to run the package, in the same machine.

Below is the screenshot of the main window of SSISCipherboy.exe. Let’s explore the features one by one in later sections.


Fig. 3.1

IV. Preparing your package for configuration

If you here reading this article, I assume that you are an experienced developer that has configured and managed SSIS packages before. However, for the sake of completeness below are msdn references that explain saving SSIS configurations in xml files:

  1. Package Configurations
  2. Understanding Integration Services Package Configurations

Most important thing, if you don’t uncheck the Enable package configurations in SSIS Package Configurations Organize and if there is a configuration set up for the package, then the config files passed to the package using the /config option of dtexec.exe will not be effective. This might seem counter intuitive but that’s how SQL Server 2008 Integration Services works.

In the following steps, we will be running an unmodified package named AdvWrksLocalLoad2.dtsx with its original configuration AdvWrksLocalLoad2.dtsConfig, then run the modified package AdvWrksLocalLoad2-Mod.dtsx with an encrypted configuration AdvWrksLocalLoad2.dtsConfig, and then run the latter on a Windows 2008 R2 server (just like a production environment).

V. Step 1 – Using SSISCipherBoy.exe – Select and encrypt configuration entries

Now, without further delay, let’s pick a package and let’s encrypt its configuration entries. All the samples along with the tools are zipped and attached to this article. If someone’s interested in looking through the source code of SSISCipherBoy.exe and SSISCipherUtil.dll or enhancing its functionally or aesthetically, please contact me, I’d be pleased to share them.

Below is a list of files that we will be working with for demonstration.


Fig. 5.1

AdvWrksLocalLoad2.dtsx in Business Intelligence Development Studio is a package that does a few things, and the task the package performs is irrelevant here because we are concentrating on encrypting its configuration values in the xml configuration file. AdvWrksLocalLoad2.dtsx is protected with the password test [ProtectionLevel=EncryptAllWithPassword and PackagePassword=test].


Fig. 5.2

AdvWrksLocalLoad2.dtsConfig is the configuration file for AdvWrksLocalLoad2.dtsx that appears like below in Internet Explorer. As you could see the connection strings are mere plain text.


Fig. 5.3

Let’s encrypt them. Run SSISCipherBoy.exe as administrator. This program requires administrator privileges. On Windows systems with User Access Control (UAC) switched on, running as administrator is a mandatory requirement. Otherwise the program will not load properly; you will have to go to Task Manager to end it.


Fig. 5.4

When you run this program on a computer for the first time, it will install SSISCipherUtil.dll to the computer’s Global Assembly Cache (GAC).


Fig 5.5

Hit, OK to that warning, and proceed with the success message. Once the program is opened, let’s drag and drop the configuration file named AdvWrksLocalLoad2.dtsConfig. Use the Browse button to locate a configuration file if drag and drop does not work. The configuration file will be loaded in a tree view.


Fig. 5.6

Encrypting the values is as simple as selecting them and hitting the Encrypt button. However, if you pay attention to the third item, there is a User ID=EncrDemoUser, however, there is no Password provided for it in the configuration file. When you are exporting connections strings that contain a password, then SSIS Package Configurations Organizer does not export the Password property in the configuration file. It knows that a Password is sensitive information and it does not export the Password for ConnectionString. However, you could add it at your own risk – Just what we have been doing all along.

Before we do anything to this configuration file, lets test run it once.

dtexec.exe /file "C:\Maran\Project stuff\SSISCipherUtil\SSISCipher1.2.0.0\Demo\AdvWrksLocalLoad2.dtsx" /config "C:\Maran\Project stuff\SSISCipherUtil\SSISCipher1.2.0.0\Demo\AdvWrksLocalLoad2.dtsConfig" /DE test


Fig 5.7

The package runs just fine. Let’s get back to SSISCipherBoy.exe, right click on the item missing the Password property and click Edit Value to add a Password and hit the Save button.


Fig. 5.8

Nothing is saved to the original .dtsConfig file until you press the Commit changes to the config file button. Commit changes button gets enabled after the Encrypt/Decrypt buttons are clicked.

Once done, we have got two choices of encryption algorithm. To keep things simple: entries encrypted with DPAPI can only be decrypted on the computer on which it is encrypted on, however entries encrypted with RSA can be decrypted on any computer running windows if we export and import the key container used for encryption. So, if we encrypt a configuration entry on our development machine, in order to use the same configuration file across other environments, you will have to export and import the RSA key pair on the target machines using this tool SSISCipherUtil.exe. More about the algorithms are discussed in the Glossary section X-f.

Lets pick the entries that are sensitive, click the Lock/Unlock Selection button, provide a Key Container Name as myrsakey1 (you are free to provide any relevant name for the key container) and hit the Encrypt button. Wait for the success message, and now all the selected entries will be encrypted for you.


Fig. 5.9

Hit Commit changes to the config file button to save the encrypted data back to the file system.


Fig. 5.10

You may, try clicking the Lock/Unlock Selection button and try Encrypt/Decrypt/Edit Value and other operations; however until the time you click Commit changes to the config file, the changes that appear in the tree view will not be saved to the file system.

That’s it! You sensitive values are now encrypted. Next step is to prepare your package to decrypt the package at runtime. Don’t close the tool already; we will have to use it to generate decryption code.


Fig. 5.11

VI. Step 2 – Using SSISCipherBoy.exe – Prepare the package to ready to decrypt information

In our example, the package AdvWrksLocalLoad2.dtsx uses the configuration file AdvWrksLocalLoad2.dtsConfig. That is the configuration file that we encrypted in the preceding step. The dts runtime in no way knows that the configuration file is encrypted; neither there is a way we could tell it in a command line option. If you have DelayValidation=false (which is the default) in the package, then as soon as it encounters an invalid connection string (a connection string that does not have a name value pair like Initial Catalog, Server, User ID..), it throws exception saying that the validation failed and quits the execution of the job. Let’s see how to make a package ready to decrypt information during runtime.

As the AdvWrksLocalLoad2.dtsConfig is open in SSISCipherBoy.exe, check all the encrypted nodes, hit Lock/Unlock Selection and hit Generate decryption code button. This action displays a tip, hitting OK; brings you to the DecryptorCode window.


Fig. 6.1


Fig. 6.2

You are left with two options here.

#1. Manually create a ScriptTask to decrypt information

You can copy the decryption code from the right pane, create a ScriptTask before all other tasks in the target package and replace the scriptmain.cs code with the decryptor code and set the DelayValidation=true. If DelayValidation=false, then an error will be thrown because of invalid connection strings even before any of the tasks are executed. More about manually adding ScriptTask, at Glossary X-d.

#2. Make the package ready for decryption automatically

Drag and Drop a package in to the Package processor, click the Start Processing Below Packages button, and let the tool do the rest of the job for you. If Drag and Drop does not work double click on the package processor area to browse and pick a package. More about how it works, at Glossary X-e.

I am going to demonstrate option #2 here and if you are interested in option #1, refer to Glossary X-d.

With the Decryptorcode window open, add AdvWrksLocalLoad2.dtsx to the package processor and hit Start Processing Below Packages button. Hit OK to the big warning message. If the package is password protected, you will be prompted to enter a password. Enter the password as test and hit Done.

To process multiple package sharing same configuration file that was encrypted, refer to Glossary X-a.


Fig. 6.3


Fig. 6.4


Fig. 6.5

Accept the success message and close the tool. Let’s run the modified package with the encrypted configuration file. The modified package will be saved with a –Mod suffix.

dtexec.exe /file "C:\Maran\Project stuff\SSISCipherUtil\SSISCipher1.2.0.0\Demo\AdvWrksLocalLoad2-Mod.dtsx" /config "C:\Maran\Project stuff\SSISCipherUtil\SSISCipher1.2.0.0\Demo\AdvWrksLocalLoad2.dtsConfig" /DE test

The package runs as expected. It prints some base64 encoded strings to the command window, which can be neglected.


Fig. 6.6

That’s about it. Now lets try deploying the modfied package AdvWrksLocalLoad2-Mod.dtsx and the config file AdvWrksLocalLoad2.dtsConfig to a Windows 2008 R2 server and test run it.

VII. Deploying package with encrypted configuration to server – Using SSISCipherBoy.exe – Export/Import RSA key pair

As mentioned before, we can use the same encrypted configuration file on any other Windows workstations or servers.

  • You would need SSISCipherUtil.dll installed to the Global Assembly Cache (GAC) on the server. GAC is located at C:\Windows\assembly. You can drag and drop the SSISCipherUtil.dll to that folder. Or let the tool do that for you. If you could remember, when the SSISCipherBoy.exe runs for the first time on a computer, it aumatically installs SSISCipherUtil.dll to the GAC. Easiest option, let’s to that. Refer to the glossary X-b and X-c on how to install an assembly (dll) to GAC.
  • Importing the RSA key pair (that was used to encrypt the configuration) to the the server.

You can even use this tool to encryt and modify packages directly on an staging or production server, if you have done necessary testing in the development environments. The point is, if you want to use the same encrypted configuration file across all machines, then you would need to export/import the key container on all other machines.

I have logged on to a Windows server and copied the modified package – AdvWrksLocalLoad2-Mod.dtsx – and its config file – AdvWrksLocalLoad2.dtsConfig – to a location, SSISCipherBoy.exe on to my desktop. (You can place it anywhere though) (DTPOutput1.txt and Query.txt are files used by the package)


Fig. 7.1

1. Right click SSISCipherBoy.exe and select Run as administrator. Accept the User Access Control prompts, if any. SSISCipherUtil.dll will be automatically installed to the GAC, and the program loads fine.


Fig. 7.2

2. From our workstation, or from the development machine where we encrypted the configuration, let’s export the RSA key container named myrsakey1 and import it to the server. Open SSIScipherBoy.exe on your workstation or development machine (make sure to Run as administrator), provide the key container name that we used for encryption myrsakey1 and hit Export Rsa key pair. Save the file as myrsakey1.xml. And copy it to the server.


Fig. 7.3

Copy the myrsakey1.xml file to the server and use the Import Rsa key pair to import it. You should provide the same name myrsakey1 in the Key Container Name text box.


Fig. 7.4

After, successful import of RSA key pair, Destroy the file myrsakey1.xml and SSISCipherUtil.exe from the server.

That’s it! I am going to test run the package using the below command and you will see it working like it did in the development machine.

dtexec.exe /file "G:\Apps\SCOUT\Executables\ExpressNotice\AdvWrksLocalLostTest\AdvWrksLocalLoad2-Mod.dtsx" /config "G:\Apps\SCOUT\Executables\ExpressNotice\AdvWrksLocalLostTest\AdvWrksLocalLoad2.dtsConfig" /DE test


Fig. 7.5

VIII. Common errors and debugging options

  • If you get any CryptographicException during decryption, it is possible that

1. You are using DPAPI and trying to decrypt information on some other computer.

2. You are using RSA but you have not exported and imported the key pair (that was used to encrypt) yet.

3. The encrypted string is modified in some way or other and hence decryption failed.

  • If you get Connection Manager validations/runtime errors, it is possible that

1. Decryption failed

2. ConnectionString does not contain Password property

3. DelayValidation is set to false and you are getting an error because the ConnectionString property is encrypted. Since it is encrypted, it won’t contain strings like User ID, Password, Initial Catalog, Server etc., hence the validation error.

4. EnableConfiguration is set to true (i.e., Enable package configurations check box is checked in the Package Configuration Organizer wizard. And the design time associated configuration file is either missing or not encrypted).

  • To debug, the easiest way is to add a script task at the top of the package, and try accessing the Connection Manager’s ConnectionString property to see if values are getting decrypted properly. For instance, try logging them, or try a MessageBox.Show(). AdvWrksLocalLoad2.dtsx has a ScriptTask in the beginning that just alerts the ConnectionString values for a few connections.


Fig. 8.1

Or even better, add the package to a an Integration Services Project, set a break point on the ScriptTask and look if the values are getting set correctly.

  • If the Package Processor of DecryptorCode window throws any errors, close all Visual Studio instances, and try Start Processing Below Packages button again.
  • Rule of thumb, when running SSISCipherBoy.exe always Run as administrator.

IX. What now?

Hence you protect sensitive information in your SSIS Xml Config files. While the aforementioned methods describe an automated way of achieving encryption decryption, if any of the tasks fail, you could always try the manual lengthy process, or if you are interested in more information, the glossary section should suffice. Report any bugs, enhancement requests, set up assistance at

X. Glossary

a. Using SSISCipherBoy.exe – Processing multiple packages sharing same config

Under the heading “Step 2 – Using SSISCipherBoy.exe – Make the package ready to decrypt information” we saw how to process a package and make it ready for decryption. In that demonstration we added a package named AdvWrksLocalLoad2.dtsx that used a configuration named AdvWrksLocalLoad2.dtsConfig, which is a very common scenario. Another, common scenario is that we have one configuration file that will be shared by many packages. To make the job easier in these situations, the DecryptCode functionality allows you to add multiple packages to the Package Processor and process them all at one shot.

Let’s imagine that the configuration file named AdvWrksLocalLoad2.dtsConfig is used by multiple packages listed in the figure below.


Fig. a.1

In order to process them, Drag and drop all the packages or double click and select all the packages to the Package Processor of DecryptCode window; hit the Start Processing Below Packages button. Supply password if required, hit OK on the success message that appears after processing each package. If Drag and drop does not work double click and add multiple packages.


Fig. a.2

After processing, the processed packages are stored with a -Mod suffix on the same folder which looks like below.


Fig. a.3

b. Using SSISCipherBoy.exe – Dump SSISCipherUtil.dll to GAC / local directory

The encryption and decryption functionality is provided by the SSISCipherUtil.dll. The SSIS package in our example above that was modified to decrypt information at runtime, uses this dll. And the tool SSISCipherBoy.exe uses the same dll for all its primary operations. However, if you wanted to locate the SSISCipherUtil.dll in the file system, the only location you would find it is in the GAC. In case the assembly installation fails when the SSISCipherBoy.exe loads, you would be required to manually install the SSISCipherUtil.dll to GAC. Or when the package processor fails for some reason, you would want to create a Decryptor ScriptTask yourself manually. And when you create that Decryptor ScriptTask, you would need to Add a reference to the SSISCipherUtil.dll in Visual Studio in order to decrypt values at runtime. In order to accomplish any of these aforementioned tasks, you would need SSISCipherUtil.dll on some known file system location.

Run SSISCipherBoy.exe as administrator. Click the Assembly Administration … link at the top right corner.


Fig. b.1


Fig b.2

Use the buttons to perform the required operations.

c. Manually installing SSISCipherUtil.dll to GAC

Many might have observed that when adding a reference to a third party dll in a ScriptTask, we are bound to get AssemblyLoadException or FileNotFoundException if the referenced dll is not installed to the GAC. SSISCipherBoy.exe tries to install SSISCipherUtil.dll to the GAC at startup. If that does not work you can try installing it to the GAC using the Assembly Administration window. Remember that you need Administrator privileges to perform this task. So you run SSISCipherBoy.exe with administrator privileges at all times. If none of them works, the last resort is to emit the SSIScipherUtil.dll to a specific location and then manually install it to the GAC.

Installing to the GAC is simple.

1à Emit the SSISCipherUtil.dll to some file location (like explained in Glossary X-b)

2à Navigate to C:\Windows\assembly and Drag and Drop the SSISCipherUtil.dll to that folder C:\Windows\assembly. That’s it. You may also try to use the GacUtil.exe which is a program specifically meant for this purpose.


Fig. c.1


Fig. c.2

d. Manually create a ScriptTask to decrypt information

The package processor creates a ScriptTask inside a sequence container in the OnPreExecute EventHandler to decrypt information. If the Package Processor fails for some unknown reasons, you can try processing the package again or create a ScriptTask manually to decrypt information.

1à Create a ScriptTask on top of all other tasks in the Control Flow Tab of the Package Designer. Provide a relevant name.

Double click to open, hit the Edit Script button. Wait for the Visual Studio to load the project.


Fig. d.1

Add reference to the SSISCipherUtil.dll. (If you don’t have SSISCipherUtil.dll at you file system yet, use the Assembly Administration … link in SSISCipherBoy.exe and write the dll to some comfortable location – as in Glossary X-b)


Fig. d.2

4à Once the reference is added, replace the entire ScriptMain.cs code with the code from the DecryptorCode window of SSISCipherUtil.exe. Refer to the steps in Step 2 – Using SSISCipherBoy.exe – Make the package ready to decrypt information to copy the decryptor code.

Build the project; close the ScriptTask after successful build. Hit OK on the Script Task Editor. Save the dtsx package.

That completes everything, and now your package is modified to decrypt information at runtime. Let the ScriptTask and the SSISCipherUtil.dll do rest of the work for you.

e. What does the automatic Package Processor do?

When you add an SSIS package to the Package Processor of the DecryptorCode window, it does the following things:

  1. Tries to load the package at the specified location.
  2. If the package is protected with a password using EncryptAllWithPassword or EncryptSensitiveWithPassword, it prompts to enter the Password.
  3. On successful load of the package, it checks to see if there is an OnPreExecute EventHandler attached to this package.
  4. If an OnPreExecute EventHandler is attached to the package, it gets all the Tasks inside the OnPreExecute EventHandler and adds the DecryptionSequence on top of all those tasks.
  5. If an OnPreExecute EventHandler is not created for the package, it simply creates an OnPreExecute EventHandler and adds the DecryptionSequence to it.
  6. Inside the DecryptionSequence, there are two script tasks.
  7. First is a dummy ScriptTask that leads to the second ScriptTask that does the decryption.
  8. The decryption ScriptTask and the dummy ScriptTask are connected by a PrecedenceConstraint that allows the decryption ScriptTask to run only once during the execution of the package.

i.e., The decryption ScriptTask runs only during the OnPreExecute event of the package, when other tasks in the package fires an OnPreExecute event, the decryption ScriptTask is not called. This is done with the below Expression and Constraint check

@[System::SourceID]== @[System::PackageID]

  1. Sets DelayValidate=true for the package.
  2. Sets EnableConfiguration=false for the package. (the equivalent of un-checking Enable Package Configurations in Configuration wizard)


Fig. e.1

f. How does the cipher algorithm work?

SSISCipherUtil.dll supports DPAPI and RSA as we saw earlier. If you have a basic understanding of cryptography, please read forward, otherwise you may want to review the basics of Symmetric key cryptography, asymmetric key cryptography, and hashing. The following paragraphs are meant to give an overview of how DPAPI and RSA are implemented in SSISCipherUtil.dll. They might not depict the exact flow of how DPAPI and RSA work in SSISCipherUtil.dll. The source code is the only way to identify the exact implementation.


DPAPI – known as the Windows Data Protection API associates the cryptographic key used for encryption and decryption with the Windows User account and uses a machine wide key store. An application level entropy value is passed to the DPAPI method, so that only SSISCipherUtil.dll knows how to decrypt values that were encrypted by SSISCipherUtil.dll. The entropy value is an output of the Rfc2898DeriveBytes method that takes SHA-256 hash of some application wide constant values as input and salt.


RSA – an asymmetric cipher algorithm that in the .Net framework, not meant to encrypt inputs that are larger than the key size specified. In SSISCipherUtil.dll, the RSA algorithm is used to generate an exportable/importable public-private key pair stored at the RSA machine level key store. Later the public key components of the key pair are used to derive an entropy value, and the private key components are used to derive an input. The input and the entropy are later hashed with SHA-256 and sent to Rfc2898DeriveBytes. The output of Rfc2898DeriveBytes is used as a master key for RijndaelManaged algorithm which is a symmetric algorithm that works under the covers to encrypt and decrypt when using RSA.

C:\Users\All Users\Microsoft\Crypto\RSA\MachineKeys is the location in which the RSA key pairs are stored by Windows. That means, when you export/import an RSA key pair, the key pair with the specified key container name is accessed from this location.

References and Further Reading

1. SSIS: Storing Passwords –

2. SSIS: Encrypted Configurations –

3. BI xPress Secure Configuration Manager –

4. Understanding how SSIS configurations are applied –

5. Integration Services Error and Message Reference –

6. Dynamic Package Generation Samples –

7. Samples for creating SSIS packages programmatically –

8. Programmatically recompiling a ScriptTask –

9. RSA class –

10. Windows Data Protection –

11. CspKeyContainerInfo class –

Written by gmaran23

August 8, 2015 at 8:50 pm

Programmatically encrypting sections in a web.config file

leave a comment »


During the talk “Beefing Up Security in ASP.NET – Part 2 at Dot Net Bangalore 4th meet up Aug 08 2015 “ someone asked how to encrypt web.config programmatically. Here’s an extract from a snippet I have used in the past. The below code should help you with the libraries you need to call, it is not complete, some parts of the code are removed. Copy & Paste may not work Sad smile

public static void EncryptConfigurationSection(string configurationSection)
    Configuration configurationFile = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
    AppSettingsSection section = (AppSettingsSection)configurationFile.GetSection(configurationSection);

    if (!section.SectionInformation.IsProtected)
        section.SectionInformation.ForceSave = true;



Someone also asked if there is a way to specifically encrypt a particular attribute alone. I am afraid that is not possible out of the box. You could look at one of my RSCryptoServiceProvider implementation here to get started

Written by gmaran23

August 8, 2015 at 8:00 pm

Beefing Up Security In ASP.NET Dot Net Bangalore 3rd meet up on May 16 2015

leave a comment »

Practical Security Testing For Developers Using OWASP ZAP at Dot Net Bangalore 3rd meet up on Feb 21 2015

leave a comment »




Title Practical Security Testing for Developers using OWASP ZAP
Abstract Every time an application faces the world wide web, it inherently becomes vulnerable to attacks. The attackers could be script kiddies, joyriders, turning from hobbyists to downright hostile. The earlier in the development cycle you find the vulnerabilities, the better they are to fix and test. OWASP ZAP is a free and open source penetration testing tool for finding vulnerabilities in web applications; widely used by security professionals, it is also ideal for anyone new to web application security and includes features specifically aimed at developers. This session shows/demonstrates some attacks against web applications and how OWASP ZAP could be used to find those vulnerabilities, both manually and by automated builds.
Gist See live attacks against web applications and how OWASP ZAP could be used to find those vulnerabilities, both manually and by automated builds.
Speaker Marudhamaran Gunasekaran
Time & Venue 21 Feb 2015 @ Dot Net Bangalore 2nd meet up

Let your IIS worker process crash with StackOverflowException

with one comment


This article was originally published for and could be located at


Months back I posted a screenshot at, finally got time to write it down.


There was a Login page, that did some sort of authorization check beyond authenticating the user, and displayed an Access Denied page for those who weren’t lucky enough. This was all done by the ASP.NET MVC with ASPX view engine. So there’s things like Views, Partial Views, RenderPartial, and so on. The application also was heavily ajax enabled, so partial views really seemed to fit in at many places that did not want to include a master page content in the response text. There was a view file called AccessDenied.aspx that barked at unauthorized users. Things were working fine, and one day something broke, IIS was crashing without any meaningful error message. I lied, actually it did give a meaningful error message that was like – An unhandled exception of type ‘System.StackOverflowException’ occurred in mscorlib.dll. And the Call Stack showed some recursive function call. That is all there was to it.

Let’s look at a POC sample application below. Download the source from github –, Hit F5.




When you click the AccessDeniedForCrash page, the below is what you see. An unhandled exception of type ‘System.StackOverflowException’ occurred in mscorlib.dll. If you look at the Call Stack window, there would be a lot of repeated method calling method.




Let’s look at what happens when a view is requested, as in how the view engine probes the known locations to find the view definition. Click ViewDoesNotExist, and you would see an error page, that actually tells you the file locations that ASPX view engine probed to find a matching view. Pay attention to the search order where a .aspx file is searched first, and then the .ascx file.


Now, if you go back to the StackOverflowExceptionInASPXViewEngine solution, there are two files called AccessDeniedForCrash.ascx and AccessDeniedForCrash.aspx under ~/Views/Home.




The following code inside AccessDeniedForCrash.aspx calls the partial view AccessDeniedForCrash.ascx.


<asp:Content ID="Content3" ContentPlaceHolderID="FeaturedContent" runat="server">
            <section class="featured">
        <div class="content-wrapper">
            <hgroup class="title">
                <% Html.RenderPartial("AccessDeniedForCrash"); %>


A typical programming practice right? You define sub routines, and you keep calling them as and when required. Reusability! You have created a partial view here (AccessDeniedForCrash.ascx), and kept calling the partial view inside the main view (AccessDeniedForCrash.aspx). But it was the ASPX view engine’s probing method that caused the recursive method call. The view engine reached AccessDeniedForCrash.aspx, as it came through the HomeController’s action method AccessDeniedForCrash. It tried to find a partial view AccessDeniedForCrash.ascx,  but always ended up with AccessDeniedForCrash.aspx because of the file search order; you know the rest of the story about recursion without an exit condition.

So, is this a programming error? or the framework error? or the ‘programmer did not understand the framework well’ error?



You may also like –

Written by gmaran23

June 30, 2014 at 7:16 pm

Restoring TFS services after host name and domain binding changes

leave a comment »


This article was originally published for and could be located at


I have a local TFS server set up for testing CI integration of certain tools. The database storage (sql server 2012 express), the application tier, the build agent, the controller everything set up in localhost. I am working with TFS 2012, which TFS services running under <<computername>>\TfsUser.


The computer was recently migrated to another domain, which involved the computer name change, and obviously the domain name change itself. That’s it. TFS services started with 503 Service unavailable. The TFS application pool was stopped, and never started again. The TFS Administrator Console was always throwing all sorts of error messages. I was not prepared for any of these changes, it took me some time to fix all of them and get the CI functionality working flawlessly again. Ironically, all these happened after I happily blogged about Migrate user profiles to new domain account in a jiffy with Profwiz. But, here I am documenting my steps one by one. If your (local) TFS server installation has incurred a domain change, you may find these steps helpful. You may be at best when you follow the steps sequentially. All the steps involve changing the old machine name to the new machine name and fixing the Windows identities.


1. Verify/Update the Application Tier web.config

Navigate to the TFS Application Tier Web Services folder, and edit the applicationDatabase appSettings value. The Data Source should be be <<newcomputername>>\databaseServer.

C:\Program Files\Microsoft Team Foundation Server 11.0\Application Tier\Web Services\web.config



2. Verify/Update the TFS sql server database Logins

I use <<machinename>>\TfsUser as an admin console user. Connect to the sql server where Tfs configurations are saved, Remove the logins with the old machine names. (If the old machine name’s Login exists, then it will result in a SID conflict later during other stages). Add new logins with the new <<machinename>>. Let them have sysadmin permissions.

“TF255507: The security identifier (SID) for the following SQL Server login conflicts with a specified domain or workgroup account: <<oldcomputername>>\user. The domain or workgroup account is: <<newcomputername>>\user.  The server selected to host the databases for Team Foundation Server is: <<newcomputername>>\sql2012express.
You can resolve this issue by renaming the conflicting login.”



3. Verify/Update the Tfs Application Pool identities

Make sure the Tfs Application Pools Microsoft Team Foundation Server Application Pool, and Microsoft Team Foundation Server Message Queue Application Pool in IIS runs under the <<newcomputername>>\<<yourIdentify>>. In my case it is TfsUser.



4. iisreset at will. Couple of time during the entire troubleshooting process.


Try browsing to http://localhost:9000/tfs (or wherever your http://hostname:portnumber/tfs is),  you should be done here if you get the tfs Getting Started screen.

5. Dealing with Sync error for identity

However, If you encounter ‘The trust relationship between this workstation and the primary domain failed’, or the below errors, proceed.

TF53010: The following error has occurred in a Team Foundation component or extension:
Date (UTC): 15-05-2014 18:01:13
Machine: <<machinename>>
Application Domain: TfsJobAgent.exe
Assembly: Microsoft.TeamFoundation.Framework.Server, Version=, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a; v4.0.30319
Service Host: 
Process Details:
  Process Name: TFSJobAgent
  Process Id: 3020
  Thread Id: 4640
  Account name: <<machinename>>\TfsUser

Detailed Message: TF200035: One or more errors occurred when Team Foundation Server attempted to synchronize the following identity: Administrators. Number of errors that occurred: 1.
Sync error for identity: Administrators
The trust relationship between this workstation and the primary domain failed
   at Microsoft.TeamFoundation.Framework.Common.SidIdentityHelper.ResolveSid(SecurityIdentifierInfo securityIdInfo, String& domain, String& userName, AccountType& type, Boolean& isDeleted, Boolean& migrated)
   at Microsoft.VisualStudio.Services.Identity.WindowsProvider.ResolveIdentity(IdentityDescriptor descriptor, String providerInfo, AccountSubType& subType, Boolean& migrated)
   at Microsoft.VisualStudio.Services.Identity.WindowsProvider.TrySyncIdentity(IdentityDescriptor descriptor, Boolean includeMembership, String providerInfo, TeamFoundationRequestContext requestContext, SyncErrors syncErrors, Identity& identity)
   at Microsoft.VisualStudio.Services.Identity.IdentitySynchronizer.SyncOneGroupMembership(TeamFoundationRequestContext requestContext, Identity groupToSync)





Ask your System administrator to Reset the computer account in AD. That is right click on the computer and do Reset Account.


img src –


Then, Start –> Run –> sysdm.cpl , Hit the Network ID… button. Follow the steps to join the computer to a domain. This step would require a Domain Admins account, use your System Administrator’s or AD Administrator’s help, and complete the Join a Domain or Workgroup wizard.


Doing a Reset Account on AD computer account, and Joining it again to the domain via Network ID… made my ‘The trust relationship between this workstation and the primary domain failed’ error disappear.

6. Verify/Update Application Tier’s Notification URL, Server URL, Web Access URL


In Team Foundation Server Administration Console, Click Change URLs in Application Tier Summary, and update the Notification URL, Server URL to the <<newmachinename>>.



7. Unregister/Register the Build service with new machine name

Unregister the build service that uses the <<oldcomputername>>. Register a build service with the <<newcomputername>>. And do the same for the agent and the controller.




That’s should be it. At least the steps that I did to got my TFS installation working again. If you want to check the Check in, and build service, then follow the steps below.

8. Fixing the workspace conflict in Visual Studio TFS Client

Simple solution by Anand is to remove the current workspace the solution was bound to, so the VS TFS Client would automatically create one. I did not have any pending changes.

Open Developer Command Prompt for VS2012, run

C:\Program Files (x86)\Microsoft Visual Studio 11.0>tf workspaces


to see existing workspaces, and remove the workspaces bound to the <<oldcomputername>> with

C:\Program Files (x86)\Microsoft Visual Studio 11.0>tf workspaces /remove:<<oldcomputername>>


TFS client should connect fine now, and should have created a new workspace for you. Map the source control to the local directory.


Edit your build definition to update the Build Controller: to the newly created build controller.



Check in, and see your CI working again with all tests and other configured tools.