Phrozen Timeline

Read more about this technique HERE

Delphi

program NtSetDebugFilterState;

{$APPTYPE CONSOLE}

uses
  WinAPI.Windows, System.SysUtils;

var
  NtSetDebugFilterState : function(AComponentId : ULONG; ALevel : ULONG; AState : Boolean) : NTSTATUS; stdcall;

  hNTDLL  : THandle;
  AStatus : NTSTATUS;

begin
  try
    hNTDLL := LoadLibrary('ntdll.dll');
    if (hNTDLL = 0) then
      Exit();
    try
      @NtSetDebugFilterState := GetProcAddress(hNTDLL, 'NtSetDebugFilterState');

      if NOT Assigned(NtSetDebugFilterState) then
        Exit();

      AStatus := NtSetDebugFilterState(0, 0, True);

      writeln(AStatus);

      if (AStatus <> 0) then
        WriteLn('Not Debugged.')
      else
        WriteLn('Debugged.');
    finally
      FreeLibrary(hNTDLL);
    end;
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
end.
Read more...

Read more about this technique HERE

Delphi

program IsDebuggerPresent;

{$APPTYPE CONSOLE}

uses
  WinAPI.Windows, System.SysUtils;

begin
  try
    if IsDebuggerPresent() then
      WriteLn('Process is currently getting debugged.')
    else
      WriteLn('Process is not likely getting debugged.');

    readln;
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
end.
Read more...

Read more about this technique HERE

Delphi

program OutputDebugString;

{$APPTYPE CONSOLE}

uses
  WinAPI.Windows,
  System.SysUtils;

var AErrorValue : Byte;

begin
  try
    randomize;

    AErrorValue := Random(High(Byte));

    SetLastError(AErrorValue);

    OutputDebugStringW('TEST');

    if (GetLastError() = AErrorValue) then
      WriteLn('Debugger detected using OutputDebugString() technique.')
    else
      WriteLn('No debugger detected using OutputDebugString() technique.');
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
end.
Read more...

Read more about this technique HERE

Delphi

program SuspendThread;

{$APPTYPE CONSOLE}

uses
  WinAPI.Windows, System.SysUtils, Generics.Collections, tlHelp32, Classes;

type
  TProcessItem = class
  private
    FName      : String;
    FProcessId : Cardinal;
    FThreads   : TList<Cardinal>;

    {@M}
    procedure EnumThreads();
  public
    {@C}
    constructor Create(AName : String; AProcessId : Cardinal; AEnumThreads : Boolean = True);
    destructor Destroy(); override;

    {@G}
    property Name      : String          read FName;
    property ProcessId : Cardinal        read FProcessId;
    property Threads   : TList<Cardinal> read FThreads;
  end;

  TEnumProcess = class
  private
    FItems : TObjectList<TProcessItem>;
  public
    {@C}
    constructor Create();
    destructor Destroy(); override;

    {@M}
    function Refresh() : Cardinal;
    procedure Clear();

    function Get(AProcessId : Cardinal) : TProcessItem; overload;
    function Get(AName : String) : TProcessItem; overload;

    {@G}
    property Items : TObjectList<TProcessItem> read FItems;
  end;

{
  Import API's From Kernel32
}
const THREAD_SUSPEND_RESUME = $00000002;

function OpenThread(
                      dwDesiredAccess: DWORD;
                      bInheritHandle: BOOL;
                      dwThreadId: DWORD
          ) : THandle; stdcall; external kernel32 name 'OpenThread';

{
  Global Vars
}
var LFindWindowSignatures  : TDictionary<String, String>;
    LProcessNameSignatures : TStringList;
    LProcesses             : TEnumProcess;

{
Read more...

Read more about this technique HERE

Delphi

program FindWindowAPI;

{$APPTYPE CONSOLE}

uses
  System.SysUtils, WinAPI.Windows, Generics.Collections, psAPI;

{
Read more...

Read more about this technique HERE

Delphi

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

RunAs Attached (Local) - 32bit / 64bit

RunAsAttached is a program to locally run a new terminal as another user without spawning a new console window.

Very useful during Penetration Tests to escalate as another user without while having an initial shell.

It mimic the "su" program from UNIX systems but for Windows (natively)

Read more...

RunAs (Microsoft Windows) - 32bit / 64bit.

This program is an example about how to easily run any programs as any user.

Usage

Mandatory

  • -u <username> : Launch program as defined username.
  • -p <password> : Password associated to username account.
  • -e <program> : Executable path (Ex: notepad.exe).
Read more...