hola estoy intentando desencryptar las claves wifi almacenadas en mi pc (solo en windows 7)
para lograrlo uso CryptUnprotectData (el cual me da un error de datos invalidos)
y para que suceda la desencriptacion
el programa debe correr como local system (lsa),lo cual consigo lanzando un servicio(system)
que ejecuta mi aplicacion la cual hereda la sesion del servicio , pero creo ue este metodo no
funciona por el tema de las seciones distintas(system 0) en la que ocurre esta situacion y el
programa no puede comunicarse con mi sesion
mi pregunta es como podria lanzar mi aplicacion como sytem
y cual es el problema con el error de datos invalidos de la funcion desencriptadora

si no me estoy dando a entender bien , diganme y reveo la pregunta
es te es mi codigo

Mostrar/Ocultar

paresco malo ,pero soy bueno
Tengo que reconocer que ha sido un poco dificil leer el código al no estar correctamente indentado, pero pude leerlo finalmente..

El único error que veo con CryptUnProtectData es el que dice, no coinciden los tipos.

Si abres los XML's con el notepad, verás que las claves están almacenadas hexadecimalmente, lo primero que tienes que hacer es convertir esa cadena hexadecimal a string y por último reconvertirlo a bytes, de ese modo la api podrá leer el contenido.

Un saludo.
UDTools.net
GitHub: https://github.com/MetalUDT
jaja si, el codigo esta muy ofuscado,
lo que pasa es que soy muy desprolijo y voy
con copy and paste en el momento y no lo limpo hasta que termine la
idea general .
voy a probar lo de pasar hex a---> string----> byte
y despues te comento
gracias metal.
paresco malo ,pero soy bueno
Vi que en Dudas preguntabas cómo pasar hex string a array of byte, bueno, el proceso consiste en leer la cadena que a simple vista está en hexadecimal, por ejemplo:

FFECFADDA9

Lo he separado por colores para que veas cómo tienes que leer la cadena.

Recorres la cadena, de modo que leas 2 caracteres cada vez, y a esos 2 caracteres le haces un strtoint('$' + 'AquíLos2Caracteres'), eso nos devolverá el ordinal correspondiente a esos 2 caracteres (1 byte), si fuera FF, la cosa sería strtoint('$' + 'FF'); y nos devolvería 255 ($FF).

Una vez tengamos cada byte en un bytearray, los reconvertimos a String, PChar, y finalmente a PByte, que es el tipo correspondiente de pbData, quedando algo tal que así:

Dst.pbData:= PByte(PChar(Dato)); //Dato es de tipo string, como dije

Es lo que se me ocurre, disculpa por explicarme como un libro en llamas.

Saludos
UDTools.net
GitHub: https://github.com/MetalUDT
hola metal , estuve intentando traducir un ejemplo en c++ a delphi
y salio este code (solo lo probe en delphi7 y xp,ya que desmonte mi disco duro con win 7 por el momento)y si bien por las diferencias de so , ya no me arroja invalid data , no se si esta correcto pero creria que funcionara cuando lo lanze desde un servicio en win 7,
mi idea de todo esto es solo postear un recovery de password estilo el de nirsoft ,que si bien es un programa que funciona muy bien me gustaria poder recuperar las claves por mi codigo y asi aprender algo mas
aca esta mi enjendro de codigo

Código: Seleccionar todo

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

    const
     CRYPTPROTECT_LOCAL_MACHINE = 4;//$4
      CRYPTPROTECT_UI_FORBIDDEN = 1;//$1
      CRYPT_STRING_HEX          =4;

type

  TDATA_BLOB = record
    cbData: DWORD;
    pbData: PByte;
  end;
  PDATA_BLOB = ^TDATA_BLOB;

  TCRYPTPROTECT_PROMPTSTRUCT = record
    cbSize: DWORD;
    dwPromptFlags: DWORD;
    hwndApp: HWND;
    szPrompt: PWChar;
  end;
  PCRYPTPROTECT_PROMPTSTRUCT = ^TCRYPTPROTECT_PROMPTSTRUCT;

  TForm1 = class(TForm)
    Button1: TButton;
    Edit1: TEdit;
    Memo1: TMemo;
    Memo2: TMemo;
    Button2: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
    size :dword = 1024;
    byteKey:  array[0..1024] of pbyte;
    key:ansistring;
    Src, Dst: TDATA_BLOB;
    resp:bool;

   function CryptUnprotectData(pDataIn: PDATA_BLOB; szDataDescr: PWChar;
  pOptionalEntropy: PDATA_BLOB; pvReserved: Pointer;
  pPromptStruct: PCRYPTPROTECT_PROMPTSTRUCT; dwFlags: DWORD; pDataOut: PDATA_BLOB
): BOOL; stdcall; external 'Crypt32.dll';

function CryptStringToBinary(pszString: PwideChar; cchString: DWORD; dwFlags: DWORD;
  pbBinary: pbyte; var pcbBinary: dword; pdwSkip: PDWORD;
  pdwFlags: PDWORD): BOOL; stdcall;
  external 'Crypt32.dll' name 'CryptStringToBinaryA';

