Tech Off Thread

31 posts

Forum Read Only

This forum has been made read only by the site admins. No new threads or comments can be added.

Secrets

Back to Forum: Tech Off
  • User profile image
    PerfectPhase

    If you had to embed a secret (password/identifier for example) in your .Net app, how would you do it to make it hard to find?

     

    I know there is no way to securely do this, if it's on a machine someone will always find it no matter how many times I encrypt it and ultimately this is an act in futility.

     

    Just wondering how you would do it, to add just enough pain to dissuade the casual hacker.    Oh yes, and the person trying to extract this information from my assembly would have full admin permissions on the box this is installed on.

     

    Cheers,

     

    Stephen.

     

  • User profile image
    staceyw

    For casual, I may do one of below:

    1) Use DPAPI and add secondary entropy from a string inside your app.  Decide if you can use User level DPAPI security or have to settle for Machine.  If using machine, it may be no better then hiding password in some hash. http://www.obviex.com/Samples/Dpapi.aspx

     

    2) Use some long random string in your app as the raw AES key.  Hash it (once or more times) and take the number of bytes you need for the AES key.  Encrypt and Decrypt your data using AES and your key.  This will stop most but people who can open your app in reflector and read your code to figure out how your hashing and making your password.  Could also use some Obfuscator on your app to raise the bar more. 

  • User profile image
    W3bbo

    Why is the information so valuable? If it's something like a database un/pw then the DBMS should be configured to limit the amount of damage that Login can do. If it's a web-service key then the WS could have an IP whitelist.

     

    I'm with Stacey in that I advocate using DPAPI.

  • User profile image
    PerfectPhase

    W3bbo said:

    Why is the information so valuable? If it's something like a database un/pw then the DBMS should be configured to limit the amount of damage that Login can do. If it's a web-service key then the WS could have an IP whitelist.

     

    I'm with Stacey in that I advocate using DPAPI.

    We have a app, it's a shrink wrap system installed on the clients infrastructure.  When installed, all our services are protected with X509 certs and a few other things, so from the outside we're quite secure.   Are services are all WS-* type WCF services,
     
    I now have a new request from sales, we have to protect access to our services from third parties that are trying to integrate with our system, where the third party is on the same box and the system admin is deemed to be complicit.  Seems they want some sort of 'certified partner' program.
     
    So I'm faced with finding a way of identifying which inbound calls to our services are from our services and which are not, given the fact that they have access to our service accounts, binaries and X509 certs!  Kind of like protecting a DRM key in a media player binary.

     

    Oh yes, one last thing, no internet access either.

  • User profile image
    W3bbo

    PerfectPhase said:
    W3bbo said:
    *snip*

    We have a app, it's a shrink wrap system installed on the clients infrastructure.  When installed, all our services are protected with X509 certs and a few other things, so from the outside we're quite secure.   Are services are all WS-* type WCF services,
     
    I now have a new request from sales, we have to protect access to our services from third parties that are trying to integrate with our system, where the third party is on the same box and the system admin is deemed to be complicit.  Seems they want some sort of 'certified partner' program.
     
    So I'm faced with finding a way of identifying which inbound calls to our services are from our services and which are not, given the fact that they have access to our service accounts, binaries and X509 certs!  Kind of like protecting a DRM key in a media player binary.

     

    Oh yes, one last thing, no internet access either.

    You could look into using the TPM.

     

    What do you mean by "no internet access either"?

  • User profile image
    PerfectPhase

    W3bbo said:
    PerfectPhase said:
    *snip*

    You could look into using the TPM.

     

    What do you mean by "no internet access either"?

    This system sometimes sits on secured subnet, no external access, so rules out things like activations servers we host.

     

    Honestly I hate the whole idea, I'm think I'm just going to bury a key somewhere in the binary under multiple layers of encryption and and obuscate the hell out of it and say that's the best we can do, it'll stop a script kiddy but anyone with a map to the clue tree will work it out.

     

    Forgot to add, we need to run in VMs (Hyper-V, ESX etc) so no TPM

  • User profile image
    W3bbo

    PerfectPhase said:
    W3bbo said:
    *snip*

    This system sometimes sits on secured subnet, no external access, so rules out things like activations servers we host.

     

    Honestly I hate the whole idea, I'm think I'm just going to bury a key somewhere in the binary under multiple layers of encryption and and obuscate the hell out of it and say that's the best we can do, it'll stop a script kiddy but anyone with a map to the clue tree will work it out.

     

    Forgot to add, we need to run in VMs (Hyper-V, ESX etc) so no TPM

    USB dongles? I think ESX does USB redirection, dunno about Hyper-V.

  • User profile image
    AndyC

    W3bbo said:
    PerfectPhase said:
    *snip*

    USB dongles? I think ESX does USB redirection, dunno about Hyper-V.

    USB dongles wouldn't fly in any environment where virtualisation is being fully exploited, since you really wouldn't want a virtual machine tied to a single physical box.

     

    Basically it's the "How do I identify the caller of my function?" problem, which can't be solved. So yeah, embedding some sort of magic number sequence into the app is about the best you're going to be able to do. At least it'll keep out casual prodding.

     

    The other alternative, of course, is to keep breaking the API's, but that's not usually a practical solution!

  • User profile image
    W3bbo

    AndyC said:
    W3bbo said:
    *snip*

    USB dongles wouldn't fly in any environment where virtualisation is being fully exploited, since you really wouldn't want a virtual machine tied to a single physical box.

     

    Basically it's the "How do I identify the caller of my function?" problem, which can't be solved. So yeah, embedding some sort of magic number sequence into the app is about the best you're going to be able to do. At least it'll keep out casual prodding.

     

    The other alternative, of course, is to keep breaking the API's, but that's not usually a practical solution!

    Couldn't you use a small native component (that would be hard to disassemble) to provide some kind of authentication? You could employ some cheap tricks in there to find out what process loaded the native DLL and see if has the digital signature of your application.

  • User profile image
    cheong

    W3bbo said:

    Why is the information so valuable? If it's something like a database un/pw then the DBMS should be configured to limit the amount of damage that Login can do. If it's a web-service key then the WS could have an IP whitelist.

     

    I'm with Stacey in that I advocate using DPAPI.

    There could be more use than that.

     

    Consider that you have a 3rd party component that requires license key to unlock main features. You certainly won't want your key be stolen away, but you have to ship the production key with your application. So you have to find some way to hide it.

     

    IMO, Base64 encrypting the key and lots of other (perhaps) useless stuff will be good enough. Intentionally add a few GOTO statements, decode calls to fake keys, complex logics using functions that known to only return true or only return false on parameter specified, etc. Shall add enough pain to anyone who want to get it even if there's refactor tools to disassemble to binary.

     

    Except that all these methods fails if he inserted a breakpoint just before the call to validate the key. Sad

     

    On a box that the cracker has full control, you're destinated to lose before the battle has began. Just look at those DRM implementers.

    Recent Achievement unlocked: Code Avenger Tier 4/6: You see dead program. A lot!
    Last modified
  • User profile image
    SlackmasterK

    hmmm...  If I actually wanted to make things interesting at least... Might even be fun... One or more...

     

    Misdirection. Security through obscurity and plain sneakiness.

    1. The password would be concatenated over a series of different methods (in both senses of the term)
    2. encoding tricks (i.e. GB2312) and calling in-memory codegen
    3. Escaping and de-escaping different ways
    4. Cryptography, of course. Maybe using a few different types.
    5. Have the app perform reads and writes to files and registry keys that contain encrypted dummy text that, when decrypted via vanilla MD5, looks like a password (i.e. $biLLy443); but is not really used.  Throw them off the scent and have some fun in the process.
    6. Have the app send a DES-encrypted message to a webservice somewhere and have the webservice return something else encrypted. Maybe one real (using a more secure algorithm) and two decoy calls. Could be to local. Use parameters with names like 'Key' and 'Token'. Optionally, build the parameter names in code since they'll be passed as strings in the XML anyway. Maybe use a custom object as a parameter, which can be easily deserialized into something that looks intentional.
    7. Throw in some really random stuff that nobody would ever associate with security or encryption, such as converting part of a number to the character of the sum of its commensurate part ASCII codes (i.e. 488 becomes  4X instead of ♦◘◘) instead of or in addition to converting through binary into its decimal equivalent.
    8. Put some large hex strings in a variable or two.  Have them contain a hidden message like "You're getting close" when they're really not.
    9. Have an official-looking URL in memory somewhere, something that sounds like an NSA/Echelon webservice.
    10. Do some fancy math that a "casual hacker" as you put it would probably not know.
    11. Obviously, dotfuscate. Maybe use variable names that look like they already have been dotfuscated.
    12. I'm not a Win32 programmer, but I might look into some Win32 API calls that return a result other than what is documented under certain circumstances.  I'm fairly sure I've read somewhere that this happens.  Pass part of the password through some of these calls.
    13. Cryptography key could be tied to the physical start sector on the disk, and mark that sector as system/immovable. Or just use the start sector of the first permanent swapfile since that's already marked immovable.  This has the additional benefit of changing on every machine it's put on.
    14. High ASCII characters are always unexpected.
    15. Read the value of some system registry key that never changes after initial install. Use that as a key somewhere.
    16. Read the PCI ID and other extended properties of some system device that probably won't change without a mobo swap.  That usually ends up requiring a reinstall anyway.  Use these data in the same manner as above.
    17. Have two services that talk to each other in-memory but don't actually exchange anything related to the task.
    18. Multithreading. It's hard enough when you know what you're doing.
    19. Force GC on any object that had access to the plaintext original, as quickly as possible. If neccessary, kill the process and spawn a new one.
    20. Random reads and writes to variables in memory that don't actually do anything.  Use them in the code somewhere so the compiler thinks it can't be optimized away.
    21. Put dummy code in a try block and cause a specific but unusual type of throw. Put real code in the catch.
  • User profile image
    PerfectPhase

    SlackmasterK said:

    hmmm...  If I actually wanted to make things interesting at least... Might even be fun... One or more...

     

    Misdirection. Security through obscurity and plain sneakiness.

    1. The password would be concatenated over a series of different methods (in both senses of the term)
    2. encoding tricks (i.e. GB2312) and calling in-memory codegen
    3. Escaping and de-escaping different ways
    4. Cryptography, of course. Maybe using a few different types.
    5. Have the app perform reads and writes to files and registry keys that contain encrypted dummy text that, when decrypted via vanilla MD5, looks like a password (i.e. $biLLy443); but is not really used.  Throw them off the scent and have some fun in the process.
    6. Have the app send a DES-encrypted message to a webservice somewhere and have the webservice return something else encrypted. Maybe one real (using a more secure algorithm) and two decoy calls. Could be to local. Use parameters with names like 'Key' and 'Token'. Optionally, build the parameter names in code since they'll be passed as strings in the XML anyway. Maybe use a custom object as a parameter, which can be easily deserialized into something that looks intentional.
    7. Throw in some really random stuff that nobody would ever associate with security or encryption, such as converting part of a number to the character of the sum of its commensurate part ASCII codes (i.e. 488 becomes  4X instead of ♦◘◘) instead of or in addition to converting through binary into its decimal equivalent.
    8. Put some large hex strings in a variable or two.  Have them contain a hidden message like "You're getting close" when they're really not.
    9. Have an official-looking URL in memory somewhere, something that sounds like an NSA/Echelon webservice.
    10. Do some fancy math that a "casual hacker" as you put it would probably not know.
    11. Obviously, dotfuscate. Maybe use variable names that look like they already have been dotfuscated.
    12. I'm not a Win32 programmer, but I might look into some Win32 API calls that return a result other than what is documented under certain circumstances.  I'm fairly sure I've read somewhere that this happens.  Pass part of the password through some of these calls.
    13. Cryptography key could be tied to the physical start sector on the disk, and mark that sector as system/immovable. Or just use the start sector of the first permanent swapfile since that's already marked immovable.  This has the additional benefit of changing on every machine it's put on.
    14. High ASCII characters are always unexpected.
    15. Read the value of some system registry key that never changes after initial install. Use that as a key somewhere.
    16. Read the PCI ID and other extended properties of some system device that probably won't change without a mobo swap.  That usually ends up requiring a reinstall anyway.  Use these data in the same manner as above.
    17. Have two services that talk to each other in-memory but don't actually exchange anything related to the task.
    18. Multithreading. It's hard enough when you know what you're doing.
    19. Force GC on any object that had access to the plaintext original, as quickly as possible. If neccessary, kill the process and spawn a new one.
    20. Random reads and writes to variables in memory that don't actually do anything.  Use them in the code somewhere so the compiler thinks it can't be optimized away.
    21. Put dummy code in a try block and cause a specific but unusual type of throw. Put real code in the catch.

    'Obviously, dotfuscate. Maybe use variable names that look like they already have been dotfuscated.'

     

    I was wondering what the effect of ofuscating my code, decompiling with reflector and the running that through dotfucator a second time would be Smiley

  • User profile image
    W3bbo

    PerfectPhase said:
    SlackmasterK said:
    *snip*

    'Obviously, dotfuscate. Maybe use variable names that look like they already have been dotfuscated.'

     

    I was wondering what the effect of ofuscating my code, decompiling with reflector and the running that through dotfucator a second time would be Smiley

    Probably something that doesn't compile. There are many cases where obfuscation of CIL results in something that can't be disassembled by Reflector and it either uses bad constructs (a bug in reflector) or gives you an error message.

  • User profile image
    staceyw

    PerfectPhase said:
    W3bbo said:
    *snip*

    We have a app, it's a shrink wrap system installed on the clients infrastructure.  When installed, all our services are protected with X509 certs and a few other things, so from the outside we're quite secure.   Are services are all WS-* type WCF services,
     
    I now have a new request from sales, we have to protect access to our services from third parties that are trying to integrate with our system, where the third party is on the same box and the system admin is deemed to be complicit.  Seems they want some sort of 'certified partner' program.
     
    So I'm faced with finding a way of identifying which inbound calls to our services are from our services and which are not, given the fact that they have access to our service accounts, binaries and X509 certs!  Kind of like protecting a DRM key in a media player binary.

     

    Oh yes, one last thing, no internet access either.

    "where the third party is on the same box and the system admin is deemed to be complicit.  Seems they want some sort of 'certified partner' program"

     

    huh?  Why they have to be on the same box?  If sales can't afford another box for 3rd parties in the DMZ, then they can not be serious about security.  When on the same box, you may as well do nothing.

  • User profile image
    AndyC

    W3bbo said:
    AndyC said:
    *snip*

    Couldn't you use a small native component (that would be hard to disassemble) to provide some kind of authentication? You could employ some cheap tricks in there to find out what process loaded the native DLL and see if has the digital signature of your application.

    That still boils down to "How can I identify the calling program?" and the answer is still "You can't. Ever"

  • User profile image
    W3bbo

    AndyC said:
    W3bbo said:
    *snip*

    That still boils down to "How can I identify the calling program?" and the answer is still "You can't. Ever"

    Citation needed.

  • User profile image
    AndyC
  • User profile image
    blowdart

    W3bbo said:
    AndyC said:
    *snip*

    Couldn't you use a small native component (that would be hard to disassemble) to provide some kind of authentication? You could employ some cheap tricks in there to find out what process loaded the native DLL and see if has the digital signature of your application.

    In fact there's a CAS demand for that. Of course it relies on the CLR not being hacked, and that's certainly possible to do.

Conversation locked

This conversation has been locked by the site admins. No new comments can be made.