CGI (Perl) Vulnerabilities and Preventive Measures

Source: Internet
Author: User
Tags perl script

CGI (Perl) Vulnerabilities and preventive measures (1)

In general, programming language itself is not the main cause of security risks. In fact, the overall security of software is still largely dependent on the knowledge, understanding and security awareness of software manufacturers.

In this section, we will introduce some of the most commonly misused and neglected properties in Perl, as well as the threats to system and data security after these attributes are misused, it also explains how to discover and discover these risks to make changes.

1. vulnerabilities in user input

One of the security issues in the Perl script is that the script that submits information does not confirm the information entered by the user at runtime, resulting in a threat to the server. Every time a Perl program obtains input information from an untrusted user, even if it uses a non-direct method, it still threatens system security. When writing CGI scripts using Perl, developers should consider that malicious users may enter malicious information. If they do not confirm the information, they will recognize and use it, it is likely to cause many system errors. Currently, the most common and obvious error is that the system may execute other programs defined in user submission information without confirmation.

2. syetem () and exec () Functions

Perl is known for its ability to be used as a "cohesive" language-it can do a great job in the following ways: when calling other programs to work for it, collect the output of a program, reformat it into a specific way, and then pass it to other programs and coordinate the operation of other programs, so that each program can run better.

As the Perl publisher tells us: there are more than one way to do the same thing.

One way to execute an external program and a system command is to call the exec () function. When Perl encounters an exec () statement, it will examine the parameters at which exec () is called, and then start a new process to execute this specific command. Perl never returns Control
To the original process that calls exec.

Another similar function is system (). The running mode of system () is very similar to exec (), the only big difference between them is that Perl first splits a child process from the parent process, and the child process serves as a parameter provided to system, the parent process waits until the child process finishes running.
Then run the rest of the program. We will discuss system () calls in more detail below, but most of these discussions also apply
In exec ().

The parameter passed to system () is a list. The first element in the list is the program name of the program to be executed. Other elements are the parameters passed to the program. However, if there is only one parameter, the execution method of system () varies. In this case, Perl will scan this parameter to see if it contains any shell Conversion characters. If so, it will explain these characters through shell, and generate a shell command line to work. Otherwise, Perl splits the string into words and then calls the more efficient C-database function execvp (), which cannot understand special shell characters.

Now let's assume that we have a CGI form that asks for the user name and then displays a file containing the user statistics. We can use system () to call a and use "c t" to achieve that requirement as follows:

System ("cat/usr/stats/$ username ");
 

The user name comes from a form like this:

$ Username = param ("username ");
 

For example, after the user adds username = jdimov to the form, Perl does not find any conversion character creation in the string "cat/usr/stats/jdimov, therefore, it calls the execvp () function to run "cat" and return it to our script. This script may seem to have no potential risks, but it is easily exploited by a malicious attacker.

The problem is that by using special characters in the form's "username" field, an attacker can execute any command through shell. For example, if an attacker passes such a string "jdimov; cat/etc/passwd", Perl treats the semicolon as a conversion character and passes it to shell, the result is as follows:

Cat/usr/stats/jdi/mov; cat etc/passwd
 

We mentioned earlier that system () has a parameter table, and regards the first element as a command for execution, while other elements are passed as parameters. So We Can slightly change the script so that the program we want to execute can be executed:

System ("cat", "/usr/stats/$ username ");

If attackers want to destroy the file, they only need to send "; rm rf/*". In this way, attackers can obtain both the source file and the password file. However, since we specify program parameters separately, shell will never be called. Therefore, sending "; rm-rf/*" will not work, because the Attack String will only be interpreted as a file name.

This method is much better than the version of a single parameter because it avoids using shell commands but still has potential defects. In special circumstances, we need to consider whether the value of $ username will be exploited by attackers. For example, an attacker can use our rewritten code to set $ username to the string "../etc/passwd" to obtain the system password file.

Sometimes, some applications interpret special character sequences as requests for executing a shell command, which may cause errors in many places. A common problem is that for some versions of Unix mail tools, "~!…" is found in a certain context. A shell command will be executed when the character sequence is such as "~! Rm-rf * "user input will cause problems.
CGI (Perl) Vulnerabilities and preventive measures (2)

3. Open () function

