Header-Bar

Showing posts with label All. Show all posts
Showing posts with label All. Show all posts

June 26, 2013

Stack Buffer Overflow Reverse engineering: OverFlowMe.exe


Hello again and welcome to my blog. I've recently encountered a very nice riddle hitting BoF and RE fans at the same time. This overwhelming riddle takes the trainee another step out of the box, testing he’s capabilities in understanding how to Reverse Engineer a program and maliciously execute a Buffer Overflow exploit. Stay tuned :P
Let’s take a look at the simple executable:


What this innocent file does is legitimately asking a question, waiting for the user to enter reply with his name.
Entering a name will save the string in the stack as a local variable and recall it to the command line as text.


**That’s the right time to say that if you don’t know what RE or BoF is, it will be best if you research a bit about the two and come back when you’re better prepared.
Long story short, RE is of course Reverse-Engineering, the art of crafting a program in a way that a malicious user or a programmer could inject malicious input or extend its functionality respectively. Extending functionality can of course at the same time be to exploit the program to things it’s not supposed to do.

BoF is a short for an vulnerability called – Buffer Overflow. This "bug" is characterized by an injection of malicious string into a program, forcing it to “step out” of its allocated buffer in order to rewrite memory variables and saved areas in a way that will cause a failure or a malicious script to execute.
There are multiple ways to exploit this vulnerability. We’ll be focusing on Stack BoF.
Here’s the deal:


From left to right – Let’s say I wrote a code saying I would like to create a char c[12] array, and initialize it to “hello”;. The stack will look something like the second image.
If you’ll notice the green and red areas – those are the saved areas for the Frame Pointer and the Return Address. Those two are very important, making sure we know where we are on the stack and where to return to.
In my code I've also created a function that rewrites this variable, but I didn't add any restrictions on how to write to this variable. This mistake was expensive, causing a main() loop in the size of 200 ‘A’s to rewrite my stack variable (see image 3) and exceed the buffer, also rewriting the Frame Pointer and the Return Address. When my function will reach its retrun; command it will use the Return Address from the stack which has 0x41414141 (AAAA) in it. This address is of course not mapped and will cause an Access Violation. Windows crashes the application because the lack of an Exception Handler.

Now let’s take a minute to think what would of happened if a malicious user could exploit this vulnerability and create a BoF in that program. Well yeah, the program than crashed, Hacker is happy, but what else?
You’re right, if an attacker can overwrite the Return Address to some REAL address in the Address Space, she can call a malicious code to be executed from the stack. This is exactly what we are about to do!

First thing first, we need to use a disassembler to virtually build the stack and see what exactly do we need in order to exploit this executable.

**I’m using IDA pro (free version) and OllyDBG (IDA is static analysis while Olly can analyze in run-time)


Here is our executable in the static code analysis tool. If we look at the “View-A” window we can see our binary file laid out, row by row, even though it says nothing about how it will be organized in the stack.
On the left of that window we can see the .text representation : [address].
Starting from the first line: EBP is of course our Base Pointer being initialize and mov (move) sets the Stack Pointer in its place (the top of the stack, cause its empty). Then a subtract of 40h (Hex) is being allocated on the stack and the Source Identifier is being pushed to mark the start of a code section.
Then comes the printf() function and its content (mov, push, call). User then inputs a var_40+ebp content into register ‘A’ (eax) and the push stores it in the stack. After this action, the program automatically calls gets() function with the offset of “Hello” and calls (prints) the data stored in var_40+ebp, which is of course the user’s input and prints the rest of the sentence.
Now we know our Stack looks as followed:

40 Hex stack variables
4 Dec – Frame Pointer
4 Dec – Return Address

What I would like to do is to overwrite the whole stack. The problem is that if I’ll do that, the stack will have no Return Address and then I won’t be able to execute my malicious code. To solve this issue I’ll need to create a new/custom Frame Pointer and Return Address so the program will logically run with no errors, keeping the stack in a correct structure.
Here is what I’m about to do:
40 Hex stack variables
4 Dec – Frame Pointer
4 Dec – Return Address
My Frame Pointer
My Return Address














Now that I know what I want to do I need to calculate exactly how much garbage I would like to inject into the program in order to get it to write the new Return Address in the right place. Once I got there, the second step will be to pour an address into my Return Address, which will instantly take me to my malicious code.

Oppsss… wait a second. Take a look at the program again:


