If you can sudo, you already have root, albeit limited. It's more of an ergonomic feature to discourage users logging in as root and destroying the system, than any kind of reliable security compartmentalization.
Realistically speaking, most applications you would want to allow others to run as sudo were never designed to withstand such attacks and will likely fail in the hands of a competent attacker that is free to use any command line, feed any input etc.
> If you can sudo, you already have root, albeit limited. It's more of an ergonomic feature to discourage users logging in as root and destroying the system, than any kind of reliable security compartmentalization.
I figured it was so you can identify the user who ran the command in an audit, instead of everyone just appear as "root"
I figured it was so you can identify the user who ran the command in an audit, instead of everyone just appear as "root"
This goal can still be performed if auditd is enabled. The transition from non-root to root is tracked with the right rules in place. In my opinion it is best to rely on auditd and immutable after being tested rules as there are many ways to elevate privileges and many ways to improperly configure or bypass sudo. Auditd has a plugin to log directly to syslog and/or forwarded to ELK, Splunk or other tools. Auditd is also important when applications are exploited and someone then uses a privilege escalation vulnerability otherwise the person will just run it again after the machine/VM/container is re-imaged. Sudo was never intended to be a security control as much as it was to give a non sysadmin the ability to restart something or launch an on-demand process that required root or other accounts despite people using it in their documented controls. Many people will disagree with me on this as has been the case since the inception of sudo.
One caveat being auditd with the most useful rules in place can get rather noisy and more to the point, costly in terms of storage and/or Splunk license. It comes down to the priorities of an organization or business.
Yeah I meant more when folk `ssh root@host` over `su - root`
But I do recall it being a lot more pleasant tracing who ran what sequence of commands, on a host used by many people in concurrent workflows, when it's sudo over su.
It's also been some ~20 years since I've been in a role that required I do this so I (most probably) have forgotten a lot.
One of the main benefits of sudo is that nobody needs to know the root password to switch to root (like one would need when using su). The actual root password can be saved in some break glass system, and admins only need to manage their own passwords.
Sigh. It's disappointing to hear that this is the default in Ubuntu Server. As long as I'm understanding it, it doesn't appear to be an immediate concern, but it does demonstrate that the security design is quite a bit half-baked at least in this specific area.
I don't think every Linux distribution needs to aspire to be as proactive about security as OpenBSD, but it would be nice to see better care put into features like this to make sure they're restricting capabilities as expected, with at least more than one mechanism protecting the system from compromise.
Unfortunately my kneejerk reaction is to assume that most of the work on Ubuntu Server is going into development of Snap-based Ubuntu Core, wherein the security model is completely different and none of this applies, perhaps? But a ton of people deploy ordinary Ubuntu Server today, possibly more than Core... so that doesn't bode well.
(OK, maybe I really do just want OpenBSD.)
edit: Wait a minute. This post says "brand new", which made me think this was stock configuration. However, is it? I would feel immediately relieved, and my entire comment would be irrelevant, if that wasn't the case.
The post doesn't do a good job explaining whether this is the stock configuration or purely a hypothetical. My initial reaction was the same as yours, but upon further reflection I get the feeling it's just a thought exercise.
I'm a bit miffed that people are getting downvoted for not realizing this is not the default behavior, when I have no idea how you were supposed to gather that from reading the article. I did actually check to see (in Ubuntu 23.04) but honestly, that doesn't clear up much given that I have no idea what different installation modes of Ubuntu may yield.
Yeah, it's fair enough that it completely negates all of the points to be made about distro security, but also, it's not really our fault that the article is unclear.
Yeah, nobody really cares about the dumb number next to the posts anyway. What's actually annoying is being misunderstood, because the article seems to have produced mainly two comments:
1. "That's a pretty bad default." (it would be, after all.)
2. "That scenario is quite contrived."
The former is just a misunderstanding, but I think the reason why it happened is simple: the article is written in a way that doesn't really make it clear whether it is a condition they added or a condition they observed. On the other hand, giving someone the benefit of the doubt, I personally assumed that it was unlikely someone would intentionally add this, since it's, well, you know... Quite contrived.
I think I understand the purpose now (it's intentionally contrived, merely for practice with probably a less contrived setup in the future) and I hate to be overly harsh on the article, since it's perfectly fine for someone's personal blog, but when I see something on HN's frontpage, I generally have some expectation for how interesting it is. After all, plenty of genuinely very interesting things die in new, why would this make it out? Alas, sometimes it just happens.
My takeaway from reading all this is that there is no reason this article should have made it to the front page of HN, as all it did was create confusion and burn 10 minutes of my time trying to clarify what was happening. Nothing about this article or the discussion it has created is interesting, just frustrating.
I don't think it's really fair to say that this has anything to do with Ubuntu Server at all, or that it reflects on Ubuntu's security. After all, this issue only occurs if you decide to enable a sudo command for a user and, if you're doing that, it's on you to understand the risks; risks which you'd have to take into consideration regardless of the distro.
For example, if I told you that I've identified a security risk in giving sudo access to a user for the command "rm -rf /", would you conclude that Ubuntu is an insecure distro?
If Ubuntu Server shipped with a configuration out of the box that let a user run 'sudo rm -rf /' _by default_ then yes, I would conclude that Ubuntu is an insecure distro.
The missing context is that I misinterpreted the article to mean that this sudoers rule was here by default. It's not... which makes this an entirely different story. I had an inkling that this was the case, but I was too busy to verify personally and by the time I had actually realized, it was too late to delete/edit the comment.
Which makes this whole thing annoying. The article shouldn't be flagged, because there's nothing technically wrong with it. I just found it confusing, and I wonder if maybe part of the reason why it was deemed interesting enough to be propelled to the frontpage is due to similar misinterpretation. (After all, I would find it VERY interesting if this WAS a default.)
I think PolKit can be used to delegate fine-grained control to users. Which other tools are available on Linux to control users' access to fs and network resources? File permissions, systemd-nspawn?
One could write a very small custom binary in C/C++/Rust that runs the command, and then give that binary setuid permissions. That binary can simply run a subprocess, and nothing else.
By the way: SSH_ORIGINAL_COMMAND is a command like you would give to sh -c, basically a tiny snippet of sh code. Its not an argument vector! You either need a shell to kind of eval it or parse it with wordexp(3) before you can reliably tell which executable name it refers to.
Mean people might send one starting with '$(' or another expansion. Remember this is valid:
Why would a random user account have access to `sudo logrotate`? logrotate is presumably for rotating logs, and the only need for root is to rotate system logs. So under what circumstances does it make sense for a random, otherwise unprivileged user to have ability to rotate system logs, but not the ability to do other administrative tasks?
It's also a tool that operates on random user-specified files, so makes for an absolutely terrible choice of command to let an unprivileged user to run.
I suppose the intent here is showing how a supposedly restricted sudo ability can be exploited into something bigger. That is a good point, but I think logrotate makes for a weird example of it.
Also, use journald and just have it deal with that. If there's a need to deal with log rotation by hand something isn't setup quite right.
So do most bugs and seemingly safe assumptions that lead to privilege escalation.
In practice, it's unlikely an untrusted user would have access to calling logrotate directly, but would instead call it through a chain of mechanisms that each individually seem innocuous, but become dangerous when combined together. Maybe they've got a foothold through parameter pollution allowing them to execute shell scripts as the apache user, which has sudo privileges for logrotate. Combine that with the ability to write relatively arbitrary data to logs, and you can see how things might begin to fall apart.
For example, here's a HackTheBox writeup [0] that exploits a race condition in logrotate on the path to getting root. It's not the exact same scenario as in OP, but it's a similar idea.
IMO it's not very interesting if you start with a blatantly unsafe assumption like putting a wildcard NOPASSWD line in sudoers. This would be interesting if it was somehow a default configuration, but it's blatantly weird to add it and then break it, given that it is a contrived configuration that I don't think you could easily convince sysadmins to add.
I assume the point of this is as a practice exercise for a potentially less contrived use case. That's cool, but it's still not particularly interesting...
sudo less <root 0755 log file> is/was also escalatable, which is much more innocuous for a an untrusted user to read error.log files for their account.
The example contains an asterisk in the allowed commands field. That's not something you would normally do with users who would not otherwise have root privileges. There are (figuratively) an unlimited number of ways to compose commands that do arbitrary things. Security audits explode in complexity.
Always list every literal command that is allowed. Make a command wrapper if necessary. (Also, never allow arbitrary environment variables.)
I too can break into my own house when I leave a door wide open for myself. There is nothing wrong with logrotate, ubuntu, ssh, or sudo here.
Once you are passing arbitrary strings to bash as root -- yeah it's gonna be game over. This reminds me of the time a pentester found an XSS vuln and spent the entire rest of the engagement stuffing a keylogger into it. Like, OK, thanks, we already understand the implications of XSS.
The solution provided is suboptimal because all the focus is spent in making a good exploit demo instead of considering the root cause(s): the configuration of ssh, sudo, and the godawful shell script the author dredged up from parts unknown.
As I have seen this style of script being used with forced commands in authorized_keys, my conclusion is that the author loosely followed some online guide for restricting SSH access to certain commands and either inherited the flawed original script or made the error adapting it to the local requirements.
Proper options for restricting the shell abound. From the top of my head: rssh, sshdo, PolicyKit, rbash, rush
OP here: I never said it's something wrong with logrotate, ubuntu, ssh, or sudo. It's a thought challenge with a guide, and could be a stage in a CTF challenge to get root.
It's "something wrong" with the configuration chosen by a system administrator to allow "/usr/sbin/logrotate *" to be run as root without consideration of what the logrotate binary may do with certain arguments.
As I have seen this style of script being used with forced commands in authorized_keys, my conclusion is that the author loosely followed some online guide for restricting SSH access to certain commands and either inherited the flawed original script or made the error adapting it to the local requirements.
Proper options for restricting the shell abound. From the top of my head: rssh, sshdo, PolicyKit, rbash, rush
Did you actually read the article at all? If you use rbash or rshell and logrotate can be run as root, this issue still persists. The logrotate binary is the one performing these actions, not bash.
Once you are passing arbitrary strings to bash as root
Passing arbitrary strings to bash as root? It's about passing arbitrary arguments to logrotate.
> Passing arbitrary strings to bash as root? It's about passing arbitrary arguments to logrotate.
No it's not; you are just exploiting bash's argument expansion in a badly written script you wrote to feed some additional shell stuff to bash /after/ the logrotate command. You could have done this as easily with 'sudo /bin/false' in there. Yes, you made logrotate do some things, but that's just a red herring in this case. The entire security issue is with the dumb bash script; it has nothing to do with anything else.
Nothing in ubuntu's documentation anywhere tells you to "use this insecure bash script" to restrict a user to running a single command. It doesn't tell you to give global passwordless sudo privileges to the user that you want to do this either. Your configuration is cobbled from suggestions you found online and proceeded to implement incompletely/poorly.
/etc/sudoers does not use "bash's argument expansion".
to feed some additional shell stuff to bash /after/ the logrotate command
Wrong. It's clearly about a sudoers rule which uses wildcards (see sudoers(5) "Wildcards" section.
The entire security issue is with the dumb bash script; it has nothing to do with anything else.
The security issue is that a sudoers(5) rule allows a nonprivliged user to run logrotate with any arguments, and as it turns out, those arguments can be used to achieve root.
It doesn't tell you to give global passwordless sudo privileges
A /etc/sudoers rule of
user ALL=(ALL:ALL) NOPASSWD: /usr/sbin/logrotate \*
does not provide the user with "global passwordless sudo privileges".
It's ok to be wrong; it's not ok to change your original writeup and continue to insist that you have been right all along. To the extent there is a security issue here, it does not lie with any of the software in question. You have not exploited sudo, ssh, bash, logrotate, wget, or anything else in the system.
The failure is instead a systemic one that allowed an ineffective and insecure configuration to be applied to a system. Some process (or maybe no defined process) 1) led "the administrator" of the system in question to do it and 2) didn't provide any verification or review of the configuration change.
> rtfm of sudoers(5).
OK; it literally tells you to watch your ass with a glob and to do your commandline security elsewhere. Then it gives an actual practical example of argument stuffing:
Wildcards in command line arguments should be used with care.
Command line arguments are matched as a single, concatenated string. This mean a wildcard character such as ‘?’ or ‘*’ will match across word boundaries, which may be unexpected. For example, while a sudoers entry like:
%operator ALL = /bin/cat /var/log/messages*
will allow command like:
$ sudo cat /var/log/messages.1
It will also allow:
$ sudo cat /var/log/messages /etc/shadow
which is probably not what was intended. In most cases it is better to do command line processing outside of the sudoers file in a scripting language.
The failure is instead a systemic one that allowed an ineffective and insecure configuration to be applied to a system. Some process (or maybe no defined process) 1) led "the administrator" of the system in question to do it and 2) didn't provide any verification or review of the configuration change.
Almost as if the post is therefore detailing _how_ it is an ineffective and an insecure configuration.
last time I checked (several years ago), rbash is full of security holes, and while those may have been patched now I really would not trust it to lock down a privileged shell session.
50 comments
[ 2.9 ms ] story [ 195 ms ] threadRealistically speaking, most applications you would want to allow others to run as sudo were never designed to withstand such attacks and will likely fail in the hands of a competent attacker that is free to use any command line, feed any input etc.
I figured it was so you can identify the user who ran the command in an audit, instead of everyone just appear as "root"
This goal can still be performed if auditd is enabled. The transition from non-root to root is tracked with the right rules in place. In my opinion it is best to rely on auditd and immutable after being tested rules as there are many ways to elevate privileges and many ways to improperly configure or bypass sudo. Auditd has a plugin to log directly to syslog and/or forwarded to ELK, Splunk or other tools. Auditd is also important when applications are exploited and someone then uses a privilege escalation vulnerability otherwise the person will just run it again after the machine/VM/container is re-imaged. Sudo was never intended to be a security control as much as it was to give a non sysadmin the ability to restart something or launch an on-demand process that required root or other accounts despite people using it in their documented controls. Many people will disagree with me on this as has been the case since the inception of sudo.
One caveat being auditd with the most useful rules in place can get rather noisy and more to the point, costly in terms of storage and/or Splunk license. It comes down to the priorities of an organization or business.
But I do recall it being a lot more pleasant tracing who ran what sequence of commands, on a host used by many people in concurrent workflows, when it's sudo over su.
It's also been some ~20 years since I've been in a role that required I do this so I (most probably) have forgotten a lot.
Very limited!
I don't think every Linux distribution needs to aspire to be as proactive about security as OpenBSD, but it would be nice to see better care put into features like this to make sure they're restricting capabilities as expected, with at least more than one mechanism protecting the system from compromise.
Unfortunately my kneejerk reaction is to assume that most of the work on Ubuntu Server is going into development of Snap-based Ubuntu Core, wherein the security model is completely different and none of this applies, perhaps? But a ton of people deploy ordinary Ubuntu Server today, possibly more than Core... so that doesn't bode well.
(OK, maybe I really do just want OpenBSD.)
edit: Wait a minute. This post says "brand new", which made me think this was stock configuration. However, is it? I would feel immediately relieved, and my entire comment would be irrelevant, if that wasn't the case.
Yeah, it's fair enough that it completely negates all of the points to be made about distro security, but also, it's not really our fault that the article is unclear.
1. "That's a pretty bad default." (it would be, after all.)
2. "That scenario is quite contrived."
The former is just a misunderstanding, but I think the reason why it happened is simple: the article is written in a way that doesn't really make it clear whether it is a condition they added or a condition they observed. On the other hand, giving someone the benefit of the doubt, I personally assumed that it was unlikely someone would intentionally add this, since it's, well, you know... Quite contrived.
I think I understand the purpose now (it's intentionally contrived, merely for practice with probably a less contrived setup in the future) and I hate to be overly harsh on the article, since it's perfectly fine for someone's personal blog, but when I see something on HN's frontpage, I generally have some expectation for how interesting it is. After all, plenty of genuinely very interesting things die in new, why would this make it out? Alas, sometimes it just happens.
https://news.ycombinator.com/newsguidelines.html
It's also a bit disingenuous to make a third-person reference to your own post ('people are getting downvoted').
For example, if I told you that I've identified a security risk in giving sudo access to a user for the command "rm -rf /", would you conclude that Ubuntu is an insecure distro?
Would you not?
Which makes this whole thing annoying. The article shouldn't be flagged, because there's nothing technically wrong with it. I just found it confusing, and I wonder if maybe part of the reason why it was deemed interesting enough to be propelled to the frontpage is due to similar misinterpretation. (After all, I would find it VERY interesting if this WAS a default.)
selinux is the primary one that comes to mind, it definitely ticks the "fine-grained control" checkbox for sure
Mean people might send one starting with '$(' or another expansion. Remember this is valid:
Why would a random user account have access to `sudo logrotate`? logrotate is presumably for rotating logs, and the only need for root is to rotate system logs. So under what circumstances does it make sense for a random, otherwise unprivileged user to have ability to rotate system logs, but not the ability to do other administrative tasks?
It's also a tool that operates on random user-specified files, so makes for an absolutely terrible choice of command to let an unprivileged user to run.
I suppose the intent here is showing how a supposedly restricted sudo ability can be exploited into something bigger. That is a good point, but I think logrotate makes for a weird example of it.
Also, use journald and just have it deal with that. If there's a need to deal with log rotation by hand something isn't setup quite right.
Which makes things like this useful for when you get code execution in the web interface and want to break root
So do most bugs and seemingly safe assumptions that lead to privilege escalation.
In practice, it's unlikely an untrusted user would have access to calling logrotate directly, but would instead call it through a chain of mechanisms that each individually seem innocuous, but become dangerous when combined together. Maybe they've got a foothold through parameter pollution allowing them to execute shell scripts as the apache user, which has sudo privileges for logrotate. Combine that with the ability to write relatively arbitrary data to logs, and you can see how things might begin to fall apart.
For example, here's a HackTheBox writeup [0] that exploits a race condition in logrotate on the path to getting root. It's not the exact same scenario as in OP, but it's a similar idea.
[0] https://0xdf.gitlab.io/2020/07/11/htb-book.html
I assume the point of this is as a practice exercise for a potentially less contrived use case. That's cool, but it's still not particularly interesting...
When will distros take security seriously?
Always list every literal command that is allowed. Make a command wrapper if necessary. (Also, never allow arbitrary environment variables.)
Once you are passing arbitrary strings to bash as root -- yeah it's gonna be game over. This reminds me of the time a pentester found an XSS vuln and spent the entire rest of the engagement stuffing a keylogger into it. Like, OK, thanks, we already understand the implications of XSS.
The solution provided is suboptimal because all the focus is spent in making a good exploit demo instead of considering the root cause(s): the configuration of ssh, sudo, and the godawful shell script the author dredged up from parts unknown.
As I have seen this style of script being used with forced commands in authorized_keys, my conclusion is that the author loosely followed some online guide for restricting SSH access to certain commands and either inherited the flawed original script or made the error adapting it to the local requirements.
Proper options for restricting the shell abound. From the top of my head: rssh, sshdo, PolicyKit, rbash, rush
It's "something wrong" with the configuration chosen by a system administrator to allow "/usr/sbin/logrotate *" to be run as root without consideration of what the logrotate binary may do with certain arguments.
It's just an explanation of how to exploit this situation if you find a server using this type of configuration. That's the whole basis of projects like https://gtfobins.github.io/ and https://gtfoargs.github.io/.
Did you actually read the article at all? If you use rbash or rshell and logrotate can be run as root, this issue still persists. The logrotate binary is the one performing these actions, not bash. Passing arbitrary strings to bash as root? It's about passing arbitrary arguments to logrotate.> The scenario is this: a brand new Ubuntu 22.04 server has an account which is restricted to running sudo logrotate .
It might have been better to say:
> The scenario is this: take a brand new Ubuntu 22.04 server and create an account which is restricted to running sudo logrotate .
No it's not; you are just exploiting bash's argument expansion in a badly written script you wrote to feed some additional shell stuff to bash /after/ the logrotate command. You could have done this as easily with 'sudo /bin/false' in there. Yes, you made logrotate do some things, but that's just a red herring in this case. The entire security issue is with the dumb bash script; it has nothing to do with anything else.
Nothing in ubuntu's documentation anywhere tells you to "use this insecure bash script" to restrict a user to running a single command. It doesn't tell you to give global passwordless sudo privileges to the user that you want to do this either. Your configuration is cobbled from suggestions you found online and proceeded to implement incompletely/poorly.
rtfm of sudoers(5).
The failure is instead a systemic one that allowed an ineffective and insecure configuration to be applied to a system. Some process (or maybe no defined process) 1) led "the administrator" of the system in question to do it and 2) didn't provide any verification or review of the configuration change.
OK; it literally tells you to watch your ass with a glob and to do your commandline security elsewhere. Then it gives an actual practical example of argument stuffing:I removed the section about the bash restriction (which was not particularly important), but the content of the post did not change: https://github.com/MegaManSec/JoshuaHu/commit/11cd746a0efb02...
The failure is instead a systemic one that allowed an ineffective and insecure configuration to be applied to a system. Some process (or maybe no defined process) 1) led "the administrator" of the system in question to do it and 2) didn't provide any verification or review of the configuration change.
Almost as if the post is therefore detailing _how_ it is an ineffective and an insecure configuration.
https://gtfobins.github.io
Some previous discussions about it on HN,
GTFOBins (https://news.ycombinator.com/item?id=28849101) - October 2021 (54 comments)
List of Unix binaries that can be used to bypass local security restrictions (https://news.ycombinator.com/item?id=36628976) - July 2023 (99 comments)
Living Off the Land in Linux (https://news.ycombinator.com/item?id=20648329) - August 2019 (35 comments)