[HN Gopher] Unprivileged process injection techniques in Linux
       ___________________________________________________________________
        
       Unprivileged process injection techniques in Linux
        
       Author : joe_v
       Score  : 135 points
       Date   : 2023-12-29 02:27 UTC (2 days ago)
        
 (HTM) web link (joev.dev)
 (TXT) w3m dump (joev.dev)
        
       | grugq wrote:
       | The history actually goes back quite a bit further.
       | 
       | Exactly 20 years ago I wrote and released userland exec().
       | 
       | https://seclists.org/bugtraq/2004/Jan/2
       | 
       | Good to see that the technique is still viable after two decades.
       | 
       | On a related note, this sort of issue (difficulty researching the
       | origins of techniques, and hacking history in general) is a
       | problem that will only get worse. As a community we haven't
       | created an institutional memory beyond "the oldest hacker you
       | know."
        
         | Retr0id wrote:
         | > Good to see that the technique is still viable after two
         | decades.
         | 
         | It absolutely blew my mind to learn that Debian is still
         | shipping with Yama mitigations disabled by default (last time I
         | checked, which was about a year ago). I think they're one of
         | the only mainstream distros to be doing this, although I
         | haven't done a comprehensive survey.
        
           | deadlydose wrote:
           | I think this is so users can choose what level of restriction
           | they want using kernel.yama.ptrace_scope with sysctl, 0 being
           | the default and 2 being the most restrictive.
        
             | Retr0id wrote:
             | You can configure it on most distros, it doesn't excuse
             | having an insecure default.
        
           | secure wrote:
           | The Debian patch for this setting is:
           | https://salsa.debian.org/kernel-
           | team/linux/-/blob/master/deb...
           | 
           | The decision made there is from 2013 (see
           | https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=712740), so
           | it might be worth revisiting.
           | 
           | Could you file a bug report to get the discussion started?
        
         | fluoridation wrote:
         | Ha. I did the exact same thing on Windows to inject DLLs into
         | Chrome once.
         | 
         | EDIT: Geez. I sure wish I knew what's so objectionable about
         | what I said.
        
           | ImPostingOnHN wrote:
           | I didn't vote either way until you edited your post to add
           | the meta comment. I don't like posters discussing moderation
           | of their posts (I find that discussion about themselves to be
           | vain and distracting from the topic), and I feel gross and
           | off topic myself talking about it even now.
           | 
           | The chrome thing sounds cool.
        
             | throwaway892238 wrote:
             | The strange taboos of ingroups
        
               | ImPostingOnHN wrote:
               | To be fair, the guidelines _[0]_ request of us:
               | 
               |  _> Please don 't comment about the voting on comments.
               | It never does any good, and it makes boring reading._
               | 
               | Which, yeah.
               | 
               |  _[0] -https://news.ycombinator.com/newsguidelines.html_
        
               | WhackyIdeas wrote:
               | Maybe one day HN will realise that giving the ability to
               | downvote is pretty pointless and needlessly open to
               | abuse.
               | 
               | That negative ability just promotes negativity itself and
               | a bloody pia when I am reading a greyed out message
               | because I am too stubborn to go into the settings and
               | change defaults - so I just steam on thinking HN are
               | using a relic of an ideology.
        
             | fluoridation wrote:
             | I didn't comment about the voting itself, I asked what was
             | wrong with my comment. There's a difference between "oh,
             | I'm getting down-voted, this sucks" and "what's wrong with
             | what I said?" The former is whining, while the latter
             | invites discussion. If telling someone else what you think
             | about their comment counts as "meta" discussion and is
             | therefore boring then that kind of kills the purpose of a
             | discussion forum.
        
           | Retr0id wrote:
           | I didn't vote, but to answer your question, you couldn't
           | possibly have done the "exact same thing" as a linux-specific
           | userland exec technique and have it work as a DLL injection
           | technique on Windows. I'm sure it could've been conceptually
           | similar, but not identical, and maybe those differences would
           | be interesting to discuss.
        
             | fluoridation wrote:
             | "Exact same thing" as in re-implemented a basic OS feature
             | in user mode to bypass an intercepted feature. Obviously it
             | can't be literally exactly the same thing, because that
             | wouldn't be implementing something, but rather using
             | existing source code.
        
         | joe_v wrote:
         | Hah! I was just referencing this paper the other day when
         | mucking with the linker for an unrelated reason. I probably
         | should have chosen a better name for my article - I am trying
         | to cover the cases of "you have Linux command execution, how do
         | you run native code?" as opposed to your approach which as I
         | understand is more: "you are running native code, how can you
         | load a separate ELF in-process?"
         | 
         | Agreed about institutional memory; zines/blogs are very
         | important; but at the end of the day I usually end up just
         | asking in some corner of IRC.
        
           | codethief wrote:
           | > "you have Linux command execution, how do you run native
           | code?"
           | 
           | I was going to ask you what the precise situation is in which
           | you'd apply the ideas from the blog post as I don't know what
           | exactly is meant by "process injection". I think the article
           | would benefit from providing a little bit more background for
           | us non-hackers / non-pentesters. Still, very interesting
           | article - thank you!
           | 
           | PS: The article says
           | 
           | > you need a writable location on disk; this is not always
           | true in e.g. read-only chroots, filesystems, containers, etc
           | 
           | Couldn't you create a temporary file in-memory (e.g. in
           | /dev/shm or in some tmpfs), make it executable (+x) and then
           | execute it?
        
             | joe_v wrote:
             | Apologies it's a little scattered. Roughly it's about
             | dealing with situations where you can execute a command but
             | now want to run a native executable, and how much noise
             | such a thing will make in the presence of monitoring.
             | 
             | > Couldn't you create a temporary file in-memory (e.g. in
             | /dev/shm or in some tmpfs), make it executable (+x) and
             | then execute it?
             | 
             | It all depends on how your environment is set up: whether a
             | tmpfs or shm device is mounted and writable by your user is
             | up to the admin. For example, on many embedded devices you
             | often want to avoid writes to prevent any sort of
             | filesystem wear, or because you have a write-once media
             | like a ROM; so the whole fs will be mounted readonly. With
             | chroots it's best practice to provide a minimal environment
             | - unless tempfiles are needed there will usually not be a
             | /tmp. Try `docker run --read-only -ti ubuntu bash` as
             | another example:
             | 
             | ``` root@9302f159e0e0:/tmp# touch a touch: cannot touch
             | 'a': Read-only file system ```
        
           | grugq wrote:
           | Ah, so, in 2005 I wrote about that when I implemented rexec()
           | -- remote exec() -- which takes a binary and then copies it
           | over an arbitrary text only link (like ssh) and executes it
           | completely in memory without touching disk.
           | 
           | http://phrack.org/issues/62/8.html
           | 
           | The idea was that if you have access to a box via a shell and
           | you want to run your own binary without leaving evidence
           | behind, you'd use rexec() to do that.
        
             | joe_v wrote:
             | That is a really useful implementation and a good way to
             | use gdb to "live off the land". It is interesting how ops
             | changes like moving to containers/VMs affect pentesting
             | techniques; over the last decade I find myself relying less
             | and less on live-off-the-land in a lot of engagements. When
             | you can use them though they have a lot of advantages.
             | 
             | Also never realized that others have implemented (and I
             | guess patented?) syscall proxying, I have heard that idea
             | discussed before for offensive tooling and wondered how
             | well it works in practice.
        
               | grugq wrote:
               | Syscall proxying was very old even when I wrote that
               | article. The problem with syscall proxying is that it is
               | slow. Take any process and imagine adding network latency
               | to every single syscall. On a local network is incredibly
               | slow, but over any sort of real distance it is just
               | impossible.
               | 
               | That's why I pushed everything to the target system. Run
               | it local as much as possible.
               | 
               | Back then there were no containers or VMs to use. These
               | days I think you should be bringing your environment with
               | you. Unless there are serious reasons not to.
        
               | joe_v wrote:
               | That makes sense, something like `grep $USER /etc/passwd`
               | would shuffle the whole passwd file over the wire, etc;
               | for a lot of post-exploitation stuff I could see it
               | causing more trouble than it's worth.
        
         | aengelke wrote:
         | Userland exec was a very interesting read when I came across it
         | some years ago; thanks for publishing it!
         | 
         | The technique still mostly works, but on recent glibc+Linux,
         | you also have to unregister the rseq area before cleaning out
         | the address space (which requires computing the address first,
         | which is a little cumbersome). Otherwise, if the rseq area is
         | registered but unmapped, the kernel will forcefully stop the
         | program.
         | 
         | (That said, nowadays memfd_create + fexecve is likely a more
         | robust alternative in many cases.)
        
           | grugq wrote:
           | Yup, probably the more robust approach.
        
         | throwaway892238 wrote:
         | > we haven't created an institutional memory beyond "the oldest
         | hacker you know."
         | 
         | Which I'd wager is due to over-reliance on search engines. The
         | net is stuffed to the brim with useless bullshit designed to
         | steal eyeballs, so finding anything somebody published two
         | decades ago is now impossible. Internet Archive is useful if
         | you already know what website used to exist, not so useful if
         | you don't.
         | 
         | Whatever happened to that website that was a combination of
         | blog + archive of exploit POCs? Wasn't it called PacketStorm? I
         | just tried to find it with two search engines and came up
         | empty. That would've been an ideal place to track down old
         | techniques and news.
        
         | contingencies wrote:
         | Happy opseccy new year Grug :)
        
       | Retr0id wrote:
       | Hi, I'm the author of the `dlinject` tool referenced in the
       | article. Sadly I haven't been maintaining it and it doesn't work
       | on modern distros anymore - not for any fundamental reasons, it
       | just needs some compatibility tweaks. However, it's been forked
       | as `asminject`[1], with bug fixes and other bells and whistles. I
       | consider it to be the latest evolution of that particular
       | approach, and I should probably update the dlinject readme to
       | point at it.
       | 
       | Thank you for the writeup!
       | 
       | [1] https://github.com/BishopFox/asminject
        
       | charcircuit wrote:
       | Why does Bash have permission to ptrace or read other process's
       | memory. This should already be locked down, but I suspect it's
       | not because for some reason a lot of systems do not use LSMs or
       | don't care about security in general.
        
         | khuey wrote:
         | The same bash instance is the parent of the process being
         | attacked so it meets the requirements to ptrace at
         | yama/ptrace_scope == 1.
        
           | Retr0id wrote:
           | In the case of stelf-loader, the bash instance is attacking
           | itself. It's not especially unexpected for a process to be
           | able to modify its own memory.
        
       | gavinray wrote:
       | It's a bit wild, but you can use _memfd_create_ to do things like
       | load libraries or binaries, on a filesystem that has no read
       | /write access and _noexec_ enabled.
       | 
       | I have been meaning to do a blog post about this, since it
       | doesn't seem to be common knowledge.
       | 
       | Originally, I thought of it as a response to a Reddit question:
       | "How can I load a shared library from a .jar directly into
       | memory?"
       | 
       | https://old.reddit.com/r/java/comments/15lcwil/load_shared_l...
        
         | Retr0id wrote:
         | > on a filesystem that has...
         | 
         | memfd_create's whole selling point is that it isn't backed by a
         | filesystem; it isn't "on" one in the first place, so there is
         | nowhere for it to inherit such restrictions from. The
         | consequences of that can be surprising though, I agree, and are
         | worth exploring and writing about.
        
       ___________________________________________________________________
       (page generated 2023-12-31 23:00 UTC)