Fwd: Fwd: Getting path in inode_permission
Apologies for the late reply. On Sat, Feb 7, 2015 at 8:52 AM, <Valdis.Kletnieks@vt.edu> wrote:
On Sat, 07 Feb 2015 07:27:13 +0530, noyb noybee said:
I am trying to enhance the security features of the chroot "jail"(I know it wasn't built for the purpose). I am trying to prevent access to files outside the "jail" unless they specify a specific
The right thing to do is design the jail so it *never* references files outside.
passsphrase. Whenever an inode is accessed, inode_persmission is called. I get the pid of the calling process by current->pid in the hook and check if it is a child of the original process for which
Bzzt! Wrong. Trivially beatable - all I have to do is double-fork, exit the child process, the grandchild gets reparented to PID 1, and your check fails.
You are correct. I missed out on that fact. Well, there's still a workaround. I will put in some kind of data in the security structure of task_struct as soon as it is created.
chroot was run. If yes + if this process hasn't specified a passphrase + the path of the inode shows that it is outside the "jail", the request is blocked. I am also blocking all mounts in the "jail".
Plus the whole passphrase thing is probably equally easy to defeat. (Hint - how does the passphrase get passed to the kernel in the first place?)
I am planning to create a new system call for that and I am not sure how that would be insecure. Please correct me if I am wrong. What you're saying is definitely simpler than my approach but it probably violates some POSIX standards(including chdir in chroot) which I don't want to. Also, I aim for my tool to be just a simple addendum to the traditional system call rather than adding a completely new call to handle the entire process.
On Wed, 11 Feb 2015 03:42:50 +0530, noyb noybee said:
Apologies for the late reply.
Plus the whole passphrase thing is probably equally easy to defeat. (Hint - how does the passphrase get passed to the kernel in the first place?)
I am planning to create a new system call for that and I am not sure how that would be insecure. Please correct me if I am wrong.
You missed the point. How does the process *securely* get the passphrase that will be passed into the syscall? (Hint - a keystroke logger is only the *start* of your problems. Think about why the kernel module signing code uses public-key crypto instead of symmetric private keys...)
What you're saying is definitely simpler than my approach but it probably violates some POSIX standards(including chdir in chroot) which I don't want to. Also, I aim for my tool to be just a simple addendum to the traditional system call rather than adding a completely new call to handle the entire process.
The problem with "simple addendum" is that it's *really* hard to get it right.
On Wed, Feb 11, 2015 at 4:29 AM, <Valdis.Kletnieks@vt.edu> wrote:
On Wed, 11 Feb 2015 03:42:50 +0530, noyb noybee said: You missed the point. How does the process *securely* get the passphrase that will be passed into the syscall? (Hint - a keystroke logger is only the *start* of your problems. Think about why the kernel module signing code uses public-key crypto instead of symmetric private keys...)
I was planning that the calling process would call the new system call which would return a pseudo-random key that is used as the pass-phrase.
On Thu, 12 Feb 2015 00:31:45 +0530, noyb noybee said:
I was planning that the calling process would call the new system call which would return a pseudo-random key that is used as the pass-phrase.
So what prevents malicious code from doing a fork and then calling the new syscall to get its own pseudo-random key to use as a passphrase? Like I said, this is a lot harder to make secure than it looks.
On Thu, Feb 12, 2015 at 2:07 AM, <Valdis.Kletnieks@vt.edu> wrote:
On Thu, 12 Feb 2015 00:31:45 +0530, noyb noybee said:
I was planning that the calling process would call the new system call which would return a pseudo-random key that is used as the pass-phrase.
So what prevents malicious code from doing a fork and then calling the new syscall to get its own pseudo-random key to use as a passphrase? Well, any program which has root credentials is still allowed to call chroot(it needs to get a new passphrase before) but not any program with root credentials can exit it. The passphrase last generated(and still unused) will be used as the passphrase for a chroot system call(both needed to be called by the same processes, ofc). Once a passphrase is used for a chroot system call, it is never returned(pseudo-random) again.
On Thu, 12 Feb 2015 03:19:46 +0530, noyb noybee said:
Well, any program which has root credentials is still allowed to call chroot(it needs to get a new passphrase before) but not any program with root credentials can exit it.
Well see... now you have a problem. If you don't allow that chroot program to fork() or exec(), you now have the passphrase sitting in memory someplace (since you need to pass it back), and exploit code can find it in memory. If you allow fork/exec into other programs, it gets worse - now you need to pass that passphrase to children. And if you're using the passphrase for the chroot() call *itself*, you have an even bigger problem - whatever access that passphrase adds is now available *anywhere inside the chroot*. So all I need to do is find a way to exploit the chroot, and now I have access to resources outside the chroot. At which point your security scheme is *totally* broken. Instead of your original:
I am trying to prevent access to files outside the "jail" unless they specify a specific passsphrase.
You've just handed unfettered access to the files to the exploit. How about you concentrate on "how were they able to access files outside the chroot in the first place"?
Once a passphrase is used for a chroot system call, it is never returned(pseudo-random) again.
Or so you hope. :) It's easy to design security schemes that work if code follows the rules. The fun is designing code that withstands attempts to break the rules. Consider abuse of inherited file descriptors - say stderr is open to a logfile. My exploit code closes fd 2. What happens the next time somebody opens a file, and then something does fprintf(stderr,....)? What happens if code trawls the process image and finds the magic key? What happens if somebody forks? Or double/triple forks? What happens if somebody sets LD_PRELOAD and then causes an exec()? What happens if somebody manages to attach a child process to your process and then triggers an unexpected SIGCHLD? (Hint - it's *trivial* to actually do that - see if you can guess how before reading the link below...) Henry Spencer, a long time ago, wrote a good set of things to worry about when writing set-UID programs - most of which also apply to chroot code. Note that this is *not* a complete list, it's *just* the low-hanging fruit. http://www.daemon-systems.org/man/setuid.7.html Now, can you explain what problem you're trying to solve with this security scheme?
On Thu, Feb 12, 2015 at 3:44 AM, <Valdis.Kletnieks@vt.edu> wrote:
And if you're using the passphrase for the chroot() call *itself*, you have an even bigger problem - whatever access that passphrase adds is now available *anywhere inside the chroot*.
So all I need to do is find a way to exploit the chroot, and now I have access to resources outside the chroot. At which point your security scheme is *totally* broken.
You are right. Even on adding the passphrase, if the original program that executed chroot is exploitable(which my solution tried to take into account), it could still access the passphrase and we would be back at square one.
How about you concentrate on "how were they able to access files outside the chroot in the first place"? So, closing all open file descriptors that are outside the new root directory + changing the CWD + blocking any mounts.
On Thu, 12 Feb 2015 23:41:18 +0530, noyb noybee said:
On Thu, Feb 12, 2015 at 3:44 AM, <Valdis.Kletnieks@vt.edu> wrote:
How about you concentrate on "how were they able to access files outside the chroot in the first place"? So, closing all open file descriptors that are outside the new root directory + changing the CWD + blocking any mounts.
That's a good start. Now, for bonus points - explain why you wanted something inside a chroot to be able to access something outside the chroot. (Hint - why can't you just bind-mount it into the chroot hierarchy before launching the chroot'ed program?)
participants (2)
-
noyb noybee -
Valdis.Kletnieks@vt.edu