On Wednesday 28 November 2001 23:04, CYWare wrote:
> You're right.  Setting the uid of the CGI program to root is way too
> dangerous.  Besides, I am already forced to run Apache as user
> "oracle" to allow my CGI program to access the shared OCI libraries
> and the Oracle environment.
>
<snip>
>
> On Windows, I've done this using ISAPI on IIS.  Basically, my ISAPI
> runs under the IIS web user but I am able to programatically login as
> Administrator, switch privileges, do whatever I needed to do, then
> logoff the Administrator.  All this takes about a split second so
> security really isn't too much of an issue.
>
> Does UNIX support this functionality?

i was going to send this privately, but i think i'll post to the list so that
those who know what they're doing can point out bugs.

what others have said (write a suid program, drop privileges as
soon as possible, etc) is pretty much what you describe with ISAPI
on IIS.  it is just as secure (or insecure) there as it is on linux (that is, 
i avoid doing it in any OS unless there is a gun pointed at my head, 
and even then i will go into considerable contortions to see if it can't 
be done some other way that doesn't require becoming root). 
no matter how quickly it runs (split second), the smallest error can 
get you 0wn3d.

anyway, you have been warned by lots of people on why you don't want to do
this.  i repeat their warnings.  with exclamation points.  on the other hand,
sometimes there is just no other way to get the job done...

general techniques for making your program less buggy and more secure
(drop privileges as soon as you can, keep things simple, be very strict 
on what data you accept, triple check everything to make sure an attacker 
isn't spoofing you somehow) are assumed to be familiar to you.  or others
will mention them here (perhaps by those pointing out bugs in this email :).

1.  write a C/C++ program and make the binary suid (i.e., chmod +s the
    binary).  you need to protect yourself (it's not going to help much if 
    the C/C++ is exploitable, e.g., via a buffer overflow, but it helps against
    naive attacks by local users) by making the program owned by root
    (or whichever UID it needs to run as) and the group be some group of
    which the httpd process owner is a member and potential attackers are
    not.  e.g., if httpd runs as www, then you want to:
         chown root.www theCGIexe
         chmod ug+rx theCGIexe
         chmod +s theCGIexe
    or something similar.

    the CGI program needs to be extremely paranoid about the data it
    receives.  you cannot afford buffer overflows or following dangerous
    logic paths when given weird data.  it would be best to just die if the 
    data you receive does not fit the straightjacket into which you
    require it to fit.  also, considering doing the following:

             put it under https, password protect it, 

             put a cookie on the client (with a random session code) so you can
                keep track of the client (unless this is a one-shot deal, but use the
                cookie anyway.  paranoia is good... this helps against session 
                hijacking attacks... might as well have the whole session be under
                https so the cookie can't be read as it goes by), 

             keep user data on the server side but accessible via the random 
                session code in the cookie),

             specify a very precise syntax for the input data.  be extremely
                paranoid about the syntax.  check everything when you receive the
                data and reject with error if the smallest part is bad, e.g.,
        
2.  if you don't want to make the program suid, you can make it sudo instead.
    and then (from your perl or php script which parses and validates the input
    data *in a language that handles strings more safely than C/C++*) execute 
    sudo with the -S param and pass the www password to it on the command 
    line.  this is still insecure (someone doing ps at the right time can get the 
    www password and do the sudo himself at will later), but it minimizes your 
    exposure a little.  so, for instance, if the www password is
        "xyz333445"
    and the program is jjj and it is all set up in /etc/sudoers, then your program
    could just exec:

        echo "xyz33345" | sudo -S jjj [parameters go here]
 
    a little better than that (not exposing the password to ps but embedding the
    www password [not the root password] in the script) would be to use popen
    and just feed the password (and any necessary parameters) to sudo, e.g.,

    $fp=popen("sudo -S jjj [parameters go here]","w");
    fputs($fp,"xyz33345");

3.  write a daemon that sits on a socket.  the daemon runs as root (or whatever
     user you need it to run as).  clients (your CGI program) make socket connections
     to the daemon, authenticate themselves as necessary, and make the request,
     the daemon performs the necessary operations and returns the reply via the
     socket.

     this makes the cracker's job a little more difficult since a buffer overflow 
needs 
     to first work without killing the CGI program, and then when it runs in the 
daemon,
     it's probably not going to be interactive, so a buffer overflow payload would have
     to be complete and self-contained in one request.

     i like this approach but, frankly, i've only done it once because it's too much 
     complexity for your average CGI program, and after thinking about it, i'm not
     sure it's any more secure than any of the above (except for the part about 
     separating client and daemon, with buffer overflows in the client not affecting
     the daemon).

4.  use a nicer language if you can.  ian prefers perl.  i prefer php.  if you must do 
it
    in C/C++, spend just as much time at auditing and securing the code as in writing
    the basic functionality.  one problem with perl or php is, chmod +s on the script
    doesn't work.  you have to chmod +s the interpreter.  so you would probably have
    to make an suid copy of the interpreter and invoke that in the #! at the top of the
    script.  on the other hand, if you're doing that, you are exposing yourself to 
incredible
    risk (e.g., any PHP or perl user who can put a script on the web server can become
    suid...).  best not to do it unless you're willing to hack the interpreter so it 
only 
    executes for a certain circumscribed set of scripts (it refuses to run if the 
script it
    is being given is not one of the authorized scripts).

hmmm, i'm curious, how do you become administrator temporarily using ISAPI?  
you have to provide a password (which is probably embedded in your exe)?   or there is 
something like the suid bit which can be set so that no passwords need to be embedded 
in programs.  embedding administrator or root passwords in programs is a VERY bad 
thing.  even file access controls (e.g., u+x, og-rwx, windows or linux) aren't going 
to help 
you if someone can boot with a floppy and copy the binary to floppy and strip the 
strings 
out at leisure.

tiger

-- 
Gerald Timothy Quimpo                     [EMAIL PROTECTED]  [EMAIL PROTECTED]
           Entia non sunt multiplicanda praetere necessitatem
                         Mene sakhet ur seveh
_
Philippine Linux Users Group. Web site and archives at http://plug.linux.org.ph
To leave: send "unsubscribe" in the body to [EMAIL PROTECTED]

To subscribe to the Linux Newbies' List: send "subscribe" in the body to 
[EMAIL PROTECTED]

Reply via email to