Scrolling down the Strings window we can see that the file uses a DLL called MSVCR80.dll which maybe indicates that the program is using this DLL. Looking at the DependencyWalker (next screenshot) we can confirm our suspicion. (next to the red '1').

Let’s check Google for this file’s capabilities, so maybe we can spare calling a malicious DLL, and leverage the attack by calling some function from a legitimate DLL the program uses.

Looking quickly into Google I found that - ”msvcr80.dll is a module associated with Microsoft Visual Studio 2005 from Microsoft Corporation. It is the Microsoft C Runtime Library and is used by programs written with Microsoft Visual Studio 2005.

Conclusions is that maybe this DLL has system() or _execv() capabilities. Using DependencyWalker we would try and find the base address this DLL loads from and find the relative offset of this functions. Here is what I found:




The DLL loads from 0x78130000 and the offset to the system() function is 0x003009B, means we need to add the one to the other using a Hex calculator:
Go to calc.exe (startàrunàcalc) and View as Programmer (Alt+3). Switch Decimal to Hex in the upper left wing of the calculator and simply input the two addresses:


Now we know that in order to call the system() we need to create an overflow in the stack, build some random (4 decimal) Frame Pointer that we won’t be even using so we don’t care about its content and concatenate in with the address to the loaded function, exactly as we calculated right now.
But wait, don’t we missing something? Let’s see again:
      1)      Overflow the program – check!
      2)      Create a new Frame Pointer and Return Address to keep stack logic structure – check!
      3)      Pour into the Return Address our call for the system() function from its original address – check!
Ohh… we’re missing the system()’s argument!

Now we need to find a way to create a pointer to the place where we put our argument. The argument for this example will be “start cmd”, which will open a new Command Line window, waiting for you to maliciously take over the machine.
Keep a close eye because that’s a tricky one. Here’s how the stack should look like:

     Stack abstract            Stack input
40 Hex stack variables
4 Dec – Frame Pointer
4 Dec – Return Address
My Frame Pointer
My Return Address
Pointer to command address
malicious command

AAAAx40H
AAAA
AAAA
BBBB
78 16 00 9B
Some pointer
“start cmd”













**Notice that when we’re injecting addresses we’re using “Little Endian”, which basically says we need to write the address backwards, but keep the Hex. Example: 00 B7 78 16 à 16 78 B7 00

To get the pointer we cannot use IDA pro, because IDA, as we said earlier, is a static binary analysis. If we like to dynamically analyze the code we need a tool that can make this magic happened.
OllyDBG is exactly what we need (you can also use Immunity Debugger or alike).
Why do we need to analyze the program in run-time?
The thing is that we want to know the address of our new code, which will only be created after we run the program and input our string.

Here is the next procedure:



Now we would like to execute the file, input the string that causes the overflow and calculate exactly where the call to system() should end.
Starting the program we can see the binary, and by holding the step over button (F8), until it automatically stops, we get to the following address – 00 18 FF 4C:



This address is of course the location where the user supposed to insert his input. If we’ll look at the Command Line prompt we should see:



Now we have everything we need but a comfortable editor to write our exploit in.
I recommend a nice editor called HxD, but you can also use Hex Editor Neo and others.
Our exploit should look as following:

40Hex (stack variables) + 10Hex (4 Dec Frame Pointer + 4 Dec Return Add + 4 Dec New FP) + MSVCR80.DLL address (system() location) + 4Hex pointer + system command (start cmd)

This how it looks in the HxD:


**Notice that addresses are supposed to be written in the Hex (left) side while ASCII are being written in the Decimal side (right).

Let’s save this file as exploit.dat and do the following:
      1)      Open Command Line
      2)      Go to overFlowMe.exe location
      3)      Run the following command: overFlowMe.exe < c:\filepath\exploit.dat
a.       This command will execute the .exe file and when user-input call initiates, the exploit content will be poured into the gets() location, exploiting the program.
 But wait… we got an error:



Why is that?! We did everything as it supposed to be…
Do you have any idea?
Well I’ve encountered this error and after a quick brain storming with myself I understood that it has to be one of the three options:
      1)      Something is wrong in the overflow
a.       Countermeasure – calculated everything again. It went out exactly the same.
      2)      Something is wrong with the return address – could be.
      3)      Something is wrong with the pointer – couldn't be. If it was a pointer issue the error was different. Trust me on that for now.

