Delphi-PRAXiS
Seite 2 von 2     12   

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi Password hash in RDP files (https://www.delphipraxis.net/88732-password-hash-rdp-files.html)

marabu 29. Mär 2007 08:09

Re: Password hash in RDP files
 
Hi Remko,

please, notice the camelcase test data I provided - HexToBin() is not that picky as the documentation tries to make us believe. Could be version dependend, though.

As far as the SHR SHL Operations are concerned, I am free minded here. One should only do, what is understood.

First class function result types are all those types which are intended to be used in an expression. That's all there is to it, for me. At least for now, since I must fly to my next meeting...

Regards

Remko 29. Mär 2007 09:59

Re: Password hash in RDP files
 
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.

Remko 22. Okt 2007 12:57

Re: Password hash in RDP files
 
For more information on the subject of encrypting and decrypting rdp passwords you can look at my site. I have placed the article here: http://remkoweijnen.nl/blog/2007/10/...are-encrypted/


Alle Zeitangaben in WEZ +1. Es ist jetzt 23:00 Uhr.
Seite 2 von 2     12   

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz