Safety program design

zhaozj2021-02-17  48

Safety program design

Overview In the current software industry, too many procedures have security issues, the code is only very few tests before being released, even if some professional testers have fewer testing tests, the reason is lacking. A understanding of security programming technology. This article will try to give programmers a relatively clear concept, secure vulnerability, and avoid security vulnerabilities, making the write security program process relaxed. It is very important to use good programming skills, and even your code is just under the limits and restrictions. Many programmers often transcend their initial design range, and most of the security vulnerabilities appear in the initial programmers don't know or have not been thought. Typically, programmers assume that the current system call never fails, or the program parameters will never be more than a certain length. Thus, the best thing to do is to assume the programs for the problem, carefully analyze whether they are correct, and imaginary conditions can make it fail.

INTERNET development? The host counts 43 million? The netizen number of netizens is 1547 billion? 2001 netizen number 450 million? US netizen number of netizens is 83 million? 2001 US netizens number of 13 billion? American online tax 25 million 38%? AOL users 17 million 42%? WEB server 5 million? Yahoo browsing 2.35 billion times a day, 147%? Online news release 233,89%? Online stock market transaction 336 million 125%? E-commerce business is $ 211 billion 154%

The two most fundamental causes caused by the security vulnerability overflow: the actual length that exceeds the data structure can accommodate during the data stored process can be overflow.

The theoretical basis for generating overflow:

1. Plane memory structure, 4GB or larger logical address space program can be loaded to relatively fixed address space, making it easier to determine the attack code address

2. Data and code are in an address space. The stack can perform code data to store this modern computer model to make the overflow attack truly feasible. Attackers can carefully prepare input data to get the power right.

3. CPU CALL Call Utage Stack Save Return Address CALL Call Use Stack Save Return Address so that the address is possible to return the address.

4. The C function saves local variables in the stack to see the code generated by modern almost all compilers, and find that there are similar code PUSH EBP MOV EBP, ESP SUB ESP, and the compiler in all calls. Support function Nesting calls use stacks to save local variables

5. C Language No Auto Boundary Check Function C Language does not perform data boundary inspections, and cannot be found when the data is covered

6. Stack from a high address to low address growth data storage from low to high, but the stack is high to low growth, and when the number of returns when the Call call subroutine will be pressed into the stack, this means when Call occurs When calling, the program return address will be located at the height of the subroutine data area, making the malicious overlay return address, as long as the input data is carefully arranged, jump to the desired address when the input data is carefully arranged.

A spilled example #include #include