In Perl, the open () function is used to open files. The most common usage of this function is as follows:

Open (FILEHANDLE, "filename ");


In the preceding statement, the file "filename" is opened in read-only mode. If "filename" is the prefix containing ">", it is opened for the output, and if the file already exists, it will overwrite the original file; if the prefix ">" is included, it is opened for the append. If the prefix "<" is used to open the file for input operations, this is the default method when the prefix is not included. When unconfirmed user input is used as part of the file name, the problem is always obvious. For example, you can still use this method by looking back at the directory.

In addition, there are other issues worth worrying about. Now we use open () to replace "cat" to modify our script file. The command is as follows:

Open (STATFILE, "/usr/stats/$ username ");


Then we read the code from the file and display it. The Perl document tells us that if the file name starts with "-|", the file name will be interpreted as an output pipeline command; otherwise, if the file name ends with "|-", the file name will be interpreted as the pipeline for output.

Therefore, you can run any command in the/usr/stats directory by adding a "|" prefix. The back-tracing directory operation allows users to execute any program in this system.

There is a way to solve this problem: for the file you want to open and enter in it, it is always indicated by adding the "<" mark.

Sometimes we do need to call an external program. For example, we want to modify a script file so that the script file can read the old plain text file/usr/stats/username, however, you must use an HTML filter before displaying it to users. We have a convenient way to implement this intention right away. The method is as follows:

Open (html, "/usr/bin/txt2html/usr/stats/$ username |"); print while;
Unfortunately, this still needs to pass through the shell layer. However, we can use another form of calling open () to avoid shell involvement: The method is as follows: open (HTML, "-| ") or exec ("/usr/bin/txt2html", "/usr/stats/$ username"); print while;


When we open a pipeline command, or to read ("-|") or write ("|-"), Perl generates a branch in the current process, and return the child process PID to the parent process, and return 0 to the child process. The "or" statement is used to determine whether we are in the parent process or in the child process. If we are in the parent process (the returned value is non-zero), we will continue to execute the print () statement. If we are in the child process, we will execute the txt2html program and use exec () containing more than one parameter () to avoid passing any command to the shell layer. The child process promises the STDOUT output produced by txt2html, and then silently disappears (remember: exec () never returns), and the parent process reads the result from STDIN. This technique can be used to import results to an external program through pipelines. The corresponding code is as follows:

Open (PROGRAM, "|-") or exec ("/usr/bin/progname", "$ userinput"); print PROGRAM, "This is piped to/usr/bin/progname ";
 
When pipelines are required, the preceding open () function should always be used preferentially than the open () command of the pipeline because they do not pass through the shell layer. Now we want to convert static text into HTML pages. For convenience, we need to store the converted HTML files in the same directory as the Perl scripts that display these pages. The open () statement format may be as follows:
Open (STATFILE, "<your username.html ");
 
For example, when a user passes through the table and transmits username1_jdimo, the script displays jdimov.html, which may still be attacked. Unlike C ++ and C, Perl does not end the string with NULL bytes. In this case, the jdimov/lo/bah string is interpreted as "jdimo" in the calls to a vast number of C libraries ", but in Perl, it is "jdimovblah ". When Perl passes a string containing null characters to a C language program, this problem becomes more prominent. What happens when you use the following method to call the script?
Statscrit. plusername = jdimov/% 00


This program will pass the string "jdimov/%. html "to the corresponding system call to open it, but because those system calls use C language programs, accept the Null Byte string method, the result is like this, if there is a file "jdimov", the file will be displayed. What happens if I use "statscript./pusername = statscript. p/%" to call the script? If the script and HTML file are in the same directory, you can use the input data to fool the script to display all the content. In this case, there may be no major security risks, but it can be used by other programs because it allows attackers to analyze the sources of other usable defects.

4. Single quotes

In Perl, another way to read the output of an external program is to put the command in single quotes. So if we want to save the content of our stats file in a hierarchical $ stats file, we can do this:

$ Stats = 'cat/user/stats/$ username ';
This is indeed implemented through the shell layer. Any script that contains user input in a pair of single quotes poses a risk to all the security issues discussed earlier. There are many ways to try to make shell do not misunderstand all possible conversion characters, but the safest thing is not to use but quotation marks. Instead, open

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.