home *** CD-ROM | disk | FTP | other *** search
/ Cuteskunk BBS / cuteskunk.zip / cuteskunk / unsorted-zines / secure-faq.txt < prev    next >
Text File  |  2003-06-29  |  73KB  |  1,427 lines

  1.                  Secure UNIX Programming FAQ 
  2.                  --------------------------- 
  3.  
  4.   Version: 0.3 
  5.  
  6.   Last Modified: Sun Apr 11 22:32:06 PDT 1999 
  7.  
  8.   The master copy of this FAQ is currently kept at 
  9.  
  10.   http://www.whitefang.com/sup/ 
  11.  
  12.   The webpage has a more spiffy version of the FAQ in html. 
  13.  
  14.   A moderated mailing list has been setup for the discussion of 
  15.   Secure UNIX programming. You can find a copy of the announcement 
  16.   at: 
  17.  
  18.   http://www.whitefang.com/sup/announcement.txt 
  19.  
  20.   This FAQ is also posted to comp.security.unix (c.s.u) , 
  21.   comp.answers , news.answers. 
  22.  
  23.   Please do not mirror this FAQ without prior permission. Due to the 
  24.   high volume of readers I'm worried that old versions of the FAQ are 
  25.   left to grow stale, consequently receive email based on fixed 
  26.   errors/omissions. 
  27.  
  28. Copyright 
  29. --------- 
  30.  
  31. I, Thamer Al-Herbish reserve a collective copyright on this FAQ. 
  32. Individual contributions made to this FAQ are the intellectual 
  33. property of the contributor. 
  34.  
  35. I am responsible for the validity of all information found in this 
  36. FAQ. 
  37.  
  38. This FAQ may contain errors, or inaccurate material. Use it at your 
  39. own risk. Although an effort is made to keep all the material 
  40. presented here accurate, the contributors and maintainer of this FAQ 
  41. will not be held responsible for any damage -- direct or indirect -- 
  42. which may result from inaccuracies. 
  43.  
  44. You may redistribute this document as long as you keep it in its 
  45. current form, without any modifications. Read -- keep it up to date 
  46. please!! :-) 
  47.  
  48. Introduction 
  49. ------------ 
  50.  
  51. This FAQ answers questions about secure programming in the UNIX 
  52. environment. It is a guide for programmers and not administrators. 
  53. Keep this in mind because I do not tackle any administrative issues. 
  54. Try to read it as a guide if possible. I'm sorry it sounds like a bad 
  55. day on jeopardy. 
  56.  
  57. At the risk of sounding too philosophical, this FAQ is also a call to 
  58. arms. Over almost the last decade, a good six years, a movement took 
  59. place where security advisories would hit mailing lists and other 
  60. forums at astonishing speed. I think the veterans are all to familiar 
  61. with the repetitive nature of these security advisories, and the 
  62. small amount of literature that has been published to help avoid 
  63. insecure programming. This text is a condensation of this movement 
  64. and a contribution made to it, placed in a technical context to 
  65. better serve the UNIX security community. As the Usenet phrase goes: 
  66. "Hope this helps." 
  67.  
  68. Additions and Contributions 
  69. --------------------------- 
  70.  
  71. The current FAQ is not complete. I will continue to work on it as I 
  72. find time. Feel free to send in material for the Todo sections, and 
  73. for the small notes I've left around. Also, compatibility is an issue 
  74. I struggle with sometimes. The best I can do for some UNIX flavors is 
  75. read man pages. Corrections/addendums for compatibility notes is 
  76. greatly appreciated, and easily done as a collective effort. All 
  77. contributions, comments, and criticisms can be sent to: 
  78.  
  79. Secure UNIX Programming FAQ <sup@whitefang.com> 
  80.  
  81. Please don't send them to my personal mailbox, because I can keep 
  82. things organized better with the above e-mail address. Also please 
  83. try to be as concise as possible. Remember I will usually quote you 
  84. directly if you have something to add. 
  85.  
  86. Finally, although the contributors list is currently short, the 
  87. material in this FAQ did not pop out of my head in a pig-flying 
  88. fashion. Attribution is given where applicable. If you feel any of 
  89. this is unfair to something you have published, do let me know. The 
  90. bibliography is found at the end. 
  91.  
  92. Special thanks to John W. Temples, Darius Bacon, Brian Spilsbury, 
  93. Elias Levy, who had looked at some of the drafts of past material 
  94. that made it into this FAQ. As usual, all mistakes are mine and only 
  95. mine. 
  96.  
  97. Also kudos to the people at netspace.org for hosting Bugtraq all 
  98. these years. The archive is invaluable to my research. 
  99.  
  100. Table of Contents 
  101. ----------------- 
  102.  
  103.   1) General Questions: 
  104.     1.1) What is a secure program? 
  105.     1.2) What is a security hole? 
  106.     1.3) How do I find security holes? 
  107.     1.4) What types of attacks exist? 
  108.     1.5) How do I fix a security hole? 
  109.  
  110.   2) The Flow Of Information: 
  111.     2.1) What is the flow of information? 
  112.     2.2) What is trust? 
  113.     2.3) What is validation? 
  114.  
  115.   3) Privileges and Credentials 
  116.     3.1) What is a privilege and a credential? 
  117.     3.2) What is the least privilege principle? 
  118.     3.3) How do I apply the least privilege principle safely? 
  119.  
  120.   4) Local Process Interaction: 
  121.     4.1) What is process attribute inheritance? Or why should I not 
  122.     write SUID programs? 
  123.     4.2) How can I limit access to a SUID/SGID process-image safely? 
  124.     4.3) How do I authenticate a parent process? 
  125.     4.4) How do I authenticate a non-parent process? 
  126.  
  127.   5) Accessing The File System Securely: 
  128.     5.1) How do I avoid race condition attacks? 
  129.     5.2) How do I create/open files safely? 
  130.  
  131.   6) Handling Input: [ Todo ] 
  132.   7) Handling Resources Limits: [ Todo ] 
  133.   8) Bibliography 
  134.   9) List of Contributors 
  135.  
  136.     1) General Questions 
  137.     -------------------- 
  138.  
  139.       1.1) What is a secure program? 
  140.       ------------------------------ 
  141.  
  142.       The simplest definition would be : a program that is capable of 
  143.       performing its task withstanding any attempts to subvert it. 
  144.       This extends to the attribute of "robustness." Most importantly 
  145.       the program should be able to perform its task without 
  146.       jeopardizing the security policies of the system it is running 
  147.       on. This is done by making sure it adheres to local security 
  148.       policies at all times. To draw an analogy, a locksmith will 
  149.       install a lock, and the home owner will decide whether or not 
  150.       he will lock the door at any given time. It is the lock smith's 
  151.       responsibility to make sure the lock performs its function of 
  152.       keeping an intruder out. It is just as much the responsibility 
  153.       of the programmer to make sure the program adheres to the local 
  154.       security policies. Thus returning to the introduction, this FAQ 
  155.       is about the programmer's responsibilities and not the 
  156.       administrator. 
  157.  
  158.       The problem with that analogy is that when it is translated 
  159.       back into UNIX terms one thinks of an authentication program. 
  160.       By all means 'login' needs to be secure, but so do all the 
  161.       system components. To quote the U.S. Department of Defense 
  162.       Trusted Computer System Evaluation Criteria (a.k.a The Orange 
  163.       Book): 
  164.  
  165.       "No computer system can be considered truly secure if the basic 
  166.       hardware and software mechanisms that enforce the security 
  167.       policy are themselves subject to unauthorized modification or 
  168.       subversion." 
  169.  
  170.       Unfortunately this doesn't really help because we are sadly 
  171.       left thinking of firewalls, access control lists, persistent 
  172.       authentication systems etc. and we miss out on the other system 
  173.       components that must also be considered. So the quote can be 
  174.       re-written as such: 
  175.  
  176.       "No computer system can be considered truly secure if the basic 
  177.       hardware and software mechanisms that _can affect_ the security 
  178.       policies are themselves subject to unauthorized modification or 
  179.       subversion." 
  180.  
  181.       This gives us a much better view of what a secure program is, 
  182.       and places a distinction between a secure program and a 
  183.       security program. The security program enforces security 
  184.       policies; however, the secure program does not enforce any 
  185.       policies but must also co-exist with the security policies. 
  186.       This allows a much broader view of every program on the system. 
  187.       All the applications, and all the servers, and all the clients 
  188.       must be implemented securely. Granted that this approach is a 
  189.       bit extremist, it is actually quite reasonable. Programming 
  190.       securely should always be done as will be seen by some of the 
  191.       points brought up in this FAQ. 
  192.  
  193.       Finally, to finish this definition, consider a Mail User Agent 
  194.       (MUA), such a 'pine' or 'elm.' Both have to be written securely 
  195.       because they can affect the security policies if they were not. 
  196.       In light of an advisory posted to Bugtraq (Zalewski 1999), pine 
  197.       was reported to have a security hole. Even though it is not 
  198.       enforcing security policies it still failed to adhere to them. 
  199.  
  200.       1.2) What is a security hole? 
  201.       ----------------------------- 
  202.  
  203.       The term is somewhat colloquial but it has been used in 
  204.       technical context enough times to warrant common usage in 
  205.       security advisories. It just means the program has a flaw that 
  206.       allows an attacker to "exploit it." Thus comes the "exploit" 
  207.       that denotes a program, or technique to take advantage of the 
  208.       flaw, or "vulnerability." The terms mentioned here will be 
  209.       found in many advisories, and in this FAQ so familiarity with 
  210.       them is essential. 
  211.  
  212.       1.3) How do I find security holes? 
  213.       ---------------------------------- 
  214.  
  215.       Careful auditing of source code is usually the way. One way of 
  216.       doing it is going through this FAQ in its treatment toward 
  217.       specific security holes and attempt to find them throughout the 
  218.       code in question. I will attempt to give tips toward finding a 
  219.       said security hole where applicable. 
  220.  
  221.       However, if you really really need to find that security hole, 
  222.       disassemble the binary image of the program, grok the asm 
  223.       output into your head, run it slowly but carefully keeping 
  224.       track of registers, stacks etc -- and yes grasshopper, that is 
  225.       the One True Way. 
  226.  
  227.       1.4) What types of attacks exist? 
  228.       --------------------------------- 
  229.  
  230.       There are three main types of attacks (Saltzer 1975): 
  231.  
  232.           Unauthorized release of privileged information. 
  233.  
  234.           Unauthorized modification of privileged information. 
  235.  
  236.           Denial of service. 
  237.  
  238.       The word unauthorized speaks for itself. If information can be 
  239.       read, or modified when it should not have been, security has 
  240.       been breached. A denial of service attack is any attack that 
  241.       stops a program from performing its function. When considering 
  242.       whether a program is secure from its design, provisions for 
  243.       these three attacks need to be accounted for. 
  244.  
  245.       Obviously these attacks are aggregates of the more specific 
  246.       ones that exploit security holes. But that should give you an 
  247.       idea of what you're looking out for. 
  248.  
  249.       1.5) How do I fix a security hole? 
  250.       ---------------------------------- 
  251.  
  252.       Traditionally there are three approaches to fixing a security 
  253.       hole. At the risk of going slightly off topic, let us go back 
  254.       to the heyday of the SYN flood attack (daemon9 1997). 
  255.  
  256.       SYN flooding is when a host sends out a large number of TCP/IP 
  257.       packets with an unreachable source address, and a TCP flag of 
  258.       SYN. The receiving host responds and awaits for the SYN-ACK to 
  259.       complete the three-way handshake. Since the source address is 
  260.       unreachable the receiving host never receives a response to 
  261.       complete the handshake. Instead it is left in a "half open" 
  262.       state till it times out. The problem is that there is a finite 
  263.       number of "slots" per connection received on the listening 
  264.       socket. This is because the host needs to store information in 
  265.       order to recognize the last part of the TCP three-way 
  266.       handshake. This results in a denial of service where the 
  267.       receiving host would simply stop accepting new connections till 
  268.       the bogus half-open connections timed out. They are called 
  269.       half-open connections because the handshake is never completed. 
  270.  
  271.       Interestingly enough several different approaches were used to 
  272.       solve this problem: 
  273.  
  274.       Cisco Systems Inc., implemented a TCP Intercept feature on its 
  275.       routers. The router would act as a transparent TCP proxy 
  276.       between the real server, and the client. When a connection 
  277.       request was made from the client, the router would complete the 
  278.       handshake for the server, and open the real connection only 
  279.       after the handshake has completed. This allowed the router to 
  280.       impose a very aggressive strategy for accepting new 
  281.       connections. It would place a threshold on the amount of 
  282.       connection requests it would handle: If the amount of half-open 
  283.       connections exceeded the threshold it would lower the timeout 
  284.       period interval, thus dropping the half-open connections 
  285.       faster. The real servers were completely shielded while the 
  286.       routers took the brunt and handled it aggressively. 
  287.  
  288.       The OpenBSD developers implemented a work-around that caused 
  289.       old half-open TCP connections to be randomly dropped when new 
  290.       connection requests arrived on a full backlog. This allowed new 
  291.       connections to be established even with a constant SYN-flood 
  292.       taking place. The old bogus connections would be dropped at the 
  293.       behest of a new connection, legitimate or not. The randomness 
  294.       was implemented to be fair to all incoming connections. 
  295.       Although arguably with a large enough flood this technique may 
  296.       fail, it did have good results as tested by the developers. 
  297.  
  298.       Dan Bernstein (Bernstein 1996; Schenk 1996) proposed SYN 
  299.       cookies, which would eliminate the need to store information 
  300.       per half open connection. When a connection is initiated, the 
  301.       server generates a cookie with the initial TCP packet 
  302.       information. The server would then respond with the cookie. 
  303.       When the client responded with a SYN-ACK to complete the 
  304.       handshake, the server would redo the hash, this time with the 
  305.       information taken from the recent SYN-ACK packet. This would of 
  306.       course entail decrementing the sequence numbers since they have 
  307.       been incremented in the client response. If the new hash 
  308.       matched that of the returned sequence numbers, the server would 
  309.       have completed the three-way handshake. Only the secret was 
  310.       stored, the rest of the information is gathered from the 
  311.       incoming packets during the handshake. This meant only one 
  312.       datum for all incoming connections. Thus an infinite amount of 
  313.       half open connections could exist. 
  314.  
  315.       Three different methods were used. Cisco used a "wrapper." The 
  316.       actual UNIX system was completely unconcerned with what the 
  317.       router did and required no modification. This is good for a 
  318.       scalable solution, but does not remove the problem entirely. 
  319.       The wrapper just acts as a canvas. 
  320.  
  321.       The OpenBSD solution was to fix the problem in the 
  322.       implementation itself. This is usually the case with most 
  323.       security holes, especially the less complicated ones. 
  324.  
  325.       The solution presented by Dan Bernstein was more of a design 
  326.       change. The system's responses were changed, but remained 
  327.       reasonably well in conformance with the TCP standard. Some 
  328.       compromises were made however (see Schenk 1996). 
  329.  
  330.       There is no one True Way of fixing security holes. Approach the 
  331.       problem first in the code, then design, and finally by wrapping 
  332.       it if you really must. 
  333.  
  334.     2) The Flow Of Information 
  335.     -------------------------- 
  336.  
  337.   Although what is presented here is a bit cross platform and not 
  338.   UNIX dependent, it is so essential that I had to put it in its own 
  339.   section. 
  340.  
  341.       2.1) What is the flow of information? 
  342.       ------------------------------------- 
  343.  
  344.       Every program can be considered to follow a simple design: it 
  345.       accepts input, processes it, and produces output. Input may 
  346.       come from the keyboard, a file, or the network. As long as it 
  347.       is gained from an external source that is not part of the 
  348.       program, it is considered input. Output is not necessarily 
  349.       information printed on the screen, or in a log file, it may be 
  350.       an affect like the creation of a file. The processing may be 
  351.       any work from simple arithmetic, to parsing strings. 
  352.       Mathematically speaking, at least, your program should really 
  353.       be a function taking variables and producing results. This 
  354.       cycle may happen more than once during a program's lifetime. 
  355.  
  356.       Most programmers, for purposes of keeping things simple, will 
  357.       make assumptions about input. Particularly its format, and 
  358.       whether to apply sanity checks. There are probably entire books 
  359.       on doing this correctly: designing your program correctly, 
  360.       picking the right data formats and so on. This FAQ isn't 
  361.       interested in that aspect of processing information. Instead it 
  362.       is interested in three things: trust, validation, and acting on 
  363.       input. 
  364.  
  365.       2.2) What is trust? 
  366.       ------------------- 
  367.  
  368.       When trust is given to an external source of input, a program 
  369.       accepts information from it while considering the information 
  370.       valid. Secure programs need to be very untrusting and always 
  371.       validate information gained from external sources. Some 
  372.       programs, such as Dan Bernstein's 'qmail' distrust information 
  373.       gained from within. Usually trust is only given to an external 
  374.       source after it has been authenticated. Take the login program 
  375.       under UNIX. Once authenticated the user is trusted to do 
  376.       whatever he wishes to do under his own credentials. Although 
  377.       this example fails because the login program vanishes and is 
  378.       replaced by a shell, you get the idea. 
  379.  
  380.       As a general rule: any information than an attacker can 
  381.       manipulate cannot be given trust. For example: 
  382.  
  383.       In March 1994 Sun Microsystems released a security update for 
  384.       SunOS 4.1.x that fixed a security hole related to "/etc/utmp". 
  385.       The file acted as a database that keeps track of current users 
  386.       logged onto the system with additional information such as the 
  387.       terminal, and time of login. Certain daemons such as comsat, 
  388.       and talkd, would access the file to retrieve the terminal name 
  389.       associated with a user. The terminal name would consist of the 
  390.       path to the terminal device. The daemons would open the file 
  391.       specified by the path, and write to it. Users could modify the 
  392.       file, because it was world writable, and set arbitrary file 
  393.       names for the terminal. This resulted in potentially having the 
  394.       daemons open sensitive files while running with special 
  395.       privileges, and writing to them at the behest of the attacker. 
  396.       This is a good example of trusting information that can be 
  397.       manipulated by an attacker. 
  398.  
  399.       2.3) What is validation? 
  400.       ------------------------ 
  401.  
  402.       When information is received from an untrusted source it must 
  403.       be validated prior to processing it. In the case of the 
  404.       aforementioned talkd hole, the daemon should have made sure the 
  405.       path to the terminal file was indeed correct. This could have 
  406.       been done by simply checking the password database, making sure 
  407.       the ownership matched, and that the terminal path did indeed 
  408.       point to a terminal. Later in the FAQ, the concept of the least 
  409.       privilege principle is explained, and it would have worked 
  410.       wonders with the aforementioned security hole. 
  411.  
  412.       There are several ways you can validate information depending 
  413.       on what it is supposed to be. A good place to start is by 
  414.       defining its attributes. Is it supposed to hold a file name? 
  415.       Does the file exist? Is the user allowed access to that file? 
  416.       That as mentioned previously is what the talkd daemon should 
  417.       have done. In the "Handling Input" section a security hole 
  418.       found in SSH(*) will be brought up where privileged ports could 
  419.       be bound to by normal users. In that particular case the 
  420.       function binding to a port did not properly check to make sure 
  421.       the port number was not > 1024, and as such the attacker could 
  422.       bind to privileged ports; however, the security hole entailed 
  423.       another error on the part of the program that is discussed in 
  424.       more detail in the coming section. 
  425.  
  426.       2.4) What do you mean by "acting on input"? 
  427.       --------------------------------------------- 
  428.  
  429.       [ I need a more formal term for it. Unfortunately I'm lost for 
  430.       words. ] 
  431.  
  432.       When you pass input directly to a system call, external 
  433.       program, memory copying routine etc. Basically you perform an 
  434.       operation with the aid of the information. In the 
  435.       aforementioned talkd hole the pathname read from the utmp 
  436.       database was passed to a file opening system call directly. The 
  437.       program assumed it was valid, and would not be malicious. This 
  438.       is a wrong assumption. 
  439.  
  440.       PERL supports "tainting" (Wall, Schwartz 1992). All input 
  441.       passed from an external source is tainted unless explicitly 
  442.       untainted. Any tainted input that is passed directly to a 
  443.       system call results in an error. This method of validation is 
  444.       quite ingenious. Regardless of whether or not you are using 
  445.       PERL, the methodology is a good one to follow. 
  446.  
  447.  
  448.     3) Privileges and Credentials 
  449.     ----------------------------- 
  450.  
  451.       3.1) What are privileges and credentials? 
  452.       ----------------------------------------- 
  453.  
  454.       Every process under UNIX has three sets of credentials: Real 
  455.       credentials, effective credentials, and saved credentials. The 
  456.       credentials are split into two groups, user and group 
  457.       credentials. Additionally the process has a list of 
  458.       supplemental group credentials. The different "set*id()" system 
  459.       calls allow a process to change the values in these sets. Only 
  460.       the root user can change them arbitrarily. Non-root users are 
  461.       limited to what they may change their credentials to. 
  462.  
  463.       It is essential to know how the system calls work on the 
  464.       credential sets (see Stevens 1992 for a more exhaustive 
  465.       reference). The following table lists each system call and what 
  466.       credential set it affects, and what credentials it will allow 
  467.       the process to change into. The credential sets are abbreviated 
  468.       with RUID standing for real user ID, EGID for effective group 
  469.       ID, SVUID for the saved user ID. ( Self explanatory really.) 
  470.  
  471.       System Call  Changes                  Can change to            
  472.  
  473.       setuid       RUID EUID SVUID          RUID EUID SVUID          
  474.  
  475.       setgid       RGID RGID SVGID          RGID RGID SVGID          
  476.  
  477.       setreuid     RUID EUID                RUID EUID                
  478.  
  479.       setregid     RGID EGID                RGID EGID                
  480.  
  481.       setruid      RUID                     RUID EUID                
  482.  
  483.       setrgid      GUID                     RGID EGID                
  484.  
  485.       seteuid      EUID                     RUID EUID                
  486.  
  487.       setegid      EGID                     RGID EGID                
  488.  
  489.       Make sure you've read the man pages, and just use the table for 
  490.       reference. When changing credentials make sure you change the 
  491.       right ones. 
  492.  
  493.       The credentials are checked by the kernel for access control. A 
  494.       process is considered privileged if its credentials give it 
  495.       access to privileged information, or privileged facilities. 
  496.       This FAQ will make use of three main privilege levels: 
  497.  
  498.           Special User -- The root user. 
  499.  
  500.           Normal User -- A local user without root privileges. 
  501.  
  502.           Anonymous User -- A user that has not been authenticated, 
  503.           or logged, into the local system. 
  504.  
  505.       The definitions above are a bit misleading without some 
  506.       elaboration. The root user is considered special because the 
  507.       kernel gives him special abilities; his access to files is not 
  508.       limited by file permissions; he can bind to privileged ports; 
  509.       he can change resource limits; he can arbitrarily change his 
  510.       own credentials lowering them to any other credential; he can 
  511.       send signals to any other process, and on some UNIX flavors 
  512.       trace any other process. Although there are some other special 
  513.       abilities the root user has, the list consisted of some of the 
  514.       more important abilities. However, on certain systems 
  515.       privileged information is accessible by non-root users. For 
  516.       example, on SCO 5.0.4 the passwd database is accessible by any 
  517.       user in group "auth." Thus non-root users in that group can 
  518.       still access privileged information. In the case of SCO 5.0.4 
  519.       it is also modifiable by users in that group. The astute reader 
  520.       will note that modifying the password database can effectively 
  521.       lead to modifying one's credentials. So keep in mind that the 
  522.       usage of special privileges in this FAQ is meant to encompass 
  523.       any user who has special abilities that are not conferred upon 
  524.       other local users. This may seem ambiguous but I hope the 
  525.       definition serves its purpose well. 
  526.  
  527.       The normal user has been authenticated, but is regarded as 
  528.       normal without any special privileges. The traditional UNIX 
  529.       kernel itself without any augmentation will not recognize any 
  530.       user except for the root user. The special user and the normal 
  531.       user have both been authenticated, but the special user is 
  532.       recognized to have higher privileges. 
  533.  
  534.       The anonymous user is one who has not been authenticated. It is 
  535.       very important to recognize this user when network applications 
  536.       are written. For example, consider an FTP server using the 
  537.       "anonymous" user open to everyone. In the same way consider the 
  538.       FTP client that connects to the FTP server. The client is run 
  539.       by a local "normal user," (or special user if the admin is 
  540.       nutty enough) but it is connecting to a completely anonymous 
  541.       entity. It must not give the server any special abilities on 
  542.       the local system, and allow only a set of abilities such as 
  543.       writing to a predefined file (downloading from the server). 
  544.       Indeed some advisories discussed the simplest of programs such 
  545.       as 'tar' (Tarreau 1998;Der Mouse 1998) where the tar archive 
  546.       itself could subvert the application into unauthorized 
  547.       modification of privileged information. 
  548.  
  549.       Depending on the privilege level, the application must take 
  550.       into account what the privilege allows the entity to do. 
  551.       Consider a web server that allows clients to browse the entire 
  552.       file system under a normal user ID (or the username 'www'). The 
  553.       web server should still not allow the client to browse just any 
  554.       file or it has given away part of the normal privileges to 
  555.       every user on the net. 
  556.  
  557.       3.2) What is the least privilege principle? 
  558.       ------------------------------------------- 
  559.  
  560.       When an application runs with higher privileges than the source 
  561.       of input, it can prevent the occurrence of security holes by 
  562.       only using the higher privileges for specific tasks. This is 
  563.       known as the least privilege principle (Saltzer 1975), because 
  564.       the lowest privileges are used during the program's execution. 
  565.       If the attacker is able to trick the program into accomplishing 
  566.       a specific task, it will do so with his privileges. 
  567.  
  568.       Most UNIX flavors come with a utility that allows the user to 
  569.       change his personal information. It is usually called chfn. The 
  570.       information is copied to a temporary file from the password 
  571.       database. The utility then forks a child process which executes 
  572.       an editor on the temporary copy. The user is subsequently given 
  573.       control of the editor and is free to modify the copy. Once the 
  574.       user completes modifying the copy and exits from the editor, 
  575.       the utility reads the temporary copy, performs any sanity 
  576.       checks on the input, and copies it back to the password 
  577.       database. The least privilege principle must be applied in this 
  578.       case. The child process running the editor cannot do so with 
  579.       special privileges. The editor may allow the user to run a 
  580.       shell, or open other files. chfn must revert the privilege to 
  581.       that of the user in the child process before executing the 
  582.       editor. 
  583.  
  584.       A security hole that was reported concerning XFree86 (plaguez 
  585.       1997) The server would run with root privileges and read any 
  586.       configuration file specified from a command line option. The 
  587.       advisory demonstrated how the shadowed password database could 
  588.       be read by pointing the server to it as its configuration file. 
  589.       Since the server ran with root privileges it could open the 
  590.       database, and would inadvertently output its contents as part 
  591.       of its error reporting. Thus an attacker could read files he 
  592.       would not normally be able to. Had the X server used the same 
  593.       privileges as the end user when attempting to read the 
  594.       configuration file, it would not have been able to. The 
  595.       attacker would only be able to access files readable by him. 
  596.       The file opening operation should have been done with the least 
  597.       privilege principle. 
  598.  
  599.       3.3) How do I apply the least privilege principle safely? 
  600.       --------------------------------------------------------- 
  601.  
  602.       The least privilege principle can be applied by either lowering 
  603.       privileges temporarily, or completely dropping privileges so 
  604.       that they will never be regained again. However, there are 
  605.       viable attacks that can occur from both operations. Also 
  606.       lowering privileges is not always enough without doing away 
  607.       with privileged information. 
  608.  
  609.       Note on saved credentials 
  610.       ------------------------- 
  611.  
  612.       Before discussing the details of lowering credentials properly, 
  613.       the saved credential set needs to be elaborated upon. The saved 
  614.       credential set is initialized to the effective credentials of 
  615.       the process at the time of its execution. So if the 
  616.       process-image has a set-id-on-execution (SUID) or 
  617.       set-group-id-on-execution (SGID) bit set, the saved credentials 
  618.       will match that credential. This is very useful if the program 
  619.       wishes to temporarily drop its effective credentials and then 
  620.       regain them. 
  621.  
  622.       Lowering privileges temporarily entails changing one of the 
  623.       credential sets, usually the effective credentials because they 
  624.       are most often checked by the kernel. The seteuid() and 
  625.       setegid() system calls allow a process to set its effective 
  626.       credentials to its real credentials or its saved credentials. 
  627.       This is where the switching between the two credential sets 
  628.       becomes very useful. A SUID or SGID process can change its 
  629.       effective credentials to its real credentials, which are 
  630.       inherited from the parent process, and then switch them back to 
  631.       its saved credentials which it inherits from the SUID or SGID 
  632.       file permission. In doing so the SUID or SGID program is 
  633.       toggling its privileges between its caller and the 
  634.       process-image owner. 
  635.  
  636.       Because a process cannot get its saved credentials via any 
  637.       system call, it is recommended to do a geteuid() and getegid() 
  638.       at the beginning of execution and store them internally. This 
  639.       works because the saved credentials are an exact copy of the 
  640.       effective credentials at the start of a process' execution. 
  641.       This will work: saved_uid = geteuid(); saved_gid = getegid(); 
  642.  
  643.       To change effective credentials to the saved credentials do a 
  644.       setegid(saved_gid); seteuid(saved_uid); Now to switch them back 
  645.       to match the real credentials do a setegid(getgid()); 
  646.       seteuid(getuid); Simple and straight forward. 
  647.  
  648.       The second method of applying the least privilege principle is 
  649.       to completely drop privileges and never regain them again. 
  650.       Recall the chfn example mentioned in question 3.2? It would 
  651.       have to drop the privileges in its child process completely 
  652.       because it gave the user control of the child process. This is 
  653.       done by calling setgid() and then setuid(). A common mistake is 
  654.       to drop the user ID first, and this will fail if the process is 
  655.       relying on the fact that it has root privileges! 
  656.  
  657.       There are, as mentioned earlier, viable attacks. The first is 
  658.       the signal attack. BSD derived operating systems allow a 
  659.       process to send a signal to another process if: 
  660.  
  661.           The real user ID of process A is that of the root user. 
  662.  
  663.           The real user ID of process A matches the real user ID of 
  664.           process B. 
  665.  
  666.           The effective user ID of process A matches the effective 
  667.           user ID of process B. 
  668.  
  669.           The real user ID of process A matches the effective user ID 
  670.           of process B. 
  671.  
  672.           The effective user ID of process A matches the real user ID 
  673.           of process B. 
  674.  
  675.           Both processes share the same session ID. 
  676.  
  677.       With those semantics it is obvious that if a process lowered 
  678.       its effective credentials to that of the user, he would be able 
  679.       to send it a signal. In the event that the process begins to 
  680.       run with the same real credentials as the user (all SUID or 
  681.       SGID processes start out this way), it should change its 
  682.       credentials if it expects to trust signals. Keep in mind that 
  683.       by lowering its effective credentials to that of the user's 
  684.       real credentials it _is_ susceptible. This access check on 
  685.       signals is quite a mishmash. Also, change the session ID via 
  686.       setsid(). 
  687.  
  688.       In April 1998, a Bugtraq posting discussed the circumvention of 
  689.       a protection scheme employed by implementations of the BSD ping 
  690.       utility (Sanfilippo 1998) The ping utility would use the alarm 
  691.       routine to synchronize the periodical sending of Internet 
  692.       Control Message Protocol (ICMP) echo requests to a remote host, 
  693.       and would not allow the normal user to send requests repeatedly 
  694.       in a flooding manner. The protection scheme was simply there to 
  695.       prevent abusive users from flooding other hosts with a large 
  696.       number of ICMP echo requests. The normal user, of course, 
  697.       cannot send an ICMP packet because performing this task 
  698.       requires the use of a raw socket. Only the root user can open a 
  699.       raw socket because of the security implications associated with 
  700.       raw network access -- receiving incoming packets rawly from the 
  701.       network, and sending raw packets into the network. Thus the 
  702.       ping utility is normally installed as SUID to root. The 
  703.       technique Sanfilippo used to get around ping's security 
  704.       mechanism was to constantly send the SIGALRM signal to it, 
  705.       subverting the protection scheme it attempted to implement. 
  706.       Since the alarm routine would schedule an occurrence of SIGALRM 
  707.       after a specified interval, the ping utility would have a 
  708.       signal handler for it, that sends the ICMP echo request. 
  709.       Obviously the process may not install handlers and act on them 
  710.       blindly if an attacker can trigger the signal handlers. 
  711.  
  712.       Some UNIX flavors support the SA_SIGINFO option that can set 
  713.       when setting the signal handler via 'sigaction'. This passes 
  714.       the handler additional information with regards to who sent the 
  715.       signal, and whether or not it is kernel generated. Another 
  716.       method is by using internal sanity checks. In the case of 
  717.       'ping' this could have been done by simply keeping track of the 
  718.       time that passed in between signals being generated and not 
  719.       honoring them unless a sufficient amount of time had passed. 
  720.  
  721.       However, a worse case would be a SIGTERM or SIGKILL that halts 
  722.       a process when it is in between a critical state. In the case 
  723.       of 'chfn' it would be downright despicable of a user to halt it 
  724.       just as it was writing out the new password file. If a process 
  725.       is in an "unclean state" it should not allow itself to be 
  726.       halted by an attacker and retain higher privileges untill the 
  727.       point whence it can afford to be halted. 
  728.  
  729.       A common mistake is to assume that a process with lowered 
  730.       credentials is no longer a security hazard. In fact it just 
  731.       might be, even with the previous attacks accounted for. 
  732.  
  733.       A well known, but ancient, technique of getting the password 
  734.       file from an old SunOS box was to cause its ftp daemon to dump 
  735.       core. Similar security holes were later reported (Temmingh 
  736.       1997). If a privileged process reads the password database into 
  737.       memory and is then caused to dump core because of a signal 
  738.       attack, the core image may hold a copy of the password file 
  739.       which is then easily readable by the attacker. But cleaning up 
  740.       internal memory may not be enough. A security hole was found on 
  741.       OpenBSD's chpass utility with file descriptor leakage (Network 
  742.       Associates Inc. 1998). The child process was passed a 
  743.       privileged file descriptor because the descriptor was never 
  744.       properly closed before giving the user control over the 
  745.       process. 
  746.  
  747.       Finally, process tracing attacks may take place. FreeBSD, and 
  748.       NetBSD both allow a process to trace any process with a 
  749.       matching real user ID. Tracing implies complete control over 
  750.       the process, including the file descriptors, memory, and 
  751.       executable instructions etc; however, a process may not be 
  752.       traced if it is SUID or SGID. 
  753.  
  754.       Here's a check list for lowering real and effective 
  755.       credentials: 
  756.  
  757.       Lowering Effective Credentials 
  758.       ------------------------------ 
  759.  
  760.           The process should not have any cleaning up to do. The 
  761.           state of external objects should be in a form that is 
  762.           suitable for reuse. This includes lock files, updates to 
  763.           databases, and even temporary files. 
  764.  
  765.           All signal handlers that may be triggered should not be 
  766.           trusted; they must be validated for authenticity. 
  767.  
  768.           All privileged information held in the process memory 
  769.           should be cleared so that a core dump will not contain them 
  770.           (don't just free up dynamic privileged memory, clean it out 
  771.           before freeing). 
  772.  
  773.       Lowering Real Credentials: 
  774.       -------------------------- 
  775.  
  776.       Previous steps must be followed as well. Additional steps take 
  777.       into account the process tracing attacks which are not viable 
  778.       on all systems. 
  779.  
  780.           Privileged information may not be held by the process. This 
  781.           includes file descriptors or sockets referencing privileged 
  782.           information. 
  783.  
  784.           The effective credentials should be dropped to the real 
  785.           credentials as well, since a process that is traced can be 
  786.           forced to execute arbitrary code under this effective 
  787.           credential. 
  788.  
  789.     4) Local Process Interaction: 
  790.     ----------------------------- 
  791.  
  792.       4.1) What is process attribute inheritance? Or why should I not 
  793.       write SUID/SGID programs? 
  794.       
  795.       ----------------------------------------------------------------
  796.       
  797.  
  798.       Process attribute inheritance (AFAIK a term I coined), is when 
  799.       a child process inherits attributes from the parent process' 
  800.       environment. I did see this referred to as "state variables", 
  801.       but I forgot by who and all searching has led nowhere. The 
  802.       problems with process attribute inheritance were fore shadowed 
  803.       by the 'ping' security hole mentioned in question 3.3, as well 
  804.       as the OpenBSD 'chpass' hole mentioned in that section. 
  805.  
  806.       A child process is an exact copy of its parent except for the 
  807.       process ID and the parent process ID. These change for obvious 
  808.       reasons. However, all other attributes are the copied with the 
  809.       exception of file descriptors. File descriptors, however, are 
  810.       shared. (For a more exhaustive explanation see Stevens 1992). 
  811.  
  812.       A process is executed after a call to execve() or one of the 
  813.       other routines in its family. This system call filters out many 
  814.       of the process attributes, but lets some through. This is 
  815.       considered a UNIX "feature" and is relied upon by daemons such 
  816.       as inetd. Keep in mind that a SUID process is a child that has 
  817.       been execve()'d, so it does inherit these attributes. Before I 
  818.       present a list of process attributes (albeit probably an 
  819.       incomplete list), some known security holes will be discussed 
  820.       to illustrate the types of attacks that can occur (Bishop 
  821.       1986). 
  822.  
  823.       A post was made to Bugtraq that discussed a weakness in a 
  824.       popular Mail User Agent package elm because it trusted an 
  825.       environment (Jensen 1994) variable. An autoreply utility was 
  826.       packaged with elm that would run with special privileges, and 
  827.       perform its own internal checks to prevent exploitation by the 
  828.       user. One of the checks included making sure a user did have 
  829.       read access to an arbitrary file before allowing him to read it 
  830.       (can you see what's wrong with this picture?). If the full path 
  831.       to the file was not specified, the utility simply prepended 
  832.       whatever was in the HOME environment variable, and opened the 
  833.       file for reading, without performing any checks. This allowed 
  834.       users to read files with the same privileges as the autoreply 
  835.       process. The mistake was to assume that environment variables 
  836.       can be trusted for valid information, and that the files in a 
  837.       user's home directory are his to read. Both these assumptions 
  838.       are false. Environment variables are inherited from a parent 
  839.       process, and thus can contain arbitrary information. The 
  840.       attacker can manipulate environment variables before forking 
  841.       the child process. It is also not true that the user would have 
  842.       access to the files in his home directory, necessarily. This 
  843.       was a tragic case of giving trust to information that can be 
  844.       manipulated by an attacker. 
  845.  
  846.       In December 1993, Sun Microsystems released a security 
  847.       bulletin, which among other subjects brought up a weakness in 
  848.       the modload and loadmod system utilities. The weakness was 
  849.       trusting the Internal Field Separator (IFS) environment 
  850.       variable. Since the shell would use the IFS to split the 
  851.       contents of variables after they are expanded, the attacker can 
  852.       specify how the contents are split. A path name such as 
  853.       "/bin/cat" , could indeed cause the file "bin" to be executed 
  854.       if the IFS is set to '/'. This is because the character '/' 
  855.       would be recognized as a field to separate the other strings in 
  856.       the variable. Since both these utilities would call upon a 
  857.       shell during their execution, the attacker could arbitrarily 
  858.       trick the utilities to run his process-images with their 
  859.       privileges by modifying the IFS variable. We might think that 
  860.       shells should not make use of the IFS variable if the shell is 
  861.       not run in interactive mode. This is not a solution, since this 
  862.       only canvases the problem of passing down harmful process 
  863.       attribute. The solution is not to pass the variable in the 
  864.       first place. If the aforementioned utility would not have 
  865.       called a shell, it may still have encountered problems with 
  866.       other child processes. For example the LD_PRELOAD environment 
  867.       variable is used by the run-time linker to load code from any 
  868.       shared library the variable specifies. Although the run-time 
  869.       linker will ignore such environment variables for SUID or SGID 
  870.       processes, the child process of a privileged process may 
  871.       inherit them nonetheless and not have such protection. Since 
  872.       the child process in turn inherits its parent's privileges, the 
  873.       parent is effectively compromised through the child process. So 
  874.       remember, the SUID process may have children that are passed 
  875.       down harmful environment variables that would not affect the 
  876.       SUID program necessarily but affect its children. 
  877.  
  878.       At this point I must concede that there may very well be 
  879.       implementations of run-time linkers (read: haven't done the 
  880.       research yet) that do not make the mistake of using the 
  881.       LD_PRELOAD variable even in the child process of a SUID or SGID 
  882.       process. Nonetheless, why risk it on an old box? 
  883.  
  884.       Finally a reminder of the OpenBSD chpass hole, and the 
  885.       descriptor leak. If you haven't read it in section 3.3, go and 
  886.       read it. 
  887.  
  888.       Thus four types of attacks are viable: 
  889.  
  890.           Child process trusts process attribute to contain valid 
  891.           information. (elm hole) 
  892.  
  893.           The process attribute affects the child process directly. 
  894.           (ping hole) 
  895.  
  896.           A process inherits an attribute and passes it down to a 
  897.           child process that is affected by it. This is the same as 
  898.           the second attack, but it is the child process of the 
  899.           secure process that is affected. (or the grandchild of the 
  900.           attacker). (LD_PRELOAD attack) 
  901.  
  902.           The child process of the secure process is passed an 
  903.           attribute containing privileged information. (chpass hole) 
  904.  
  905.       Now for the list of process attributes and how to go about 
  906.       avoiding any security holes. 
  907.  
  908.           Credentials: 
  909.  
  910.           Just a review of section 3. Processes running with the same 
  911.           credentials, or similar (see section 3!) can be attacked by 
  912.           process tracing, or sent signals that affect them. 
  913.  
  914.           File Descriptors: 
  915.  
  916.           The 'chpass' security hole had a file descriptor leak. A 
  917.           quick and easy way of avoiding file descriptor leaks is by 
  918.           setting the FD_CLOEXEC flag on the descriptor (again, see 
  919.           Stevens 1992 as he discusses this rather well). But that's 
  920.           not the end of it. In 1998 the OpenBSD team released a 
  921.           patch for OpenBSD which would not allow a SUID or SGID 
  922.           program from inheriting empty file descriptors in the first 
  923.           three slots. It would instead set them pointing to 
  924.           /dev/null. Theo deRaadt mentioned to me one of the problems 
  925.           that could occur: if the inherited descriptor would be 
  926.           opened as a raw socket, and error reporting by the standard 
  927.           C library (standard error) would be sent through it, bogus 
  928.           packets could be sent to the socket. Although he did 
  929.           mention for other reasons programs such as traceroute were 
  930.           not susceptible. As a workaround for systems without this 
  931.           security feature, doing a stat on the first three file 
  932.           descriptors to check their availability and opening them to 
  933.           "/dev/null" should do. It just adds bloat to your code, and 
  934.           should really be handled by the kernel. 
  935.  
  936.           Environment Variables: 
  937.  
  938.           Don't trust environment variables to contain valid 
  939.           information. In the case of the above mentioned 'elm' hole, 
  940.           it would have been wiser to look up the home directory in 
  941.           the password database. Another more subtle issue is not 
  942.           placing privileged information in an environment variable 
  943.           (Smith 1998). Specifically, a security hole related to 
  944.           FreeBSD's 'ps' utility. The utility would allow users to 
  945.           view another process' environment variables. Consequently 
  946.           applications like pppd that accepted passwords via 
  947.           environment variables became vulnerable to unauthorized 
  948.           release of privileged information attacks. In fact, the 
  949.           hole was not related to 'ps' if you think about it 
  950.           critically. The application that places privileged 
  951.           information in the environment variable is at fault. 
  952.  
  953.           Finally comes the security hole related to having an 
  954.           environment variable affect an external program. IFS and 
  955.           LD_PRELOAD, as discussed previously, are viable environment 
  956.           variables, but a secure program should remove all 
  957.           environment variables except the ones it chooses to use and 
  958.           knows will not affect it. A good idea is to get rid of 
  959.           every environment variable you don't need and keep the ones 
  960.           you know are useful and actually have a use for. 
  961.  
  962.           File Mode Creation Mask: 
  963.  
  964.           Although it is very common for a robust program to reset 
  965.           its file mode creation mask by calling umask(), it should 
  966.           still be noted as a viable security concern. An attacker 
  967.           can pass a mask that would affect the file permissions of 
  968.           files created by open() and mkdir(). Resetting the mask to 
  969.           0 suffices to prevent a file mode creation mask attack. 
  970.  
  971.           Working and Root Directories 
  972.  
  973.           Both the current working directory, and the root directory 
  974.           are inherited from the parent process. The working 
  975.           directory affects file system calls if they are not passed 
  976.           a full path name. This can be made into an attack. Thus it 
  977.           is advisable to both set the current working directory, and 
  978.           use full paths when making file system calls. The root 
  979.           directory should not be a concern. Only the root user can 
  980.           change the root directory. 
  981.  
  982.           Resource Limits 
  983.  
  984.           The setrlimit() system call allows a process to set soft or 
  985.           hard limits on its consumption of resources. When a process 
  986.           reaches its soft limit a signal is sent depending on which 
  987.           limit is reached. SIGSEV for the maximum stack size, 
  988.           SIGXFSZ for an I/O operation that exceeded a file size 
  989.           limit etc. The list is left till the section on resource 
  990.           limits, but the signals if not handled will result in the 
  991.           process being terminated. A careful attacker may trigger a 
  992.           denial of service attack where the process is terminated in 
  993.           the middle of performing a critical operation. When the 
  994.           hard limit is reached, the process is prevented from 
  995.           executing any further. The soft limits may be raised or 
  996.           lowered at the process' own discretion. Thus by setting all 
  997.           limits to infinity, the process can relieve itself of any 
  998.           resource limit attacks. However, the hard limit can be 
  999.           lowered by a normal user, but cannot be raised except by 
  1000.           root. A viable attack is to lower the hard resource limits, 
  1001.           and have the child process choke from underneath. The most 
  1002.           obvious solution is not to begin execution if the hard 
  1003.           limits are too low, and to heighten the soft limits to 
  1004.           infinity. Raising the soft limits over the hard limits will 
  1005.           not work. Thus the process will begin by specifying how 
  1006.           much of the individual resources it requires, and if the 
  1007.           setrlimit() system call returns an error it will not begin 
  1008.           execution as to avoid resource starvation. This is not very 
  1009.           helpful though, and better treatment of resource limits is 
  1010.           given in its own section below. 
  1011.  
  1012.           Scheduling Priority 
  1013.  
  1014.           The scheduling priority on a process can be modified by a 
  1015.           call to nice() or setpriority(). This is usually done to 
  1016.           tell the scheduler how important the process is. A very low 
  1017.           priority may cause the process to execute slower, which can 
  1018.           aid an attacker if he is attempting to exploit a race 
  1019.           condition.The semantics of setpriority() requires the user 
  1020.           to have an effective user ID matching the real or effective 
  1021.           user ID of the peer process. So this may not necessarily be 
  1022.           inherited. However, the priority of a process can only help 
  1023.           an attacker exploit a race condition more easily. It does 
  1024.           not really constitute a denial of resource attack unless 
  1025.           the process has time constraints. Regardless of the speed 
  1026.           of a process, a race condition can always be exploited. 
  1027.           Even with the element of luck, or by slowing down the 
  1028.           system as a whole. Race conditions need to be eliminated 
  1029.           and not made harder to exploit. Keep an eye out for this 
  1030.           scheduling priority in the rare case that it actually does 
  1031.           matter. 
  1032.  
  1033.           Interval Timers 
  1034.  
  1035.           Three interval timers that can be manipulated by the 
  1036.           setitimer() system call. The alarm facility is usually 
  1037.           wrapped around a call to setitimer(). Since the interval 
  1038.           timers are inherited, a parent process could set a timer to 
  1039.           send its child process SIGALRM, SIGVTALRM or the SIGPROF 
  1040.           signal. These could be used to either subvert a program if 
  1041.           it were to handle them, or terminate it. These signals 
  1042.           should be ignored at the beginning of the process' 
  1043.           execution or the timers should be reset. 
  1044.  
  1045.           Signal Handlers 
  1046.  
  1047.           Although all signal handlers are reset to their defaults, 
  1048.           blocked signals remain blocked and so do ignored signals. 
  1049.           This could be a problem if our program design is built 
  1050.           around receiving a signal before carrying on, and assumes 
  1051.           it is not blocked or ignored. Resetting the state of the 
  1052.           signal mask, and resetting signal handlers should also be 
  1053.           done without any preconceptions of default settings. 
  1054.  
  1055.       With all of this SUID/SGID programming is daunting at best. A 
  1056.       better technique (proposed by Thomas Ptacek on the newsgroup) 
  1057.       would be to use a server-client model where the server is 
  1058.       privileged but does not inherit the environment of its parent 
  1059.       process -- a would be attacker. That way the client runs with 
  1060.       no privileges, connects to the privileged server and passes the 
  1061.       relevant information through the IPC channel. 
  1062.  
  1063.       4.2) How can I limit access to a SUID/SGID process-image 
  1064.       safely? 
  1065.       
  1066.       ----------------------------------------------------------------
  1067.       
  1068.  
  1069.       The question may seem vague but sometimes it would seem 
  1070.       attractive to have a SUID process that is only executable by a 
  1071.       particular set of users. Some time ago I implemented a 
  1072.       distributed network monitoring package that had java clients 
  1073.       talk to it remotely, and sniffers running on different servers 
  1074.       (a very ambitious undertaking). The actual servers where run 
  1075.       under a special group called "sly" that would in turn have 
  1076.       access to a SUID process-image to do all the sniffing. The 
  1077.       child process ran as root, but could only be executed by users 
  1078.       in the group "sly." 
  1079.  
  1080.       At first this looks good. The actual server does not run with 
  1081.       special privileges, and it would seem that if it got exploited 
  1082.       the attacker would not gain root privileges. However, he would 
  1083.       gain privileges for the group "sly" that would let him sniff 
  1084.       the local network. If he was then able to exploit the sniffer, 
  1085.       he would gain root privileges. But he needs to exploit the 
  1086.       server to the point of executing arbitrary code on the machine. 
  1087.       Creating a file, or tricking it into sending privileged 
  1088.       information would not equate to gaining the privileges of group 
  1089.       "sly" necessarily. So this does not lessen the need for secure 
  1090.       code, but it _could_ in the long run lessen the chances of 
  1091.       complete compromise. I'm going to call this technique, at the 
  1092.       risk of coining yet another term, privilege segmentation. The 
  1093.       attacker may gain privileges to a specific group but has more 
  1094.       work to do in order to gain higher privileges. 
  1095.  
  1096.       Fair warning that security via "chance" or "hope" is not good. 
  1097.       I don't particularly like hearing about "risk management," and 
  1098.       the above technique is just that: risk management. 
  1099.  
  1100.       4.3) How do I authenticate a parent process? 
  1101.       -------------------------------------------- 
  1102.  
  1103.       Since the child process inherits the parent's real user ID, a 
  1104.       call to getuid() does the trick. Unfortunately due to a 
  1105.       misconception, some programmers are led to believe that 
  1106.       getuid() is not sufficient. This stems from the thinking that 
  1107.       if a user managed in exploiting a SUID process into running 
  1108.       another process, the child would have a real user ID matching 
  1109.       the parent process' effective user ID. This is not true, 
  1110.       because the real user ID keeps propagating from parent to child 
  1111.       regardless of the SUID feature. As mentioned in 2.1, the child 
  1112.       process inherits the credentials directly, a perfect copy with 
  1113.       the exception of the effective credentials if the SGID or SUID 
  1114.       feature. The saved credentials are also reset. But this 
  1115.       exception does not extend to the real credentials which are 
  1116.       directly inherited. 
  1117.  
  1118.       However, if the exploited SUID process was to change its real 
  1119.       user ID to match its effective user ID, which is easily done 
  1120.       with setuid(), then getuid() is not sufficient. There is a 
  1121.       logical fallacy here: if the parent process has already been 
  1122.       exploited to the point where the attacker can cause it to 
  1123.       switch credentials what's the point in faking it anymore? 
  1124.       Nonetheless, additional steps can be taken but not portably. On 
  1125.       systems where login information is stored in the kernel, and 
  1126.       not on the file system, by setlogin(), getlogin() will always 
  1127.       return the username associated with the session. [ FreeBSD 
  1128.       stores login information in kernel. ] 
  1129.  
  1130.       On OpenBSD, and FreeBSD the issetugid() system calls can be 
  1131.       used to find out if the current process is a SUID or GUID 
  1132.       process. This propagation continues unless a child process 
  1133.       clears all its privileges, to quote the OpenBSD man page "uid 
  1134.       != euid or gid != egid". So this system call may be used in 
  1135.       conjunction with getuid to be even more paranoid. 
  1136.  
  1137.       A good suggestion is to do a getuid(), check getlogin() if the 
  1138.       information is stored in the kernel, and finally do a 
  1139.       issetugid(). If all tests pass, you know you are talking to the 
  1140.       Real McCoy. In saying that, caution should not be thrown to the 
  1141.       wind. Using passwords, cookies, 
  1142.       insert-fancy-authentication-mechanism-here etc. is always 
  1143.       recommended, but the previous approach is the more light weight 
  1144.       kernel supported method. 
  1145.  
  1146.       4.4) How do I authenticate a non-parent process? 
  1147.       ------------------------------------------------ 
  1148.  
  1149.       [ I could use writing on SO_PEERCRED (Linux) doors (Solaris) 
  1150.       and LOCAL_CREDS (NetBSD). Also I have some example code for the 
  1151.       techniques discussed below. If you tackle the any of the issues 
  1152.       above, you would be a very nice contributor to provide example 
  1153.       source. Also this is advanced stuff so I'll elaborate more when 
  1154.       I fix it up] 
  1155.  
  1156.       It is possible to authenticate processes via IPC channels 
  1157.       (Bernstein 1999). However the methods differ on different UNIX 
  1158.       flavors making it a very non-portable mess to write. 
  1159.  
  1160.       BSD derived systems support the concept of access rights 
  1161.       (Stevens 1990). The facility allows a process to pass a file 
  1162.       descriptor through a UNIX domain socket, and with a small hack 
  1163.       it can be used to authenticate a local process. The term hack 
  1164.       is only used because the facility was not intended for 
  1165.       authentication. However, if the client sends a descriptor 
  1166.       referencing a file that has read permissions only for its 
  1167.       owner,the receiver knows the sender is the owner. Thus the file 
  1168.       acts as an identifier. However, on systems where a user may 
  1169.       give away files with chown() this method cannot be used. The 
  1170.       attacker can simply create a file with read permissions only 
  1171.       for himself, open it, and then chown it to another user. 
  1172.       Fortunately this is a System V "feature," and on many systems 
  1173.       can be turned off as a kernel configuration option. 
  1174.  
  1175.       A similar technique is found under System V derived systems. 
  1176.       This is done by receiving file descriptors via a STREAMS file. 
  1177.       Only the file descriptor is discarded because the UID is passed 
  1178.       along with it. This is done by using an ioctl call with the 
  1179.       I_SENDFD and I_RECVFD flags on a streams file used as an IPC 
  1180.       channel. This technique does not suffer from the chown attack 
  1181.       because the credentials are passed _along_ with the descriptor. 
  1182.  
  1183.       BSD/OS, FreeBSD and other BSD derived operating systems also 
  1184.       have SCM_CREDS that sends credential information through a UNIX 
  1185.       domain socket. [ Ok, someone point me to some standard that 
  1186.       documents the semantics. Every BSD camp is doing it differently 
  1187.       ":( ] 
  1188.  
  1189.     5) Using The File System Securely 
  1190.     --------------------------------- 
  1191.  
  1192.   [ The first contributor to find a better solution to 5.2 gets a 
  1193.   donut ] 
  1194.  
  1195.   Sadly too many past security holes show that the average programmer 
  1196.   fails to note that the file system is a database with links 
  1197.   pointing to resources, and that filenames act only as identifiers. 
  1198.   Indeed that is how we get race condition attacks, and symlink 
  1199.   attacks. Both are given treatment below, but keep in mind that the 
  1200.   principles are open to other databases that follow the same model 
  1201.   as the file system. In particular race conditions may occur in 
  1202.   non-file-system related operations. 
  1203.  
  1204.       5.1) How do I avoid race condition attacks? 
  1205.       ------------------------------------------- 
  1206.  
  1207.     A race condition occurs when two or more operations occur in an 
  1208.     undefined manner (McKusick et al. 1996). Specifically in file 
  1209.     system races the attacker attempts to change the state of the 
  1210.     file system in between two file system operations on the part of 
  1211.     the program. Usually the program expects the two operations to 
  1212.     apply to the same file, or expects the information retrieved to 
  1213.     be the same. If the file operations are not atomic, or do not 
  1214.     reference the same file this cannot be guaranteed without proper 
  1215.     care. As an added note see Bishop 1996 for a more exhaustive and 
  1216.     but more theoretical discussion. 
  1217.  
  1218.     Solaris 2.x's 'ps' utility had a security hole that was caused by 
  1219.     a race condition (Chasin 1995). The utility would open a 
  1220.     temporary file, and then use the chown() system call with the 
  1221.     file's full path to change its ownership to root. This was easily 
  1222.     exploitable by slowing the system down, finding the file created, 
  1223.     deleting it, and then slipping in a new file with a mode of 1777 
  1224.     (world writable with SUID bit). After the file was created with 
  1225.     that mode and chowned to root, the attacker simply copies a shell 
  1226.     into the file. Viola, instant root shell. (The exploit itself 
  1227.     made use of symlinks to slip in the new file, but I'm leaving the 
  1228.     concept of symlinks untill the next 5.2) 
  1229.  
  1230.     At first glance to the less perceptive reader it may seem that if 
  1231.     the original file was not created world writable the attacker 
  1232.     could not delete it. Well it was not world writable and he could. 
  1233.     The file was created under the temporary directory (usually 
  1234.     "/var/tmp" or "/tmp") which had world writable permissions. 
  1235.     Global temporary directories are setup this way or they aren't 
  1236.     usable, hence the world global. It's a completely different issue 
  1237.     to argue whether having global temporary directories is a good 
  1238.     idea. I won't be discussing philosophical issues here, let's 
  1239.     stick to the facts (for a similar security hole see Hull 1996). 
  1240.  
  1241.     The problem was that the second operation used the file name and 
  1242.     not the file descriptor. If a call to fchown() would have been 
  1243.     used on the file descriptor returned from the original open() 
  1244.     operation, the security hole would have been avoided. File names 
  1245.     are _not_ unique. The file name "/tmp/foo" is really just an 
  1246.     entry in the directory "/tmp". Directories are special files. If 
  1247.     an attacker can create, and delete files from a directory the 
  1248.     program cannot trust file names. Instead it should use file 
  1249.     descriptors to perform its operations. 
  1250.  
  1251.     There are other race conditions that can occur. Using stat() and 
  1252.     instead of fstat(). Using access() and thinking that the 
  1253.     information will persist untill the next few lines of code. It 
  1254.     will not so don't expect it to. The only way to make sure the 
  1255.     file permissions will not change, and that you have the file you 
  1256.     want is to fstat() after an open(). See below for a treatment 
  1257.     toward opening files safely. 
  1258.  
  1259.     5.2) How do I create/open files safely? 
  1260.     --------------------------------------- 
  1261.  
  1262.   A symbolic link is a file that stores a pathname to another file. 
  1263.   The kernel just uses the path to reference the file. It is a 
  1264.   convenient way to keep links to files which may not necessarily 
  1265.   always exist. Hard links on the other hand create a new link to the 
  1266.   file (see McKusick et al. 1996 [ page 251]). 
  1267.  
  1268.   A security hole reported for SUN's license manager stemmed from the 
  1269.   creation of a file without checking for symbolic links (or soft 
  1270.   links) (Eriksson 1996). An open() call was made to either create 
  1271.   the file if it did not exist, or open it if it did exist. The 
  1272.   problem with symbolic link is that an open call will follow it and 
  1273.   not consider the link to constitute a created file. So if you had 
  1274.   "/tmp/foo" symlinked to "/.rhosts" (or "/root/.rhosts" depending on 
  1275.   your cultural background), the latter file would be transparently 
  1276.   opened. The license manager seemed to have used the O_CREAT flag 
  1277.   with the open call making it create the file if it did not exist. 
  1278.   To make matters worse, it created the file with world writable 
  1279.   permissions. Since it ran as root, the ".rhosts" file could be 
  1280.   created, written to, and root privileges attained. I'll leave it as 
  1281.   an exercise to the reader to work out how a world writable 
  1282.   ".rhosts" file can be used to get root privileges. (Back in those 
  1283.   days a world writable ".rhosts" was OK on the part of rlogind) 
  1284.  
  1285.   There is a problem here that relates to the previous discussion on 
  1286.   race conditions. A program needs to both check for the existence of 
  1287.   a file, and make sure it's pathname is not the result of a symbolic 
  1288.   link. At first the O_EXCL flag comes to mind. If used with O_CREAT 
  1289.   it will return an error if the file exists. Sadly, the UNIX98 
  1290.   standard does not define behavior for symbolic links and O_EXCL. 
  1291.   FreeBSD 2.2.7 does, to quote its man page: 
  1292.  
  1293.   "If O_EXCL is set and the last component of the pathname is a 
  1294.   symbolic link, open() will fail even if the symbolic link points to 
  1295.   a non-existent name." 
  1296.  
  1297.   The astute reader will note that this only relates to files with 
  1298.   the "last component" meaning the last part of the path. Also, to 
  1299.   rely on semantics that are not standard is just asking for trouble. 
  1300.   I strongly suggest inserting a check at compile time to look for 
  1301.   these semantics, and steadfastly refuse to compile if they don't 
  1302.   exist. For the sake of absolute security, the discussion will 
  1303.   continue without taking these semantics into consideration. 
  1304.  
  1305.   One of the work arounds is to create a file with write only 
  1306.   permissions for the program's real user ID (we'll consider it to be 
  1307.   root for the sake of discussion). Then an fstat() can be made and 
  1308.   the program will know the full path to the file it has opened. If 
  1309.   it is the correct file, go about business as usual, fchmod() if you 
  1310.   want as well. However, if it is the wrong file it needs to be 
  1311.   deleted. Here it comes: there's no funlink(), or at least none on 
  1312.   any standard or box that I've seen. 
  1313.  
  1314.   The reader may claim that if the file being deleted is a symbolic 
  1315.   link, then the symbolic link will be unlinked and not the actual 
  1316.   file. This is true, but what if the symbolic link was between 
  1317.   directories and not the last component. Consider the path 
  1318.   "/usr/foo/bar/footest" to the file "footest" now make a symbolic 
  1319.   link with "/usr/foo2" pointing to "/usr/foo/bar." Now unlink() with 
  1320.   "/usr/foo2/footest", and "/usr/foo/bar/footest" will be deleted. 
  1321.   Since the directory is a symbolic link, and not the last component, 
  1322.   the symbolic link is unaffected by the unlink() call. 
  1323.  
  1324.   So there's no way to safely delete files. How do you like them 
  1325.   apples? If it is ok to leave files around, then this work around 
  1326.   will do. However, let's continue, yet again, for the sake of 
  1327.   absolute security. 
  1328.  
  1329.   A special directory can be created. It would have permissions that 
  1330.   allow only the process to read, write, and create files in it. This 
  1331.   is probably the best solution. The global tmp directory won't work 
  1332.   because all the other users have access to it. Directories created 
  1333.   by the program for itself seems to be the only solution. No 
  1334.   symbolic links can linked into the directories, so no trickery can 
  1335.   take place. Only this means a human has to create the special 
  1336.   directory, because as we have seen it's impossible to completely 
  1337.   avoid symbolic link attacks. This is by all means possible, 
  1338.   consider using directories in /var that are owned and accessible by 
  1339.   the secure process only. 
  1340.  
  1341. 8) Bibliography 
  1342. --------------- 
  1343.  
  1344.     Chasin, Scott "BUGTRAQ ALERT: Solaris 2.x vulnerability" Online 
  1345.     posting. 14. Aug. 1995. Bugtraq. 
  1346.  
  1347.     Bernstein, Dan "Secure Interprocess Communication" 1998. <URL: 
  1348.     //koobera.math.uic.edu/www/docs/secureipc.html> 
  1349.  
  1350.     Bernstein, Dan "Re: A thought on TCP SYN attacks" Online posting. 
  1351.     26 Sept. 1996. SYN-Cookies Mailing List. 
  1352.  
  1353.     Bishop, Matt "How to write a setuid program" login 12(1) Jan/Feb 
  1354.     1986. 
  1355.  
  1356.     Bishop, Matt "Checking for Race Conditions in File Accesses," M. 
  1357.     Bishop and M. Dilger, Computing Systems 9(2) (Spring 1996) pp. 
  1358.     131-152. 
  1359.  
  1360.     daemon9, route, infinity "Project Neptune" Phrack, Vol.7, No. 48, 
  1361.     July 1996, [ File 13 of 18 ] 
  1362.  
  1363.     Der Mouse "Re: Tar "features"" Online posting. 25 Sept. 1998. 
  1364.     Bugtraq. 
  1365.  
  1366.     Eriksson, Joel "License Manager's lockfiles (Solaris 2.5.1)" 
  1367.     Online posting. 12 Oct. 1998. Bugtraq. 
  1368.  
  1369.     Hull, Gregory "r00t advisory -- sol2.5 su(1M) vulnerability" 
  1370.     Online posting. 26 Aug. 1996. 
  1371.  
  1372.     Harrison, Roger "License Manager's lockfiles (Solaris 2.5.1)" 
  1373.     Online posting. 23 Oct. 1998. Bugtraq 
  1374.  
  1375.     Jensen, Geir Inge "Another autoreply security hole" Online 
  1376.     posting, 12 Mar. 1994. Bugtraq. 
  1377.  
  1378.     Network Associates Inc. "Network Associates Inc. Advisory 
  1379.     (OpenBSD)" Online posting. 10 Aug. 1998. Bugtraq. 
  1380.  
  1381.     plaguez, shegget "XFree86 insecurity" Online posting. 21 Nov. 
  1382.     1997. Bugtraq. 
  1383.  
  1384.     Saltzer, J.H., and M.D. Schroeder, "The Protection of Information 
  1385.     in Computer Systems," Proc. IEEE, Vol. 63, No. 9, Sept. 1975, pp. 
  1386.     1278-1308. 
  1387.  
  1388.     Sanfilippo, Salvatore "pingflood.c" Online posting. 9 Apr. 1998. 
  1389.     Bugtraq. 
  1390.  
  1391.     Schenk, Eric "A thought on TCP SYN attacks" Online posting. 25 
  1392.     Sept. 1996. SYN-Cookies Mailing List. 
  1393.  
  1394.     Stevens, Richard W. "UNIX Network Programming" New Jersey, 
  1395.     Prentice Hall, 1990. 
  1396.  
  1397.       Stevens, Richard W. "Advanced Programming In The UNIX 
  1398.       Environment" Reading, Massachusetts, Addison-Wesley, 1992. 
  1399.  
  1400.       Smith, Ben "ps(1) for freebsd." Online posting. 12 Aug. 1998. 
  1401.       Bugtraq. 
  1402.  
  1403.       Tarreau, William "Tar "features"" Online posting. 22 Sept. 
  1404.       1998. Bugtraq. 
  1405.  
  1406.       Temmingh, Roelof W "FreeBSD rlogin and coredumps" Online 
  1407.       posting. 17 Feb. 1997. Bugtraq 
  1408.  
  1409.       Wall, Larry and Schwartz, Randal L. "Programming Perl" : 
  1410.       Sebastopol, California : O'Reilly And Associates, 1992. 
  1411.  
  1412.       Zalewski, Michal "ipop3d (x2) / pine (x2) / Linux kernel (x2) / 
  1413.       Midnight Commander (x2)" Online posting. 7, March 1999. 
  1414.       Bugtraq. 
  1415.  
  1416.     9) List of Contributors 
  1417.     ----------------------- 
  1418.  
  1419.       Thamer Al-Herbish <shadows@whitefang.com> 
  1420.  
  1421. "Youth, Nature, and relenting Jove, 
  1422. To keep my lamp _in_ strongly strove,
  1423. But Romanelli was so stout, 
  1424. He beat all three -- _and blew it out_."
  1425.  
  1426. -- George Gordon Byron "My Epitaph" From "Occasional Pieces"
  1427.