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



Section 07



CGI, Perl, Scripts, etc.



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



07-1. What is CGI?



CGI stands for Common Gateway Interface. It is a way for users to 

submit requests and have the server perform some function, typically

a function that is native to the operating system, to either send a

more "dynamic" response to the user, or to gather information about

the user. For example, the user fills out a survey form and mails it

in, or requests information on a part number and the server looks up

the price from a database before sending the user the HTML page.



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



07-2. Are there default vulnerabilities?



Yes and no. There are "default" vulnerabilities that exist in several

example files, as mentioned in Section 02, but there aren't any real

default vulnerabilities for the most part. What you have are default

bad programming habits that can be taken advantage of.



The bad habits usually involve not properly parsing user-supplied

information. This is why some of the stuff in Section 02 works, I've

just stated a few examples there. You could get REAL psychotic about

this stuff. Besides just grabbing the passwd file, you could try:



	- Get any file that is readable from the UID of httpd.

	- Kick off several "finds" that eat server CPU.

	- Spawn a high port and telnet in.



If the target site for some stupid reason has put PERL.EXE in say,

/cgi-bin/ (I've seen this on some NT servers before),you should buy 

that book on Perl ;-). You can send entire Perl scripts for PERL.EXE

to execute including all of the above mentioned items.



One vulnerability that I haven't mentioned is looking for files in

/cgi-bin/ with a ~ on the end. If the administrator was editing

change-your-password.pl with a package like emacs in the /cgi-bin/,

there might be a change-your-password.pl~ backup file that the editor

has created. You may be able to find holes in this code if you can

read it, instead of simply guessing.



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



07-3. How do I spot code with holes?



If you can get ahold of actual Perl code, you can check to see if

things are being parsed. Let's say you grab finger.pl~ from the /cgi-bin/ 

directory the way stated at the end of 07-2. Let's say you see the 

following line (example is for a Unix server):



#!/usr/local/bin/perl  <--- The first line says we're using Perl, duh

.

.

.

print `finger $account_to_finger`;



Okay so we can finger an account. The Web page allows you to type in

a user name and finger them to see if they are online. In that 

example supplying nobody;echo "toor::0:0::/:/bin/sh">>/etc/passwd as a 

user name might yield some interesting results, especially if the httpd is

running under root. Why does this work? Because in Perl the command in ` `

is run from a spawned shell.



Now what does code look like that is "safe"? Well, first look for Perl

running tainted. This means that Perl will assume all user input is

tainted and could spread to other parts of the system. Taint checks are

similiar to these examples:



#!/usr/local/bin/perl -T  <--- Perl v5 invoking taint checks

.

.

.

# untaint the address

$user_to_finger=~/([\w-.]+\@[\w-.]+)/;

$untainted_user = $1;

# path hardcoded

$ENV('path') = '/usr/bin;/usr/local/bin:/bin';

# still paranoid let's hardcode the path to finger

system("/usr/local/bin/finger $untainted_user");



Obviously someone is taking more precautions here.



How about more examples of bad code? Well, here's a common example, a 

simple text file "database" that can be grepped against to return data:



	system("grep $variable database_file"); or

	sprintf(tmp, "grep %s database_file", variable); system(tmp);



Now what happens if you supply "0:0 /etc/passwd;id" as the variable? You'd

get root or root equivalent lines from /etc/passwd, and you'd see which id

the httpd process is running under. Of course if it looks like this, a

shell is never invoked (note the -e in quotes):



	system("grep", "-e", $variable, "database_file");



If you see this, your failed intrusion attempt will simply end up in a log

file somewhere. 



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



07-4. Why are buffers so important?



Let's look at some code first discussed in Section 02. Note the following:



/* code snippet in C, although you can do the same type thing in Perl */

sprintf(buffer, "/usr/lib/sendmail -t %s < %s", foo_address, input_file);

system(buffer);



Now let's assume that somewhere at the start of the code is this statement:



char buffer[60];



What will happen if you overflow that buffer? I guess it would depend on

the operating system and whether you were running your httpd daemon as

root or nobody. 



Well, Mr. Admin, you say that no one looks at your source code except 

existing personnel? Okay, that's fair, and for the sake of argument we

will assume that those contractors you hired and you drove like dogs to

finish their code are uncorruptable angels ;-), so what about vendor

code? What about sample code? What about freeware?



Serious intruders will review the code of common shareware and freeware

utilties and look for these types of details. Knowing the OS, it's 

revision, and that a piece of code whose buffer could be overrun an 

intruder can simply duplicate the environment as best as possible and then 

start writing their own code until a crack is found.



---------------------------------------------------------------------------