pam_exec and security - pam

I would really like to use the PAM module pam_exec to do some account setup and teardown activities during a session. I have written a simple test script that runs and logs some runtime data so that i can see what is happening.
It seems to me that the exec'd script has to be executable by the effective UID of whoever is running the command that triggers PAM. This makes sense. However, I want a bit more security in this process. For example, it seems to me that if I have a script that pokes a record into a database on account login/logout then that script has to be executable by ALL users all the time.
I would much prefer to have the script be visible and executable ONLY by root or some other special-purpose account and have pam_exec suid the script for the unprivileged user.
Why? In the case of the database script I would not want the user to login then execute the script by hand to seemingly "logout".
I've thought about trying to put the script in the "sudoers" file but that still enables anyone to run it whenever they like.
It seems like the only option is to hack pam_exec to allow a "run as" option.
It is late on a Friday afternoon and I may be missing something trivial. Is there a better way?

It seems to me that the exec'd script has to be executable by the
effective UID of whoever is running the command that triggers PAM.
This makes sense.
Sounds like you are running pam_exec under the "session" line. If you run your pam_exec script from "auth" it will be run by the root users (UID 0), so it doesn't need to be executable by the user any longer. This way the user will not be able to run the script manually to spoof a logout.
You could probably also run your script from the "account" line, I believe the only time that a pam module executes with user permissions is when it is executing pam_open_session() or pam_close_session().

I'm not entirely sure that I understand the problem. If you're tracking a user login session, that is set up by a process running as root (whether it be sshd or login or some other similar program). The PAM stack generally all runs as root through opening the session. I'm not entirely sure where in the session creation process the UID is permanently changed, but it's fairly late in the process, since writing to utmp, etc., all has to be done as root.
You therefore are unlikely to run into this problem with normal login sessions. The main places where PAM is used by non-root users is for things like screensavers that run on behalf of the user, but that seems like exactly the case where you don't want the user to run your script.
If you're trying to run something as part of sudo or su, the problem may be that pam_exec by default runs the program as the real user ID. In those cases, I think you may need to run the program as the effective user ID to accomplish what you want. There is a seteuid PAM option to pam_exec that tells pam_exec to do that.

Related

Jenkins store unix password

I have a design question. I am using jenkins to automate tasks. Let's say someone wants to perform taskA, he would run a pexpect file using jenkins and everything would be done automatically. Some of these tasks require to switch unix user and I was wondering if there is a more nice and secure way to get/set passwords for these users instead of just putting them in a property file. The solution I have right now is to ask the user to set the password in jenkins before running the task, and to put the passwords in a property file which will be used by the pexpect file. I know it's very bad to hardcode passwords but this is for internal tasks test only so if there is no other way to do it I'll probably go for that option.
Thanks!
You could use add Jenkins to the sudo list to allow the jenkins user to become anyone.
Finally the solution was quite simple, I used 'Build with parameters' and passwords are sent to my server as password type parameters.

access(2) system call security issue