Void Sayhello (Char * Str) {Char Buffer [8]; STRCPY (TmpName, Name); Printf ("Hello% S / N", TMPNAME);

INT main (int Argc, char ** argv) {SayHello (Argv [1]); Return 0;}

run:

$ ./example sunx hello sunx

It seems that everything is normal, there will be no problem. . . . Try again. . .

$. / example sunxsunxsunx hello sunxsunxsunx? ? ? ? ? Segmentation Fault (Core Dumped) When the program is printed, it has collapsed after entering the data. Why is this? The function of this program contains a typical memory buffer encoding error. This function does not perform a boundary check to replicate the string provided, incorrectly use strcpy () without using strncpy (). If you run this program, you will generate a section. Error. The reason is that the data "SUNXSUNXSUNX" in the command line exceeds the local variable length in the Sayello function, so that the return address above the stack is overridden. After print, let's take a look at the stack when the function is called. Swear:

Analysis: Memory layout of the program

Stack Stack Data Section Code Segment 0xfffffffffff

Stack direction 0x00000000

The first time running into the stack behind Sayhello

Stack of the second run into Sayhello

Sununxsunx

What happened here? The answer is simple: strcpy () copies the content of * STR (larger_string []) to buffer [] until an empty character in the string. Obviously, buffer [] ratio * STR small A lot. Buffer [] only 16 bytes long, and we try to fill in 12 bytes in the inside. This means that 4 bytes in the stack are overwritten after the Buffer structure. Include RET address, we already The 12 bytes of buffer points to memory into "sunxsunxsunx", which means that the current return address is 0x786e7573. When the function returns, the program tries to read the next instruction of the return address, and we get a section. Error. Therefore, the buffer overflow allows us to change the return address of the function. So we can change the execution process of the program.

If an attacker carefully prepares data JMP Label2 Label1: POP ESI MOV [ESI 8], ESI XOR EAX, ESI MOV [ESI 7], Al Mov [ESI 12], ESIM AL, 0BH MOV EBX, ESI Lea ECX [ESI 8] Lea Edx, [ESI 12] INT 80H XOR EBX, EBX MOV EAX, EBX INC EAX INT 80H Label2: Call Label1 CMD: DB "/ BIN / SH", 0

The machine code of the above code char shell_code [] = "/ x76 / x08 / x31 / xc0" "/ x88 / x46 / x07 / x89 / x46 / x0c / xb0 / x0b" "/ x89 / XF3 / X8D / X4E / X08 / X8D / X56 / X0C "" / XCD / X80 / X31 / XDB / X89 / XD8 / X40 / XCD "" / XFF / XE8 / XDC / XFF / XFF / XFF / BIN / SH " ;

If you enter this data with the program, you can get a command line shell.

The actual utilization method of overflow vulnerabilities Remote Root Exploit remote, not certified, mainly for the program: various Daemon HTTP, FTP, POP, Sendmail ... Local Root Exploit, use the program's vulnerability to be executed, mainly used To enhance user permissions primarily for programs: all privileges

Those programs have privileges: daemon http, ftp, pop, sendmail ... System Services Some systematic services such as: syslog ... Suid / SgID program Unix a special technology, making ordinary users can also do only superusers to execute task lpasswd , AT, CRO NTAB, PINs above the normal RWX plus the S bit, KERNEL automatically uses the process valid user / subscript to identify the master / group example: ls -l / bin / Eject -rs - x - x 1 root / usr / bin / passwod itself

Solution The more careful programming will isolate security-related functions to a carefully checked code. The non-executable codes will cause several technical problems based on compiler-based methods to automatically increase the boundary check (Very Slow) in the code. Slight Slowdown Rearrange Stack Variables (No Slowdown)

Enter filter About Perl

Perl is one of the main languages ​​of CGI programming, and its security is also very concerned. In the "CGI Scripts" chapter of W3C's "WWW Secur ITY FAQ", Perl security programming accounts for a whole. This shows the importance of Perl CGI security programming. --------------------- 1, NULL characters ---------------------

Developers have become accustomed to work mode of C language If strcmp ("root", "root / x00") == 0, I believe there is no objection. But in Perl "ROOT"! = "R OT / 0" For each security expert or hacker who wants to find CGI vulnerabilities, one of the most common methods is by passing a special character (string), bypass CGI restrictions Perform system-level calls or programs. Read the following example:

# PARSE $ user_INPUT $ database = "$ user_INPUT.DB"; Open (file "<$ database");

This example is used to open the database file specified by the client. For example, the client enters "Haha", the system will open the "Hah A.DB" file test mode). This processing is very common in web applications. Now let's enter "Haha% 00" on the client, $ Database = "Haha / 0.db" in this Perl program, and then call the Open function to open the file. But what is the result? The system will try to open the "haha" file. This is because Perl allows the NULL empty character to be used in the string variable, so there is "root"! = "Root / 0" and characters in the C language The string is based on the NULL character as the end flag of the string, so "root" == "root / 0" (in the C language). Since the Perl itself is written using C, when Perl passes the "backend / 0.db" string to the C run library, the character will be ignored by the character of this programming defect. Imagine if you write a Perl program that modifies other user passwords except root using the above programming principle:

$ user = $ argv [1] # user the jr admin wants to change if ($ user ne "root") {# do wherever needs to be done for this user}, smart, you should know how to bypass this restriction modification Root user password? Yes, as long as $ user = "root / 0", Perl executes the statement in the praggard in the above program. Unless all processing processes use Perl, once the variable is passed to the system, security issues are caused. Modify the root user password, etc. Maybe you think it is difficult to encounter this situation that will cause serious safety issues, then can we use it as an indirect means for finding the website source program vulnerability? ;-) I don't know if you have often encountered this type of CGI program, which is used to open the page of the client (submitted)? Such as:

Page = 1

Then whether the website returns to the page "1.html"? ;-) Good, now change it to:

Page = Page.cgi% 00 (% 00 == '/ 0' escaped)

In this way, we can get the content we are interested in! This method can also bypass the "-e" parameters of Perl:

$ file = "/ etc / passwd / 0.txt.w atver.we.want"; Die ("Hahaha! Caught you!) IF ($ file eq" / etc / passwd "); if (-e $ file) { Open (File, "> $ file");

The consequences of bypass this program You should imagine get it? :) Solution? The simplest, filter NULL empty characters. In the Perl program,

$ INSECURE_DATA = ~ S // 0 //g;

------------------------ 2, backslash (/) ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- --------

The W3C's WWW Security FAQ lists the suggested filtered characters:

&; `'/" │ *? ~ <> ^ () [] {} $ / N / r

But in many times, the backslash (/) is often forgotten. The following is the correct filtration expression:

S / ([/ &; / `'/// │" *? ~ <> ^ / (/) / [/] / {/} / $ / n / r]) /// $ 1 / g;