Eliminating (1) and (3), I started checking whether the address is wrong. A quick consultation with a friend got me to a very interesting solution. My friend told me that the DependencyWalker only displays a preferred address and that I better double check it in the OllyDBG and so I did.

Here is what I did:
      1)      Open Olly and click on the ‘M’ (Memory) button.
      2)      A window will open, with an organized table containing everything you need to know about your stack memory.
      3)      Look for your DLL under the “owner” column and check what address it is load from.
      4)      In the following image we can see that MSVCR80.DLL PE header is being load from – 74 B0 00 00


Now let’s correct our exploit:
74 B0 00 00 + 00 03 00 9B = 74 B3 00 9B
** 00 03 00 9B is the offset to system()  remember?


Let’s rerun overFlowMe.exe < c:\filepath\exploit.dat


Again an error!
Well now the error is very clear. The pointer is wrong, and the system() gets a command it does not understand. It is equal to – c:\>wrong windows command
Error: “‘wrong’ is not recognized as an internal or external command…”

What is missing?
If we look at the error we see that system() tried to execute a code from our exploit only it executed too early in the code.
Going back to Olly and double clicking the address column on the bottom right table we see that we are in the wrong offset by 8. Double clicking again to go back to the addresses represented by ‘==>’ will probably show us the right address that will execute the right code section.


The address near ‘==>’ is 00 18 FF 54
**don’t forget “Little Endian”
Let’s rewrite the exploit again and see if that fixed our error.

  
Executing the .exe again with our exploits gives us the following:


Viola! We got it. Our exploit worked!
We managed to create a Buffer Overflow, rebuild the stack and execute system(“start cmd”);

Hope you've enjoyed (:



June 10, 2013

TryThis0ne - Enigma Code Riddle: Solved in C#

As we all know the Enigma machine is any of a family of related Electro-Mechanical Rotor Cipher machines used for the encryption and decryption of secret messages.
Enigma was invented by a German engineer back in the second decade of the last century, right after the 1st World War.
Adopted by military and governments the Enigma became very popular from the early 20's.


But enough history for now.
A very good friend of mine [cp77fk4r] wrote a very nice challenge based on one variant of the Enigma machine.

Here is a quick snapshot of the challenge:


IMAGE I

**The riddle can be found in: www.TryThis0ne.com

Let's see what it says:

"As you can see by the diagram that our spy achieved, there are 3 boards: A, B and C. After each type, board A will move one level up, and board B will move one level down. Board C is a routine and its a reflector in this machine" 
"We got an encrypted key: XRSPVIQOLWY" (10 chars total)
"We need to pull out the original key"

"Hint:"
"As we know, one of the boards was unplugged"

You can solve this one manually, but it will take you a day or two of frustrating finger to finger walk through. So I've decided to solve this 0ne by writing an automated script that will print the path of each letter in each iteration so I can sit back and enjoy looking at my creation as its solving the cipher in less than 1 seconds.

I've chosen to use C# on Visual Studio 2012 Enterprise Edition, but you can use any language and platform you feel comfortable with. 

How did I do it? you'll be amazed to know how easy it is. Let's start.
First thing you can do is look at the blocks A and B. What do you see?
They are the same. So that means ttthhhhaaatttt... right, the dictionary is also the same.
But wait, let's create a routine just to make sure we are correct about how the path from one letter to another looks like.
Let's for example take 'A' where our counter (the boards are moving on each iteration, right? so the first iteration has 0 moves) equals 0.

IMAGE II

So 'A', while counter equals 0, is pointing to 'B' and as you can see we walked through 5 blocks:
1) A
2) B
3) C
4) B backwards
5) A backwards

But A and B are equal, so how many dictionaries do we need? not 5, right.
Take out a pen and a piece of paper and right down your dictionaries.
After you've manually created a dictionary of the A-Z Key:Value it is now time to write some code!

We know that our Key is changing at each block (reminder: our Key is the letter that starts as a cipher and ends at the final step of the Enigma as text). Furthermore, we need to count our iterations in order to calculate the number of moves (up or down) of each block, A and B.

Example:
If our Cipher is "SECRET" so the 2nd iteration is Key='E' and the counter is 1 (cipher[1]). the function A will add 1 to the Key and the function for B will subtract 1 from the Key (simulating the up & down movement).

static int counter = 0;                                          
static char key;                                                  

Next we need to create this static string being typed by the user. You can improve your code later to be dynamic, but for now we will use a simple array to make sure that the Text becomes Cipher and returns safely as the same Text we sent earlier.
in the main() create the following array:

