./c0de/php/vulnscanner.txt

0.
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
164.
165.
166.
167.
168.
169.
170.
171.
172.
173.
174.
175.
176.
177.
178.
179.
180.
181.
182.
183.
184.
185.
186.
187.
188.
189.
190.
191.
192.
193.
194.
195.
196.
197.
198.
199.
200.
201.
202.
203.
204.
205.
206.
207.
208.
209.
210.
211.
212.
213.
214.
215.
216.
217.
218.
219.
220.
221.
222.
223.
224.
225.
226.
227.
228.
229.
230.
231.
232.
233.
234.
235.
236.
237.
238.
239.
240.
241.
242.
243.
244.
245.
246.
247.
248.
249.
250.
251.
252.
253.
254.
255.
256.
257.
258.
259.
260.
261.
262.
263.
264.
265.
266.
267.
268.
269.
270.
271.
272.
273.
274.
275.
276.
277.
278.
279.
280.
281.
282.
283.
284.
285.
286.
287.
288.
289.
290.
291.
292.
293.
294.
295.
296.
297.
298.
299.
300.
301.
302.
303.
304.
305.
306.
307.
308.
309.
310.
311.
312.
313.
314.
315.
316.
317.
318.
319.
320.
321.
322.
323.
324.
325.
326.
327.
328.
329.
330.
331.
332.
333.
334.
335.
336.
337.
338.
339.
340.
341.
342.
343.
344.
345.
346.
347.
348.
349.
350.
351.
352.
353.
354.
355.
356.
357.
358.
359.
360.
361.
362.
363.
364.
365.
366.
367.
368.
369.
370.
371.
372.
373.
374.
375.
376.
377.
378.
379.
380.
381.
382.
383.
384.
385.
386.
387.
388.
389.
390.
391.
392.
393.
394.
395.
396.
397.
398.
399.
400.
401.
402.
403.
404.
405.
406.
407.
408.
409.
410.
411.
412.
413.
414.
415.
416.
417.
418.
419.
420.
421.
422.
423.
424.
425.
426.
427.
428.
429.
430.
431.
432.
433.
434.
435.
436.
437.
438.
439.
440.
441.
442.
443.
444.
445.
446.
447.
448.
449.
450.
451.
452.
453.
454.
455.
456.
457.
458.
459.
460.
461.
462.
463.
464.
465.
466.
467.
468.
469.
470.
471.
472.
473.
474.
475.
476.
477.
478.
479.
480.
481.
#!/usr/bin/php -q 
<?php
 
/**
 *     Php Vulnerability Scanner by KingOfSka @ http://www.contropoterecrew.org
 *    still very early release, just for testing and coding purpose :)
 *    
 *    Changelog:
 *    
 *    12/09/06    Version 0.1 : First "working" version, should work on "almost" site, report any bug to help me :)
 *    25/09/06        0.2 : Better crawling, less bandwith/resource usage, speed improved, better vuln finding code
 *
**/
 