However, in many commercial CGI programs, the backslash is not included in it, which may be fascinated by the programmer to write the program when it is confused by these filtering expressions? So, do you have a safety problem without filtering the anti-slash? Imagine if it is sent to your program:

User Data `RM-RF /`

In most cases, the programmapped program writes will filter the above content:

User data / `rm -rf //`

This protects the system. But if the Perl program is forgotten, the backslash is filtered, and when the client is submitted to the program:

User Data / `RM-RF / /`

After the matching expression is:

User data // `rm -rf / //`

How, did you see dangerous? Since the two anti-slabs are explained by the system, it is a character "/", but the `characters are therefore not filtered,` rm -rf / / `will be executed by the system! However, because there is also a backslash character, an error is implemented. Do you find a way to bypass this limit? ;-) Another application using a backslash - bypasses the system catalog into restrictions. Please see the following expression: s //././/g;

This matched expression is very simple, it is ".." in the filter string. When the input is:

/usr/tmp/../../etc/passwd

Will be filtered to:

/ usr / tmp /// ETC / passwd

This way, you will not be able to access the / etc / passwd file. (Note: * NIX system Allow ///, try the 'ls -l / etcpasswd' command will know.) Now, let our "good partner" backslash to help. Change the input to:

/usr/tmp/. / ././etc/passwd

The presence of a backslash does not meet the filtration expression. When there is the following block in Perl,

$ FILE = "/ usr / tmp /././.// ETC / passwd"; $ file = s //. // g; system ("ls -l $ file");

When running to the execution system call, the executed command will be "ls -l /usr/tmp/./././etc/ passwd". Want to know what to get? Try it yourself. ;-) However, the above method only applies to system calls or `` commands. Unable to bypass '-e' commands and Open functions in Perl (non-pipeline). The following procedure:

$ file = "/ usr / tmp /./././// etc / passwd"; Open (file, "<$ file") or Die ("No Such file");

"No Such file" will be displayed and exit. I have not yet to find ways to bypass this restriction. ()

Workaround: As long as you don't forget to filter the backslash character (/), it is enough.

-------------------------------- 3, characters "│" ------------ --------------------

In the Open function of Perl, if you add "│" after the file name, Perl will execute this file instead of opening it. which is:

Open (file, "/ bin / ls")

Will open and get the binary code of / bin / ls, but

Open (file, "/ bin / ls│")

Will execute / bin / ls command! Filter expression below

S / (/ │) / / / $ 1 / g

This method can be limited. Perl will prompt "Unexpected End of File". If you find a way around this restriction, please tell me. :-)

Integrated application

Now let us integrate several programmed security vulnerabilities. For example, $ FORM is a variable that the client needs to be submitted to the CGI program. And there is a statement in the CGI program:

Open (File, "$ form")

Then we can pass "LS│" to the $ FORM variable to get the current directory list. Let us now consider the following block:

$ filename = "/ SAFE / DIR / TO / READ / $ FORM" Open (file, $ filename how to execute "ls" command? As long as you can make $ form = "../../../../ bin / ls│" can. If the system is added to the directory operation ".." filtering, it can be bypassed by a loose hole. In this program, we can also add parameters in the command. Such as "Touch / Backend│" will create / backen d files. (But I won't use this file name because it is my name. :-)) Now let us join more security restrictions in the block:

$ filename = "Safe / Dir / to / read / $ form" if (! (- e $ filename)) DIE ("I don't think so!" Open (file, $ filename)

This way we also need to bypass "-e". Since we use the "│" character in the $ FORM variable, when the "-e" operator checks "LS│" file, because this file is not exported. How to remove the duct when "-e" checks, and the OPE N function contains a pipeline? Recalling the use of NULL characters talked earlier, we know how to do it. Just make $ form = "ls / 0│" (Note: "LS% 00│") is "LS% 00│") in the form submitted. The principle of reviewing will understand the content mentioned earlier. It should be noted that in the above block, we cannot perform commands with parameters as appropriate, because the "-e" operator restriction is caused. For example, as follows:

$ filename = "/ bin / ls / etc│" Open (file, $ filename)

The list of files in the / etc directory will be displayed.

$ filename = "/ bin / ls / etc / 0│" IF (! (- E $ filename)) exit; open (file, $ filename)

It will result in exiting due to no files.

$ filename = "/ bin / ls / 0 / etc│" IF (! ((- e $ filename) exit; open (file, $ filename)

Will only display the list of files in the current directory.

About these websites in the ASP put the password into the database, use the following SQL in the login verification, (in ASP) SQL = "Select * from user where usrname = '" & username & "' and pass = '" & pass "" At this point, you can construct a special username and password according to SQL, such as: Ben 'or' 1 '=' 1, you can enter the page you don't have privilege. Let's take a look at the statement above: SQL = "SELECT * From user where username = '"& username" This point, you only need to construct a special username and password according to SQL, such as: Ben' or '1' = '1, the program will It turns this: SQL = "Select * from username where username =" & Ben'or'1 '= 1 & "and pass =" & pass "or is a logical operator, the role is when it is judged, as long as one The condition is established, then the equation will be established. In the language, it is true (established) in 1. So in this line of statement, "And" verification of the original statement will no longer continue, because "1 = 1 "and" OR "to return to true value .. In addition, we can also construct the following usernames: username = 'aa' or 'aa' or pass <> 'aa' About PHP PHP Safety Example: PHP Version 3.0 is an HTML embedded scripting language. Most of its syntax transplants in C, J Ava and Perl and combines PHP characteristics. This language allows web developers to quickly create dynamic web pages.

Because it is executed on the web server and allows the user to execute code, the PHP has built-in security features called 'Safe_Mode',

Used to control the execution command in the Webroot environment that allows PHP operations.

Its implementation mechanism is transmitted to escapeshellcmd () by enforcing system calls that enforce shell commands.

Function, this function is used to confirm that the command cannot be executed outside the Webroot directory.

In some versions of PHP, escapeshellcmd () is invalid when using the popn () command, causing malicious users.

To use the 'Popen' system call to make illegal operations.

-------------------------------------------------- ------------------------------

test program:

Warning: The following procedures (Methods) may have an aggressive, only for security research and teaching. Users are at your own risk!

n"; while ($ line = fgets ($ FP, 1024)): Printf ("% s
N", $ line =; endew; pclose ($ fp); phpinfo ();?>

The output is as follows:

1 Total 53 -RWXR-XR-X 1 root root 52292 Jan 3 22:05 LS Uid = 30 (wwwrun) gid = 65534 (nogroup) Groups = 65534 (NOGROUP) and from the configuration values ​​of phpinfo (): SAFE_MODE 0 1 About Unix Shell Script The same is started by example: #! / Bin / sh read name evrating: $ ./HELLOD SUNX HELLO SUNX Rough seems to have no problem, it is a total of things. / hellod sunx; ls; hello sunx hellod hellod.c

It can be seen that the content in the input content "Sunx; LS" is actually executed may have not serious enough, further assume that if a similar program is put on the Internet $ VI

In /etc/inetd.conf Add: INGRESLOCK STREAM TCP NOWAIT ROOT / TMP / HELLOD HELLOD Normal Running: $ TELNET LOCALHOST 2000 Trying 127.0.0.1 ... Connected to localhost. Escape character is '^]'. Sunx hello sunx connection closed by foreign host.

The invader is maliciously utilized: $ Telnet localhost 2000 TRYING 127.0.0.1 ... Connected to localhost. Escape character is '^]'. What's your name? Sunx; id; hello sunx uid = 0 (root) gid = 0 Root): Command Not Found Connection CLOSED by Foreign Host.

This is why? The reason is ";" This character is characterized in UNIX, a robust program should filter out these special characters' & ','; ',' `',': ',' │ │ ','> ',' <','? ',') ',', ',' {','} ',' ^ ',' ~ 'Security Program The principle of security programming UNIX system provides many children to programmers Programs, these subroutines can access various security properties. Some information subroutines, return file properties, actual and valid UID, GID and other information. Some subroutions can change file properties. UID, GID and other handling password files And group files, there are also some completion of encryption and decryption. This section mainly discusses the security of system programs, standard C library subprograms, how to write secure C procedures and introduce the program design from root (only by root) Program). Common System Subprints (1) I / O Subprints * Creat (): Create a new file or rewrite a temporary file. You need two parameters: file name and access license value (8 envelopes). Such as: Creat ("/ usr / pat / read_write", 0666) / * Establish an access license method 0666 file * / Call this subroutine process must have a write and execution license for the creation of the created file, The licensing mode variable to creat () will create the files modified by Umask () settings, the owner and team of the new file is determined by the valid UID and GID. The return value is a new file descriptor. * Fstat : See Stat (). * Open (): Open file inside the C program. Two parameters are required: file path name and open mode (I, O, I & I &

O). If you call this subroutine does not have the correct access to the file to be opened (including all directory components on the file path), the execution failed. If this subroutine is called to open does not exist File unless the O_CREAT flag is set, the call will not succeed. At this point, 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 file. The access license of the directory does not affect the I / O operation of the file. * Read (): Read information from the file that has been opened and used as input by Open (). It does not care about the access license of the file. Once the file is opened as an input, you can read the information from the file. * Write (): Output information is in a file that has been opened and used as an output. Like read () it does not care about the file. Take a license. (2) Process control * Exec (): including Execl (), Execv (), Execle (), Execve (), Execlp (), Execvp () can copy a executable model to the calling process possession Storage space. Programs that are being called processes will not exist, the new program replaces its location. This is the only way to perform a program in the UNIX system: Cover the original program with the executed program. Secure pay attention Matters:. The actual and effective UID and GID passed to programs that do not have SUID and SGID licenses by Exec (). If there are SUID and SGID licenses, the programs are being licensed if there are SUIDs and SGID licenses, which are valid UID and GID will set it to the owner or group of the program. The file establishing the shield value will be passed to the new program. In addition to the file of the exec () shutdown flag, all open files are passed to the new program. With FCNTL ( The subroutine can set the shutdown flag to Exec (). * For (): It is used to create a new process. The sub-process established is exactly the same copy as the process of calling fork () (except the process number) Safety Precautions: The child process will inherit the actual and effective UID and GID and GID of the Parent process. The child process inherits the file to establish a shield value. All open files pass to the child process. * Signal (): Allow process handling possible Unexpected events and interrupts. Two parameters are required: the subroutines to be called when the signal number and signal occur. The signal number is defined in Signal.h. The subroutine to be called when the signal occurs, can be written by the user, or the value given by the system , As: SIG_IGN signal will be ignored, SIG_DFL signal will be processed by the default method of the system. Such as many security-related programs prohibit end interrupt information (BREAK and DELETE), so as not to be run by the user terminal. Some signals The core dump of the process of generating the UNIX system (the contents of the process are received when the process receives the signal, sometimes containing important information), which can be used to disable the core dump.

(3) Document attribute * Access (): Detect whether the accessibility of the specified file meets the specified access type. Requires two parameters: file name and access type (integer) to be detected. There is also 喔 (19%) │ End ← │ / ↑ / pgup / PGDN Mobile │? Auxiliary Description │ Requires two parameters: File name and access type (integer) to be detected. The access type is defined as follows: 0: Check if the file exists 1: Check if Executable (Search) 2: Check if you can write 3: Check if you can write and execute 4: Check if you can read 5: Check if you readable and execute 6: Check if you can read you can perform these numbers and chmod commands The numeric meaning of the licensing method is the same. This subroutine uses the actual UID and GID detection file access capabilities (generally valid UID and GID to check file access capabilities). Return Value: 0: License-1: no License. * Chmod (): Change the access method of the specified file or directory to a new license method. Requires two parameters: file name and new access method. * Chown (): At the same time change the owner of the specified file And the group's UID and GID. (Different with the chown command). Since this subroutine changes the owner and group of the file, you must cancel the SUID and SGID license of the file to prevent the user from establishing the SUID and SGID programs, then run Chown () gets the permissions of others. * stat (): Returns the status of the file (attribute). Requires two parameters: File path name and a structural pointer, point to the location of status information. The structure is as follows: ST_MODE: File type And access licensing method ST_INO: I node number ST_DEV: ID ST_RDEV: Id ST_NLINK: File Link Number: File Owner's Uid ST_GID: File Group's GID ST_SIZE: File Size ST_AATIME: Last Access Time (Read) ST_MTIME: Last modified time (write) and final state change ST_CTIME: The last state modification time return value: 0: Success 1: Failure * umask (): Will call the process and its sub-process The file establishment shield value is set to the specified access license. Requires a parameter: new file setup screen value. (4) UID and GID processing * getUID (): Return the actual UID of the process. * GetGID (): return process The actual GID. The above two subroutines can be used to determine who is running the process. * GetEuid (): Returns the effective UID of the process. * GetEgID (): Return to the process of effective GID. The above two The subroutine can be used in a program to determine if it is running a user rather than a SuID program that runs its user, which can be called to check that this program is indeed running with the user's SUID. * SETUID : Used to change the effective UID. For the general user, this subroutine is only useful to the SUID program to be converted between the valid and actual UID (from the original valid UID to actual UID) to protect the process is not secure. Hazard. In fact, the process is no longer a SUID mode operation. * Setgid (): Used to change the effective GID.

Standard C Library (1) Standard I / O * FOPEN (): Open a file for reading or writing, security considerations as Open (). * Fread (), getc (), fgetc (), gets (), Scanf () and fscanf (): Read information from the files that have been read from FOPEN (). They don't care about the access license of the file. This is READ (). * fwrite (), PUT (), FPUTC (), PUTS, FPUTS (), Printf (), FPRINTF (): Write information is in files that have been overwritten by fopen (). They don't care about file access licenses. With Write (). * getpass (): From the terminal, you don't return the characters entered by the user. Require a parameter: prompt information. The subroutine will prompt the message to display on the terminal, disable character back function, from / dev / tty read the password, 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 Convenient access to the / etc / passwd file, you can read the file or write new entry item or update. * GetPwUID (): Get the specified UID entry from the / etc / passwd file Item. * GetPwnam (): For the specified login name, in the / etc / passwd file retrieve entry item. The above two subroutions returns a pointer to the Passwd structure, which is defined in /usr/include/pwd.h, define 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. Call getpwent (), open / etc / passwd and return to the pointer to the first entry item in the file, keep the files between the files between files, and then call getpwent () can sequentially Returns the entry items in the password file. Call setPwent () Re-set the pointer of the password file to 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 child The program writes the entry entry into a specified file, which is generally a temporary file, and the direct write password file is very dangerous. It is best to do file blocked before execution, so that the two programs cannot be written at the same time. The algorithm is as follows:. Establish an independent temporary file, ie / etc / passnnn, nnn is the PID number. Establish a new temporary file and standard temporary file / etc / ptmp chain, if there is a chain failure, it is using / etc / ptmp Wait until / etc / ptmp can be used or exit. Copy / etc / passwd to / etc / ptmp, you can make any modifications to this file. Move / etc / passwd to backup file / etc / opasswd.. / etc / ptmp and / etc / passwd chain.. Disconnect / etc / passnnn and / etc / ptmp chain. Note: The temporary file should be built in the / etc directory to ensure that the file is in the same file system, the chain can Success, and temporary files will not be unsafe. In addition, if the new file already exists, even if the chain is the root user, it will fail to ensure that no one can insert internally after the temporary file is successfully built. Of course, programs that use temporary files should ensure that all temporary files are cleared, and the signal is properly captured.

(3) / etc / group processing There is a set of information similar to the previous subroutine handling / etc / group, and must use the INCLUDE/clud./grp.h file to add the /usr/include/grp.h file to its own program. Defining the Group structure will return the Group structure pointer by getGRNAM (), getGRGID (), getGrent (). * GetGRNAM (): Search the specified group name in the / etc / group file, then return to the pointer to the team entry item. * getgrgid (): Similar to the previous subroutine, the different is the specified GID. * getGrent (): Returns the next entry item in the group file. * setGrent (): Restore the file pointer of the group file to the starting point of the file * endgrent (): After completing the work, turn off the Group file. * getUID (): Returns the actual UID of the calling process. * getPruid (): Take the actual UID returned by getUid () as a parameter, determine the corresponding UID Login name, or specify a UID as a parameter. * GetLogin (): Returns the user's pointer to 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, terminal name is used to find users listed in the / etc / utmp file, which is maintained by login, used by the WHO program to confirm the user. * CUSERID (): First call getLogin (), if getLogin () Returns NULL pointer , Then call GetPWUID (GetUID ()). * The following is the command: * logName: Lists the username of the login to the terminal. * Who am i: Show the login name of the user running this command. * ID: Show actual UID and GID (if effective UID and GID and actual different simultaneous display valid UID and GID) and corresponding login names. (4) Encrypted subroutines in January 1977, NBS announced a US federal government ADP system Standard encryption method: Data Encryption Standard, DES, DES, for non-confident applications. Des handle 64BITS block, 56-bit encryption key. * SetKey (), encrypt (): Provide user's access to DES .. Both sonograms take a 64bits long character array, each element in the array represents a bit, 0 or 1.SetKey () setting, will be done by the DES processing, ignore each of the 8th bit constitutes a 56-bit encryption key. .Encrypt () then encrypts or decrypts a given 64BITS long, encrypted or decrypts the second change in the subroutine, 0: Encryption 1: Decryption. * Crypt (): is a password encryption program in the UNIX system, and is also called by the / usr / lib / makekekey command. The Crypt () subroutine is independed, it is related to / usr / lib / makeKey Take 8 characters long keywords, 2 SALT characters. Key words give to setKey (), SALT characters for mixing the DES algorithm in encrypt (), and finally call Encrypt () repeat 25 times to encrypt one of the same strings. 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 At the time of the command, its standard input or output is coupled to the file pointer returned by POPEN (). Both call for (), exec (), POPEN () also calls PIPE (), complete the work, so Fork () And Exec () safety considerations begin to work. Write secure C procedures

There are generally two security issues, you must consider when writing: (1) Make sure that any temporary files established without confidential data, if there is a confidential data, set the temporary file only to read / write yourself. Make sure to establish temporary files The directory is only writable for yourself.

(2) Ensure any commands you want to run (via system (), popen (), execlp (), execvp () running commands that you want to run, not what other orders, especially your own procedures Be careful when licensed for SUID or SGID. The first side is relatively simple, call Umask (077) before the program begins. To make the file read more people, you can again adjust CHMOD (), or use the following language to establish a "Invisible" temporary file. Creat ("/ tmp / xxx", 0); file = open ("/ tmp / xxx", o_rdwr); unlink ("/ tmp / xxx"); file / TMP / XXX established After opening, then disconnect, but the memory assigned 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 be accessed. This temporary file, while other processes cannot access the file because it is deleted by UNLINK () in / TMP. The second aspect is more complicated and subtle, due to system (), POPEN (), Execlp (), When Execvp () is executed, if the full path to execute the command can be "cheated" user program to perform different commands. Because the system subscriber is based on the PATH variable which directory search for specified Command, this is called a Suid trap. The safest way is to change the effective UID to the actual UID before calling System (), and another better method is to use the full path name command as the parameter .Execl (), Execv ( ), execle (), execve () requires full path name as a parameter. Another way to set the SUID trap is set in the program, because system () and POPEN () start SHE LL, so shell syntax can be used SuSTem ("Path = / BIN: / USR / BIN CD"); this allows the user to run the system command without knowing which directory to be executed, but this method cannot be used for EXE CLP (), Execvp () Because they cannot start the shell execute the command string passing by the call sequence. About the shell explanation to the mode line of system () and popen (), there are two other problems:

* Shell uses the characters in the IFS shell variable to break the command line into a word (usually this shell variable is space, Tab, wrap), such as the IFS is /, string / bin / ED is explained into a word bin, next It is a word ED, thereby causing the misinterpretation of the command line.

Again again: Before running another program through his own procedure, the effective UID should change the actual UID. After another program exits, change the effective UID back to the original effective UID.SUID / SGID program Guidance criterion

(1) Do not write a SUID / SGID program, most of the time no need. (2) Set the SGID license, do not set up the SUID license. You should establish a new group alone. (3) Do not use Exec () to perform any programs. Food exec () is also called by System () and POPEN (). To call EXEC () (or system (), POPEN ()), you should use setgid (getGID ()) to set effective GID plus actual GI D If you cannot use setgid (), type IFS: POPEN ("IFS = / T / N; Export IFS; / BIN / LS", "R"); use The full path name of the command to be executed. If the full path name cannot be used, you should set PATH: POPEN before command ("IFS = / t / n; export import; path = / bin: / usr / bin; / BIN / LS "," R ");

Do not pass the parameters specified by the user to System () or POPEN (); if you cannot avoid it, you should check if there is a special shell character in the paragraph string.

If the user has a large program, call EXEC () to perform many other programs, do not set the large program to SGID license. You can write one (or more) smaller, the simpler SGID program must have SGID. Licensed tasks and then execute these small SGID programs by large programs.

(4) If the user must use the SUID instead of SGID, remember (2), (3) content in the same order, and adjust it accordingly. Do not set the ROOT SUID license. Select another household. (5) If the user wants Give others a license to perform your own shell program, but don't want them to read the program, set the program to only permit only, and can only run through your own shell program.

Compile, when installing the SUID / SGID program, you should follow the following methods (1) to ensure that all SUID (SGID) programs are unwritable for groups and other users, and the access rights limit is less than 47 55 (2755) Come trouble. You can only strictly .4111 (2111) will make others unable to find security vulnerabilities in the program. (2) Be wary of external 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 in the Makefile file that may establish a SUID / SGID file. Root program design

There are several subroutines to call from the effective UID 0 process. Many previous subprograms that will be completed and originally different when they are called from the root process. Mainly ignored the check permission. By root The user running the program is of course the root process (except for SUID), because the effective UID is used to determine the access permission of the file, the process of calling fork () generated from the ROOT program, is also the root process. (1) setuid : When calling setUID () from the root process, the processing is different, and setUID () will set the valid and actual UI D to the specified value. This value can be any integer. And the non-root process You can only call setuid (). (2) setgid (): When calling setgid () in the system process, set the setuid (), will actually and effectively GID Both have changed to the value specified by its parameters. * When calling the above two subprograms, you should pay attention to the following:. Call a setUID () (setGID ()) will set the valid and actual UID (GID), independently set effective or The actual U ID (GID) is very good, but it is impossible to do this. SetUID ()) Set the valid and actual UID (GID) to any integer, its value does not have to be sure to / etc / The user (group) in Passwd (/ etc / group) is associated. 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 not delete the SUID and / or SGID license of the file, but when the non-RO OT process runs Chown (), Chown () will cancel the file SUID and / or SGID License. (4) Chroot (): Change the process of the root directory, after calling chroot (), the process cannot change the current work directory to any of the new root directory, all the path search, Starting from the new root directory. (5) MKNOD (): Used to create a file, similar to creat (), difference mknod () does not return the file descriptor of the opened file, and can establish any type of file (ordinary Files, special files, directory files). If you call mknod () from non-root process failure, only the FIFO special file (a famous pipe file) is created, in any case, mknod () must be called from the root process (). Creat () can only establish normal files, mkNod () is the only way to establish a directory file, so there is only RO OT can create a directory, which is why the mkdir command has a SUID license and belongs to all.

MkNod () is generally not called from the program. Usually use the / etc / mknod command to create special device files and these files can generally not build and delete when using the use, and the mkdir command is used to establish a directory. When using mknod () to establish special files It should be noted that you 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 the file. When the directory is specified, unlink () must be called from the root process, which is a unique condition that the unlink () must be called from the root process. This is why the rmdir command has a root SGID license.

(7) Mount (), umount (): Calling by the root process, which is used to install and disassemble the file system. These two subroutions are also called by the Mo Unt and Umount commands, and their parameters are basically the same as the parameters of the command. Call Mount ), Need to give a special file and a 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> Still only read <1> .umount () parameters is a pointer to a special file to be disassembled. System Design

Regardless of the programming language, program use, and what technique written, the following rules can help you determine if the program is bug-free.

1. Minimal permissions. Preparation and use least enough permissions to complete the task, ask yourself, "Software * must * What permissions?", Not "What permissions needed". 2. Structural economy. Short, simple code generated bug is certainly less than a small and complex, and implements the system as possible. 3. Fully detection. Check all the ways to access objects, all calls return the code, and the variable value of the keypoint. 4. Open design. Do not use a concealed approach to ensure safety 5. Privilege. Different times in different programs or functions only give the most needed permissions. 6. The minimum common mechanism should be given to the user. 7. Psychological acceptability. Safety control must be easily used, otherwise it is easy to use the user to do not use security characteristics. 8. Default error protection. Default rejection, and error shutdown 9. Code reuse. Use the previously tested code 10. Do not trust unknown. All information obtained from users, or from the outside program can be suspected . 11. Precursive prediction before the problem. Determines what security issues that may occur before you start writing the program.

Secure Programming Method 1. Check all command line parameters 2. Check all system call parameters and return code 3. Check environment parameters, do not rely on UNIX environment variables 4. Determine all caches have been checked 5. In the content of variables Copy the variables to border check 6. If you create a new file, use the O_EXCL and the O_CREATE flag to determine that the file does not have existing 7. Use lstat () to determine that the file is not a symbolic connection 8. Use the following file calls : fgets (), STRNCPY (), STRNCAT (), snprintf () instead of other similar functions, can be said to use only functions of the length. 9. The same, careful use of Execve () if you must derive One process 10. Explicitly changed the directory (chDIR ()) to the appropriate place 11. Restrict the Core file generated when the program fails, there may be password and other memory status information. 12. If Use temporary files to consider using the system call TMPFile () or mkTemp () to create them (although many mkTemp () libraries can have RACE CONDition) 13. There are code 14 for integrity checks, do a lot of log records. , Including date, time, uid, and effective uid, gid, and effe ctive gid, terminal information, pid, command line parameters, errors, and hostnames 15. Make the core as small as possible 16. Always use full path names Parameter 17. Check the user's input to ensure that only "good" characters 18. Using good tools such as Lint 19. Understand Race Conditions, including deadlock status and sequential state 20. Set Timeouts and load levels in the program of network read requests Restrictions. 21. Place Timeouts 22 in the network write request 22. Use session encryption to avoid session robbery and hidden verification information 23. Use chroot () setup program environment 24. If possible, static connection security programs 25. When needed Presentation using DNS Reverse Interpretation 26. Disperse and restrict excessive load in the network service program 27. Place appropriate Timeout restrictions on the network read and write 28. If appropriate, prevent the service program from run more than more than one copy is not safe Programming method 1. Prevent functions that do not check the Buffer boundary when processing strings, such as gets (), struffpy (), strcat (), sprintf (), fscanf (), scanf (), vSprintf (), Realp Ath (), getopt (), get Pass (), streadd (), stread (), and stratrns () 2. Avoid using Execlp () and Execvp () 3. Never use system () and popen () system calls 4. Do not create files In all people writable directory 5. Usually, do not set the SETUID or SETGID's shell scripts 6. Do not want the port number code, you should use the getServbyName () function 7. Do not assume that the connection from the small number port number is legal and trustworthy 8. Do not believe any IP address, if you want to verify, use a password algorithm 9. Do not use the clear text method to verify that the information is not commonly used to recover from a serious error, then the details are output and then interrupt L 1 Consider using Perl -t or TaintperL SetUID's Perl program

Test Program Security 1. Use Cracker's method to do software test: 2. Try all cache overflows in the program 3. Try to use any command line option 4. Try to establish possible Race Condition 5. Designers do code Review and Test 6. Read all the code, like Cracker thinking to find a vulnerability

转载请注明原文地址:https://www.9cbs.com/read-28607.html

New Post(0)