02Dec 2020

General Concept of Runtime Application Self-Protection (RASP)

In this article, we present the general concepts behind a proactive protection mechanism (sentinel RASP) for mobile banking application development

We provide several concrete examples and we offer an insight view, using a C# test project.

Overview of the Project

Here we demonstrate the features of a sentinel system in a mobile context. This system might also be referred to as Runtime Application Self-Protection or simply RASP.

A sentinel system is a background process that is usually not easily detectable. It monitors “in real-time” several parameters associated with the mobile operating system and the applications it protects.

For instance, a sentinel could detect attempts to use an emulator or a debugger. It could also check the integrity of files and scan the memory (flash, RAM, EEPROM) for viruses. A sentinel would have two parts: a “detector” part and a “reactor” part. The detector would signal that it detected possible attempts to attack the application while a reactor would take the proper decision following that information.

In what follows, we will create a small sentinel system, acting as concept proof to concretely illustrate how such a system would work.

Creating a Test Mobile Application

Creating a Test Mobile Application

The Test Banking App “Specifications”

To develop a rapid test mobile application, we shall use visual studio 2008. We will develop a small application in C# for windows phones. Of course, we could develop the same test application for Android or Ios using Xamarin but our application is only created for the purpose of demonstrating the concepts of sentinels.

Our “banking application” will have a log in button with a username and password.

Our small banking imaginary application allows sending directly money to any VISA or MASTERCARD credit card from a funding credit card which has been previously registered and loaded to a remote server.

The program will hash the password using a complicated function taking as input the username, hashed password, and the IMEI of the mobile phone, then send some ciphered data to a remote server, get a ciphered response and then returns to the caller a one-time authorization code acting as a symmetric key K1. Once authenticated, the application offers to transfer money to an account. The application will sign the transaction data using its private key K2, append the signature to the transaction data and cipher the whole thing using the one-time symmetric key K1.

The application will send the following banking transaction data:

Here we explain the meaning of the different parameters.

TIMESTAMPTimestamp computed when the application generates the data
USERNAMEUsername of the user of the application 
HASHED_PASSWORDthe hashed password of the user
IMEIThe mobile phone IMEI
AMOUNTAmount of the transaction in U.S dollars
CARD_RECIPIENTThe 16 digits of the recipient’s credit card
DATE_EXP_RECIPIENTThe expiration date of the recipient’s credit card
CVV_RECIPIENTThe CVV of the recipient’s credit card
FIRSTNAME_RECIPIENTThe first name of the recipient’s credit card
LASTNAME_RECIPIENTThe last name of the recipient’s credit card
FUNDING_CARD_TOKENA token representing the sender’s funding credit card, registered in a token vault

Our goal is to demonstrate how an attacker can break the security of such a protocol and how sentinels can prevent this attacker to do so.
This “imaginary” protocol is not so uncommon as many developers clearly lack serious IT security culture and create often homebrew solutions, especially in the Android world. Rather than asking developers to re-write the application, the sentinels prevent and protect actively that banking application.

functioning of test mobile banking application

Development of the Application

Development of the Application

We will use, as we mentioned earlier, Visual Studio 2008 and the smart Device development kit. We also will need the windows mobile 6 SDK.

We create a new project in Visual 2008.

Of course, the windows mobile 6 is no longer actively supported on actual smartphones and mobile devices – since support from Microsoft stopped in 2013 – but we wish only to present the concept proof of the sentinel. Besides Windows mobile, version 10 is still present on the market – as of 2019 – with the Lumia phones. 

We develop the front-end screens with the fields for the username and the password.

We develop the application by making sure most of the essential functions are coded.

Of course, we lack code quality, we do not control the input from the user and we even do not catch exceptions!

Here is how the test program will work:

The username and password are entered, the password is hashed and sent to a third party library which will contact an authorization server.

String Username = textBox1.Text;
String Password = textBox2.Text;

parameters.username = Username;

String hash_password = Utils.Hash_password(Username, Password);

parameters.hashed_password = hash_password;

//generate access code to DLL
Int32 code = GenCode.GenerateNewCode();

The main form can access the third party protected dll only by generating a one-time code.

That one time-code uses  common counter between the DLL and the caller and generate the code as such:

//generate the one time secret 
        static public Int32 GenerateNewCode()

            Random r = new Random(counter);

            for (int i = 0; i < counter; i++)
                secret = (Int32)((secret * r.Next()) % 100.000);



            return secret;

The Dll is equipped with a few protection against bruteforcing and disable access after a certain amount of unsuccessful attempts. Only that Dll may contact the authorization server.

The dll will then do supposingly some tricky operations and contact the authorization server to receive back the one-time code that will generate the transaction 3DESkey.

Here is the way it is processed on the (stub) bank server, which we represent by a separate dll, StubTestBankServer.dll:

public static long getAnswerfromServerAuthCode(string username, string hash_password)
            //we should validate plenty of things
            //we simply verify that user and password matches our files
            //here there is but just one user in bank!

                //password= !!32!book!DECIDED!

               String res= Utils.Hash_password("hitchcock7","!!32!book!DECIDED!");

                       return getAnswerfromServerAuthCode();

                return 0;


            return 0;

