Einzelnen Beitrag anzeigen

Benutzerbild von Remko
Remko

Registriert seit: 10. Okt 2006
Ort: 's-Hertogenbosch, Die Niederlande
222 Beiträge
 
RAD-Studio 2010 Arc
 
#12

Re: Password hash in RDP files

  Alt 29. Mär 2007, 10:59
Yes I should have noticed you used CamelCase. I will test with my Delphi version (BDS 2006) and confirm, I'm assuming you're right and the documentation is wrong. As for the SHR thing I copy/pasted this from http://www.delphibasics.co.uk/RTL.asp?Name=Shr.
Personally I do think using shr is clever and probably faster than div.

http://www.merlyn.demon.co.uk/del-bits.htm:
Zitat:
The basic Delphi operations are shl and shr, apparently on the unsigned bit patterns. One can also use *2 and div 2 which should treat the sign of the value arithmetically.

Be careful about possible unexpected (or needed) behaviour of the leftmost bit on a shift right, or vice versa; it appears ill-defined, and may (or perhaps should) depend on whether the type is signed.

Consider that a variable of a small type, such as a shortint, may be extended before the operation is carried out. Check, in particular, what happens with shr and div on a negative value.
I conclude that shr is allright with positive values, therefore fine in this solution.

Not really sure what you mean by this sentence: First class function result types are all those types which are intended to be used in an expression.


Something in else (in case anyone finds it usefull):
Below a sample to create an rdp file in UniCode and start a session with it. It uses Rijndael encryption to hide the real password.
To make it secure you should hide the secret and delete the rdp file after connecting.

Delphi-Quellcode:
uses uRDPHash, Windows, JwaWinNt, SysUtils, Classes, shFolder, LbCipher, LbClass;
{$R *.res}
const
   BOM_UTF16 = $FEFF; // BOM = Byte Order Mark
var
   fs : TFileStream;
   BOM : WideString;
   sFolder: string;
   sRDPFileName: string;
   LocalAppData: PAnsiChar;
   lpRect: TRect;
   Helper: TLbRijndael;
   sServer: string;
   si: _STARTUPINFOW;
   pi: PROCESS_INFORMATION;
   pwCmdLine: PWideChar;
   pwMsg: PWideChar;
const
  SHGFP_TYPE_CURRENT = 0; // current value for user, verify it exists

procedure WriteLnFs(var fs: TFileStream; sLine: String);
var ws: WideString;
begin
  ws := WideString(sLine) + WideChar($0D) + WideChar($0A);;
  try
    fs.WriteBuffer(ws[1], Length(ws) * SizeOf(WideChar));
  except
    // Handle Exception
  end;
end;

begin
  // Set folder path
  sFolder := 'C:\Temp\gprmc.rdp';

  // Try to find LocalAppData folder
  GetMem(LocalAppData, MAX_PATH);
  if ShGetFolderPath(THandle(nil),
                     CSIDL_LOCAL_APPDATA,
                     THandle(nil),
                     SHGFP_TYPE_CURRENT,
                     LocalAppData) = S_OK then
  begin
    // and create GPRMC subfolder
    sFolder := String(LocalAppData + '\GPRMC');
    if not DirectoryExists(sFolder) then
    begin
      MkDir(sFolder);
    end;

    sRDPFilename := sFolder + '\GPRMC.rdp';
    // Cleanup
    FreeMem(LocalAppData);
  end
  else
  begin
    MessageBox(0, PAnsiChar(SysErrorMessage(GetLastError)), 'ShGetFolderPath', MB_OK);
  end;

  sServer := 'SERVER';

  // Obfuscate the password key
  Helper := TLbRijndael.Create(nil);
  Helper.CipherMode := cmECB;
  Helper.KeySize := ks128;
  Helper.GenerateKey('The Secret Key Which you should hide somewhere');

  // Get Screen Width and Height
  GetWindowRect(GetDesktopWindow, lpRect);

  // RDP Unicode Byte Order Mark (BOM)
  BOM := Widechar(BOM_UTF16);

  // Create RDP File
  fs := TFileStream.Create(sRDPFileName, fmCreate);

  // Write BOM
  fs.WriteBuffer(BOM[1], Length(BOM)*sizeof(Widechar));

  // Write RDP file
  WriteLnFs(fs, 'screen mode id:i:1');
  WriteLnFs(fs, Format('desktopwidth:i:%d', [lpRect.Right]));
  WriteLnFs(fs, Format('desktopheight:i:%d', [lpRect.Bottom - 50]));
  WriteLnFs(fs, 'session bpp:i:16');
  WriteLnFs(fs, 'winposstr:s:2,3,247,0,1055,627');
  WriteLnFs(fs, Format('full address:s:%s', [sServer]));
  WriteLnFs(fs, 'compression:i:1');
  WriteLnFs(fs, 'keyboardhook:i:2');
  WriteLnFs(fs, 'audiomode:i:2');
  WriteLnFs(fs, 'redirectdrives:i:0');
  WriteLnFs(fs, 'redirectprinters:i:0');
  WriteLnFs(fs, 'redirectcomports:i:0');
  WriteLnFs(fs, 'redirectsmartcards:i:0');
  WriteLnFs(fs, 'displayconnectionbar:i:1');
  WriteLnFs(fs, 'autoreconnection enabled:i:1');
  WriteLnFs(fs, Format('username:s:%s', ['USERNAME']));
  WriteLnFs(fs, Format('domain:s:%s', ['DOMAIN']));
  WriteLnFs(fs, 'password 51:b:' + CryptRdpPassWord(Helper.DecryptString('GSMZHifunaBaegL6ehnkmw==')));
  WriteLnFs(fs, 'disable wallpaper:i:1');
  WriteLnFs(fs, 'disable full window drag:i:1');
  WriteLnFs(fs, 'disable menu anims:i:1');
  WriteLnFs(fs, 'disable themes:i:1');
  WriteLnFs(fs, 'disable cursor setting:i:0');
  WriteLnFs(fs, 'bitmapcachepersistenable:i:1');

  // Cleanup
  Helper.Free;
  fs.Free;

  ZeroMemory(@si, SizeOf(si));
  si.cb := SizeOf(si);
  si.lpDesktop := nil;
  
  pwCmdLine := PWideChar(WideString('mstsc.exe ' + '"' + sRDPFileName + '"'));
  if not CreateProcessW(nil,
                        pwCmdLine,
                        nil,
                        nil,
                        False,
                        0,
                        nil,
                        nil,
                        si,
                        pi) then
  begin
    pwMsg := PWideChar(WideString('Failed to start MSTSC.EXE' +#10#13+
                                  SysErrorMessage(GetLastError)));
    MessageBoxExW(0,
                  pwMsg,
                  'Sample Program',
                  MB_ICONERROR or MB_OK,
                  MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL));
  end;
end.
  Mit Zitat antworten Zitat