Elevate privileges programmatically on mono - c#

From my mono application, running under Linux, I want to run another one as root user. At the moment I use Process.Start, running gksudo.
This solution works quite well under one condition - there is gksudo installed.
I need a mechanism to elevate privileges for a mono assembly (not necessarily as another process) that does not rely on a particular, desktop-dependant application like gksudo or kdesu and is not console-based (like good ol' sudo).
Actually I believe I need a way to PAM-ify my application.
The solution does not have to be Windows compliant, but it would be a nice bonus.
I've seen many possible answers to my problem, but none did resolve all the issues.
A very nice approach was https://stackoverflow.com/a/16276287/882200, but it requires an assembly to be ran as root, which is not possible.
This inspired me to try a new approach. I've tried running
Process.Start("whoami", "otheruser", password, "");
The output should be otheruser, but it is not.
Please mind that I leave the domain (last parameter) empty (is that OK?) and I fill password according to this example.
This solution is not the best one - it requires me to provide means to grab a password, but it is acceptable, although not working.
The best option for me would be to make my environment choose the correct way to receive a password - either by a Qt/GTK popup or a console prompt.
The last thing to keep in mind - to run an app as root I'd love to be able to provide a sudoer password, not necessarily a root password (according to sudoers configuration).

Related

Protect Windows Applications against password recovery tools

I am developing a c# application where a user will enter some informations like server, database, user and password (the password is hidden this.txtPassword.PasswordChar = '*';), if I use a password recovery tool like BulletsPassView it reveals the password while I know some applications are protected from this tool (skype, yahoo messenger, ...).
I want to know what I must do to protect my application
Workaround: quote from the site you linked:
This utility works fine with most password text-boxes, but there are some applications that don't store the password behind the bullets, in order to increase their security. In such cases, BulletsPassView will not be able to reveal the password.
which means that you might be able to protect yourself by getting the actual password out from the PasswordBox and replacing it with dummy characters on every keystroke.
Better Approach: Use Current, Relevant Technology as opposed to archaic winforms:
I just tested with a WPF PasswordBox and it is not detected/revealed by the BulletsPassView tool.
If your computer is compromised than no amount of obfuscation and tricks(Skype tricks) can help you against the determined attacker - your app will have to use password(or other secret information) in its clear form(it may be hashed, encrypted, does not matter - in the end it will be in the same form used for the authentication). Modern user operating systems are not designed to protect you against the belligerent administrator or compromised core.
I think that you should not worry about the disclosure of your password in the PasswordBox control - if some one is able to do something similar on your machine than he is able to do something much worse. That is not the threat anybody can effectively deal with in such the circumstances.
The only real way to protect your password(or secret key) is ... to not store it in your app at all and use it only on secure trusted computers for the shortest amount of time possible, removing and clearing all the info after.
EDIT(after comments):
With such amount of ready made tools and exploits you should not underestimate the script kiddies.
If you want to protect Windows.Forms.PasswordBox from BulletsPassView-like tools than you should name your question accordingly(if it is your goal then rename it - your question will be less broad with very determined goal).
About actual protection for PasswordBox:
As I suppose BulletsPassView just accesses targeted windows through hooks(like Spy++) and gets needed values(Spy++ hooks internals).
If you want protection against BulletsPassView you could try some non-standard PasswordBox or use another UI. But I am not sure that it will really solve the problem for eternity.
There is not much you could actually do against hooks that I know of. As I've already said the main protection is the environment that restricts everything not allowed and runs everything with the least privileges. You can't protect your system against everything - create some formal finite threat model and implement features needed to deal with the identified threats.
P.S.: I am not very knowledgeable in dll hooks - may be someone knows a way.
P.P.S.: And do not forget to rename the question to reflect your actual goals and problems.

C# DLL from VBScript, no regasm

Is it possible to access a C# DLL's method from VBScript without registering it with regasm? I will be creating the DLL so pretty much any exotic requirement to make it visible to VBScript, I can do...
I have read here that it might be possible to use GetObject from VBScript to achieve this, but I have tried that with no success... Is there anything else I need to do aside from making the DLL "COM visible" to make this work?
The reason why I need to avoid regasm is that it requires admin rights, and I need to deploy this DLL "silently" to many clients that may or may not have admin rights.
No, registration is required, the only way that the script interpreter can find the DLL that contains the ProgId that you use in the script's CreateObject() call. Isolated COM with a manifest doesn't work, you can't modify the manifest for the script interpreter.
There is a technical solution, you can write registry keys in the HKCU registry hive without acquiring UAC elevation. The Regasm.exe tool always writes them in the HKLM hive. That registers the assembly as well, but only for the user that runs Regasm.exe. It is however pretty painful and easy to get wrong, you have to write your own registration method and apply the [ComRegisterFunction] attribute. It is now your job to use the RegistryKey class to set the keys. Same for the [ComUnregisterFunction], it should delete the keys again. There are a lot of bad examples out on the interwebs, best way to get this right is to use SysInternals' ProcMon to observe the registry keys that get written when you use Regasm.exe normally, then reproduce that in your own code, using HKCU instead.
Do note the other side of that medal, you are in fact making configuration changes to the machine that allows arbitrary code to run. Trying to hide that doesn't do the user any favors and should never be considered if you honor the user's desire to keep the machine safe and predictable. UAC is not there to stop you from making changes, it is only there to inform the user about it.
The accepted answer is incorrect that registration is required to use a DLL. You can use the GetObject() method instead of the CreateObject() method as shown in my answer to this question.
Using DLLs in VBScript

Deploying a C# application - user form (novice)

I'm virtually a complete novice, I've tried Googling for answers and become totally confused.
Using Visual Studio 2010, I have a C# application which is an email notifier for a friend. The external (Arduino) hardware works, the main code (from a website) works but I'm sending it to her on the other side of the world to use and she is very 'non-technical' - hence the need for a 'setup form'.
I have created a form where she can enter comm port (selected from a list), username and password (all to be used by the main code), but that form should run only when the application is first installed on the PC.
At the moment it runs in VS-2010 (though I need to iron out a couple of snags), validates and hides - but I don't know how to a) store the data and make it available to the main code, b) ensure that the form only runs at setup, or c) exactly what I need to do or include to create an installable application.
Could somebody either help or direct me to some tutorials that don't assume I understand all the terminology?
I just want to create something that she can instal from a memory stick. I know it can be done and it's proababy quite simple for those who understand - I'm trying to learn but I'm no longer young and it's a struggle.
Thanks
a) store the data and make it available to the main code,
write the data on a file!
you have millions of possibilities, for isntance reading and writing a plain text file can be done with few lines of code, but if you want to encrypt your file (it may be the case if you want to store the password) you can use System.Security.Cryptography as shown in this guide
b) ensure that the form only runs at setup,
once you have written the file, then it means that the program has run already at least once, so you don't need to ask the user again (just read the data from the file)
c) exactly what I need to do or include to create an installable application.
Visual Studio already comes with the Setup project for this task. See this good guide.
From your comment and link to the code project for the Arduino, I gather that this is your first venture into writing code in C#, or very close to it. And ideally you'd like to make this as easy for your friend as possible. The best advice I can give you is not to try to run before you learn to walk. If you try to create a custom setup project and use a configuration file, which is what you are talking about doing, you may hit so many barriers that you never get to a successful end of the project. That kind of experience is discouraging and I'd hate for you to lose the drive to ever want to try another software project.
Make this initial project easy on yourself. This is not good programming practice for most situations, but if you only have one user, hard-code her configruation information for this first version. In other words, put her username, password, com port, etc directly into the main program. This eliminates the need for both the configuration, and any custom setup form. If you still want to make the whole thing configurable and versatile, do that in your next version. Custom setup is not a beginner task. It will be a lot easier to take on with the encouragement of your friend's excitement and compliments over a first version that works.

