~ Essays ~
         to essays    essays
(Courtesy of fravia's advanced searching lores)

(¯`·.¸ a php network security scanner ¸.·´¯)
by Devergranne
published at fravia's searchlores in May 2000

Included at the bottom: [DQ open comments to Devergranne]

Here you will find a php network security scanner. Actually 2
files are  included :
- [scan.php3]: a very
simple port scanner.
- [cgi-scan.php3]: a
cgi scanner (111 checks)
I might write some more soon but for now I don't have more time to spend on it :-(

Why a php scanner ?

Many free web hosting companies are proposing a php support for your web pages.
While you can forget about cgi's for security reasons, many trust php to be a
more secure language. In fact it is not.
And we are not even talking about variables here.
Firstly because it allows you to scan networks while the source of the scan
appears to be the the person hosting the script. Secondly because by chaining
proxies the person using the script might remain anonymous.
And finally because poorly configured hosts might alloud a local port scan while
denying remote scans.
3 reasons to write a php network scanner.
Both scripts are very simple, they were just made quickly to demonstrate a new
problem.
The port scanner goes in 5 lines code that is:
for($port = $from; $port <= $to; $port++)
{
$fp = fsockopen("$host", $port);
if ($fp)
{
print("port $port opened \r");
fclose($fp);
}

Obviously you can't scan more than 40 000 ports at the time (time limitations).
The cgi scanner checks only for a file and if it gets a "200 OK" it will tell
you what file was found.
It's simple but it works.
Devergranne

"a php network security scanner"

by Devergranne


scan.php3
<FORM ACTION="<?PHP echo($PHP_SELF); ?>" METHOD="post">
Host to scan
<INPUT TYPE="text" NAME="host" SIZE="30" MAXLENGTH="100" value="127.0.0.1"> <br>
Number of ports to scan <br>

from :<INPUT TYPE="text" NAME="from" SIZE="8" MAXLENGTH="100">
to :<INPUT TYPE="text" NAME="to" SIZE="8" MAXLENGTH="100">

<INPUT TYPE=submit VALUE="Find out">
</FORM>

<?PHP


/*
*  Php network security scanners
*
* (c) 2000 by: Devergranne thi颡ut
*
* View Example @  http://persoweb.francenet.fr/~tbilger/linux/
*
* Permission to use and modify this software and its 
* documentation for any purpose other than its incorporation 
* into a commercial product is hereby granted without fee, 
* as long as the author is notified that this piece of software 
* is being used in other applications. 
* Permission to copy and distribute this software and its 
* documentation only for non-commercial use is also granted 
* without fee, provided, however, that the above copyright 
* notice appear in all copies, that both that copyright notice 
* and this permission notice appear in supporting documentation. 
* The author makes no representations about the suitability 
* of this software for any purpose.  It is provided ''as is'', 
* without express or implied warranty. 
*
* I'm not responsable for the use you make of those files.
* Do not abuse.
*/

function zob()
{
$count = 0;
$toobad = 0;
}

for($port = $from; $port <= $to; $port++)
{
$fp = fsockopen("$host", $port);
if ($fp) 
{
print("<b>port $port opened </b><br>\r");
$count++;
$toobad++;
fclose($fp);
}
else { $count++; }
}
if ($count > 1){
print("<br>number of scanned port: $count <br>");
print ("number of open ports: ");
if ($toobad < 1){ print ("0"); }
elseif ($toobad != 0) {
print ("$toobad <br>");
}

}
?>


cgi-scan.php3
<?PHP


/*
*  Php network security scanners
*
* (c) 2000 by: Devergranne thi颡ut
*
* View Example @  http://persoweb.francenet.fr/~tbilger/linux/
*
* Permission to use and modify this software and its 
* documentation for any purpose other than its incorporation 
* into a commercial product is hereby granted without fee, 
* as long as the author is notified that this piece of software 
* is being used in other applications. 
* Permission to copy and distribute this software and its 
* documentation only for non-commercial use is also granted 
* without fee, provided, however, that the above copyright 
* notice appear in all copies, that both that copyright notice 
* and this permission notice appear in supporting documentation. 
* The author makes no representations about the suitability 
* of this software for any purpose.  It is provided ''as is'', 
* without express or implied warranty. 
*
* I'm not responsable for the use you make of those files.
* Do not abuse.
*/

$cginame[] = "AnyForm2";
$cginame[] = "AT-admin.cgi";
$cginame[] = "AT-generate.cgi";
$cginame[] = "architext_query.pl";
$cginame[] = "anyform.cgi";
$cginame[] = "aglimpse";
$cginame[] = "ax-admin.cgi";
$cginame[] = "axs.cgi";
$cginame[] = "bb-hist.sh";
$cginame[] = "bnbform";
$cginame[] = "bnbform.cgi";
$cginame[] = "campas";
$cginame[] = "carbo";
$cginame[] = "cachemgr.cgi";
$cginame[] = "classified.cgi";
$cginame[] = "classifieds";
$cginame[] = "Count.cgi";
$cginame[] = "count.cgi";
$cginame[] = "dfire.cgi";
$cginame[] = "download.cgi";
$cginame[] = "dumpenv.pl";
$cginame[] = "environ.cgi";
$cginame[] = "finger.pl";
$cginame[] = "finger.cgi";
$cginame[] = "finger";
$cginame[] = "flexform";
$cginame[] = "flexform.cgi";
$cginame[] = "file.pl";
$cginame[] = "filemail.pl";
$cginame[] = "faxsurvey.cgi";
$cginame[] = "formail";
$cginame[] = "guestbook";
$cginame[] = "glimpse";
$cginame[] = "handler";
$cginame[] = ".htaccess";
$cginame[] = "htmlscript";
$cginame[] = "hello.bat";
$cginame[] = "info2www";
$cginame[] = "imagemap.exe";
$cginame[] = "jj";
$cginame[] = "loadpage.cgi";
$cginame[] = "LWGate";
$cginame[] = "lwgate";
$cginame[] = "LWGate.cgi";
$cginame[] = "lwgate.cgi";
$cginame[] = "man.sh";
$cginame[] = "maillist.pl";
$cginame[] = "nph-test.cgi";
$cginame[] = "nph-publish";
$cginame[] = "nph-test-cgi";
$cginame[] = "nlog-smb.pl";
$cginame[] = "pfdispaly.cgi";
$cginame[] = "perl.exe";
$cginame[] = "perlshop.cgi";
$cginame[] = "php";
$cginame[] = "php.cgi";
$cginame[] = "phf";
$cginame[] = "plusmail";
$cginame[] = "ppdscgi.exe";
$cginame[] = "printenv";
$cginame[] = "responder.cgi";
$cginame[] = "rwwwshell.pl";
$cginame[] = "s97.cgi";
$cginame[] = "search97.vts";
$cginame[] = "survey.cgi";
$cginame[] = "survey";
$cginame[] = "test-cgi";
$cginame[] = "textcounter.pl";
$cginame[] = "uploader.cgi";
$cginame[] = "view-source";
$cginame[] = "visadmin.exe";
$cginame[] = "webdist.cgi";
$cginame[] = "webgais";
$cginame[] = "websendmail";
$cginame[] = "webbbs.cgi";
$cginame[] = "webmap.cgi";
$cginame[] = "wwwacl";
$cginame[] = "../wwwboard/wwwboard.pl";
$cginame[] = "ws_ftp.ini";
$cginame[] = "w3-sql";
$cginame[] = "www-sql";
$cginame[] = "whois_raw.cgi";

// other specials

$cginame[] = "../~root/";
$cginame[] = "../_vti_pvt/users.pwd";
$cginame[] = "../_vti_pvt/administrators.pwd";
$cginame[] = "../_vti_pvt/service.pwd";
$cginame[] = "../_vti_pvt/authors.pwd";
$cginame[] = "../_vti_bin/shtml.dll";
$cginame[] = "../_vti_bin/shtml.exe";


$cginame[] = "../scripts/issadmin/bdir.htr";
$cginame[] = "../scripts/CGImail.exe";
$cginame[] = "../scripts/tools/newdsn.exe";
$cginame[] = "../scripts/fpcount.exe";
$cginame[] = "../scripts/counter.exe";

$cginame[] = "../?PageServices";
$cginame[] = "perl?-v";

// let's check for a shell

$cginame[] = "ash";
$cginame[] = "bash";
$cginame[] = "csh";
$cginame[] = "ksh";
$cginame[] = "sh";
$cginame[] = "tcsh";


$cginame[] = "..//etc/passwd";
$cginame[] = "../../../../../../etc/passwd";

$cginame[] = "../webcart/orders/";
$cginame[] = "../webcart/orders/carts/.txt";
$cginame[] = "../webcart/config/";
$cginame[] = "../webcart/carts/";
$cginame[] = "../webcart/config/clients.txt";
$cginame[] = "../webcart-lite/config/clients.txt";
$cginame[] = "../webcart-lite/orders/import.txt";


$cginumber = count($cginame);


if ($host) {

 for ($count = 0 ; $count < $cginumber ; $count++) {
  $fp = fsockopen($host, 80);
        if(!$fp){ echo "Could not open connection \n"; }
          
    else {
    fputs($fp,"GET  $path$cginame[$count] HTTP/1.0\n\n");

         while(!feof($fp))
         {

            $nom=fgets($fp,200);
         
            if (ereg("200 OK",$nom))
            {
             print("<b>Found something here: $cginame[$count] </b><br>\n");
             break;
            }

                                         // else > break;
             else
            {
             print("not found $cginame[$count] <br> \n");
             break;
            }
        }

  fclose($fp);

      }

 }    
}

?>

<FORM ACTION="<?PHP echo($PHP_SELF); ?>" METHOD="post">

HOST <INPUT TYPE="text" NAME="host" SIZE="10" MAXLENGTH="100" value="localhost">
<br>
Here's the path : <INPUT TYPE="text" NAME="path" SIZE="10" MAXLENGTH="100"
value="/cgi-bin/">

<INPUT TYPE=submit VALUE="Find out"><INPUT TYPE=reset VALUE="Reset">
</FORM>

Devergranne, May 2000
DQ's comments

Devergranne, I had a look at your essay "a php network security scanner" and like to make some comments. You can hit me afterwards ;-)

Let's first start with cgi-scan.php3. That's a nice CGI scanner, but I would strongly advise anyone against using it!

Is that code copyrighted by yourself? Are you the author or did you just do a rewrite, taking sources out of the web and translating them into PHP? There's something called CGIcheck99, which is coded in REBOL and written by deepquest.

Anyway, before running that CGI scanner, please have a look at the excellent specifications for Whisker , done by rain forest puppy.

As a general advice to those who just want to start with this stuff: Please be aware of the inner workings of the servers you want to attack. Study them, learn the configuration options, know about booby-traps, and please stop scanning for the phf vulnerability!

Now regarding scan.php3. Please resolve the host name to an IP before starting your loop through your XXXX ports, that way you contribute to reduce internet pollution. Relevant functions are:
string gethostbyname(string hostname);
array gethostbynamel(string hostname);

Second point: Do you really want to scan all those ports? What are you going to do once you found an open port? Why don't you just create an array with those ports you really care about?
For example, if you want to scan for available services, include 21, 23, 25, 80, 110, etc.
If you want to check for proxy access, include 80, 81, 3128, 8080, 8081, etc.
If you want to check for SubSeven and other backdoors, include only those relevant ports.

Just scanning from zero to who knows what glorious 5 digit number just wastes your patience, increases your phone bill and does nothing useful.

A quick patch would be to reduce the default timeout of ten seconds to 3 in the fsockopen() line as follows:
$fp = fsockopen("$host", $port, &$errno, &$errstr, 3);

Nevertheless, you have a point when demonstrating this new security problem. Perhaps this activates the awareness of people regarding PHP.
DQ, May 2000



Petit image

(c) 2000: [fravia+], all rights reserved