CLR: SecureString

Started by stanl, May 01, 2019, 04:45:03 AM

Previous topic - Next topic

stanl


Error that method AppendChar() not found. It's in the docs.


Code (WINBATCH) Select


ObjectClrOption("useany","System")
oSS = ObjectClrNew('System.Security.SecureString')
Message("Secure String Length",oSS.Length)
oSS.Clear()
oSS.AppendChar('T')

td

As has been mentioned before the CLR uses a method's signature to identify a method.  This is necessary because the CLR is object based and follows the principles of object-oriented programming.   In object-oriented programming, methods can be overloaded so a method's parameter types are used as part of a method's signature.

In the vast majority of cases, WinBatch automatically converts method parameters to the correct mscorelib types for you by asking the mscorelib for the appropriate type interface for the variant type before making the method call.

In this case, the CLR expects the method "AppendChar" to have a Unicode character as its only parameter.  A single Unicode character is not the same type as a Unicode string.  The CLR cannot find the method because there is no method  "AppendChar" that takes a string as its only parameter. 

Unfortunately, MSFT doesn't provide a way to consistently convert between a variant and a Char mscorlib struct type so the method call fails because the method will not accept any variant value that WinBatch passes to it.  There is no direct conversion between a bstr or int variant and a Char struct. You could call it a bug in MSFT's interfaces into the CLR I suppose but that doesn't help solve the problem.  You can, however,  get a more descriptive error message by casting the parameter to the correct type:

oSS.AppendChar(System.Char:'T')

This produces an Invalid Parameter error message that more accurately describes the reason for the failure in this case.  Another method accepting the Char type might actually work using this technique.  It depends on the vagaries of the assembly you are calling into.

Typecasting is a technique to keep in mind when you encounter a method not found error.  It will either resolve the issue or at the very least give you are a more specific error message.


"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade

td

This approach doesn't always work for miscreant types but it does seem to work for "System.Char":

Code (winbatch) Select
ObjectClrOption("useany","System")
oSS = ObjectClrNew('System.Security.SecureString')
Message("Secure String Length",oSS.Length)
oSS.Clear()

objChar = ObjectClrNew('System.Char')
ObjChar.Parse('T')

oSS.AppendChar(ObjChar)
Message("Secure String Length",oSS.Length)


"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade

stanl

and now the second half, re-displaying the securestring as plain text. There is obviously another conversion step needed, or do I need to run another for...next
Code (WINBATCH) Select


string="GameofThrones"
ObjectClrOption("useany","System")
oSS = ObjectClrNew('System.Security.SecureString')
Message("Secure String Length",oSS.Length)
oSS.Clear()


For i = 1 To Strlen(string)
   objChar = ObjectClrNew('System.Char')
   ObjChar.Parse(StrSub(string,i,1))
   oSS.AppendChar(System.Char:ObjChar)
Next
n =  oSS.Length
Message("Secure String Length",n)


oPS = ObjectClrOption("useany",'System.Management.Automation')
oPS1 = ObjectClrNew('System.Management.Automation.PSCredential','testing',oSS)
pw =  oPS1.GetNetworkCredential().Password


Message("Secure String Text",pw)


oSS=0
oPS=0
oSS=0
Exit

td

Couldn't tell you.  I was under the impression that Windows encrypts system passwords in one direction so that you can't get the plain text version but I wouldn't know if that applies in this case.  The "SecurePassword" method seems to return something which makes sense since you are setting a secure password and not a plain text password on the object.

Code (winbatch) Select
pw =  oPS1.GetNetworkCredential().SecurePassword
Message("Secure String Text Length",pw.Length)
"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade

td

It's typo time again.  I changed the phrase, "but I would know if that applies in this case" to "but I wouldn't know if that applies in this case" in the above post.  Hopefully, the reply now makes a little more sense...
"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade

stanl

NP.  I was trying to replicate a simple PS script which seems to indicate that the Password property can decrypt the secure string


$secret = Read-Host -Prompt 'Enter Keypass' -AsSecureString
[System.Management.Automation.PSCredential]::new('hehe',$secret). GetNetworkCredential().Password

td

MSFT documentation indicates the "Password" property returns a "SecureString".  It also states that the "SecureString" class is not visible to COM and the class should not be used in new development.
"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade