UNIX system programming common library function description
UNIX systems provide a number of subroutines for programmers, which can access various security properties. Some information subroutines, return file properties, actual and valid UID, GID, etc. Some subroutions can change file properties Some of .uid, GID, etc. have some password files and group files, and some completion of encryption and decryption. This article mainly discusses the security of system programs, standard C library subroutines, how to write secure C procedures and introduce program design from root (The subroutine that can only be called). 1. System subroutine (1) I / O subroutine * Creat (): Create a new file or rewrite a temporary file. Requires two parameters: File name and access The license value (8 enclosure). Such as: Creat ("/ usr / pat / read_write", 0666) / * Establish an access license method 0666 file * / Call this subroutine process must have a file The write and execution of the directory, the licensing mode of the Creat () will be modified by the files set by Umask () settings, the owner and team of the new file is determined by the valid UID and GID. Return value is new File descriptor. * Fstat (): See Stat (). * Open (): Open file inside the C program. Two parameters: File path name and open mode (i, o, i & o). If calling The process of this subroutine does not have the execution failure for the correct access to the file to open (including all directory components on the file path), will cause the execution to fail. If this subroutine is called to open the unsaved file, unless set The O_CREAT flag will be unsuccessful. At this time, the access license of the new file is the third parameter (can be modified by the user's umask). When the file is turned on, change the file or the directory where the file is located. The license does not affect the I / O operation of the file. * Read (): Read information from the file that has been opened and used by Open (). It doesn't care about the access license of the file. Once the file is opened as input You can read information from this file. * Write (): Output information is in a file that has been opened and used as an output. Like read () which does not care about the file's access license.
(4) UID and GID processing * getUID (): Return the actual UID of the process. * GetGID (): Returns the actual GID of the process. The above two subroutions can be used to determine who is running the process. * GetEuid (): return process Effective UID. * GetGID (): Returns the effective GID of the process. The above two subroutions can be used in a program to determine if it is useful when running a user rather than the SuID program that runs its user, you can adjust them to check Confirmation This program is indeed running in the user's SUID. * Setuid (): Used to change the effective UID. For the general user, this subroutine is only useful to transform the SUID program to be converted between valid and actual UIDs. (From the original valid UID transform to actual UID), the protection process is not safe hazard. In fact, the process is no longer SUID mode. * Setgid (): Used to change the effective GID.2. Standard C library (1) Standard I / O * FOPEN (): Open a file for reading or writing, safety considerations as Open (). * Fread (), getc (), fgetc (), gets (), scanf () and fscanf ( : Read information from files that have been opened by FOpen (). They don't care about the file access license. This is the same as read (). * Fwrite (), put (), fputc (), puts, FPUTS (), Printf (), FPRINTF (): Write information to files that have been overwritten by fopen (). They don't care about the file access license. With Write (). * getpass (): from the terminal Read to more than 8 characters long passwords, do not return the characters entered by the user. Requires a parameter: prompt information. The subroutine displays the prompt information on the terminal, disabling the character backup function, read the password from / dev / tty. Then restore the character backup function, return the pointer to the password that just knocked into the password. * POPEN (): Introduction to the shell in (5). (2) / etc / passwd Processing has a set of subroutines to / etc / passwd Convenient access, you can read the file or write new entry item or update. * GetPwUID (): Get the entry item entry of the specified UID from the / etc / passwd file. * GetPwnam () : For the specified login name, in the / etc / passwd file search entry item. The above two subroutions returns a pointer to the Passwd structure, which is defined in /usr/include/pwd.h, defined as follows: struct passwd {char * pw_name; / * Login name * / char * pw_passwd; / * Encrypted password * / uid_t pw_uid ; / * UID * / GID_T PW_GID; / * GID * / CHAR * PW_AGE; / * Agent information * / char * pw_comment; / * Note * / char * pw_gecos; char * pw_dir; / * main directory * / char * pw_shell ; / * Use shell * /};
* getpwent (), setpwent (), endpwent (): Subsequent processing for password files. First call getPwent (), open / etc / passwd and return the pointer to the first entry item in the file, keep the file between the call Open status. Then call getPwent () can sequentially return the entry items in the password file. Call setPwent () Re-set the pointer of the password file as the beginning of the file. Use the full port file to call EndPwent () Close password file. * Putpwent (): Modify or add the entry item in the / etc / passwd file. This subroutine writes the entry entry into a specified file, which is generally a temporary file, and the direct write password file is very dangerous. Best Before performing a file blockade, make two programs can't write a file at the same time. The algorithm is as follows:. Establish a separate temporary file, ie / etc / passnnn, nnn is the PID number .. Establish a new temporary file and standard temporary file / ETC / PTMP chain, if the chain failed, someone is using / etc / ptmp, waiting until / etc / ptmp available or exits .. Copy / etc / passwd to / etc / ptmp, you can do this file Any modification .. Move / etc / passwd to backup file / etc / opasswd .. Create / etc / ptmp and / etc / passwd chain .. Disconnect / etc / passnnn and / etc / ptmp chain. Note: Temporary The file should be built in the / etc directory, in order to ensure that the file is in the same file system, the chain can be successful, and the temporary file will not be unsafe. In addition, if the new file already exists, even the chain is the root user, will also fail, This ensures that no one can insert internally, once the temporary file is successfully built. Of course, the program with temporary files should ensure that all temporary files are cleared, and the signal is correctly captured. (3) / etc / group processing has a set Similar to the previous subroutine processing / etc / group information, you must use the INCLUDE/grp.h file to add the /usr/include/grp.h file to your own program when using the file. This file defines the GROUP structure and will be made by getGRNAM (), getGrgid. (), getGrent () returns the Group structure pointer. * getGRNAM (): Search in the / etc / group file search specified group name, then return to the pointer to the group entry item. * getGRGID (): Similar to the previous subroutine, Different are the specified GID. * GetGrent (): Returns the next entry entry in the Group file. * SetGrent (): Restore the file pointer of the group file to the starting point of the file. * Endgrent (): used to complete the work After the work, close the group file. * GetUid (): Returns the actual UID of the calling process. * GetPruid (): The actual UID returned by getUId () is the parameter, determines the login name corresponding to the actual UID, or specify a UID as a parameter * getLogin (): Returns the pointer of the user logged in on the terminal. The system checks stdin, stdout, stderr is associated with the terminal, and the standard input associated with the terminal is used to determine the terminal name, the terminal name is used to find it. / etc / uTMP file, the file is maintained by login, by the WHO program to confirm the user. * CUSERID (): First call getLogin (), if getLogin () returns a Null pointer, then call GetPwuid (GetUID ()) * The following is the command: * logname: Lists the username of the login to the terminal. * WHO AM i: Shows the login name of the user running this command. * ID: Display the actual UID and GID (if effective UID and GID and actual differently display valid UID and GIDs) and corresponding login names.
(4) Encrypted subroutine In January 1977, NBS announced a standard encryption method for networks for the US federal government ADP system: Data encryption standards, DES, used for non-confident applications. Destead handle 64BITS block, 56-bit Encrypted key. * SetKey (): Encrypt (): Provides user access to DES. This two subroutine takes a 64bits long character array. Each element in the array represents a bit, 0 or 1.SetKey () Set the encryption key that will be processed by the DES, ignore each of the 8th bits, a 56-bit encryption key .Encrypt () then encrypts or decrypts a given 64BITS long, encrypted or decrypts the second change depending on the subroutine Yuan, 0: Encryption 1: Decryption. * Crypt (): is a password encryption program in the UNIX system, and is also called by the / usr / lib / makekey command .crypt () subroutine is independed, it is related to / usr / lib / makeKey Take 8 character's keywords, 2 SALT characters. Key words give to setKey (), SALT characters for mixing the des algorithm in encrypt (), and finally call Encrypt () repeated 25 times of encryption String. Returns the encrypted string pointer. (5) Run the shell * system (): Run / bin / SH execute the command specified by its parameter, return when the command is completed. * POPEN (): Similar to System () Different is the command runtime, its standard input or output is coupled to the file pointer returned by POPEN (). Both call for (), exec (), POPEN () also calls PIPE (), completing its respective work, Thus, fork () and Exec () safety considerations begin to work. 3. Write secure C procedures generally have two security issues, must consider when writing: (1) Ensure that any temporary files established are not With confidential data, if there is a confidential data, set the temporary file to read / write yourself. Make sure the directory that establishes the temporary file is only writable to yourself. (2) Make sure you want to run any command (via system (), POPEN ), execlp (), execvp () running commands Indexer to the command you want to run, not what other commands, especially when your program is SuID or SGID license. First aspect is relatively simple, starting in the program UMASK (077). To make the file read more people, you can adjust CHMOD () or create a "invisible" temporary file. CREAT ("/ tmp / xxx", 0 ); file = open ("/ tmp / xxx", o_rdwr); unlink ("/ tmp / xxx"); file / TMP / XXX is created, open, then disconnect, but division The memory that is given to the file is not deleted until the file channel that ultimately points to the file is turned off. Open the file and any child process can access this temporary file, and other processes cannot access Document, because it is deleted by unlink () in / tmp. The second aspect is more complicated and subtle, due to system (), POPEN (), execlp (), execvp () is executed, if not The full path of the command can "lie" users' programs to perform different commands. Because the system subscriber is based on the Path variable which directory search for specified commands, this is called SUID traps. Space The way is to change the valid UID to the actual UID before calling system (), and another better method is to use the full path name command as a parameter .Execl (), execv (), exec (), execve () requires The full path name is a parameter. Another way to the SUID trap is set in the program, because system () and popen () start the shell, so shell syntax can be used. Such as: system ("path = / bin: / USR / BIN CD ");
This allows the user to run system commands without knowing which directory to be executed, but this method cannot be used in Execlp (), Execvp (), because they cannot start the command string of calling sequence passed. About Shell Interpret the way to pass to system () and popen () command line, there are two other questions: * Shell uses the characters in the IFS shell variable, break down the command line into words (usually this shell variable is space, Tab, Renewal), such as /, string / bin / ED is interpreted as a word bin, which is the word Ed, causing the misinterpretation of the command line. Retraunction: Before running another program through his own procedure, Change the valid UID to the actual UID, wait for another program to exit, then change the effective UID back to the original valid Uid.suid / SGID program Guidance Guidelines (1) Do not write a SUID / SGID program, most of which is necessary. (2) Set up the SGID license, do not set up a SUID license. You should establish a new group alone. (3) Do not perform any programs with EXEC (). Remember that EXEC () is also called by system () and popen () .. To call EXEC () (or system (), POPEN ()), you should use setgid in advance (getGID ()) to set the actual GID. If you can't use setgid (), type system () or POPEN () When you should set IFS: POPEN ("IFS = / T / N; Export IFS; / BIN / LS", "R") ;. Use the full path name of the command to be executed .. If you can't use a full path name, Path: POPEN should be set before command ("IFS = / t / n; export IFS; path = / bin: / usr / bin; / bin / ls", "r"); do not pass the parameters specified by the user Give system () or POPEN (); if you cannot avoid it, you should check if there is a special shell character in the variable chart string. If the user has a large program, call EXEC () to perform many other programs, do not The large program is set to SGID license. You can write a smaller, a simpler SGID program execution must have a task licensed by the SGID, and then execute these small SGID programs by large programs. (4) If the user must use SUID Not SGID, remember (2), (3) content in the same order, and adjust it accordingly. Do not set up the ROOT SUID license. Choose a other account. (5) If the user wants to give other people to execute their own shell programs License, but don't want them to read the program, set the program to only permit only, and can only run through its own shell program.
Compile, install the SUID / SGID program, you should press below (1) to ensure that all SUID (SGID) programs are unbearable for groups and other users, and the access rights limit is below 4755 (2755) will bring Trouble. Only more stringent. 4111 (2111) will make others unable to find security vulnerabilities in the program. (2) Be wary of foreign coding and make / install methods. Some Make / Install methods do not select SUID / SGID Program .. Check the encoding of SuiD / SGID licenses that violate the above guidelines .. Check commands that may establish a Suid / SGID file in the Makefile file. 4.Root program has several subrouties to call from the effective UID 0 . Many previous subprograms that will be completed and originally different from the ROOT process. Mainly ignored the check permission. The procedure running by the root user is of course the root process (except for SUID), The effective UID is used to determine the access permission of the file, so from the process of calling fork () from a process, it is also a root process. (1) SetUID (): When calling setuid () from the root process, Different, setuid () will set effective and actual UIDs to specified values. This value can be any integer. And the non-root process can only be variables with actual UID or this process. The value is called setuid (). (2) setgid (): When calling setGID () in the system process, the actual and valid GID changes to the value specified by its parameter. * Call the above two subroutines At the time, you should pay attention to the following:. Calls a setUID () (setgid ()) will set the valid and actual UID (GID), independently set effective or actual UID (GID) is very good, but you can't do this .. setUID () (setGID ()) Sets the valid and actual UID (GID) to any integer, and its value does not have to be associated with the / etc / passwd (/ etc / group) user (group) .. Once the program is setUID () in a user's UID (), the program is no longer running as root, or it is impossible to get ROOT privileges. (3) Chown (): When the root process runs chown (), chown () will SUID and / or SGID licenses for files are not deleted, but when the non-root process runs chown (), Chown () will cancel the SUID and / or SGID license of the file. (4) chroot (): Change the process of the root directory After calling chroot (), the process cannot change the current work directory to the new root directory. All directories, all path search in / start, start from the new root directory. (5) MKNOD (): Used to create a file, similar to creat (), difference mknod () does not return the files opened Document descriptor, and can establish any type of file (normal file, special file, directory file). If you call mknod () from a non-root process failure, only the FIFO special file (a famous pipe file) exception, other In case, MkNod () must be called from the root process. Since Creat () can only establish a normal file, mkNod () is the only way to establish a directory file, so that only root can establish a directory, this is why the mkdir command has Suid license All of ROOT. MakNod () is generally not called in the program. Usually use the / etc / mknod command to create special device files and these files can generally not create and delete when using, and the mkdir command is used to create a directory. When using mknod () When establishing special documents, you should pay attention to the confirms of the special files that are not allowed to access memory, disks, terminals, and other devices. (6) unlink (): Used to delete files. The parameter is to delete the path name pointer to delete the file. When you specify a directory, you must call unlink from the root process (), which is a unique condition that you must call unlink () from the root process, which is why the rmdir command has root's SGID license. (7) mount (), umount : The root process is called, which is used to install and disassemble the file system. These two subroutions are also called by the mount and umount commands, the parameters are basically the same as the parameters of the command. Call mount (), need to give a special file and one The directory pointer, the file system on the special file will be installed in this directory, and give a logo option when calling, specifying the installed file system to be read / write (0) or read only (1) .umount () Parameters are a pointer to a special file to be disassembled. This article is compiled or original by ISBase member.