print_r('
-------------------------------------------------------------------------------
Php Vulnerability Scanner by KingOfska @ http://contropotere.netsons.org
    kingofska [at] gmail [dot] com
-------------------------------------------------------------------------------
');
 
if ($argc < 2) {
print_r('
Early release, please send bug report to help improving this script
--------------------------------------------------------------------------------
Usage: '.$argv[0].' host [start_path][port][debug]
host:      target server (ip/hostname)
path:      path from which to start scanning, if none entered starts from \'/\'
port:       port of the http server, default 80
 
Examples:
'.$argv[0].' localhost /folder/script.php 81
 
--------------------------------------------------------------------------------
');
die;
}
$host= $argv[1];  // Insert the host site i.e. : www.website.com
$start_page = $argv[2];     // Insert the start page for the scan, if empty will start from index.*
$port = 80 ;
$additional_vars = array('id','page');
$locator = array("123'",'\'\';!--"<XSS>=&{()}','some_inexisistent_file_to_include.php');  //XSS Locator from ha.ckers.org
 
$debug = TRUE;
/**    Compatibility for php < 5
 *    stripos() function made by rchillet at hotmail dot com
 *
 */
if (!function_exists("stripos")) {
  function stripos($str,$needle,$offset=0)
  {
     return strpos(strtolower($str),strtolower($needle),$offset);
  }
}
/**
 *    Do not edit below unless you know what you do...
 */
$reqmade = 0 ;
$time_start = getmicrotime();
set_time_limit(0);
error_reporting(E_ERROR);
$checkedpages[]='';
$result[] = '';
$links[] = '';
$checkedlinks[] = '' ;
echo "Starting scan on $host:\r\nStarting page: $start_page\r\n";
$site_links = index_site();
$count = count($site_links);
echo "Starting to scan $count pages...\r\n";
 
foreach($site_links as $cur){
 
echo "Testing: $cur \r\n";
test_page($cur);
 
}
 
$time_end = getmicrotime();
$result['time'] = substr($time_end - $time_start,0,4);
$result['connections'] = $reqmade;
$result['scanned'] = count($checkedpages);
 
echo "Report:";
 
foreach ($result['vuln'] as $type=> $url){
echo "\r\n$type vulnerability found:\r\n";
$url = array_unique($url);
foreach($url as $cur){
echo "$cur \r\n";
}
}
$server = get_server_info();
echo "\r\nAdditional infos:\r\n";
echo "Site running on: ".$server['software']."\r\n";
echo "Powered by: ".$server['powered']."\r\n";
echo "Scan took ".$result['time']." seconds to scan ".$result['scanned']." pages using ".$result['connections']." connections\r\n";
 
 
 
function index_site(){
global $start_page;
array($links);
$tmp = get_links($start_page,true);
    foreach($tmp as $cur){
    $tmp2 = get_links($cur,true);
    $links = array_merge_recursive($links,$tmp2);
    }
$links = array_unique(clean_array($links));
$links[] = $start_page;
sort($links);
return($links);
}
 
 
/**
 * Testes a form using global vuln locator, both GET and POST method, and print result to screen
 * @author KingOfSka <[email protected]>
 * @param array $form Form to test
 * @return void
*/
 
function test_form($form){
$ret = '';
$tmp = '';
global $host,$port,$locator,$debug,$result ;
if($form['action'][0] != '/' AND stripos($form['action'],'http://') === FALSE ){$form['action'] = '/'.$form['action'];}
if ($form['method'] = 'get'){
foreach($form['vars'] as $current){
        foreach($locator as $testing){
        $testing = urlencode($testing);
        $conn =  fsockopen ("$host", $port, $errno, $errstr, 30);
            if (!$conn) {
                echo "$errstr ($errno)<br>\n";
            } else {
                if (!stripos('?',$data['action'])){
                $req = "GET ".$form['action']."?$current=$testing HTTP/1.0\r\nHost: $host\r\nConnection: Close\r\n\r\n";
                }else{
                $req=  "GET ".$form['action']."&$current=$testing HTTP/1.0\r\nHost: $host\r\nConnection: Close\r\n\r\n";
                }
                if ($debug == TRUE){echo $req;}
                fputs ($conn, $req);
                while (!feof($conn)) {
                $tmp .= fgets ($conn,128);
 
                }
            fclose ($conn);
 
                do_test($tmp,$form['action'],$current);
 
                $tmp = '';
            }
        }
    }
 
}else if ($form['method'] = 'post'){
 
foreach($form['vars'] as $current){
        foreach($locator as $testing){
        $testing = urlencode($testing);
        $conn =  fsockopen ("$host", $port, $errno, $errstr, 30);
            if (!$conn) {
                echo "$errstr ($errno)\r\n";
            } else {
                $req="POST ".$form['action']." HTTP/1.0\r\nHost: $host\r\nContent-Type: application/x-www-form-urlencoded\r\nConnection: Close\r\nContent-Length: ".strlen($postit)."\r\n\r\n$postit\r\n\r\n";
                $postit = "$current=$testing" ;
                if ($debug == TRUE){echo $req;}
                fputs ($conn, $req);
                while (!feof($conn)) {
                $tmp .= fgets ($conn,128);
                }
            fclose ($conn);
 
                do_test($tmp,$form['action'],"POST: $current");
                $tmp = '';
            }
        }
    }
 
 
}
 
 
}
/**
* Catches and Parses HTML forms 
* @author KingOfSka <[email protected]>
* @param string $page   Page to scan for forms
* @return Array
**/
 
function catch_forms($page){
array($form);
$data = get($page);
preg_match_all('#<form .+?>.+?</form>#is',$data['content'],$matches);
foreach ($matches[0] as $data['content']){
preg_match('#<form (.+?)>(.+?)</form>#is',$data['content'],$matches);
$form['setup'] = $matches[1];
$form['content'] = $matches[2];
preg_match('#method\s?=\s?["\']?(get|post)["\']?#i',$form['setup'],$matches);
if (isset($matches[1])){
    $form['method'] = $matches[1];
    }else{ 
    $form['method'] = 'get';
}
preg_match('#action\s?=\s?["\']?([^"\']*)["\']?#i',$form['setup'],$matches);
$form['action'] = $matches[1];
preg_match_all('#<input (.*)>#i',$form['content'],$input);
foreach($input[0] as $cur){
preg_match('#name\s?=\s?["\']?(\w*)["\']?#i',$cur,$matches);
$form['vars'][] = $matches[1];
}
print_r($form);
test_form($form);
}
}
 
function get_server_info(){
global $site_links;
array($server);
foreach($site_links as $link){
if(stripos($link,'.php')){ 
$right = $link;
break;
}
}
$data = get($right);
preg_match('#Server:\s?(\w.*)#',$data['headers'],$matches);
$server['software'] = $matches[1];
preg_match('#X-Powered-By:\s?(\w.*)#',$data['headers'],$matches);
if (isset($matches[1])){
$server['powered'] = $matches[1];
}
return $server;
}
 
function test_page($page){
global $checkedpages;
 
 
if (in_array($page,$checkedpages)){
return;
}
 
 
catch_forms($page);
$plinks = get_links($page,true);
foreach ($plins as $cur){
    test_link($cur);
}
$checkedpages[] = $page ;
 
}
 
    /**
     * Perform a simple GET request,returning an array containing 
     * server-sent headers and content
     *
     * @author KingOfSka <[email protected]>
     * @param string $path Path to the resource to request
     * @param string $cookie Cookie string to pass along with the request (still to implement....)
     * @return Array
     **/
 
    function get($path = '/',$cookie = ''){
        global $host,$port,$debug,$reqmade,$checkedlinks;
 
        array($ret);
        $tmp = '';
        $conn =  fsockopen ("$host", $port, $errno, $errstr, 30);
        $reqmade++;
 
        if($path[0] != '/' AND stripos($path,'http://') === FALSE){$path = '/'.$path;}
            if (!$conn) {
                echo "$errstr ($errno)<br>\n";
            } else {
                if ($debug == TRUE){echo "GET $path HTTP/1.0\r\nHost: $host\r\n\r\n";}
                fputs ($conn, "GET $path HTTP/1.0\r\nHost: $host\r\nConnection: Close\r\n\r\n");
                while (!feof($conn)) {
                $tmp .= fgets ($conn,128);
                }
            fclose ($conn);
            }
 
//echo $tmp;
        preg_match('#HTTP\/1\.\d (\d\d\d)#',$tmp,$matches);
 
        if ($matches[1]!= 200){
            $ret = "HTTP Error Code N°".$matches['1'];
            if ($debug == TRUE){echo "Debug:\r\n$tmp<br/>\r\n";}
        }
        if ($matches[1]== 302 OR $matches[1] == 301){
            preg_match('#Location:(.*)#',$tmp,$matches);
            if (!in_array($matches[1],$checkedlinks)){
 
            return get($matches[1]);
            }
        }        
        $b = preg_split('#Content-Type: text/html#',$tmp);
 
        $ret['headers'] = $b[0];
        $ret['content'] = $b[1];
        if ($debug == TRUE){echo "Debug:\r\n".$ret['headers']."\r\n";}
    return $ret;
    }
 
    /**
     * Catches all the links in a webpage, checking they are not pointing to
     * files external at the host being scanned.
     *
     * @author KingOfSka <[email protected]>
     * @return Array
     **/
 
    function get_links($data,$getpage = FALSE){
    global $host,$links;
        if ($getpage == TRUE){
        $tmp = get($data);
        $data = $tmp['content'];    
        }
 
        preg_match_all('#<a href=[\'"].+?[\'"].+?>#i',$data,$matches);
 
        foreach ($matches[0] as $current){
 
 
                preg_match('#<a href=["\'](.+?)["\'].+?>#i',$current,$matches);
 
                $current = $matches[1];
                if (is_valid_url($current)){
                if (stripos($current,$host) != FALSE OR stripos($current,'http://') === FALSE ){
 
                if ($current[0] == '?'){
                $current= 'index.php'.$current;
 
                }
 
                if (stripos($current,$host) === FALSE OR stripos($current,'http://') === FALSE){
 
                $current = "http://$host/$current";
 
                }
                if (!in_array($current,$links)){
                $retlinks[] = $current ;
                }
                }
            }
        }
    return array_unique($retlinks) ;
    }
 
    /**
     * Parse a link returning an array with the name of the file which 
     * the link is pointing to, and the GET variables passed trhough it.
     *
     * @author KingOfSka <[email protected]>
     * @return Array
     * @param string $link Link to parse
     **/
 
    function parse_link($link){
        array($ret);
 
 
        $matches = explode('?',$link);
        $ret['action'] = $matches[0] ;
        $matches = explode('&',$matches[1]);
            foreach($matches as $cur){
            $matches = explode('=',$cur);
            $vars[] = $matches[0];
            }
 
        $ret['vars'] = $vars;
 
        return $ret;
    }
/**
 * Tests a given link echoing found vulnerabilities
 *
 * @author KingOfSka <[email protected]>
 * @return void
 * @param $link Link to test
**/
 
function test_link($link){
global $host,$port,$locator,$result;
 
$ret = '';
$tmp = '';
$data = parse_link($link);
//$data['vars'] = array_merge($data['vars'],$additional_vars);
    foreach($data['vars'] as $current){
        foreach($locator as $testing){
        $testing = urlencode($testing);
        $conn =  fsockopen ("$host", $port, $errno, $errstr, 30);
            if (!$conn) {
                echo "$errstr ($errno)\r\n";
            } else {
                if (!stripos('?',$data['action'])){
                $req = "GET ".$data['action']."?$current=$testing HTTP/1.0\r\nHost: $host\r\nConnection: Close\r\n\r\n";
                }else{
                $req=  "GET ".$data['action']."&$current=$testing HTTP/1.0\r\nHost: $host\r\nConnection: Close\r\n\r\n";
                }
                fputs ($conn, $req);
 
                while (!feof($conn)) {
                $tmp .= fgets ($conn,128);
 
                }
 
            fclose ($conn);
                do_test($tmp,$data['action'],$current);
 
                $tmp ='';
            }
        }
    }
return;
}
 
/**
 * Removes empty item from a given array
 * 
 * @return Array
 * @param $array array to clean
**/
 
function clean_array($array) {
   foreach ($array as $index => $value) {
       if(is_array($array[$index])) $array[$index] = clean_array($array[$index]);
       if (empty($value) OR !is_valid_url($value)) unset($array[$index]);
       }
   return $array;
}
 
function getmicrotime(){
   list($usec, $sec) = explode(" ",microtime());
   return ((float)$usec + (float)$sec);
   }
 
function clean_url_array($array){
    foreach ($array as $cur){
    echo $cur;
        if(!is_valid_url($cur)) unset ($array[$cur]);    
    }
return $array;
}
 
function is_valid_url($url){
 
if (!eregi("^(http|https)+(:\/\/)+[a-z0-9_-]+\.+[a-z0-9_-]",$url)){
 
return FALSE;
}else{
return TRUE;
}
}
 
function do_test($data,$path,$var){
global $result;
if (stripos($data,'\'\';!--"<XSS>=') OR stripos($data,"\'\';--\"<XSS>=") OR stripos($data,'<XSS>')){
 
                $result['vuln']['xss'][]=$path."?$var=[XSS]";
            }
 
 
if (stripos($data,'You have an error in your SQL syntax')){
                $result['vuln']['sql'][]=$path."?$var=[SQL]";
 
    }
 
 
 
if (stripos($data,'Failed opening \'some_inexisistent_file_to_include.php\' for inclusion')){
    $result['vuln']['rfi'][]=$path."?$var=[RFI]";
}
 
 
return;
}
 
?>

Back