var textFromUser=new[] {'M', 'Y', 'S', 'E', 'C', 'R', 'E', 'T'};   

and another empty array that will later collect each letter's result into one string.

char[] array = new char[20];                                      

There are many ways to create this script, but one method is to create a function for each block.
Let's see how:

1) create a static void <Block name> function that takes a single char from the Cipher as a variable on each call. 
2) your char is the characters located in your static array i.e. MYSECRET.
3) we would like to make sure that the letter (Key) finds its Value according to the dictionary we built earlier.

Creating the function for each block, we have to remember that the blocks are round. This means if I get to the letter 'A' in block B after one iteration (-1) 'A' will take 'Z's path, but in ASCII 'A'-1 equals '@'

IMAGE III

'@' = 64
'A' = 65

Which means we need to add to the tmp variable ,that stores the the current Key, the size of dictionary to prevent it from getting out of boundaries. Again, there are multiple ways to do it, that's only an example. 
- Dictionary.count = 26 (A-Z)
'@' + 26 => 64 + 26 => 90 => char(90) is 'Z'

Here is a quick snippet:

if (cipher + counter < 'A')                                      
      tmp += (char)dictionary.Count;                             
if (cipher + counter > 'Z')                                      
      tmp -= (char)dictionary.Count;                             

*Use debugging to make sure the round routine is working.

Now that we know we are always within bounds (A-Z) we need to create a Key:Value search inside the dictionary and determine a True/False state. There are other methods in C# that can search within a dictionary in O(1), but I wasn't after improving complexity so I used a foreach loop.

So for each element in the dictionary, we would like to check whether its Key equals to our tmp and a True statement will then store the Value of that Key into the static variable 'key'.
**Remember to add/sub the counter from the value to include the movement of the blocks

To save a bit time in debug mode, break; the foreach after finding the Key.

Here is a quick snippet:
                
foreach (var element in dictionary)                              
{                                                                
                                                                 
   if (element.Key == tmp)                                       
   {                                                             
      key = (char)(element.Value - counter);                     
      if (key < 65)                                              
      key += (char)dictionary.Count;                             
      if (key > 90)                                              
      key -= (char)dictionary.Count;                             
                                                                 
      break;                                                     
   }                                                             
}                                                                


**Notice that A and B are supposed to be the same function, only in Main() - A takes the first char from the textFromUser while B (and the others) takes the Value of the Key that came out of block A.
In our example it is of course the static char key;

After creating all the functions all that is left is to complete the Main() function.
We started with writing 2 arrays, now we need to take each char of the array into the journey of the Enigma machine and check the output as input once more to make sure we're returning back to our textFromUser.

Create a loop that calls the functions one by one (see under IMAGE II), then writes the output of the textFromUser[i]  to the same location [i], but in the empty array.
Your empty array will be used as a container for checking back the cipher created.

If everything was created as it should
MYSECRET should pop out of the machine as PKHAIMOY.

IMAGE VI


Return the cipher back to MYSECRET and your done!

Now place the real cipher in the array.

Ohh and don't forget the Hint (:

May 22, 2013

Stored Cross-site Scripting in Linkedin





Hello all,


Since Linkedin has no bug bounty program, all you need to do when finding one is to inform them about the vulnerability and you can post away.

The following vulnerability was found while I was using Linkedin's customer support, submitting a question regarding my account.


This request created a Ticket in the system with the form's details.
As you probably haven't noticed yet, the form has a [Browse] option to upload files regarding the form.
A smart move from Linkedin will be to send the attached file to an inaccessible directory within the application's server. for instance:
/var/www/help.linkedin.com/TheWebSite/upload-a-file-with-form --> user uploads file

/var/www/uploads/files/ --> file will be saved here

Instead of doing that, Linkedin created the ability for the user to watch his file after upload.

At first I didn't believe the possibility of this happening so I haven't even tried to upload a file.
Instead I went to the "Support History" Just to check that my ticket is Open.


Now after opening the ticket to review. I noticed an odd feature - Update your ticket.
So I thought to myself: "Well if I'm updating my ticket.. I will be able to view the update, right?"
The update includes a file.. so...


As you can see, after a quick exploit of that upload module I tried some more variants.

Furthermore, the blue marker  on the files names is of course a link to its path on the server.
Pressing that link will take you to the malicious Javascript.

