Non-root user that (suddenly) has elevated privileges in a specific command (only). [Have I been hacked?]

GustavoM@lemmy.world to Linux@lemmy.ml – 36 points –

Title. Long,short story: creating or editing files with nano as my non-root user gives (the file) elevated privileges, like I have ran it w/ sudo or as root. And the (only) "security hole" that I can think of is a nextdns docker container running as root. That aside, its very "overkill" security-wise (cap_drop=ALL, non-root image, security_opt=no_new_privileges, etc.).

It's like someone tried to hack me but gave up halfway. Am I right or wrong to assume this? Just curious.

Thanks in advance.

28

Try an ls -l $(which nano) and look at the permissions section of the output.

Most files only have hyphens, r's, w's, and x's. (Like -rwxr-xr-x or some such.)

Particularly if there's an "s" in the output (it'll be in place of an "x"), that could explain what's going on.

Basically, that "s" means "when a user runs me, run me as root even if the user running me isn't root." It's useful on programs like "su" and "sudo" which let you run a command that (after authentication) do things as root.

But if that flag is set on nano, that's pretty weird.

Try an ls -l $(which nano) and look at the permissions section of the output.

Just did it -- output is -rwxr-xr-x 1 root root 274816 Feb 19 2022 /usr/bin/nano. Now I'm really confused. Still, I appreciate your input.

Yeah, tha'ts weird.

Maybe try alias nano and LC_ALL=C type nano. Those test whether you have an alias or function named "nano" in bash that might be being run instead of /usr/bin/nano.

Oh, also, whoami and id. Maybe there's something weird with how you're logged in and despite not having the username "root" you're still uid 1 or something strange like that?

Oh! Also maybe while you've got nano running, do a ps aux | grep nano and see which user is reported to own that process.

Alright, first one returned me "bash: alias: nano: not found". Second one, "nano is hashed (/usr/bin/nano)". Third one, my sudoer username. And the fourth one shows my sudoer username at the top of the list, with both uid and gid at 1000.

And I honestly can't really think of much to add, other than the username in the docker image being completely nonexistant (It's just a bunch of numbers, and it doesn't even have a name). I don't know, maybe someone managed to breach the container and gave this "nonexistant user" root privileges but haven't managed to do much or something like that. I'm not that much of a tech savvy, but I guess it doesn't hurt to try to guess something. Maybe there is something inside the container? Idk, I'm gonna (try to) check it out (It's a "distroless" image -- it doesn't even have a shell in it.).

You're not running nano in a docker container, are you? You're running nano on a host Linux system, yeah?

Oh, and did you see the ps aux | grep nano one? (Sorry about that. I probably edited that into my post while you were working on a response.)

No and yes. And it returns me only a single line with $mysudoerusername 28596 0.0 0.1 5896 2016 pts/0 5+ 15:52 0:00 grep nano.

It returns that while you have nano running? If so, maybe try ps aux (without the grep part) and just look through until you find "nano" listed. Just to make sure whether it's running as root or your non-root user.

(And just to be clear, "my sudoer username" means the non-root user that you're running nano as, right?)

Just a gut feeling, but it feels to me so far like this probably isn't a hack or security thing. But of course, once the (no pun intended) root issue is found, that'll provide more info.

No. ps aux remains the same. And yes, "My sudoer username" is my non-root user with sudo privileges. Therefore, the "sudoer".

And I'm not really "pulling my hair out" because of this, honestly -- just curious if this can be mentioned as a hack, a hack attempt, or whatevertheheck. Because this is the first time in my entire life that this happened with me, so yep.

Wait, why did you mentioned docker?

Just adding more (relevant) info, since its my "security hole" as of now. As mentioned in the OP.

Could I set that for Docker? I often forget to run docker-compose as sudo and it can't be used without sudo, so it's a bit silly to always have to prepend sudo there. This magical "s" you describe could solve that.

And, of course, because I want to learn: why is this a really bad idea?

If you can't run docker-compose without sudo, there's something wrong with your setup. The specifics would be specific to your distro, but most likely there's a user group you could add your user to with sudo gpasswd -a user group to make the docker run and docker-compose commands work without sudo. (Might have to log out and back in as well to make it take effect if you've ran that command during the current session.) To find the name of the group, you'll probably have to do some research about your distro in particular. On Arch (insert hate here ;) ), I think the docker group does that, and it's not unlikely that the equivalent group for your distro has the same name.

The "magical s" (called the "SUID bit") shouldn't be required to be able to run docker run and/or docker-compose without sudo. Theoretically if you did want to do that, you could do it with sudo chmod u+s /usr/bin/docker. But again it's probably better to just add yourself to the proper group (or otherwise take the correct steps for your distro.)

But also, running docker-compose (or the docker run command more directly) without sudo won't necessarily make things inside the docker container run as your user. Making it do so is a little complex, actually, but I'll go through it here.

So, most Docker images that you'd get from Docker Hub or whatever usually run by default as root. If you do something like docker run -v /path/to/some/directory/on/your/host:/dir -it python 'touch /dir/foo', even if you've got your groups set up to be able to run docker run without sudo, it'll create a file on your host named "foo" owned by root. Why? Because inside the container, the touch /dir/foo command ran as root.

