It is helpful for post-exploitation toolkits to have this functionality.
It is helpful for post-exploitation toolkits to have this functionality.
https://man.openbsd.org/ssh-agent:
> The agent will never send a private key over its request channel. Instead, operations that require a private key will be performed by the agent, and the result will be returned to the requester. This way, private keys are not exposed to clients using the agent.
This sounds like a pretty gaping security hole by Microsoft. I would not assume loading private keys to an "ssh-agent" means giving any process (browser, email client etc.) running on the same machine access to the unencrypted values!
But can't just any program do that as soon as you're logged in? (Since your login password basically unlocks the DP-API which is protected at rest.)
It doesn't.
> AFAIK the whole point of ssh-agent is that the private keys are NOT extractable by other processes.
Any process with sufficient privileges (i.e., root) can extract the private key from ssh-agent on Linux as well.
So it's not a vulnerability in the sense of an unintended exposure, but, it's certainly true that Microsoft's design gives the private key much more exposure than the design used on most Linux distros. (And it's unclear whether MS intended to deviate from this behavior.)
I don't think this is correct. ssh-agent typically will be run under your user/group; it shouldn't have the necessary privileges to setgid to ssh. Further, I have ssh-agent running on a machine, and it is still my gid. Last, that machine doesn't even have an "ssh" group.
Rather, I think ssh-agent likely protects itself from being debugged (ptrace'd) by ptrace'ing itself. My understanding is that a process can only be ptraced by one process at a time, and by ptrace'ing yourself, you deny the ability for anything else to attach to you.
For example, my uid & gid:
» printf '%s,%s\n' "$(id -u)" "$(id -g)"
1000,1000
ssh-agent running as those: » ps -eo pid,uid,gid,args | grep ssh-agent
16438 1000 1000 ssh-agent
but not debuggable: » strace -p 16438
strace: attach: ptrace(PTRACE_SEIZE, 16438): Operation not permitted
Perhaps this is just my machine however, and if I did have a `ssh` group, and I were a member of it, it would setgid to it. I don't think that's foolproof, however: something running under your uid could kill ssh-agent, and restart it under a debugger, skip or elide the setgid() and ptrace() calls, then continue to allow it to execute normally, and now be attached as a debugger.I'm also not sure if ptrace()'ing yourself prevents you from reading out the process's memory from /proc.
Edit: so, on Linux, it seems this is what it does[1]:
prctl(PR_SET_DUMPABLE, 0)
That makes the process "undumpable", which means it won't leave behind core files, /proc/pid is root:root, and it can't be ptrace()'d. I still think the caveat about starting it under a debugger applies, but that certainly makes it less trivial.[1]: https://github.com/openssh/openssh-portable/blob/5ee3fb5affd...
"being setgid to group ssh" and "calling the setgid system call to become group ssh" are two pretty different things, and it's unfortunate that UNIX uses the same terminology "setgid" to describe these two. (They don't even have the same end result; the system call changes the real group ID, and the permission bit changes the effective group ID.)
I don't think ptracing yourself is even possible (also how would you restart the process once stopped?):
$ cat src/main.rs
extern crate nix;
use nix::unistd::*;
use nix::sys::ptrace;
fn main() {
ptrace::attach(getpid()).unwrap();
}
$ cargo run
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Sys(EPERM)', libcore/result.rs:945:5
note: Run with `RUST_BACKTRACE=1` for a backtrace.
Starting it under a debugger means that you have to re-load the encrypted file from disk and re-enter the password. The attack we're worried about seems to be that the system is secure when the key is initially loaded, but at some later point some malware tries to steal the key. If you have access to the password, you can just copy the key and decrypt it on some other machine.That said, I still don't think the processes group is what stops you from debugging it (it's the undumpable flag). The group check wouldn't matter and would never take effect, since your uid matches that of the process, that would be sufficient to allow you access to the process, would it not?
titan:~ geofft$ ls -ld /usr/games/battlestar
-rwxr-sr-x 1 root games 213272 Jul 8 2014 /usr/games/battlestar
titan:~ geofft$ battlestar
[...]
^Z
[1]+ Stopped battlestar
titan:~ geofft$ jobs -p
6343
titan:~ geofft$ strace -p 6343
strace: attach: ptrace(PTRACE_ATTACH, ...): Operation not permitted
titan:~ geofft$ fg
^Cbye.
Your rating was novice.
titan:~ geofft$ ls -l /var/games/bsdgames/battlestar.log
-rw-rw-r-- 1 root games 58 May 23 15:50 /var/games/bsdgames/battlestar.log
titan:~ geofft$ cat /var/games/bsdgames/battlestar.log
Wed May 23 15:50:51 2018 geofft novice
One subtler thing is that, as 'tedunangst points out, ssh-agent changes back to your gid with the setgid syscall. But (at least on Linux, and I think on most UNIXes) that doesn't re-enable debug access, because there might be restricted data still in memory, or mmappings of restricted files, or whatever. You have to do an exec, which dumps the contents of memory, to re-enable debugging.The dumpable flag also blocks debugging on Linux, yes. The full algorithm is way at the bottom of the ptrace manpage http://man7.org/linux/man-pages/man2/ptrace.2.html#NOTES , but it's basically:
- allow debugging another thread from the same process (because threads share memory anyway)
- allow if the debugger is privileged to debug anything (CAP_SYS_PTRACE)
- require that real, effective, and saved UIDs and GIDs all match
- require that the dumpable flag isn't set
and, if you go over and read the prctl manpage http://man7.org/linux/man-pages/man2/prctl.2.html , it points out that the dumpable flag is implicitly set to undumpable if the process changes euid/egid or exec a setuid/setgid/fscaps binary, and the execve manpage says it's set back to dumpable if you exec a normal binary.