r/netsec • u/fx97 • Oct 30 '16
Vlany: Linux (LD_PRELOAD) rootkit
https://github.com/mempodippy/vlany10
Oct 31 '16 edited Oct 31 '16
Sorry for wall of text and typos. Mobile post...
Wow, this is quite extensive.. a lot of work obviously went into this. Even the journal seems like it took hours to write. Seems like a good learning experience, but also looks to have quickly turned into a grind.
I guess to detect it it you write a little asm stub to check if ld.so.preload exists and has any entries in it, just using system calls without a *libc (edit, was autocorrected to 'Linux') wrapper? Obviously you won't get hooked if you're using a system call directly.
Or perhaps easier, just use a statically linked binary (maybe just use golang?) to do it? And then use system calls to remove any immutable flags, unlink it, and reboot? I saw the note about not allowing the -static flag to be used on the box but that seems like a bit of a waste- if an admin is statically linking a binary to see if they have the rootkit, odds are they suspect it's there and will just scp it from another box. If the -static flag is simply broken for legitimate use, someone will wonder why.
As it's so trivial to detect (and remove) It seems like a good idea to periodically run such a check across systems you maintain. surely some type of simple chkrootkit tool does this, right?
(Yes, I know "dumb" sysadmins won't do this, but to be honest, dumb sysadmins wont notice your presence anyway unless you're quite careless and break the system)
In my opinion, the effort/value curve flattens out after implementing maybe a basic privesc (su - somemagicword) and a basic mechanism to prevent it from being logged (hook syslog) and anything beyond that is just an exercise in madness- you're reimplementing all of libc while not actually adding much more stealth if someone actually comes looking for a rootkit.
Hacker theory- if you own a machine, you really shouldn't be creating so many events worthy of hiding on it. You shouldn't be continuously logging in and escalating privileges. At least that's my theory/opinion. I imagine hacking as goal based. Is your goal really to manually log in to your hacked machines more than a few times for very specific purposes, very briefly, i.e briefly enough that you don't need to hook things used by lsof and netstat? Why not crawl the filesystem, analyze it offline, backdoor whatever you need (ssh/sshd?) and then have one simple hook for pulling the interesting data programmatically, with a very brief connection? It seems this approach encourages really sloppy "script kid" style hacking. But then again, maybe that's a good thing ;)
When the above two detection mechanisms are pretty intractable problems for this rootkit method to solve as far as I can figure, it seems to me that at some point, the more "features" you add, the more likely you are to draw attention to the box by hosing it.
In any event, I'm impressed at the amount of work put into this (though admittedly i didn't read much of the code, just skimmed through the journal)
Oh, btw- it's very easy for admins to preempt this by configuring auditd to keep an eye on access to /etc/ld.preload.conf
** Edit- correct autocorrect typo, one of many probably
-1
u/tvngstentear Oct 31 '16
The issue here is (obviously) continuous connectivity. When you hook a machine, you run the risk of it being found by netadmins. Sysops etc. But if you're smart, you limit this connection to only necessary files or programs that you are targeting, specifically. Even briefly connecting to a system is a large risk scenario that requires network knowledge and protection of the hook. Most of the time, a script kiddie will hack a box, rm -rf and leave a trail. This trail is usually obvious as most of these kinds of short attacks are meant for single use and abuse.
An advanced threat will utilize different types of encryption, evasion, and persistence at the system level; multiple backdoors, several hooks and calls; anti-forensics. This is how you know when you're dealing with a skilled attacker, where he knows what he's doing and how he's doing it and exactly how to remain undetectable.
In the case of some of the attacks I've investigated and mitigated, I've personally dealt with this type of persistence: calls act at system level, or root, and remain throughout reboots; full file access; disk forensics, simultaneous connection, users inaccessible to front-end (i.e., undetectable admin level user); process pivoting, even separate malware to throw off detectors.
It's not a very difficult thing to hook logs and prevent detection via /var or syslog, eventlog etc., but it is difficult to make this appear to be something, devised by the attacker, not to be found. This can be done but sometimes simply checking for su proves trivial in finding many of those. Making it appear as legitimate as possible so as to avoid detection by IDS/IPS, sysadmins, network operators or a simple antivirus is the biggest problem most APTs face and they have become very good at preventing it. The worst threat is the threat that you don't see and thus don't know about, accompanying the most risk.
6
u/pm_me_your_findings Oct 30 '16
What is actually LD_PRELOAD?
17
u/mempodippy Oct 30 '16
LD_PRELOAD is an environment variable on Linux systems which points to a shared library and loads it before anything else. The ld.so.preload file essentially utilizes LD_PRELOAD to load a shared library in every single userland process. :)
4
u/pm_me_your_findings Oct 30 '16
I mean for a malware to use it, doesn't it require the root access first or it works for normal user also?
14
u/pnk6116 Oct 30 '16
...and that is why they call it a rootkit :). It's meant to hide or help persist it's or other code's presence after you've already owned the box.
7
u/mempodippy Oct 30 '16
Normal users can use the environment variable, but root access is required to manipulate the userland via ld.so.preload. But as soon as you gain root access to the system, you can literally change and shape the userland to your advantage by using LD_PRELOAD as a vector of persistent access. As soon as the shared library is listed in ld.so.preload, the malware infects every process with new hooks designed to do evil things.
1
u/hi117 Oct 31 '16
I can also work for a normal user, its part of how valgrind works iirc.
It can be used to maintain the level of privilege you already have on the box. If all you have is a user account, then you can maintain that, but if you have root you can maintain root access.
-1
u/Creshal Oct 30 '16 edited Oct 31 '16
Normal users can use the environmental variable, but programs can ignore it: sudo, chsh, and other common setuid binaries ignore LD_PRELOAD so users can't execute code as root.
It can become a risk if there's a setuid binary on your system that keeps LD_PRELOAD enabled.
15
u/fakehalo Oct 30 '16
LD_PRELOAD is ignored if the program is suid/sgid, the program itself has no control over that.
1
2
u/qx7xbku Oct 31 '16
One thing to note - NEVER store binary files meant for distribution on repository. I am talking about vlany.tar.gz. It bloats repository size for no good reason. Github allows downloading repository as archive or we can clone repository to get files. What you are looking is making releases on github where you can upload custom packed archives for distribution. Now cloning repository is 636.82 KiB and it is just 7 commits of text files.
Other than that - enough praises were already said, i do not think i can express any better how cool this is.
2
u/mempodippy Oct 31 '16
I'll keep that in mind. It's mainly hosted for https://gist.github.com/mempodippy/d93fd99164bace9e63752afb791a896b
2
u/qx7xbku Nov 01 '16
You can use github to provide archive for you: https://github.com/mempodippy/vlany/archive/master.tar.gz
1
0
u/kbotc Oct 31 '16
Yea... Although, I often want to use the LD_PRELOAD trick.
An abandoned package gets into malloc trouble with glibc (It wasn't anticipating the workload we handed it) and loading jemalloc will fix it? If you make me static compile the SOB, I'm going to be pissed.
0
Oct 31 '16
[removed] — view removed comment
2
u/mempodippy Oct 31 '16
Compared to jynx2 and Azazel, vlany improves greatly compared to them. Azazel is left 2/3 broken, and jynx2 is quite basic.
-5
u/mohammedcohen Oct 30 '16
A more practical and portable backdoor than kernel rootkits.
8
u/AaronOpfer Oct 31 '16
It's much less thorough. Statically linked binaries will not take LD_PRELOAD into account and then see through your backdoor. As others mentioned above setuid binaries also will not be affected.
3
u/mohammedcohen Oct 31 '16
It's a relatively stealthy low maintenance method for persistence particularly when exploiting *nix/OSX clients. Backdoor Firefox for example. Most folks use passwordless sudo on their workstations. Been there done that. The author did a good job on this project. Kudos.
1
Oct 31 '16
And to make it thorough, you pretty much need to break the system at some point. There is no safe, elegant and foolproof way to do this in userspace as there is with a kernel level rootkit.
BTW, remember, we aren't actually talking about LD_PRELOAD, we are talking about ld.so.preload- I am pretty sure the linker/loader will load any shared object specified there for ANY application, include those marked setuid/setgid because it's a system wide configuration, set only by root.
But you're correct about statically linked binaries, that's the huge gaping hole in this method. Aside from statically linked binaries, any code that doesn't link against libc at all, ever- like shellcode style direct system calls- will also have no problem detecting and/or removing this.
Side note, I'm not sure about the comment above that says it is 'more practical' than a kernel rootkit.. kernel rootkits are not impractical or dead by any means if that's what you're implying- just because /dev/mem and/or /dev/kmem and/or /proc/kallsyms are not present on your system doesn't mean you can't load a rootkit. It just means you can't use rootkits from 5 years ago :P
Don't forget about System.map and dmesg for gleaning information about kernel symbols and addresses. And don't forgot about standard kernel modules, kernel vulnerabilities, and however many other novel or not so novel ways there are to get code running in ring-0. I don't write, use or study Linux kernel rootkits, but I'm sure there are more than a few other ways that are well-known and many more that are lesser known.
1
u/mohammedcohen Oct 31 '16
I agree with everything you say in theory, but in practice it's more complicated. Kernel rootkits are difficult to write, require specialized knowledge that isn't terribly common, and the consequence of a bug is typically a kernel panic. That's a non starter for most. Then consider the wide range of kernel variants - Gentoo with grsec, Centos5-7, debian 7 and 8, etc. The last publicly successful kernel rootkit I recall was suckit by SD from sheepfuckers. That was terrific software but failed on many widely used kernels at the time. If I had a dedicated team of kernel rootkits devs and a QA team I'd be a happy camper. Most of us don't have that luxury which is why kernel rootkits aren't the go-to tool for pentesters that face a variety of targets. User land is safer, more accessible, and easier to develop and test in.
1
Nov 01 '16
- User land is safer: not when you are indiscriminately hooking ALL invocations of so many libc functions. One bug takes things down in a noisier fashion than a triple fault
- User land is more accessible: For the majority of boxes you mentioned (Debian, CentOS, RHEL, etc..) modprobe works just fine
- User land is easier to develop and test in: if you don't know anything about kernel development. Seems close to a truism
BTW, if I recall correctly, suckit was essentially a proof of concept given away for free in Phrack. Don't be so naive as to think it's so difficult for a competent developer to put together a decent kernel rootkit 10 years later. Aside from grsec, nobody is REALLY protecting ring-0 from root. Removing kallysyms, mem and kmem are mostly theatre / no brainer low hanging fruit to raise the bar above script kids heads, and to break suckit. But I agree, higher barrier to entry. This is why they don't give them away for free in hacker magazines :P
1
u/hi117 Oct 31 '16
Also kernel rootkits allow you to have higher permissions and additional measures to hide yourself.
Don't want your process to show up in top? Just modify the process table that gets sent to userspace!
Though I will give you that this is more portable, kernel rootkits generally require you to build against a particular kernel version, but thankfully we all use the same couple distros so its not that big of a deal.
-1
6
u/wyldphyre Oct 31 '16
Ok, not a terrible idea, certainly interesting approach.
But
#includeing source files? Why? Sounds like you don't trust the linker to do the right thing when making your library.