Here is the path: http://help.linkedin.com/ci/fattach/get/2430905/1369216961/filename/ticket.html
**Don't worry, the script is only <script>alert(document.cookie)</script>



Let's fix that:

In order to prevent a malicious user from executing malicious scripts we first want to create a secured environment for the script to execute from. Away from the users permissions.
So first solution will be to store the file "behind" the application, and apply the right permission on that directory and files.

2nd solution will be to create a WhiteList of file extensions saying: "Hi dude, This file you're trying to upload is not registered in our list of permitted files, so please stop making a fool out of yourself!"
The code should look something like that:
---------------------------------------------------------------------------------------------------------------
if(file.extension(equals(jpg) || file.extension(equals(doc) || file.extension(equals(pdf)){
//upload the file
}
else {
 print("Hi dude, only the following are allowed: jpg, doc, pdf");
}
----------------------------------------------------------------------------------------------------------------

Consider restricting the size of the file to prevent exhausting the server resources and maybe also set the Content-type: HTTP header to render the page as text, preventing unrestricted executions.

I can think of more solutions, but I'll leave you to it.

Hope you enjoyed reading.

Ido Naor



April 6, 2013

Attack on Israel : How to stay protected

Hello everyone,

As we all know, April 7th 2013 was marked as a day of digital terrorism in the cyber space. The day was marked by the famous Hacktivists group Anonymous and the target was the Israeli cyber space including: banks, government, social media, service providers, academy and more.

We as civilians of Israel are mostly worried about our personal information resides in our banks, social media servers and Mail service providers. Any information captured by those Hacktivists will probably be published and distributed immediately in the world wide web, never to be returned. Also a risk of malicious usage in this information should be taken into account.

In order to keep you on the safe side I would like to share the following list for you to follow.

I promise that if you follow those instructions, the chance for you being a victim in this attack will decrease eve to 0%.

List of Do's and Don'ts:
1. First of all, change your main passwords: Facebook, Mail, Paypal, banks, Ebay etc. But how?
- Your password should contain at least 10 characters.
- Your password should contain Upper case letters (A,B,C) with Lower case letters (a,b,c), numbers and special characters (#,$,&,@).
- Your password should not contain:
First name
Last name
Middle name
Date of birth
Family members or spouses.
Any other famous dates
Known passwords (12345, 1q2w3e etc.)

- Do not use the same password in 2 different sites.

- Keep track of your Credit Card transactions.

- Go to Google: search for your name and other private information and try to remove any information you find irrelevant such as account one online stores, registration you made to newsletters and more.

- Avoid opening E-mail you're not sure of their integrity.

- Avoid logging into accounts from computers other than your personal one.

- Avoid download new updates for the upcoming week.

- Avoid clicking on links in Facebook or any other sites that provide a "check" to see if you're protected.

If you have any other questions, don't hesitate and simply leave a comment.

May the force be with you,

Ido Naor

February 25, 2013

Not Fedex - Malware attack; Spamming with fake receipt


Written by Bob "Wiz" Feinberg - Wiz's Blog
I want to alert my readers to a spam run I saw over the last couple of days and also explain what the purpose of the scam really is. This is a new variation of a long-running scam spoofing both your Post Office and a major brand courier service, leading directly to a malware attack.
This particular variant may well become the template for ongoing spam campaigns, if the success rate is high enough. Right now, 'tis the season to receive gifts and the bait in this email scam may well trap a lot of eager folks who just may be waiting for a promised delivery of a present or online purchase.
It starts with a message claiming to be from either "Worldwide Express Mail," or "Shipping Service," or "Postal Service," with an incomprehensible "tracking" or ID number as the subject. Most have this body text, or something almost the same as this:
Your parcel has arrived at the post office at December 20.Our courier
was unable to deliver the parcel to you.
To receive a parcel, please, go to the nearest our office and show
this receipt.
DOWNLOAD POSTAL RECEIPT
Best Regards, The FedEx Team.
Here is where wisdom and suspicion are your best friends. The message text contains horrible grammar, and both a reference to a "POSTAL RECEIPT" and to "FedEx." I hope that most of you are aware that FedEx is a courier service and is NOT associated with the "Postal Service," nor do they issue "Postal Receipts." You Country's official Postal Service does that. Yet, almost every email courier scam I have seen over the last year confuses at least two, if not three services: the US Postal Service (USPS), FedEx (a private company) and UPS (United Parcel Service).
If you receive one of these failed delivery scams and you see any sign of confusion about who was supposedly delivering the package, usually accompanied by bad grammar and sentence structure, delete it immediately.
So, if this is a scam, what is the payload and what is its purpose?
In some of the courier scams you are presented with an attachment (attached file). In others you are given a clickable link. Both of these methods are used to deliver malicious executables to your computer. But, in these current scams there is a link that downloads what would usually be an attached "Zipfile," which contains a concealed executable with the same name as the Zip file. In the current scam, the carrier file is named: "PostalReceipt.zip" and the unzipped executable payload is named "PostalReceipt.exe."
These files are not hosted by the Post Office, Postal Service, FedEx, or UPS, but are hosted on infected computers. Their job is to present you with a pop-up download box, offering the options to Open/Run or Save the Zip file. The payload is disguised as a printable receipt that one needs to claim their undelivered package, so it is understandable that many unwary people might choose to open or run that file.
What is inside PostalReceipt.zip and PostalReceipt.exe?
The Win32/Kuluoz.B Backdoor Downloader Trojan.
Once activated, this malware silently proceeds to download other malware, such as bank account stealing Trojans, or fake anti-virus, like the current crop of rogues called "Microsoft Antivirus 2013." This malware begins to scan your computer and displays an alarming number of fake detections of bad software, then tries to scam you into paying about a hundred bucks to remove the alleged threats. Other payloads may be a type of malware that locks your PC until you pay a (Police, FBI, etc.) ransom, which they call a "Fine."
If you read this before you encounter one of these scams, you will save yourself the trouble or expense of disinfecting your computers. If you fall for one that delivers a banking Trojan, you may not have any money left in your bank account to pay anybody to disinfect the PC!
These threats morph every few days, or on a weekly basis, as does the file names in the attachments, or at the end of poisoned links. Don't assume that your anti-virus already knows about these new files. It may or may not. It really takes about a day before all of the major anti-malware companies identify these variants and push out definitions to block them. You are the first line of defense! Stay alert now and forever! The bad guys really are out to get us. Chance favors the prepared mind.
If you did click on a poisoned link, you need to disinfect your computer. Here are some options for you to employ:
Have a safe, virus-free and very Merry Christmas!

October 17, 2012

Second Order SQL Injection


Taken From: http://www.esecforte.com/our-blog/

I always thought that escaping single quotes in a string based user input used for database transactions will prevent SQL injections..but this is not always the case when single quotes are escaped inconsistently (as we will see in this blog).
Say hello to SQL injection of the second order !
Basically second order SQL injections take place when one functionality of a web application takes a user input from a user, escapes (not strips) all SQL metacharacters and inserts that data input into a database. Next, some other functionality of the same application uses that data to craft another SQL query to do a database transaction without escaping that data first (bad idea!). The database transaction done by the second functionality introduces a SQL injection bug in the web application known as second order SQL injection.
I have’nt heard of any second order SQL injection attacks on real world targets, so decided to make up an example attack myself. Following are the two functionalities with their respective codes (select.php and insert2.php).
 The first functionality inserts data into the database. The second functionality uses the data inserted into the fname column to craft a SQL query and get data from the database and show it on the frontend. For making it easy to understand, all the SQL queries run by the web applications are also shown on the frontend.
Lets do a basic walk through of the applications. First using insert2.php, our details are inserted as shown:-
As we can see from the second pair of examples, this application escapes any single quotes while inserting data into the database. Now, lets use select.php to get the inserted data.

This application also escapes the user input as shown, queries the database using that value. The fname value we get from the first query is used to run another query to get all the data about a user. We can see from select.php code that the second query does not escapes the fname value returned from the database and uses that value directly to get all data. This is the point of our second order SQL injection.
So to manipulate the second query of this application in a meaningful way, we will have to inject a SQL query in the first name field of insert2.php and make sure the query is correctly formed and then use select.php to trigger the vulnerable query. We open the application insert2.php and inject the value ” aaaa’ union select version(),2,3,’a ” in the first name field as shown:-
Now, we open select.php and insert the name “attack” and hit enter to get the following:-
Allright!! we were able to exploit the vulnerability to run an arbitrary query on the database. Similarly, we can use advanced SQLi to gain unauthorized access to the database.
The way that the application was vulnerable to second order SQLi is very unlikely in real world and this was only used to demonstrate the exploitation of this vulnerability. Hope the explanation was clear and everyone liked it :)
Cheers!!

** Taken from: http://www.esecforte.com/our-blog/