The transaction 3DES key K1 is computed very basically by taking the MD5 hash of the number of CPU ticks at the current date-time. 

Then the user is authenticated and can access the transaction screen.

The form will gather the data from the user and build the transaction flow.

It will compute the IMEI as a security measure so to check the application is not been used on a non-authorized phone as the server as a list of registered phones.

public static String getIMEI()

            IntPtr hSim = IntPtr.Zero;
            byte[] iccid = new byte[10];
            int zero = 0;
            SimInitialize(0, IntPtr.Zero, 0, ref hSim);
            ref zero);
            string serial = FormatAsSimString(iccid);
            return serial;


The program uses a static KEK key which is the same for all phones because it is hardcoded in the program. 

That KEK is used to access 3DES ciphered files located in the temp folder of the phone and containing a unique RSA private key split into components. These files are 3DES ciphered so the private key is supposed to be protected. 

This is how they are retrieved by the application:

public static byte[] getRSAKey(keycomponent comp)

            //read it from the 'database'
            //decipher the key

            TripleDES tdes = TripleDESCryptoServiceProvider.Create();
            //get our 3DES key
            tdes.Key = GenerateThreeDESKeyFromKey(parameters.KEK);

            tdes.Mode = CipherMode.ECB;
            tdes.Padding = PaddingMode.PKCS7;

            StreamReader sr = File.OpenText("\\temp\\KEY" + comp + ".cipher");
            String cipher = sr.ReadLine();

            byte[] ciphered = Utils.StringToByteArray(cipher);

            byte[] decipher = tdes.CreateDecryptor().TransformFinalBlock(ciphered, 0, ciphered.Length);


            return decipher;


Concretely the form will have to call the getRSAKey function for all the key components:

public  class RSACipher 

       private static  RSACryptoServiceProvider rsa =  new System.Security.Cryptography.RSACryptoServiceProvider();
       private static System.Security.Cryptography.RSAParameters rsaparams = new System.Security.Cryptography.RSAParameters();

        public static void LoadKeys()
            rsaparams.P = Utils.getRSAKey(keycomponent.P);
            rsaparams.Q = Utils.getRSAKey(keycomponent.Q);
            rsaparams.Exponent = Utils.getRSAKey(keycomponent.E);
            rsaparams.Modulus = Utils.getRSAKey(keycomponent.MODULUS);
            rsaparams.D = Utils.getRSAKey(keycomponent.D);
            rsaparams.InverseQ = Utils.getRSAKey(keycomponent.InverseQ);
            rsaparams.DP = Utils.getRSAKey(keycomponent.DP);
            rsaparams.DQ = Utils.getRSAKey(keycomponent.DQ);





Finally, the application uses the private key to sign the transaction data which are sent to the remote server ( in fact our stub server –  dll)

Here is an example of the transaction flow sent to the server:

In clear:

Ciphered with signature added at the end:

As we see the application has some non-trivial protection mechanism.

When received by the remote server, the data will be first separated and deciphered by the transaction 3DES key. 

The transaction key is supposed to be checked for its freshness. It cannot be used for a replay attack because it can be used only once.

The transaction data are hashed and compared with the signature:

byte[] b_signature = Utils.StringToByteArray(signature);

            SHA1CryptoServiceProvider sha1 = new SHA1CryptoServiceProvider();

            byte[] h_data2 = sha1.ComputeHash(dc);


            bool result_ =  RSACipher.Verify(h_data2, b_signature);

                return bank_transaction_code.INCORRECT_DATA;

The token is retrieved from a card vault to get the card data using a stub:

credit_card funding_card = Utils.GetCardFromVault(tk);

Finally, we simulate an authorization to a credit card processor.

//simulation of an authorization request to the card processor
        private static bool AuthorizeTransaction(credit_card funding_card, credit_card receiver_card, int sum, string fn_, string ln_)
            //simulating money available on card
            if (sum > new Random().Next(5000))
                return false;
            return true;

Now that we have our test banking application, the fun is just beginning! 

In the next part, we will demonstrate how sentinels can prevent attackers to perform malevolent transactions. You can know whether you need RASP for application security.

Acodez is a leading website design and software development company in India. We offer all kinds of web design and web development services to our clients using the latest technologies. We are also a leading digital marketing company providing SEO, SMM, SEM, Inbound marketing services, etc at affordable prices. For further information, please contact us.

Looking for a good team
for your next project?

Contact us and we'll give you a preliminary free consultation
on the web & mobile strategy that'd suit your needs best.

Contact Us Now!
Jamsheer K

Jamsheer K

Jamsheer K, is the Tech Lead at Acodez. With his rich and hands-on experience in various technologies, his writing normally comes from his research and experience in mobile & web application development niche.

Get a free quote!

Brief us your requirements & let's connect

Leave a Comment

Your email address will not be published. Required fields are marked *