How to make my program not run on other computers?

I have an assignment, and it has (amongst others) two demands:
make an installer
make it so that if it is installed on one computer, anyone trying to run the same files on another computer will fail.
I'm using VS9 (2008) express, I think I can do the installer part, but I'm not sure how to do the "security" part. I don't need any hard to crack safety, just a dumb condition that will stop most users from copying the files to another computer. (Like checking the MAC address).
Any ideas?
EDIT:
I would like to check the MAC address but I want the program finalized during installation. Meaning that after I install I can't move the program to another machine. It also does not have to be a very smart or difficult condition, just bare minimum. I just don't know how to do it in the installation.
EDIT:
It's sad I don't have the complete VS then I would be able to do it easily.
If you're looking for some way to mark the first computer as the "authorized" computer, then you need some external service you can ask for permission to launch.
The first person to ask permission would be allowed, the rest would be prevented.
You'll also need to come up with some way of identifying a particular instance of your application that's different for every install.
If your app needs to be authorized for the machine, then you will need to calculate some fingerprint for the machine it can use each time (eg across installs).
[Edit]
This approach is useful when you're worried about copies of the installer being distributed as well. You did specify that its ok to install on multiple machines, so in that case MasterMind's approach is superior. It will work, and does not requires a 3rd party server
[Edit 2]
If you're looking for info on how to build a custom installer, try here
First of all, come up with some function to generate a unique PC signature, like Windows does for activation.
Your installer will be creating this signature and writing it to a local file (better encrypted). You can create a simple console executable to generate this file and include that executable into your installer package, setting it up to run silently after the successful installation.
Your program when starting will be creating the signature again using the same algorithm and comparing it to the one created during installation. If the new signature is different from the original one or the signature file is missing, then exit without loading the UI.
ADDED: If you don't need it very complex, you can just choose a few unique values like the MAC address you suggested, maybe the hard drive serial number, mainboard serial number, concatenate them into a single string and generate the hash out of it.
This approach will allow for an unlimited number of copies to run (but each installation will only be workable on one single machine where it was installed). If you stick to the identification by hardware (or OS product key as well), then the application can run on various OS installations on the same machine.
This strategy, however, implies that you control all installations (or perform them yourself) or absolutely trust your client not to install additional copies elsewhere or distribute your installer. If you need that kind of protection as well, then you should consider product activation. It can be quite complicated if you do it yourself. There are however third party products to help you. Some offer product activation services: Google: activation service
Once you have a decent fingerprint, the rest is easy. Personally I'd take something like the MAC address and the windows product ID (at HKLM\Software\Microsoft\Windows\CurrentVersion\ProductId) and use a hashing algorithm to get something reasonably obscure.
edit:
Here's a question that shows you how to get your MAC address as a string:
Read MAC Address from network adapter in .NET
Then grab your windows product ID (in case they don't have a network adapter) from the above registry key. Concatenate both strings and do a GetHashCode() (or use your favorite hashing algorithm) on the result. This is a simple way to get a UID for a computer.
Write the hash to a file or to a registry entry when your installer is executing and check it when your program starts up.
Consider using two or more values that potentially identify the machine, e.g.
Windows product code
Volume serial number of the C: drive
MAC address of an ethernet interface
And if just one of these changes but the others match, update that one value in the registry and continue running normally. Hard drives get replaced (regularly), Windows gets upgraded (occasionally), Ethernet adapters get replaced (rarely but it does happen.) It can be very frustrating when old software stops working because of this.
Bare minimum answer, assuming the only requirement here is that the software should run if installed through the installer, and won't run if copied to another computer:
Write a simple key to the registry. Most likely your product's version number, incase they copy a newer version to the computer, it has a different number to check for.
In your software, just make sure this registry value exists.
For packaging installations, I enjoy using NSIS which has simple methods for writing to the registry.
I like the idea of checking the MAC address.
I have also seen product key/online activation combinations where you enter the product key and the software contacts a web service that logs the product key and # of installs.
This isn't the most secure option or anything but you did say it didn't have to be smart...
On install, you could set a program variable to be the machine name (or a hash of it if you like).
Like:
myProgram.Properties.Settings.Default.Machine = System.Environment.MachineName;
myProgram.Properties.Settings.Default.Save();
then check that on startup:
if (System.Environment.MachineName != myProgram.Properties.Settings.Default.Machine)
{
MessageBox.Show("Can't run on this computer");
this.Close();
}
To get the installer to only work for one machine, you'd pretty much have to build it for the target machine. I dont think it would be possible to make an installer that assumes the first machine it sees is it's mommy and is attached for life.
-1 for clinging to an antiquated license-restriction policy that is a poor practice in general. Hardware dongles and "device detection" are SO 1990.
People own more than one computer. They buy new computers. They upgrade their computers. Computers break, resulting in replacement of motherboards or network cards.
All of these, given your design, will result in honest, paying customers being locked out of what they've paid for and will have to call you for support to "reset" their activation.
And each time you do so, your overhead will increase by, very likely, more than the actual cost of a license.
I'm not suggesting you give up and just send your app off to the torrentverse, but you should think more creatively about how to allow customers the freedom to use what they paid for, keep your support costs low, and discourage pirates.
One creative solution would be to cache the user's settings on your server, keyed by their serial number, and synchronize them every time the application starts and is connected to the Net.
This will allow a user to install the app on, say, both a laptop and desktop, and will actually be a value-add for customers because their settings are synchronized between devices.
But it actively discourages users from sharing their license key, since doing so would mean they would be sharing their settings with every pirate user, or that they would have to remember to stay disconnected from the Interwebs when they open or close the app.

A different Approach for anti-virus . Am I going in the right direction?

I'm currently conceiving a system that works like an anti-virus, but also uses the White Listing i.e
Preventing Viruses from Running by having a database of Known legitimate Programs
Yes , there is the Windows UAC, but still many viruses "work around" it. I'm planning on a more reliable system.
My system has also a database of known threats (cryptographic hash).
Is this approach viable,
What are the possible loop holes in this approach
I understand that there has been a lot of attempts at this. But still I want to try it out.
I'm planning to use C# and .Net for a prototype may be i'll move on to C++ for performance later
Update:
Thank you all for your time and thoughts.
I decided to do some more research in this area before actually designing something
Espcially as pointd out below the Zeroday threat problem
What about DLLs used by executables? Do you hash them too? A virus can replace a DLL.
This has been brought up before, and there are products out there which do that. (Faronics Anti-Executable works like this)
There are two main problems with this approach:
A virus can embed itself into any file; not just EXEs. Programs can load DLLs and other bits of code(macros, scripts, etc), and programs can contain bugs(such as buffer overflows) which can be exploited by malicious documents and other files.
Every time you patch a system or otherwise legitimately modify the software, you also need to update the white list.
There is products like Appsense Application Manager that do this already. It was temporarily pitched as a security product but they changed tact and focused it on licensing. I think it's because it didn't work too well as a security product.
If you are planning to work with a limited set of applications and you can work with application developers you can use a code signing model. You can find a similar approach in most mobile operating systems. You have to sign all the executable modules including libraries and need to verify they have a valid signature and not modified using a root certificate.
If you are only planning to white list applications based on their hash value you need to make sure your white listed applications verify any modules they use before they load. Even if the applications/installation files are digitally signed it does not guarantee that a library will be modified later in a malicious way.
In reality, it is not even enough to only verify executables and libraries. For example, Xbox Linux hack utilizes a malicious save file. It is a specially prepared save file that causes a legitimate and signed application behave in unexpected ways. And, of course it is not possible to white list a save file based on its hash value.
Another problem with keeping a database is zero day attacks. You need to be ahead of the curve for creating hash values for new attacks and propagating these updates to your users otherwise they will be vulnerable all new attacks. Unless you only allow only white listed applications to be executed and that would be really restrictive.
IMHO, it is really difficult build such a system on open platfom. Good luck with it.

Categories