Blind SQLi techniques

In this quick post I want to collect some cool blind SQLi techniques I recently read about. I will keep this list updated as soon as I find new stuff. For me it is nice to have a list of these techniques online and a lot of visitors are interested in SQLi as well, so I thought I share it πŸ˜‰ If you don’t know what blind SQLi is all about I recommend starting with this article about basic statistical approaches for efficient data extraction.

You can extract data more efficiently and thus safe requests and time by using the following techniques:

update 24.7.11: I just found out that the neat XML parsing function extractvalue includes invalid XML into error messages and can be used as a side channel for data extraction or conditional errors:

SELECT extractvalue(1,concat(0x2e,(SELECT @@version)));
XPATH syntax error: '5.1.36-community-log'

or
SELECT updatexml(1,concat(0x2e,(SELECT @@version)),1);
XPATH syntax error: '5.1.36-community-log'

(also published here)

If you know any other clever techniques please leave a comment.

16 Responses to Blind SQLi techniques

  1. Miguel says:

    hi Johannes!
    the last two techniques are NOT blind injection techniques.

    good recopilation, but I think you should rename the entry πŸ˜‰

    • Reiners says:

      hi miguel,
      well its all a matter of definition. just because mysql errors are shown to the user, doesn’t mean that the injection is not blind (in my opinion). think about an INSERT statement where you can inject into, but will never see the result. then this is a blind SQLi in my opinion, because you have to extract the data by subselects and timing or logic (success/fail) and cannot simply UNION SELECT data. however if mysql errors will be shown you can use those techniques.
      what do you think?

      • Miguel says:

        for me “blind” is equivalent to “not visible data” (in this context), and, at least in the last two, you can see the data already on the screen.

        I’ll never call that blind πŸ™‚ But yes, I know those techniques are quite strange and unclassifiable

      • Reiners says:

        yep, my point is that without these techniques it would be a blind SQLi because you cannot see data on the screen and a few years ago you would extract data char by char in the same scenario for MySQL. however with these not so well known techniques it is possible to extract data within the error message in a blind SQLi scenario (which makes the scenario not blind anymore, but it is still a blind SQL injection vector). well, as I said, all a matter of definition πŸ˜›

  2. Kaiza says:

    Ín Fact it Could be used FOR Blind Injection, but only if Mysql will show the error !

  3. LightOS says:

    I just want to mention that the find_in_set method doesn’t actually require find_in_set, it can be substituted for many other functions. I personally like using LOCATE/POSITION since you can do POSITION(‘a’ IN CHAR(95,96,97,98)) which makes things easier. I feel a more appropiate name for this technique would be POS10BIN since you’re taking the position of the char from the list and turning it 2 (10) binary. Early tests show that this method is able to extract data with 40% less requests than the bitshift.

  4. shp says:

    Hi,
    if you want to reduce the number of requests, why don’t you add overlaped IF in your request like that:
    Id=1 AND IF(ch=1,SLEEP(1),IF(ch=2,SLEEP(2),IF(ch=3,SLEEP(3),IF(ch=4,SLEEP(4),[…]))))

    ch = the character to bruteforce

    If SLEEP bothers you you can make conditional errors instead.

    Shp

    • Reiners says:

      @shp: the problem with this is that you need a different error message per character. that was already adressed with different regexp errors, however if errors are turned on the last 2 techniques in the list are much more efficient.
      @LightOS: thanks for your add πŸ™‚

  5. BlackFan says:

    extractvalue and updatexml with different errors
    https://rdot.org/forum/showpost.php?p=15272&postcount=17

    and short universal injection to detect version πŸ™‚ (Mysql 3-5)
    https://rdot.org/forum/showpost.php?p=15460&postcount=22

  6. Error 403 - forbidden says:

    Hello, i am a big fan of you and your blog and visit very often and id just like to say im over the moon that you have included my tutorial on error based injection with xml functions on your blog, but maybe you would like to update the link with the original tutorial from me.

    Also regarding the comment you said above about an SQL injection in an INSERT statement i have seen it done without errors being shown or blindsqli using error based with a mixture of group by having floor() rand() etc

    Regards.

    • Reiners says:

      sure, just send me the link to your original tutorial and I’ll update the post. Thank you for your positive feedback =)

  7. Syed Afzal says:

    Hi,
    Recently I was testing security of a wb app. It was php having mysql db. The injection point was after orderby! So no chance for union I guess?
    Well, I went for error based. extractvalue could get version,db etc for me. However When I tried to get table name it says “Only constant xpath query are supported ” . Any idea on getting around this one guys?
    Note: It was parameterized query I was dealing with. That too Having 3 layers of security. IDS+IPS+WAF . πŸ™‚
    Payload was squeezed out to 98 character due ” data too long ” error which the app threw. All very tight.
    It was my most stuff and enjoyable sectest πŸ™‚

  8. unknow says:

    Hello And Thank you so much for this great blog i have a very tricky question and i hope that you help me to find an answer let’s suppose that we have this:
    create table users (user varchar(20),pass varchar(20));
    insert into users values(‘admin’,’admin’);
    insert into users values(‘user’,’user’);

    and we have in php file this query
    select * from articles where id=2;

    and we know that the id parametre is vulnerable but the table articles dosn’t exist is it possible to exploit this parametre even if the table articles dosn’t exist

    Thank You

    • Reiners says:

      hi, very interesting scenario indeed, but I don’t think you can exploit this because the query is invalid and nothing will ever be evaluated that you inject.

  9. unknow says:

    Thank you so much Reiners for your help and indeed that’s a very interesting scenario i will try more tricks on it and i hope i can find somthing again Thank you so much

  10. Syed Afzal says:

    Ya there is also NAME_CONST

    and+1=(select+*+from+(select+NAME_CONST(version(),1),NAME_CONST(vers​ion(),1))+as+x)–

Leave a comment