access(2) man page says,
CAVEAT
Access() is a potential security hole and should never be used.
But what is the security hole and why I should not use it?
From my system's man pages:
Warning: Using access() to check if a user is authorized to, for example, open a file before actually doing so using open(2) creates a security hole, because the user might exploit the short time interval between checking and opening the file to manipulate it. For this reason, the use of this system call should be avoided. (In the example just described, a safer alternative would be to temporarily switch the process's effective user ID to the real ID and then call open(2).)
So, the problem is that it creates a race condition can be exploited by the user to gain access to other files.
Imagine the following example scenario. I create a file /tmp/file that I am allowed to write. Then, your uid-0 program calls access() to check if I am allowed to open this file for writing, before providing me write access to it.
In the short space between the calls to access() and open(), I can remove /tmp/file and replace it by a symlink to /etc/crontab. I can now get the system to run any program I like, since the application will happily give me write access to /etc/crontab.
Linux Man pages clearly describes it
Warning: Using access() to check if a user is authorized to, for example, open
a file before actually doing so using open(2) creates a security hole, because
the user might exploit the short time interval between checking and opening
the file to manipulate it. For this reason, the use of this system call
should be avoided.
Also note. For security reason security exploits are not easily reachable to public.
Check out: http://www.kernel.org/doc/man-pages/online/pages/man2/access.2.html
Warning: Using access() to check if a user is authorized to, for
example, open
a file before actually doing so using open(2) creates a security hole, because
the user might exploit the short time interval between checking and opening
the file to manipulate it. For this reason, the use of this system call
should be avoided. (In the example just described, a safer alternative would
be to temporarily switch the process's effective user ID to the real ID and
then call open(2).)
See also:
http://www.csl.sri.com/~ddean/papers/usenix04.pdf
What is wrong with access()?

ZEO: How can I make lets clients in read-only but make changes through the console

I'm running a script by pasting it in a console like this:
bin/client2 debug
... my script ...
The script normalizes titles of the files. Since there are more than 20k files it takes really too much to time. So I need users still can use the site but in a read-only fashion.
But I assume that setting read-only true in zeo.conf would not let me run my normalization script. Wouldn't it?
How can I solve this?
Best regards,
Manuel.
There isn't, I'm afraid.
If your users alter the site when logged in, disable logging in for them until you are done.
Generally, for tasks like these, I run the changes in batches, to minimize conflicts and allow end-users to continue to use the site as normal. Break your work up in chunks, and commit after every n items processed.
You can add another zeo client that is not RO--it's not required that a zeoserver be RO to have the clients RO.
So, all the clients that are being used, make RO, and then add an additional RW client that isn't used by anyone but your script and then leave the zeoserver RW.

How do Unix capabilities work?

it seems that starting kernel 2.2, they introduced the concept of Capabilities. According to the unix man page on capabilities, it says if you're not a root user, you can grant yourself of capabilities by calling cap_set_proc per thread basis. So does this mean that if you're writing a malware for unix, do you just grant yourself bunch of capabilities and compromise the system? If not, how does one grant capabilities required to run the program?
it seems that Unix's security model is quite flawed primitive. Am I getting this right?
I'll go more specific:
How do you (when running as a non-root user) send a signal to another process that is running under different user? On signal man page, it says you need CAP_KILL capability to perform this. However, reading the capabilities man page, I'm not sure how I can grant a process that capability.
From man cap_set_proc:
Please note, by default, the only processes that have CAP_SETPCAP available to them are processes started as a kernel-thread. (Typically this includes init(8), kflushd and kswapd). You will need to recompile the kernel to modify this default.
Trust me if it was that easy I'm sure someone would have exploited it by now. Unix's security model may be simple by comparison to other operating systems, but it doesn't mean it's "flawed".
it's impossible. Use Socket or File instead.

How do I terminate WINWORD.EXE when used by classic ASP?

I have a user who has to use Microsoft Word 2007 to create and manipulate word documents in his ASP web application. I'm well aware of the 'Considerations for server-side Automation of Office' KB article and the many third party components available to do this kind of thing, but they've gone a fair bit down this road already.
The problem he's having is that the WINWORD.EXE process never terminates even though he calls Quit on the application object.
For example:
Set objWord = Server.CreateObject("Word.Application")
'' Do work
objWord.Quit
Set objWord = Nothing
As you would expect, his server ends up littered with orphaned WINWORD.EXE
processes requiring manual intervention to terminate.
Is there a way to terminate these WINWORD.EXE processes explicitly in the script?
Update:
I've made some progress with this and I think I have a handle on what the problem is. When an Office application runs for the first time under a new Windows account it asks for your name and initials. Now because there is no visible GUI, there is no-one there to push all the right buttons. I've tried starting WINWORD.EXE as the website anonymous account identity using RUNAS, but there's some permission issue that's preventing Word or Office performing some other kind of initial setup routine it wants to do.
There are two things I can think of:
MyWorkBook.Saved has not been set to true. As a result the Quit call results in WinWord displaying a "Do you wish to save" dialog. On a server. Under a session with no desktop. Needless to say Word never manages to quit as it is waiting for the user.
Your user's script is not always making it to the Quit line. This is a frequent and perhaps biggest reasons against using the Office Automation, as you really need multiple layers of exception handling and finally statements (which isn't VBScript or the ASP classic engines strong point) to ensure that the instance is properly cleaned up.
This question is now no longer relevant. Almost all the issues were related to WINWORD.EXE requiring elevated privileges (higher than we allow for web site anonymous user accounts) to be able to perform certain tasks.
Customer has wisely decided to use ASPOSE.Words for .NET which also has a COM callable wrapper so classic ASP code can use it too.

Resources