implementation

{$R *.dfm}


procedure TForm1.Button1Click(Sender: TObject);


 begin
 key:=('01000000D08C9DDF0115D1118C7A00C04FC297EB01000000285EE6A77'
+'AAC7B4A9A2A0E08C8CC4B4200000000020000000000106600000001000020000000'
+'A6BA0828952054CB084F76C48CE6285725701C81E23DE2AB03A990297464'
+'C42D000000000E8000000002000020000000A9EA04DD5762F68E08ABB195E3852BB'
+'3276A75C315C50993C573BB4B8B33B19B10000000CE34ED2930310D148AE080CED5B'
+'88F60400000003615AA7CF32240F37BD2EDC66E8352A3EF865366D18F353BF76CC6C7C24DA'
+'AA01C41E9E0C40A5720FE52151283379E4E069219C4F9A5DDA8970A043DEAA1A0C7');

     //size:= Length(key);


resp:= CryptStringToBinary (pwidechar(Key),length(Key),CRYPT_STRING_HEX, @byteKey,size,nil, nil);




if resp =true then
begin


      dst.cbData:= (size);
       //showmessage(inttostr(size));
       Dst.pbdata :=(bytekey[1]);

if CryptUnProtectData(@Dst,nil,nil,nil,nil,CRYPTPROTECT_LOCAL_MACHINE,@Src) then
begin
showmessage('Texto descifrado: ');
showmessage('password'+shortString(pchar(Src.pbData)));
end
else begin

showmessage(SysErrorMessage(GetLastError));
  //showmessage('error1');
 end;
end;
showmessage(SysErrorMessage(GetLastError));
//showmessage('error2');
end;


en
si ves algun fallo corregilo por favor
saludos
paresco malo ,pero soy bueno
Sí, entiendo lo que quieres hacer.. aunque no importa que se lance como servicio.

Ahora estoy medio borracho, pero.. por qué array of PByte? creo que por ahí está el problema..

Yo haría la conversión exactamente como dije (desconozco la api CryptStringToBinary, sinceramente no recuerdo haberla usado nunca, pero la miraré).
UDTools.net
GitHub: https://github.com/MetalUDT
me parece que va a funcionar en mi imagen no puedo desencriptarla
por que extraje esa codificacion de otro disco mio (con win7) y por lo tanto en xp no tengo las credenciales , si se compila en delphi2010 o posteriores creria que hay que modificar las cadenas
lo de pbyte lo traduje tal cual estaba en el ejemplo en c+ creaban un array de byte para una funcion que recibia un byte(matematicamente no se que carago es un pbyte)
Imagen

igual falta pulirlo (como digo siempre)
sobre lo de obtener privilegios sytem te referis a obtener el token de otro proceso como winlogon, por que en el ejemplo que encontre lo hacian solo desde un servicio , voy a probar como anda en una aplicacion comun.
paresco malo ,pero soy bueno
Me gustó esa api para pasar de stringhex a string, tiene bastante utilidad

Revisando en ic0de algún ejemplo de uso, hice este ejemplo:
function CryptStringToBinary(pszString: PChar; cchString: dword; dwFlags: dword; pbBinary: pointer; var pcbBinary: dword; var pdwSkip: dword;
var pdwFlags: dword): Boolean; stdcall; external 'crypt32.dll' name 'CryptStringToBinaryA';


procedure TForm1.Button1Click(Sender: TObject);
var
  Key: string;
  Bin: string;
  Size: DWORD;
  pdwSkip: dword;
  pdwFlags: dword;
begin
  key:= '313233343536373839';
  Size:= Length(Key) div 2;
  SetLength(Bin, Size);
  CryptStringToBinary(pointer(Key), Length(Key), 4, pointer(Bin), Size, pdwSkip, pdwFlags);

  showmessage(Bin);
end;
Te podría servir para dejar la parte de Dst.pbData así:

Dst.pbData:= PByte(PChar(Bin));

Y ya de seguro desaparecen los errores.

Saludos.
UDTools.net
GitHub: https://github.com/MetalUDT
Aquí lo dejo como creo que está bien, pero ni idea de por qué no funciona, no sé si es que debe correr como System o qué:
program Project1;

{$APPTYPE CONSOLE}

uses
  windows,
  sysutils,
  classes,
  dialogs;

type
  TDATA_BLOB = record
    cbData: DWORD;
    pbData: PByte;
  end;

  PDATA_BLOB = ^TDATA_BLOB;

  TCRYPTPROTECT_PROMPTSTRUCT = record
    cbSize: DWORD;
    dwPromptFlags: DWORD;
    hwndApp: HWND;
    szPrompt: PWChar;
  end;

  PCRYPTPROTECT_PROMPTSTRUCT = ^TCRYPTPROTECT_PROMPTSTRUCT;

function CryptStringToBinary(pszString: PChar; cchString: DWORD; dwFlags: DWORD;
  pbBinary: pointer; var pcbBinary: DWORD; var pdwSkip: DWORD;
  var pdwFlags: DWORD): Boolean; stdcall;
  external 'crypt32.dll' name 'CryptStringToBinaryA';

