Run application as system with interactive system process support (active Windows session)
This technique doesn't rely on any external tools and doesn't require a Microsoft Service.
It spawns an NT Authority/System
process using the Microsoft Windows Task Scheduler then upgrade to Interactive System Process using cool WinApi's (Run in Active Windows Session)
Read more...
Power Remote Desktop is a fully functional Remote Desktop Application entirely coded in PowerShell.
It doesn't rely on any existing Remote Desktop Application or Protocol to function. A serious advantage of this application is its nature (PowerShell) and its ease of use and installation.
This project demonstrate why PowerShell contains the word Power. It is unfortunately often an underestimated programming language that is not only resumed to running commands or being a more fancy replacement to the old Windows command-line interpreter (cmd).
Read more...
PowerBruteLogon is a ported version of WinBruteLogon in pure PowerShell
⚠️ Notice: this version is slower than WinBruteLogon but has the serious advantage of being 100% entirely coded in PowerShell. In a near future, password attempts will be distributed to separate threads to speed up the process. Also keep in mind that this method is very noisy, each failed attempt will get logged on Microsoft Windows Event Logs.
You might find useful information about the technique used in this PoC here
Read more...
This code snippet demonstrate how Malware authors take advantage of certain Windows API's to detect the presence of Windows Services that might indicate the presence of Virtualization Technologies and/or Sandbox in order to adapt their behavior and escape detection.
Read more...Weakness Description
Microsoft Windows suffer from a serious lack of protection in their authentication mechanism which could led in privilege escalation.
Indeed, in default installation of Windows (all version), the account lockdown policy is disabled plus authentication API's doesn't limit number of attempts per seconds which could led to a medium to fast brute-force attacks.
Using our PoC and depending of the number of cores available in the target system you could test from few thousands to dozen of thousands of password per second.
Considering that those kind of authentication API's could be used by any Windows account, even a Guest user could use the PoC to recover / crack the password of any local user and escalate his privilege.
Read more...Tiny delphi unit to get and update debug flag from PEB (Process Environment Block).
This unit was created while working on a friend project called Unprotect (@fr0gger_), https://github.com/fr0gger/unprotect
Indeed, some Malware often check the value of Debug flag to know whether or not they are getting debugged and apply anti debug techniques if this is the case.
Example of implementation can be found there
(*******************************************************************************
Author:
-> Jean-Pierre LESUEUR (@DarkCoderSc)
https://github.com/DarkCoderSc
https://gist.github.com/DarkCoderSc
https://www.phrozen.io/
License:
-> MIT
*******************************************************************************)
unit UntPEBDebug;
interface
uses Windows;
const PROCESS_QUERY_LIMITED_INFORMATION = $1000;
PROCESS_BASIC_INFORMATION = 0;
// https://docs.microsoft.com/en-us/windows/win32/api/winternl/nf-winternl-ntqueryinformationprocess
var _NtQueryInformationProcess : function(
ProcessHandle : THandle;
ProcessInformationClass : DWORD;
ProcessInformation : Pointer;
ProcessInformationLength :
ULONG; ReturnLength : PULONG) : LongInt; stdcall;
hNTDLL : THandle;
{$IFDEF WIN64}
type
PProcessBasicInformation = ^TProcessBasicInformation;
TProcessBasicInformation = record
ExitStatus : Int64;
PebBaseAddress : Pointer;
AffinityMask : Int64;
BasePriority : Int64;
UniqueProcessId : Int64;
InheritedUniquePID : Int64;
end;
{$ELSE}
type
PProcessBasicInformation = ^TProcessBasicInformation;
TProcessBasicInformation = record
ExitStatus : DWORD;
PebBaseAddress : Pointer;
AffinityMask : DWORD;
BasePriority : DWORD;
UniqueProcessId : DWORD;
InheritedUniquePID : DWORD;
end;
{$ENDIF}
function GetProcessDebugStatus(AProcessID : Cardinal; var ADebugStatus : boolean) : Boolean;
function SetProcessDebugStatus(AProcessID : Cardinal; ADebugStatus : Boolean) : Boolean;
implementation
{-------------------------------------------------------------------------------
Open a process and retrieve the point of debug flag from PEB.
If function succeed, don't forget to call close process handle.
-------------------------------------------------------------------------------}
function GetDebugFlagPointer(AProcessID : Cardinal; var AProcessHandle : THandle) : Pointer;
var PBI : TProcessBasicInformation;
ARetLen : Cardinal;
begin
result := nil;
///
AProcessHandle := 0;
if NOT Assigned(_NtQueryInformationProcess) then
Exit();
///
AProcessHandle := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_WRITE or PROCESS_VM_READ, false, AProcessID);
if (AProcessHandle = 0) then
Exit;
if _NtQueryInformationProcess(AProcessHandle, PROCESS_BASIC_INFORMATION, @PBI, sizeOf(TProcessBasicInformation), @ARetLen) = ERROR_SUCCESS then
result := Pointer(NativeUInt(PBI.PebBaseAddress) + (SizeOf(Byte) * 2))
else
CloseHandle(AProcessHandle);
end;
{-------------------------------------------------------------------------------
Retrieve the target process debug status from PEB.
ADebugStatus = True : Target process debug flag is set.
ADebugStatus = False : Target process debug flag is not set.
-------------------------------------------------------------------------------}
function GetProcessDebugStatus(AProcessID : Cardinal; var ADebugStatus : boolean) : Boolean;
var hProcess : THandle;
pDebugFlagOffset : Pointer;
pDebugFlag : pByte;
ABytesRead : SIZE_T;
begin
result := false;
///
pDebugFlagOffset := GetDebugFlagPointer(AProcessID, hProcess);
if not Assigned(pDebugFlagOffset) then
Exit();
///
try
getMem(pDebugFlag, sizeOf(Byte));
try
if NOT ReadProcessMemory(hProcess, pDebugFlagOffset, pDebugFlag, sizeOf(Byte), ABytesRead) then
Exit;
///
ADebugStatus := (pDebugFlag^ = 1);
finally
FreeMem(pDebugFlag);
end;
///
result := (ABytesRead = SizeOf(Byte));
finally
CloseHandle(hProcess);
end;
end;
{-------------------------------------------------------------------------------
Update target process debug flag.
ADebugStatus = True : Set target process debug flag.
ADebugStatus = False : Unset target process debug flag.
-------------------------------------------------------------------------------}
function SetProcessDebugStatus(AProcessID : Cardinal; ADebugStatus : Boolean) : Boolean;
var hProcess : THandle;
pDebugFlagOffset : Pointer;
ADebugFlag : Byte;
ABytesWritten : SIZE_T;
begin
result := false;
///
pDebugFlagOffset := GetDebugFlagPointer(AProcessID, hProcess);
if not Assigned(pDebugFlagOffset) then
Exit();
///
try
if ADebugStatus then
ADebugFlag := 1
else
ADebugFlag := 0;
if NOT WriteProcessMemory(hProcess, pDebugFlagOffset, @ADebugFlag, SizeOf(Byte), ABytesWritten) then
Exit;
///
result := (ABytesWritten = SizeOf(Byte));
finally
CloseHandle(hProcess);
end;
end;
initialization
{
Load NtQueryInformationProcess from NTDLL.dll
}
_NtQueryInformationProcess := nil;
hNTDLL := LoadLibrary('ntdll.dll');
if (hNTDLL <> 0) then
@_NtQueryInformationProcess := GetProcAddress(hNTDLL, 'NtQueryInformationProcess');
finalization
_NtQueryInformationProcess := nil;
if (hNTDLL <> 0) then
FreeLibrary(hNTDLL);
end.
Read more...
You will find below 4 different techniques to close/kill/terminate Windows process in pure WinAPI.
Techniques
TerminateProcess()
: Classic method.ExitProcess()
: via Code Injection (32bit to 32bit ; 64bit to 64bit).Crash Process
: Inject code that will crash the process (32bit to 32bit ; 64bit to 64bit).CTRL_CLOSE_EVENT
/WM_CLOSE
: Send "close" messages to target process windows.
TerminateAProcess()
Method
Kill target process id following desired method : tmpAll
, tpmTerminateProcess
, tpmExitProcess
, tpmCrash
, tpmMessage
tmpAll
attempt to kill process from cleanest way to dirtiest way until it succeed.
You will find below an example of how to enumerate process modules using the well known Windows API CreateToolHelp32Snapshot()
, I will cover additional methods soon.
You may notice that when using CreateToolHelp32Snapshot()
, first result (row) is generally the Image Path of the process owning module. I ignore that row by checking the value of szExePath
with owner process image path.
GetProcessName()
is compatible since Windows Vista. It is possible to support Windows XP and below but not in this example.
You will find GetProcessName()
and alternatives in separated snippets threads.
This one possible technique (through QueryFullProcessImageNameW
) to get process image path from it id.
This example support Windows Vista to latest Windows version (Actually Windows 10)
I will cover other example progressively and compatible with Windows XP and below.
// Jean-Pierre LESUEUR (@DarkCoderSc)
//...
uses Windows, SysUtils;
//...
function GetProcessName(AProcessID : Cardinal) : String;
var hProc : THandle;
ALength : DWORD;
hDLL : THandle;
QueryFullProcessImageNameW : function(
AProcess: THANDLE;
AFlags: DWORD;
AFileName: PWideChar;
var ASize: DWORD): BOOL; stdcall;
const PROCESS_QUERY_LIMITED_INFORMATION = $00001000;
begin
result := '';
///
if (TOSVersion.Major < 6) then
Exit();
///
QueryFullProcessImageNameW := nil;
hDLL := LoadLibrary('kernel32.dll');
if hDLL = 0 then
Exit();
try
@QueryFullProcessImageNameW := GetProcAddress(hDLL, 'QueryFullProcessImageNameW');
///
if Assigned(QueryFullProcessImageNameW) then begin
hProc := OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, false, AProcessID);
if hProc = 0 then exit;
try
ALength := (MAX_PATH * 2);
SetLength(result, ALength);
if NOT QueryFullProcessImageNameW(hProc, 0, @result[1], ALength) then
Exit();
SetLength(result, ALength); // Get rid of extra junk
finally
CloseHandle(hProc);
end;
end;
finally
FreeLibrary(hDLL);
end;
end;
Read more...
This unit demonstrate how to enumerate DLL exported functions through PE Header manipulation.
Features
- Support both 32 and 64bit DLL's.
- Identify exported function names.
- Identify exported function ordinal value.
- Support and resolve forwarded function.
- Identify export function address and relative address.