Honestly, I'd be thrilled if Docker had ways to tell it to be smarter about that kind of thing. Something that could make Docker create the file on the host owned by your user rather than root even if inside the container, the command that creates the file runs under the user in the Docker container that is root/uid 1.

But that's not how it works. If root inside the container creates the file, the host sees it as owned by root, which makes things a little more of a pain. C'est la vie.

Now, this is a bit of an aside, but it helped me understand so I'll go ahead and include it. It seems impossible that a command run by your user (assuming you've got your groups set up correctly) shouldn't be able to create a file owned by root, right? If without sudo you try to chown root:root some_file.txt, it'll tell you permission denied. And it's not the chown command that's denying you permission. It's the Linux kernel telling the chown command that that's not allowed. So how can it be that the docker run command can create files owned by root when docker run wasn't run by root, but rather by a more restricted user?

Docker has a daemon (called dockerd) that by default runs all the time as root, waiting for the docker command to direct it to do something. The docker run command doesn't actually run the container. It talks to the daemon which is running as root and tells the daemon to start a container. Since it's the daemon actually running the container and the daemon is running as root, commands inside the container are able to create files owned by root even if the docker run command is run by your own user.

If you're wondering, yes this is a security concern. Consider a command like docker run -it -v /etc:/dir/etc alpine vi /dir/etc/sensitive/file. That command, theoretically, could for instance allow a non-root user to change the host's root password.

How do you get around that? Well, there are ways to go about running the Docker daemon as a non-root user that I haven't really looked into.

Another concern is if, for instance, you've got a web service running as root inside a Docker container with a bind volume to the host and the web app has, for instance, a shell injection vulnerability wherein a user could cause a command to run as root inside the docker container which could affect sensitive files outside. To mitigate that issue, you could either not bind mount to the host filesystem at all or run the web service in the Docker container as a different user.

And there are several ways to go about running a process in Docker as a non-root user.

First, some Docker images will already be configured to ensure that what is run inside the container runs as non-root. (When making a Docker image, you specify that by having a USER directive in the Dockerfile.) Usually if things are done that way, the user will also be present in the relevent files in /etc in the image. But as I mentioned earlier, that's usually not the case for images on Docker Hub.

Next, if you're using docker-compose, there's a "user" option for setting the user.

Another way to do this is with the -u argument on the docker run command. Something like docker run -u 1000 -it alpine /bin/sh will give you a shell process owned by the user with id 1000.

Another way is to create the user and su to that user as part of the command passed to docker run. I've been known sometimes to do things like:

docker run \
	-it \
	alpine \
	sh -c 'adduser tootsweet ; su tootsweet -c /bin/sh'

The only other thing I can think to mention. Sometimes you want not just to run something in a Docker container not as root but in fact to run it as a user id that matches the user id of a particular user on the host. For instance so that files written to a bind volume end up being owned by the desired user so we can work with the files on the host. I honestly haven't found the best way to deal with that. Mostly I've been dealing with that situation with the last method above. The useradd command allows you to add a user with a specific user id. But that's problematic if the needed uid is already taken by a user in the container. So, so far I've kindof just been lucky on that score.

Hopefully that all helps!

Edit: P.S. apparently the way lemmy.world is set up, you can't mention certain standard *nix file paths such as / e t c / p a s s w d in posts. The post just isn't accepted. The "reply" button grays out and the loading graphic spins forever with no error message and the post doesn't get saved. I'm sure this is a misguided attempt at a security measure, but it definitely affects our ability to communicate about standard Linux kind of stuff.

What are the permissions on the directory the file resides in?

I already talked about it in this thread -- it shows my sudoer username on both columns.

Show the full output of ls -ld directory (replace "directory" with real directory path).

Can you be more specific about what you mean by this: "gives (the file) elevated privileges"?

i.e file is created (as non-root), trying to remove the file (once again, as non-root) gives me a "rm: cannot remove 'dir/file.name': Permission denied" error message.

OK I see. Can you create a new file with nano and then do an "ls -l" so we can see the permissions it's given? Also provide the output of the command "umask" as the user you're working with.

Just did it, and it shows my sudoer username with ownership of the created file. umask returns me 0002.

Can you paste the line from ls -l? Sanitize the username/date/time if you need to. Example:

-rw-r--r-- 1 bolapara users 0 Nov 21 17:19 asdf

-rw-rw-r-- 1 $sudoer $sudoer $date $createdfilename.

That is not an elevated permission, your user should be able to delete that file, do the same in another directory if it works it might be a permission, or more likely an attribute, problem on the directory itself or something on the path to it.

You cannot say if user able do delete the file or not. It depends on the directory permissions (deleting a file is modifying a directory).

What are the permissions on the directory? What is command are you running to edit the file? What command are you running to delete it? (Have you got selinux turned on? What filesystem is this directory on?)

The directory you are creating your files in likely is set to immutable or append only.

lsattr -d /path/to/directory

if you see i or a, then that's the issue.

You can remove them with
sudo chattr -i /path/to/dir #removes immutable
sudo chattr -a /path/to/dir #removes append only

Same goes for files but if it happens to all files in a directory, then that is probably it.