4 ms·
> ssh-agent protects itself from being accessed by the same user account (via the debugging APIs) by being setgid to group ssh I don't think this is correct. s
by deathanatos 8y ago
> ssh-agent protects itself from being accessed by the same user account (via the debugging APIs) by being setgid to group ssh
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/5ee3fb5affd7646f141749483205ade5fc54adaf/platform-tracing.c#L38 https://github.com/openssh/openssh-portable/blob/5ee3fb5affd...
- tedunangst 8y agoDepends on the OS. Where it's setgid, it changes gid back to the user running it, so you wouldn't see it in ps anyway.
- geofft 8y ago"most Linux distros" might have been wrong, but on Debian and Ubuntu at least, the executable /usr/bin/ssh-agent has group ssh and has the sgid bit set. So, when you run it, it automatically runs as group ssh via file permissions, denying you the ability to debug it, precisely because you're not a member of group ssh. "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.
- deathanatos 8y agoI see what you mean about being setgid; I did not think to check for that. 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?
- geofft 8y agoNo - the debugging check pays attention to more than just UID, specifically because the point of being setgid is that a binary can be allowed to access files that the calling user isn't permitted to access. For instance, games are traditionally setgid games to update high scores, which users in general shouldn't be able to do. Being able to attach a debugger to a game would let you update high scores without actually playing the game. 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 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 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.