I hope the system doesn't matter as long as it's current, but I'm using Ubuntu 11.10 Server. Is there any way for any user y to see user x's environment variables? In other words, is it safe to store a password in an environment variable during an install script -- assuming that the user running the software is allowed to know it?
It is possible to access environment variables reading file /proc/*PID*/environ. But it has the same credentials as the process it concerns to.
As far as I know it's possible to capture passwords stored in memory using a memory dump. To minimize risks, password management tools overwrite memory (i.e. clipboard) after a few seconds.
Edit: Searching in the internet I've found an example of this technique in ubuntu here.
Related
For some unfortunate reasons, I have to convert a proprietary and binary library from a one-user per workstation to a multi-user per workstation setup.
Current setup. A user uses a program linked against a library. This library reads a system wide configuration file (using an hard-coded path, ie /usr/local/thelib/main.conf ) which itself contains several paths to several working directories. The wdir are themselves containing a bunch of user data files.
Desired outcome. Being able to manage several users on the same workstation. Of course, a user shall not be able to read nor alter any other user's data through the library, which should be taken care of by unix rights if I manage to feed the library a different working directory for each user.
The library might be used by several users at the same time so ln-ing the configuration file in /usr/local at runtime is not an option.
I was thinking of using FUSE in order to provide a different content for the file /usr/local/thelib/main.conf, depending on an environnement variable or the current unix user. The environnement var would then be used as a switch inside the code producing the configuration file.
I'm confortable using Python, Perl or C.
The workstation is running an up-to-date GNU/Linux Debian or Ubuntu distribution with a pretty recent kernel.
So. What do you think :
would you use FUSE ?
would you produce another kind of wrapper - using chroot(2) was suggested below per janneb - ?
use something else allowed by Linux ?
I kinda know that I would be able to produce something functional but I'll get the community advice since I don't want to reinvent the wheel right now.
Thanks.
Florian
you could use LD_PRELOAD to load a small stub that intercepts open() calls, and opens ~/.main.conf (assuming this is a shared object). Then in your application startup routine, check that LD_PRELOAD is set to the correct value, and if not, restart the app with the correct environment.
A simple way would be for the app to call chroot() before calling the library init function(s). E.g. if you chroot into $HOME/theapp then each user can have a private own config file in $HOME/theapp/usr/local/thelib/main.conf as well as private working dirs somewhere under $HOME/theapp.
I am building a suite of batch jobs that require regular access to a database, running on a Solaris 10 machine. Because of (unchangable) design constraints, we are required use a certain program to connect to it. Said interface requires us to pass a plain-text password over a command line to connect to the database. This is a terrible security practice, but we are stuck with it.
I am trying to make sure things are properly secured on our end. Since the processing is automated (ie, we can't prompt for a password), and I can't store anything outside the disk, I need a strategy for storing our password securely.
Here are some basic rules
The system has multiple users.
We can assume that our permissions are properly enforced (ie, if a file with a is chmod'd to 600, it won't be publically readable)
I don't mind anyone with superuser access looking at our stored password
Here is what i've got so far
Store password in password.txt
$chmod 600 password.txt
Process reads from password.txt when it's needed
Buffer overwritten with zeros when it's no longer needed
Although I'm sure there is a better way.
This is not a solution for cryptography. No matter the cipher used, the key will be equally accessible to the attacker. Cyrpto doesn't solve all problems.
chmod 400 is best, this makes it read only. chmod 600 is read write, which may or may not be a requirement. Also make sure its chown'ed by the the process that needs it. This is really the best you can do. Even if you are sharing the machine with other users they shouldn't be able to access it. Hopefully this is a dedicated machine, in that case there isn't much of a threat. SELinux or AppArmor will help harden the system from cross process/cross user attacks.
Edit:
shred is the tool you need to securely delete files.
Edit: Based on Moron/Mike's comments the unix command ps aux will display all running processes and the command used to invoke them. For instance the following command will be exposed to all users on the system: wget ftp://user:password#someserver/somefile.ext. A secure alternative is to use the CURL library. You should also disable your shells history. In bash you can do this by setting an environment variable export HISTFILE=
You're not far from the best approach given your constraints. You have two issues to deal with. The first is password storage. The second is using the password securely.
Dealing with the second one first -- you have a huge issue in the use of the command line program. Using options to the 'ps' command, a user can see the arguments used in running the command line program. From what you've written, this would contain the password in plain text. You mention this is an unchangeable interface. Even so, as an ethical programmer, you should raise the issue. If this were a banking application handling financial transactions, you might consider finding another job rather than being part of an unethical solution.
Moving on to securely storing the password, you don't mention what language you are using for your batch files. If you are using a shell script, then you have little recourse than than to hard code the password within the shell script or read it in plain-text from a file. From your description of storing the password in a separate file, I'm hoping that you might be writing a program in a compiled language. If so, you can do a little better.
If using a compiled language, you can encrypt the password in the file and decrypt within your program. The key for decryption would reside in the program itself so it couldn't be read easily. Besides this, I would
chmod 400 the file to prevent other users from reading it
add a dot prefix ('.') to the file to hide it from normal directory listing
rename the file to make it less interesting to read.
be careful not to store the key in a simple string -- the 'strings' command will print all printable strings from a unix executable image.
Having done these things, the next steps would be to improve the key management. But I wouldn't go this far until the 'ps' issue is cleared up. There's little sense putting the third deadbolt on the front door when you plan to leave the window open.
Don't fill the password buffer with zeros, this is pointless. The kernel can decide to swap it to an arbitrary location in the swap file or say after allocation of some memory the kernel will move the page tables around, resulting in other page tables containing the password while you only have access to the new copy.
You can prctl(2) with PR_SET_NAME to change the process name on the fly. Unfortunately I can't currently think of any other way than injecting some code into the running process via ptrace(2), which means enemy processes will race to read the process list before you get a chance to change the new processes name :/
Alternatively, you can grab the grsecurity kernel patches, and turn on CONFIG_GRKERNSEC_PROC_USER:
If you say Y here, non-root users will
only be able to view their own
processes, and restricts them from
viewing network-related information,
and viewing kernel symbol and module
information.
This will stop ps from being able to view the running command, as ps reads from /proc/<pid>/cmdline
Said interface requires us to pass a
plain-text password over a command
line to connect to the database. This
is a terrible security practice, but
we are stuck with it.
It's only a bad security practice because of problems in the O/S architecture. Would you expect other users to be able to intercept your syscalls? I wouldn't blame a developer who fell into this trap.
Is there a way to execute commands using directory traversal attacks?
For instance, I access a server's etc/passwd file like this
http://server.com/..%01/..%01/..%01//etc/passwd
Is there a way to run a command instead? Like...
http://server.com/..%01/..%01/..%01//ls
..... and get an output?
To be clear here, I've found the vuln in our company's server. I'm looking to raise the risk level (or bonus points for me) by proving that it may give an attacker complete access to the system
Chroot on Linux is easily breakable (unlike FreeBSD). Better solution is to switch on SELinux and run Apache in SELinux sandbox:
run_init /etc/init.d/httpd restart
Make sure you have mod_security installed and properly configured.
If you are able to view /etc/passwd as a result of the document root or access to Directory not correctly configured on the server, then the presence of this vulnerability does not automatically mean you can execute commands of your choice.
On the other hand if you are able view entries from /etc/passwd as a result of the web application using user input (filename) in calls such as popen, exec, system, shell_exec, or variants without adequate sanitization, then you may be able to execute arbitrary commands.
Unless the web server is utterly hideously programmed by someone with no idea what they're doing, trying to access ls using that (assuming it even works) would result in you seeing the contents of the ls binary, and nothing else.
Which is probably not very useful.
Yes it is possible (the first question) if the application is really really bad (in terms of security).
http://www.owasp.org/index.php/Top_10_2007-Malicious_File_Execution
Edit#2: I have edited out my comments as they were deemed sarcastic and blunt. Ok now as more information came from gAMBOOKa about this, Apache with Fedora - which you should have put into the question - I would suggest:
Post to Apache forum, highlighting you're running latest version of Apache and running on Fedora and submit the exploit to them.
Post to Fedora's forum, again, highlighting you're running the latest version of Apache and submit the exploit to them.
It should be noted, include the httpd.conf to both of the sites when posting to their forums.
To minimize access to passwd files, look into running Apache in a sandbox/chrooted environment where any other files such as passwd are not visible outside of the sandbox/chrooted environment...have you a spare box lying around to experiment with it or even better use VMWARE to simulate the identical environment you are using for the Apache/Fedora - try get it to be IDENTICAL environment, and make the httpd server run within VMWare, and remotely access the Virtual machine to check if the exploit is still visible. Then chroot/sandbox it and re-run the exploit again...
Document the step-by-step to reproduce it and include a recommendation until a fix is found, meanwhile if there is minimal impact to the webserver running in sandbox/chrooted environment - push them to do so...
Hope this helps,
Best regards,
Tom.
If you already can view etc/passwd then the server must be poorly configured...
if you really want to execute commands then you need to know the php script running in the server whether there is any system() command so that you can pass commands through the url..
eg: url?command=ls
try to view the .htaccess files....it may do the trick..
I posted this question a while ago regarding where to store non-user specific application data on Linux.
As you can see, I intended to use "/Library/Application Support” on Mac and perhaps "/var/lib" or "/usr/share" on Linux.
On an existing application (currently Windows only) we use “\ProgramData” on Vista & Windows 7 and “\Documents and Settings\All Users“ on Windows XP (both obtained using System.getenv("ALLUSERSPROFILE"), which does not work on Mac or Linux).
The problem I am finding with the Mac & Linux locations (unlike the Windows ones) is that they are not accessible by non-root/admin users, which sort of defeats the purpose of using them.
What is the best practice is this case? We could simply store the application data in the user's home directory. I wouldn't actually be dead against this, as it seems reasonable for the application to appear completely 'new' when a new user tries using it. The main problem this gives us is that each user would have to enter the serial number in order to activate the application (the activation info is part of the 'application data' we need to store). This isn't really ideal.
That said, if there is no real alternative then I suppose it will have to do.
What do you mean by non-user specific application data?
Read-only resources needed by application, such as localization strings or button icons:
on Mac they are stored in application bundle itself, in Resources subfolder
on Linux, they can be stored near application binary, in /opt/<app>/etc for instance.
Read/write properties, such as serial number:
you can consider this information as user-specific application data, so it should go somewhere in $HOME directory
you can consider this information as computer-wide application data, in which case its setting should be perfomed during software installation process, i.e., with administrative privileges.
/Users/Shared/ is writable for everyone. That said, if you need to support computer-wide licenses, the best place for serial numbers, IMHO, is indeed /Library/Application Support. You would have to use Authorization Services once to ask for an admin password and save the serial number there. If a user fails to enter the admin password, save the serial number in ~/Library/Application Support instead.
I want to make a web service that runs other people's code locally. Naturally, I want to limit their code's access to a certain "sandbox" directory, so that they won't be able to connect to other parts of my server (DB, main webserver, etc.)
What's the best way to do this?
Run VMware/Virtualbox:
+ I guess it's as secure as it gets. Even if someone manage to "hack", they only hack the guest machine
+ Can limit the CPU & memory the processes use
+ Easy to set up - just create the VM
- Harder to "connect" the sandbox directory from the host to the guest
- Wasting extra memory and CPU for managing the VM
Run underprivileged user:
+ Doesn't waste extra resources
+ Sandbox directory is just a plain directory
? Can't limit CPU and memory?
? I don't know if it's secure enough
Any other way?
Server running Fedora Core 8, the "other" codes written in Java & C++
To limit CPU and memory, you want to set limits for groups of processes (POSIX resource limits only apply to individual processes). You can do this using cgroups.
For example, to limit memory start by mounting the memory cgroups filesystem:
# mount cgroup -t cgroup -o memory /cgroups/memory
Then, create a new sub-directory for each group, e.g.
# mkdir /cgroups/memory/my-users
Put the processes you want constrained (process with PID "1234" here) into this group:
# cd /cgroups/memory/my-users
# echo 1234 >> tasks
Set the total memory limit for the group:
# echo 1000000 > memory.limit_in_bytes
If processes in the group fork child processes, they will also be in the group.
The above group sets the resident memory limit (i.e. constrained processes will start to swap rather than using more memory). Other cgroups let you constrain other things, such as CPU time.
You could either put your server process into the group (so that the whole system with all its users fall under the limits) or get the server to put each new session into a new group.
chroot, jail, container, VServer/OpenVZ/etc., are generally more secure than running as an unprivileged user, but lighter-weight than full OS virtualization.
Also, for Java, you might trust the JVM's built-in sandboxing, and for compiling C++, NaCl claims to be able to sandbox x86 code.
But as Checkers' answer states, it's been proven possible to cause malicious damage from almost any "sandbox" in the past, and I would expect more holes to be continually found (and hopefully fixed) in the future. Do you really want to be running untrusted code?
Reading the codepad.org/about page might give you some cool ideas.
http://codepad.org/about
Running under unprivileged user still allows a local attacker to exploit vulnerabilities to elevate privileges.
Allowing to execute code in a VM can be insecure as well; the attacker can gain access to host system, as recent VMWare vulnerability report has shown.
In my opinion, allowing running native code on your system in the first place is not a good idea from security point of view. Maybe you should reconsider allowing them to run native code, this will certainly reduce the risk.
Check out ulimit and friends for ways of limiting the underprivileged user's ability to DOS the machine.
Try learning a little about setting up policies for SELinux. If you're running a Red Hat box, you're good to go since they package it into the default distro.
This will be useful if you know the things to which the code should not have access. Or you can do the opposite, and only grant access to certain things.
However, those policies are complicated, and may require more investment in time than you may wish to put forth.
Use Ideone API - the simplest way.
try using lxc as a container for your apache server
Not sure about how much effort you want to put into this thing but could you run Xen like the VPS web hosts out there?
http://www.xen.org/
This would allow full root access on their little piece of the server without compromising the other users or the base system.