function Pars(T_, ForS, _T: string): string;
var
  a, b: integer;
begin
  Result := '';
  if (T_ = '') or (ForS = '') or (_T = '') then
    Exit;
  a := Pos(T_, ForS);
  if a = 0 then
    Exit
  else
    a := a + Length(T_);
  ForS := Copy(ForS, a, Length(ForS) - a + 1);
  b := Pos(_T, ForS);
  if b > 0 then
    Result := Copy(ForS, 1, b - 1);
end;

procedure FindFiles(StartDir, FileMask: string; recursively: Boolean;
  var FilesList: TStringList);
const
  MASK_ALL_FILES = '*.*';
  CHAR_POINT = '.';
var
  sRec: TSearchRec;
  DirList: TStringList;
  IsFound: Boolean;
  i: integer;
begin

  if (StartDir[Length(StartDir)] <> '\') then
  begin
    StartDir := StartDir + '\';
  end;

  IsFound := FindFirst(StartDir + FileMask, faAnyFile - faDirectory, sRec) = 0;

  while IsFound do
  begin
    FilesList.Add(StartDir + sRec.Name);
    IsFound := FindNext(sRec) = 0;
  end;

  FindClose(sRec);

  if (recursively) then
  begin
    DirList := TStringList.Create;
    try
      IsFound := FindFirst(StartDir + MASK_ALL_FILES, faAnyFile, sRec) = 0;
      while IsFound do
      begin
        if ((sRec.Attr and faDirectory) <> 0) and (sRec.Name[1] <> CHAR_POINT)
        then
        begin
          DirList.Add(StartDir + sRec.Name);
        end;
        IsFound := FindNext(sRec) = 0;

      end;
      FindClose(sRec);
      for i := 0 to DirList.Count - 1 do
      begin
        FindFiles(DirList[i], FileMask, recursively, FilesList);
      end;

    finally
      DirList.Free;
    end;
  end;
end;

const
  CRYPTPROTECT_LOCAL_MACHINE = 4;

var
  FilesList, datos: TStringList;

  Str, s2: String;
  Src, Dst: TDATA_BLOB;
  i: integer;
  s, t1, t2: string;
  Bin: string;
  Size: DWORD;
  pdwSkip: DWORD;
  pdwFlags: DWORD;

function CryptUnprotectData(pDataIn: PDATA_BLOB; szDataDescr: PWChar;
  pOptionalEntropy: PDATA_BLOB; pvReserved: pointer;
  pPromptStruct: PCRYPTPROTECT_PROMPTSTRUCT; dwFlags: DWORD;
  pDataOut: PDATA_BLOB): BOOL; stdcall; external 'Crypt32.dll';

begin
  try
    begin
      datos := TStringList.Create;
      FilesList := TStringList.Create;
      FindFiles('C:\ProgramData\Microsoft\Wlansvc\Profiles\', '*.xml', true,
        FilesList);

      for i := 0 to FilesList.Count - 1 do
      begin
        datos.loadfromfile(FilesList[i]);
        s := datos.text;
        t1 := (Pars('<name>', s, '</name>'));
        t2 := (Pars('<authentication>', s, '</authentication>'));
        s2 := (Pars('<keyMaterial>', s, '</keyMaterial>'));

        FilesList.SaveToFile((GetEnvironmentVariable('TEMP') +
          '\info redes.txt'));

        Size := Length(s2) div 2;
        SetLength(Bin, Size);
        CryptStringToBinary(pointer(s2), Length(s2), 4, pointer(Bin), Size,
          pdwSkip, pdwFlags);

        Dst.cbData := Size;
        Dst.pbData := PByte(PChar(Bin));

        writeln('ESSID: ' + t1);
        writeln('------------------');
        writeln('Tipo de encriptacion: ' + t2);
        writeln('------------------');
        writeln('Longitud de contraseña cifrada: ' + inttostr(Size));
        writeln('------------------');
        writeln('Contraseña cifrada:');
        writeln(Bin);

        if CryptUnprotectData(@Dst, nil, nil, nil, nil,
          CRYPTPROTECT_LOCAL_MACHINE, @Src) then
        begin
          writeln;
          writeln('Contraseña descifrada:');
          writeln(PChar(Src.pbData));
          readln;
        end
        else
        begin
          writeln;
          writeln('ERROR.');
          writeln;
          writeln(SysErrorMessage(GetLastError));
          readln;
        end;
        datos.Free;
        FilesList.Free;
      end;
    end;
  except
    on E: Exception do
      writeln(E.ClassName, ': ', E.Message);
  end;

end.
UDTools.net
GitHub: https://github.com/MetalUDT
exelente metal, esta duda ya la doy por solucionada hay que ver algunos puntos que se deben mejorar , y para poder desecncriptar la contraseña
se debe ejecutar el exe o codigo desde una cuenta system,
creo que echamos luz en este tema que a mi punto de vista estaba poco documentado en delphi
cuando termine el codigo completo si te intersa te envio el source
saludos y gracias
paresco malo ,pero soy bueno
Responder

Volver a “Delphi”