function testDirectObjectRefs($arrayOfURLs, $testId)
{
    connectToDb($db);
    updateStatus($db, "Testing all URLs for Insecure Direct Object References...", $testId);
    $log = new Logger();
    $log->lfile('logs/eventlogs');
    $log->lwrite("Identifying which URLs have parameters");
    $log->lwrite("All URLs found during crawl:");
    $urlsWithParameters = array();
    foreach ($arrayOfURLs as $currentUrl) {
        $log->lwrite($currentUrl);
        if (strpos($currentUrl, "?")) {
            array_push($urlsWithParameters, $currentUrl);
        }
    }
    $log->lwrite("URLs with parameters:");
    foreach ($urlsWithParameters as $currentUrl) {
        $log->lwrite($currentUrl);
    }
    $log->lwrite("Testing each URL that has parameters");
    foreach ($urlsWithParameters as $currentUrl) {
        $parsedUrl = parse_url($currentUrl);
        if ($parsedUrl) {
            $query = $parsedUrl['query'];
            $parameters = array();
            parse_str($query, $parameters);
            foreach ($parameters as $para) {
                if (preg_match('/\\.([^\\.]+)$/', $para)) {
                    //Check if this vulnerability has already been found and added to DB. If it hasn't, add it to DB.
                    $tableName = 'test' . $testId;
                    $query = "SELECT * FROM test_results WHERE test_id = {$testId} AND type = 'idor' AND method = 'get' AND url = '{$currentUrl}' AND attack_str = '{$para}'";
                    $result = $db->query($query);
                    if (!$result) {
                        $log->lwrite("Could not execute query {$query}");
                    } else {
                        $log->lwrite("Successfully executed query {$query}");
                        $numRows = $result->num_rows;
                        if ($numRows == 0) {
                            $log->lwrite("Number of rows is {$numRows} for query: {$query}");
                            insertTestResult($db, $testId, 'idor', 'get', $currentUrl, $para);
                        }
                    }
                }
            }
        } else {
            $log->lwrite("Could not parse malformed URL: {$currentUrl}");
        }
    }
}
function testAuthenticationSQLi($urlToCheck, $urlOfSite, $testId)
{
    connectToDb($db);
    updateStatus($db, "Testing {$urlToCheck} for Broken Authentication using SQL Injection...", $testId);
    $log = new Logger();
    $log->lfile('logs/eventlogs');
    $log->lwrite("Starting Broken Authentication SQLi test function on {$urlToCheck}");
    $postUrl = $urlToCheck;
    $postUrlPath = parse_url($postUrl, PHP_URL_PATH);
    //Check URL is not responding with 5xx codes
    $log->lwrite("Checking what response code is received from {$urlToCheck}");
    $http = new http_class();
    $http->timeout = 0;
    $http->data_timeout = 0;
    //$http->debug=1;
    $http->user_agent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)";
    $http->follow_redirect = 1;
    $http->redirection_limit = 5;
    $http->setTestId($testId);
    $error = $http->GetRequestArguments($urlToCheck, $arguments);
    $error = $http->Open($arguments);
    $log->lwrite("URL to be requested is: {$urlToCheck}");
    if ($error == "") {
        $log->lwrite("Sending HTTP request to {$urlToCheck}");
        $error = $http->SendRequest($arguments);
        if ($error == "") {
            $headers = array();
            $error = $http->ReadReplyHeaders($headers);
            if ($error == "") {
                $responseCode = $http->response_status;
                //This is a string
                $log->lwrite("Received response code: {$responseCode}");
                if (intval($responseCode) >= 500 && intval($responseCode) < 600) {
                    $log->lwrite("Response code: {$responseCode} received from: {$urlToCheck}");
                    return;
                }
            }
        }
        $http->Close();
    }
    if (strlen($error)) {
        echo "<H2 align=\"center\">Error: ", $error, "</H2>\n";
        $log->lwrite("Error: {$error}");
    }
    $html = file_get_html($postUrl, $testId);
    if (empty($html)) {
        //This can happen due to file_get_contents returning a 500 code. Then the parser won't parse it
        updateStatus($db, "Problem getting contents from {$urlToCheck}...", $testId);
        $log->lwrite("Problem getting contents from {$urlToCheck}");
        return;
    }
    //Array containing all form objects found
    $arrayOfForms = array();
    //Array containing all input fields
    $arrayOfInputFields = array();
    $log->lwrite("Searching {$postUrl} for forms");
    $formNum = 1;
    //Must use an integer to identify form as forms could have same names and ids
    foreach ($html->find('form') as $form) {
        isset($form->attr['id']) ? $formId = htmlspecialchars($form->attr['id']) : ($formId = '');
        isset($form->attr['name']) ? $formName = htmlspecialchars($form->attr['name']) : ($formName = '');
        isset($form->attr['method']) ? $formMethod = htmlspecialchars($form->attr['method']) : ($formMethod = 'get');
        isset($form->attr['action']) ? $formAction = htmlspecialchars($form->attr['action']) : ($formAction = '');
        $formMethod = strtolower($formMethod);
        //If the action of the form is empty, set the action equal to everything
        //after the URL that the user entered
        if (empty($formAction)) {
            $strLengthUrl = strlen($urlToCheck);
            $strLengthSite = strlen($urlOfSite);
            $firstIndexOfSlash = strpos($urlToCheck, '/', $strLengthSite - 1);
            $formAction = substr($urlToCheck, $firstIndexOfSlash + 1, $strLengthUrl);
        }
        $log->lwrite("Found form on {$postUrl}: {$formId} {$formName} {$formMethod} {$formAction} {$formNum}");
        $newForm = new Form($formId, $formName, $formMethod, $formAction, $formNum);
        array_push($arrayOfForms, $newForm);
        foreach ($form->find('input') as $input) {
            isset($input->attr['id']) ? $inputId = htmlspecialchars($input->attr['id']) : ($inputId = '');
            isset($input->attr['name']) ? $inputName = htmlspecialchars($input->attr['name']) : ($inputName = '');
            isset($input->attr['value']) ? $inputValue = htmlspecialchars($input->attr['value']) : ($inputValue = '');
            isset($input->attr['type']) ? $inputType = htmlspecialchars($input->attr['type']) : ($inputType = '');
            $log->lwrite("Found input field on {$postUrl}: {$inputId} {$inputName} {$formId} {$formName} {$inputValue} {$inputType} {$formNum}");
            $inputField = new InputField($inputId, $inputName, $formId, $formName, $inputValue, $inputType, $formNum);
            array_push($arrayOfInputFields, $inputField);
        }
        $formNum++;
    }
    //At this stage, we should have captured all forms and their input fields into the appropriate arrays
    //Begin testing each of the forms
    //Defintion of all payloads used and warnings to examine for
    //Payloads can be added to this
    $arrayOfPayloads = array("1'or'1'='1", "1'or'1'='1';#");
    //Check if the URL passed into this function displays the same webpage at different intervals
    //If it does then attempt to login and if this URL displays a different page, the vulnerability is present
    //e.g. a login page would always look different when you are and are not logged in
    $log->lwrite("Checking if {$urlToCheck} displays the same page at different intervals");
    $responseBodies = array();
    $http = new http_class();
    $http->timeout = 0;
    $http->data_timeout = 0;
    //$http->debug=1;
    $http->user_agent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)";
    $http->follow_redirect = 1;
    $http->redirection_limit = 5;
    $http->setTestId($testId);
    for ($a = 0; $a < 3; $a++) {
        $error = $http->GetRequestArguments($urlToCheck, $arguments);
        $error = $http->Open($arguments);
        if ($error == "") {
            $number = $a + 1;
            $log->lwrite("Sending HTTP request number {$number} to {$urlToCheck}");
            $error = $http->SendRequest($arguments);
            if ($error == "") {
                $headers = array();
                $error = $http->ReadReplyHeaders($headers);
                if ($error == "") {
                    $error = $http->ReadWholeReplyBody($body);
                    if (strlen($error) == 0) {
                        array_push($responseBodies, $body);
                    }
                }
            }
            $http->Close();
        }
        if (strlen($error)) {
            echo "<H2 align=\"center\">Error: a= {$a} ", $error, "</H2>\n";
        }
    }
    $pageChanges = true;
    $bodyOfUrl = "";
    if ($responseBodies[0] == $responseBodies[1] && $responseBodies[1] == $responseBodies[2]) {
        $bodyOfUrl = $responseBodies[0];
        $pageChanges = false;
    }
    $log->lwrite('Beginning testing of forms');
    for ($i = 0; $i < sizeof($arrayOfForms); $i++) {
        $currentForm = $arrayOfForms[$i];
        $currentFormId = $currentForm->getId();
        $currentFormName = $currentForm->getName();
        $currentFormMethod = $currentForm->getMethod();
        $currentFormAction = $currentForm->getAction();
        $currentFormNum = $currentForm->getFormNum();
        $arrayOfCurrentFormsInputs = array();
        $log->lwrite("Beginning testing of form on {$postUrl}: {$currentFormId} {$currentFormName} {$currentFormMethod} {$currentFormAction}");
        for ($j = 0; $j < sizeof($arrayOfInputFields); $j++) {
            $currentInput = $arrayOfInputFields[$j];
            $currentInputIdOfForm = $currentInput->getIdOfForm();
            $currentInputNameOfForm = $currentInput->getNameOfForm();
            $currentInputFormNum = $currentInput->getFormNum();
            if ($currentFormNum == $currentInputFormNum) {
                array_push($arrayOfCurrentFormsInputs, $currentInput);
            }
        }
        $log->lwrite("Beginning testing input fields of form on {$postUrl}: {$currentFormId} {$currentFormName} {$currentFormMethod} {$currentFormAction}");
        foreach ($arrayOfPayloads as $currentPayload) {
            echo '<br>Size of current form inputs = ' . sizeof($arrayOfCurrentFormsInputs) . '<br>';
            $arrayOfValues = array();
            //Array of PostOrGetObject objects
            for ($k = 0; $k < sizeof($arrayOfCurrentFormsInputs); $k++) {
                $currentFormInput = $arrayOfCurrentFormsInputs[$k];
                $currentFormInputName = $currentFormInput->getName();
                $currentFormInputType = $currentFormInput->getType();
                $currentFormInputValue = $currentFormInput->getValue();
                if ($currentFormInputType != 'reset') {
                    $log->lwrite("Using payload: {$currentPayload}, to all input fields of form w/ action: {$currentFormAction}");
                    //Add current input and other inputs to array of post values and set their values
                    if ($currentFormInputType == 'text' || $currentFormInputType == 'password') {
                        $postObject = new PostOrGetObject($currentFormInputName, $currentPayload);
                        array_push($arrayOfValues, $postObject);
                    } else {
                        if ($currentFormInputType == 'checkbox' || $currentFormInputType == 'submit') {
                            $postObject = new PostOrGetObject($currentFormInputName, $currentFormInputValue);
                            array_push($arrayOfValues, $postObject);
                        } else {
                            if ($currentFormInputType == 'radio') {
                                $postObject = new PostOrGetObject($currentFormInputName, $currentFormInputValue);
                                //Check if a radio button in the radio group has already been added
                                $found = false;
                                for ($n = 0; $n < sizeof($arrayOfValues); $n++) {
                                    if ($arrayOfValues[$n]->getName() == $postObject->getName()) {
                                        $found = true;
                                        break;
                                    }
                                }
                                if (!$found) {
                                    array_push($arrayOfValues, $postObject);
                                }
                            }
                        }
                    }
                }
            }
            if ($currentFormMethod == 'get') {
                //Build query string and submit it at end of URL
                if ($urlOfSite[strlen($urlOfSite) - 1] == '/') {
                    $actionUrl = $urlOfSite . $currentFormAction;
                } else {
                    $actionUrl = $urlOfSite . '/' . $currentFormAction;
                }
                $totalTestStr = '';
                //Make a string to show the user how the vulnerability was tested for i.e. the data submitted to exploit the vulnerability
                for ($p = 0; $p < sizeof($arrayOfValues); $p++) {
                    $currentPostValue = $arrayOfValues[$p];
                    $currentPostValueName = $currentPostValue->getName();
                    $currentPostValueValue = $currentPostValue->getValue();
                    $totalTestStr .= $currentPostValueName;
                    $totalTestStr .= '=';
                    $totalTestStr .= $currentPostValueValue;
                    if ($p != sizeof($arrayOfValues) - 1) {
                        $totalTestStr .= '&';
                    }
                }
                $actionUrl .= '?';
                $actionUrl .= $totalTestStr;
                $error = $http->GetRequestArguments($actionUrl, $arguments);
                $error = $http->Open($arguments);
                $log->lwrite("URL to be requested is: {$actionUrl}");
                if ($error == "") {
                    $log->lwrite("Sending HTTP request to {$actionUrl}");
                    $error = $http->SendRequest($arguments);
                    if ($error == "") {
                        $headers = array();
                        $error = $http->ReadReplyHeaders($headers);
                        if ($error == "") {
                            $error = $http->ReadWholeReplyBody($body);
                            if (strlen($error) == 0) {
                                $http->Close();
                                $vulnerabilityFound = checkIfVulnerabilityFound($urlToCheck, $pageChanges, $bodyOfUrl, $log, $currentPayload, $http);
                                if ($vulnerabilityFound) {
                                    $totalTestStr = '';
                                    //Make a test string to show the user how the vulnerability was tested for
                                    for ($p = 0; $p < sizeof($arrayOfValues); $p++) {
                                        $currentPostValue = $arrayOfValues[$p];
                                        $currentPostValueName = $currentPostValue->getName();
                                        $currentPostValueValue = $currentPostValue->getValue();
                                        $totalTestStr .= $currentPostValueName;
                                        $totalTestStr .= '=';
                                        $totalTestStr .= $currentPostValueValue;
                                        if ($p != sizeof($arrayOfValues) - 1) {
                                            $totalTestStr .= '&';
                                        }
                                    }
                                    //The echo's below are for testing the function on its own i.e. requesting this script with your browser
                                    echo 'Broken Authentication Present!<br>Query: ' . HtmlSpecialChars($totalTestStr) . '<br>';
                                    echo 'Method: ' . $currentFormMethod . '<br>';
                                    echo 'Url: ' . HtmlSpecialChars($actionUrl) . '<br>';
                                    echo 'Error: Successfully Logged In with SQL injection';
                                    $tableName = 'test' . $testId;
                                    //Check if this vulnerability has already been found and added to DB. If it hasn't, add it to DB.
                                    $query = "SELECT * FROM test_results WHERE test_id = {$testId} AND type = 'basqli' AND method = '{$currentFormMethod}' AND url = '" . addslashes($actionUrl) . "' AND attack_str = '" . addslashes($totalTestStr) . "'";
                                    $result = $db->query($query);
                                    if (!$result) {
                                        $log->lwrite("Could not execute query {$query}");
                                    } else {
                                        $log->lwrite("Successfully executed query {$query}");
                                        $numRows = $result->num_rows;
                                        if ($numRows == 0) {
                                            $log->lwrite("Number of rows is {$numRows} for query: {$query}");
                                            insertTestResult($db, $testId, 'basqli', $currentFormMethod, addslashes($actionUrl), addslashes($totalTestStr));
                                        }
                                    }
                                    break;
                                }
                            }
                        }
                    }
                }
                if (strlen($error)) {
                    echo "<H2 align=\"center\">Error: ", $error, "</H2>\n";
                    echo 'Method: ' . $currentFormMethod . '<br>';
                    echo 'Url: ' . HtmlSpecialChars($actionUrl) . '<br>';
                }
            } else {
                if ($currentFormMethod == 'post') {
                    //Build query string and submit it at end of URL
                    if ($urlOfSite[strlen($urlOfSite) - 1] == '/') {
                        $actionUrl = $urlOfSite . $currentFormAction;
                    } else {
                        $actionUrl = $urlOfSite . '/' . $currentFormAction;
                    }
                    $error = $http->GetRequestArguments($actionUrl, $arguments);
                    $arguments["RequestMethod"] = "POST";
                    $arguments["PostValues"] = array();
                    for ($p = 0; $p < sizeof($arrayOfValues); $p++) {
                        $currentPostValue = $arrayOfValues[$p];
                        $currentPostValueName = $currentPostValue->getName();
                        $currentPostValueValue = $currentPostValue->getValue();
                        $tempArray = array($currentPostValueName => $currentPostValueValue);
                        $arguments["PostValues"] = array_merge($arguments["PostValues"], $tempArray);
                    }
                    $error = $http->Open($arguments);
                    $log->lwrite("URL to be requested is: {$actionUrl}");
                    if ($error == "") {
                        $log->lwrite("Sending HTTP request to {$actionUrl}");
                        $error = $http->SendRequest($arguments);
                        if ($error == "") {
                            $headers = array();
                            $error = $http->ReadReplyHeaders($headers);
                            if ($error == "") {
                                $error = $http->ReadWholeReplyBody($body);
                                if (strlen($error) == 0) {
                                    $http->Close();
                                    $vulnerabilityFound = checkIfVulnerabilityFound($urlToCheck, $pageChanges, $bodyOfUrl, $log, $currentPayload, $http);
                                    if ($vulnerabilityFound) {
                                        $totalTestStr = '';
                                        //Compile a test string to show the user how the vulnerability was tested for
                                        for ($p = 0; $p < sizeof($arrayOfValues); $p++) {
                                            $currentPostValue = $arrayOfValues[$p];
                                            $currentPostValueName = $currentPostValue->getName();
                                            $currentPostValueValue = $currentPostValue->getValue();
                                            $totalTestStr .= $currentPostValueName;
                                            $totalTestStr .= '=';
                                            $totalTestStr .= $currentPostValueValue;
                                            if ($p != sizeof($arrayOfValues) - 1) {
                                                $totalTestStr .= '&';
                                            }
                                        }
                                        //The echo's below are for testing the function on its own i.e. requesting this script with your browser
                                        echo 'Broken Authentication Present!<br>Query: ' . HtmlSpecialChars($totalTestStr) . '<br>';
                                        echo 'Method: ' . $currentFormMethod . '<br>';
                                        echo 'Url: ' . HtmlSpecialChars($actionUrl) . '<br>';
                                        echo 'Error: Successfully Logged In with SQL injection';
                                        $tableName = 'test' . $testId;
                                        //Check if this vulnerability has already been found and added to DB. If it hasn't, add it to DB.
                                        $query = "SELECT * FROM test_results WHERE test_id = {$testId} AND type = 'basqli' AND method = '{$currentFormMethod}' AND url = '" . addslashes($actionUrl) . "' AND attack_str = '" . addslashes($totalTestStr) . "'";
                                        $result = $db->query($query);
                                        if (!$result) {
                                            $log->lwrite("Could not execute query {$query}");
                                        } else {
                                            $log->lwrite("Successfully executed query {$query}");
                                            $numRows = $result->num_rows;
                                            if ($numRows == 0) {
                                                $log->lwrite("Number of rows is {$numRows} for query: {$query}");
                                                insertTestResult($db, $testId, 'basqli', $currentFormMethod, addslashes($actionUrl), addslashes($totalTestStr));
                                            }
                                        }
                                        break;
                                    }
                                }
                            }
                        }
                    }
                    if (strlen($error)) {
                        echo "<H2 align=\"center\">Error: ", $error, "</H2>\n";
                        echo 'Method: ' . $currentFormMethod . '<br>';
                        echo 'Url: ' . HtmlSpecialChars($actionUrl) . '<br>';
                    }
                }
            }
        }
    }
}
Example #3
0
function testForReflectedXSS($urlToCheck, $urlOfSite, $testId)
{
    connectToDb($db);
    updateStatus($db, "Testing {$urlToCheck} for Reflected Cross-Site Scripting...", $testId);
    $log = new Logger();
    $log->lfile('logs/eventlogs');
    $log->lwrite("Starting Reflected XXS test function on {$urlToCheck}");
    $postUrl = $urlToCheck;
    $postUrlPath = parse_url($postUrl, PHP_URL_PATH);
    //Check URL is not responding with 5xx codes
    $log->lwrite("Checking what response code is received from {$urlToCheck}");
    $http = new http_class();
    $http->timeout = 0;
    $http->data_timeout = 0;
    //$http->debug=1;
    $http->user_agent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)";
    $http->follow_redirect = 1;
    $http->redirection_limit = 5;
    $http->setTestId($testId);
    $error = $http->GetRequestArguments($urlToCheck, $arguments);
    $error = $http->Open($arguments);
    $log->lwrite("URL to be requested is: {$urlToCheck}");
    if ($error == "") {
        $log->lwrite("Sending HTTP request to {$urlToCheck}");
        $error = $http->SendRequest($arguments);
        if ($error == "") {
            $headers = array();
            $error = $http->ReadReplyHeaders($headers);
            if ($error == "") {
                $responseCode = $http->response_status;
                //This is a string
                $log->lwrite("Received response code: {$responseCode}");
                if (intval($responseCode) >= 500 && intval($responseCode) < 600) {
                    $log->lwrite("Response code: {$responseCode} received from: {$urlToCheck}");
                    return;
                }
            }
        }
        $http->Close();
    }
    if (strlen($error)) {
        echo "<H2 align=\"center\">Error: ", $error, "</H2>\n";
        $log->lwrite("Error: {$error}");
    }
    $html = file_get_html($postUrl, $testId);
    if (empty($html)) {
        //This can happen due to file_get_contents returning a 500 code. Then the parser won't parse it
        $log->lwrite("Problem getting contents from {$urlToCheck}");
        return;
    }
    //Submit these
    //If adding string to this array, add a corresponding string (to look for in response), with he same index, in the array below
    //The response to look for can be the same as the payload or different.
    $payloads = array('<webvulscan>', 'javascript:alert(webvulscan)');
    //Look for these in response after submitting corresponding payload
    $harmfulResponses = array('<webvulscan>', 'src="javascript:alert(webvulscan)"');
    //First check does the URL passed into this function contain parameters and submit payloads as those parameters if it does
    $parsedUrl = parse_url($urlToCheck);
    $log->lwrite("Check if {$urlToCheck} contains parameters");
    if ($parsedUrl) {
        if (isset($parsedUrl['query'])) {
            $log->lwrite("{$urlToCheck} does contain parameters");
            $scheme = $parsedUrl['scheme'];
            $host = $parsedUrl['host'];
            $path = $parsedUrl['path'];
            $query = $parsedUrl['query'];
            parse_str($query, $parameters);
            $originalQuery = $query;
            $payloadIndex = 0;
            foreach ($payloads as $currentPayload) {
                $http = new http_class();
                $http->timeout = 0;
                $http->data_timeout = 0;
                //$http->debug=1;
                $http->user_agent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)";
                $http->follow_redirect = 1;
                $http->redirection_limit = 5;
                $http->setTestId($testId);
                foreach ($parameters as $para) {
                    $query = $originalQuery;
                    $newQuery = str_replace($para, $currentPayload, $query);
                    $query = $newQuery;
                    $testUrl = $scheme . '://' . $host . $path . '?' . $query;
                    $log->lwrite("URL to be requested is: {$testUrl}");
                    $error = $http->GetRequestArguments($testUrl, $arguments);
                    $error = $http->Open($arguments);
                    echo "<br>Sending HTTP request to " . htmlspecialchars($testUrl) . "<br>";
                    if ($error == "") {
                        $log->lwrite("Sending HTTP request to {$testUrl}");
                        $error = $http->SendRequest($arguments);
                        if ($error == "") {
                            $headers = array();
                            $error = $http->ReadReplyHeaders($headers);
                            if ($error == "") {
                                $error = $http->ReadWholeReplyBody($body);
                                if (strlen($error) == 0) {
                                    $indicatorStr = $harmfulResponses[$payloadIndex];
                                    if (stripos($body, $indicatorStr)) {
                                        echo '<br>Reflected XSS Present!<br>Query: ' . HtmlSpecialChars($urlToCheck) . '<br>';
                                        echo 'Method: GET <br>';
                                        echo 'Url: ' . HtmlSpecialChars($testUrl) . '<br>';
                                        echo 'Error: ' . htmlspecialchars($indicatorStr) . '<br>';
                                        $tableName = 'test' . $testId;
                                        //Check if this vulnerability has already been found and added to DB. If it hasn't, add it to DB.
                                        $sql = "SELECT * FROM test_results WHERE test_id = {$testId} AND type = 'rxss' AND method = 'get' AND url = '{$testUrl}' AND attack_str = '" . addslashes($query) . "'";
                                        $result = $db->query($sql);
                                        if (!$result) {
                                            $log->lwrite("Could not execute query {$sql}");
                                        } else {
                                            $log->lwrite("Successfully executed query {$sql}");
                                            $numRows = $result->num_rows;
                                            if ($numRows == 0) {
                                                $log->lwrite("Number of rows is {$numRows} for query: {$sql}");
                                                insertTestResult($db, $testId, 'rxss', 'get', $testUrl, addslashes($query));
                                            }
                                        }
                                        $http->Close();
                                        break 2;
                                    }
                                }
                            }
                        }
                        $http->Close();
                    }
                    if (strlen($error)) {
                        echo "<H2 align=\"center\">Error: ", $error, "</H2>\n";
                    }
                }
                $payloadIndex++;
            }
        }
    } else {
        $log->lwrite("Could not parse malformed URL: {$urlToCheck}");
    }
    //Array containing all form objects found
    $arrayOfForms = array();
    //Array containing all input fields
    $arrayOfInputFields = array();
    $log->lwrite("Searching {$postUrl} for forms");
    $formNum = 1;
    //Must use an integer to identify form as forms could have same names and ids
    foreach ($html->find('form') as $form) {
        isset($form->attr['id']) ? $formId = htmlspecialchars($form->attr['id']) : ($formId = '');
        isset($form->attr['name']) ? $formName = htmlspecialchars($form->attr['name']) : ($formName = '');
        isset($form->attr['method']) ? $formMethod = htmlspecialchars($form->attr['method']) : ($formMethod = 'get');
        isset($form->attr['action']) ? $formAction = htmlspecialchars($form->attr['action']) : ($formAction = '');
        $formMethod = strtolower($formMethod);
        //If the action of the form is empty, set the action equal to everything
        //after the URL that the user entered
        if (empty($formAction)) {
            $strLengthUrl = strlen($urlToCheck);
            $strLengthSite = strlen($urlOfSite);
            $firstIndexOfSlash = strpos($urlToCheck, '/', $strLengthSite - 1);
            $formAction = substr($urlToCheck, $firstIndexOfSlash + 1, $strLengthUrl);
        }
        $log->lwrite("Found form on {$postUrl}: {$formId} {$formName} {$formMethod} {$formAction} {$formNum}");
        $newForm = new Form($formId, $formName, $formMethod, $formAction, $formNum);
        array_push($arrayOfForms, $newForm);
        foreach ($form->find('input') as $input) {
            isset($input->attr['id']) ? $inputId = htmlspecialchars($input->attr['id']) : ($inputId = '');
            isset($input->attr['name']) ? $inputName = htmlspecialchars($input->attr['name']) : ($inputName = '');
            isset($input->attr['value']) ? $inputValue = htmlspecialchars($input->attr['value']) : ($inputValue = '');
            isset($input->attr['type']) ? $inputType = htmlspecialchars($input->attr['type']) : ($inputType = '');
            $log->lwrite("Found input field on {$postUrl}: {$inputId} {$inputName} {$formId} {$formName} {$inputValue} {$inputType} {$formNum}");
            $inputField = new InputField($inputId, $inputName, $formId, $formName, $inputValue, $inputType, $formNum);
            array_push($arrayOfInputFields, $inputField);
        }
        $formNum++;
    }
    //At this stage, we should have captured all forms and their inputs into the corresponding arrays
    $log->lwrite('Beginning testing of forms');
    for ($i = 0; $i < sizeof($arrayOfForms); $i++) {
        $currentForm = $arrayOfForms[$i];
        $currentFormId = $currentForm->getId();
        $currentFormName = $currentForm->getName();
        $currentFormMethod = $currentForm->getMethod();
        $currentFormAction = $currentForm->getAction();
        $currentFormNum = $currentForm->getFormNum();
        $arrayOfCurrentFormsInputs = array();
        $log->lwrite("Beginning testing of form on {$postUrl}: {$currentFormId} {$currentFormName} {$currentFormMethod} {$currentFormAction}");
        for ($j = 0; $j < sizeof($arrayOfInputFields); $j++) {
            $currentInput = $arrayOfInputFields[$j];
            $currentInputIdOfForm = $currentInput->getIdOfForm();
            $currentInputNameOfForm = $currentInput->getNameOfForm();
            $currentInputFormNum = $currentInput->getFormNum();
            //Check if the current input field belongs to the current form and add to array if it does
            if ($currentFormNum == $currentInputFormNum) {
                array_push($arrayOfCurrentFormsInputs, $currentInput);
            }
        }
        $log->lwrite("Beginning testing input fields of form on {$postUrl}: {$currentFormId} {$currentFormName} {$currentFormMethod} {$currentFormAction}");
        for ($k = 0; $k < sizeof($arrayOfCurrentFormsInputs); $k++) {
            for ($plIndex = 0; $plIndex < sizeof($payloads); $plIndex++) {
                $testStr = $payloads[$plIndex];
                $log->lwrite("Submitting payload: {$testStr}");
                $defaultStr = 'Abc123';
                $indicatorStr = $harmfulResponses[$plIndex];
                $currentFormInput = $arrayOfCurrentFormsInputs[$k];
                $currentFormInputName = $currentFormInput->getName();
                $currentFormInputType = $currentFormInput->getType();
                $currentFormInputValue = $currentFormInput->getValue();
                if ($currentFormInputType != 'reset') {
                    $http = new http_class();
                    $http->timeout = 0;
                    $http->data_timeout = 0;
                    //$http->debug=1;
                    $http->user_agent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)";
                    $http->follow_redirect = 1;
                    $http->redirection_limit = 5;
                    $http->setTestId($testId);
                    $arrayOfValues = array();
                    //Array of PostOrGetObject objects
                    //Get the other input values and set them equal to the default string
                    $otherInputs = array();
                    for ($l = 0; $l < sizeof($arrayOfCurrentFormsInputs); $l++) {
                        if ($currentFormInput->getName() != $arrayOfCurrentFormsInputs[$l]->getName()) {
                            array_push($otherInputs, $arrayOfCurrentFormsInputs[$l]);
                        }
                    }
                    $postObject = new PostOrGetObject($currentFormInputName, $testStr);
                    //Add current input and other to array of post values and set their values
                    array_push($arrayOfValues, $postObject);
                    for ($m = 0; $m < sizeof($otherInputs); $m++) {
                        $currentOther = $otherInputs[$m];
                        $currentOtherType = $currentOther->getType();
                        $currentOtherName = $currentOther->getName();
                        $currentOtherValue = $currentOther->getValue();
                        if ($currentOtherType == 'text' || $currentOtherType == 'password') {
                            $postObject = new PostOrGetObject($currentOtherName, $defaultStr);
                            array_push($arrayOfValues, $postObject);
                        } else {
                            if ($currentOtherType == 'checkbox' || $currentOtherType == 'submit') {
                                $postObject = new PostOrGetObject($currentOtherName, $currentOtherValue);
                                array_push($arrayOfValues, $postObject);
                            } else {
                                if ($currentOtherType == 'radio') {
                                    $postObject = new PostOrGetObject($currentOtherName, $currentOtherValue);
                                    //Check if a radio button in the radio group has already been added
                                    $found = false;
                                    for ($n = 0; $n < sizeof($arrayOfValues); $n++) {
                                        if ($arrayOfValues[$n]->getName() == $postObject->getName()) {
                                            $found = true;
                                            break;
                                        }
                                    }
                                    if (!$found) {
                                        array_push($arrayOfValues, $postObject);
                                    }
                                }
                            }
                        }
                    }
                    echo '<br><br>';
                    if ($currentFormMethod == 'get') {
                        //Build query string and submit it at end of URL
                        if ($urlOfSite[strlen($urlOfSite) - 1] == '/') {
                            $actionUrl = $urlOfSite . $currentFormAction;
                        } else {
                            $actionUrl = $urlOfSite . '/' . $currentFormAction;
                        }
                        $totalTestStr = '';
                        //Compile a test string to show the user how the vulnerability was tested for
                        for ($p = 0; $p < sizeof($arrayOfValues); $p++) {
                            $currentPostValue = $arrayOfValues[$p];
                            $currentPostValueName = $currentPostValue->getName();
                            $currentPostValueValue = $currentPostValue->getValue();
                            $totalTestStr .= $currentPostValueName;
                            $totalTestStr .= '=';
                            $totalTestStr .= $currentPostValueValue;
                            if ($p != sizeof($arrayOfValues) - 1) {
                                $totalTestStr .= '&';
                            }
                        }
                        if (strpos($actionUrl, '?') !== false) {
                            //url may something like domain.com?id=111 so don't want to add another question mark if it is
                            $actionUrl .= '&';
                        } else {
                            $actionUrl .= '?';
                        }
                        $actionUrl .= $totalTestStr;
                        $error = $http->GetRequestArguments($actionUrl, $arguments);
                        $error = $http->Open($arguments);
                        if ($error == "") {
                            $error = $http->SendRequest($arguments);
                            if ($error == "") {
                                $headers = array();
                                $error = $http->ReadReplyHeaders($headers);
                                if ($error == "") {
                                    $error = $http->ReadWholeReplyBody($body);
                                    if (strlen($error) == 0) {
                                        if (stripos($body, $indicatorStr)) {
                                            //If the body that was returned from the request contains the payload, the
                                            //Reflected XSS vulnerabiltiy is present
                                            $totalTestStr = '';
                                            //Compile a test string to show the user how the vulnerability was tested for
                                            for ($p = 0; $p < sizeof($arrayOfValues); $p++) {
                                                $currentPostValue = $arrayOfValues[$p];
                                                $currentPostValueName = $currentPostValue->getName();
                                                $currentPostValueValue = $currentPostValue->getValue();
                                                $totalTestStr .= $currentPostValueName;
                                                $totalTestStr .= '=';
                                                $totalTestStr .= $currentPostValueValue;
                                                if ($p != sizeof($arrayOfValues) - 1) {
                                                    $totalTestStr .= '&';
                                                }
                                            }
                                            //The echo's are for testing/debugging the function on its own
                                            echo 'Reflected XSS Present!<br>Query: ' . HtmlSpecialChars($totalTestStr) . '<br>';
                                            echo 'Method: ' . $currentFormMethod . '<br>';
                                            echo 'Url: ' . HtmlSpecialChars($actionUrl) . '';
                                            $tableName = 'test' . $testId;
                                            //Check if this vulnerability has already been found and added to DB. If it hasn't, add it to DB.
                                            $query = "SELECT * FROM test_results WHERE test_id = {$testId} AND type = 'rxss' AND method = '{$currentFormMethod}' AND url = '{$actionUrl}' AND attack_str = '{$totalTestStr}'";
                                            $result = $db->query($query);
                                            if (!$result) {
                                                $log->lwrite("Could not execute query {$query}");
                                            } else {
                                                $log->lwrite("Successfully executed query {$query}");
                                                $numRows = $result->num_rows;
                                                if ($numRows == 0) {
                                                    $log->lwrite("Number of rows is {$numRows} for query: {$query}");
                                                    insertTestResult($db, $testId, 'rxss', $currentFormMethod, $actionUrl, $totalTestStr);
                                                }
                                            }
                                            $http->Close();
                                            break;
                                        }
                                    }
                                }
                            }
                            $http->Close();
                        }
                        if (strlen($error)) {
                            echo "<H2 align=\"center\">Error: ", $error, "</H2>\n";
                        }
                    } else {
                        if ($currentFormMethod == 'post') {
                            //Start sending requests with the values in the post values array
                            //Build query string and submit it at end of URL
                            if ($urlOfSite[strlen($urlOfSite) - 1] == '/') {
                                $actionUrl = $urlOfSite . $currentFormAction;
                            } else {
                                $actionUrl = $urlOfSite . '/' . $currentFormAction;
                            }
                            $error = $http->GetRequestArguments($actionUrl, $arguments);
                            $arguments["RequestMethod"] = "POST";
                            $arguments["PostValues"] = array();
                            for ($p = 0; $p < sizeof($arrayOfValues); $p++) {
                                $currentPostValue = $arrayOfValues[$p];
                                $currentPostValueName = $currentPostValue->getName();
                                $currentPostValueValue = $currentPostValue->getValue();
                                $tempArray = array($currentPostValueName => $currentPostValueValue);
                                $arguments["PostValues"] = array_merge($arguments["PostValues"], $tempArray);
                            }
                            $error = $http->Open($arguments);
                            if ($error == "") {
                                $error = $http->SendRequest($arguments);
                                if ($error == "") {
                                    $headers = array();
                                    $error = $http->ReadReplyHeaders($headers);
                                    if ($error == "") {
                                        $error = $http->ReadWholeReplyBody($body);
                                        if (strlen($error) == 0) {
                                            //echo $body;
                                            if (stripos($body, $indicatorStr)) {
                                                //If the body that was returned from the request contains the test string, the
                                                //Reflected XSS vulnerabiltiy is present
                                                $totalTestStr = '';
                                                //Compile a test string to show the user how the vulnerability was tested for
                                                for ($p = 0; $p < sizeof($arrayOfValues); $p++) {
                                                    $currentPostValue = $arrayOfValues[$p];
                                                    $currentPostValueName = $currentPostValue->getName();
                                                    $currentPostValueValue = $currentPostValue->getValue();
                                                    $totalTestStr .= $currentPostValueName;
                                                    $totalTestStr .= '=';
                                                    $totalTestStr .= $currentPostValueValue;
                                                    if ($p != sizeof($arrayOfValues) - 1) {
                                                        $totalTestStr .= '&';
                                                    }
                                                }
                                                //The echo's are for testing/debugging the function on its own
                                                echo 'Reflected XSS Present!<br>Query: ' . HtmlSpecialChars($totalTestStr) . '<br>';
                                                echo 'Method: ' . $currentFormMethod . '<br>';
                                                echo 'Url: ' . HtmlSpecialChars($actionUrl) . '';
                                                $tableName = 'test' . $testId;
                                                //Check if this vulnerability has already been found and added to DB. If it hasn't, add it to DB.
                                                $query = "SELECT * FROM test_results WHERE test_id = {$testId} AND type = 'rxss' AND method = '{$currentFormMethod}' AND url = '{$actionUrl}' AND attack_str = '{$totalTestStr}'";
                                                $result = $db->query($query);
                                                if (!$result) {
                                                    $log->lwrite("Could not execute query {$query}");
                                                } else {
                                                    $log->lwrite("Successfully executed query {$query}");
                                                    $numRows = $result->num_rows;
                                                    if ($numRows == 0) {
                                                        $log->lwrite("Number of rows is {$numRows} for query: {$query}");
                                                        insertTestResult($db, $testId, 'rxss', $currentFormMethod, $actionUrl, $totalTestStr);
                                                    }
                                                }
                                                $http->Close();
                                                break;
                                            }
                                        }
                                    }
                                }
                                $http->Close();
                            }
                            if (strlen($error)) {
                                echo "<H2 align=\"center\">Error: ", $error, "</H2>\n";
                            }
                        }
                    }
                }
            }
        }
    }
}
function testDirectoryListingEnabled($urlToScan, $siteBeingTested, $testId, $crawlUrlFlag)
{
    connectToDb($db);
    updateStatus($db, "Testing for {$urlToScan} for Directory Listing enabled...", $testId);
    $log = new Logger();
    $log->lfile('logs/eventlogs');
    $log->lwrite("Testing for {$urlToScan} for Directory Listing enabled");
    if ($crawlUrlFlag) {
        //Perform crawl again but allow images, etc. this time to capture every URL
        $crawlerNew =& new MyCrawler();
        $crawlerNew->setURL($urlToScan);
        $crawlerNew->setTestId($testId);
        $crawlerNew->addReceiveContentType("/text\\/html/");
        $crawlerNew->setCookieHandling(true);
        $crawlerNew->setFollowMode(3);
        $log->lwrite("Crawling {$urlToScan} again for all links including images, css, etc, in order to identify directories");
        $crawlerNew->go();
        $urlsFound = $crawlerNew->urlsFound;
        $logStr = sizeof($urlsFound) . ' URLs found for test: ' . $testId;
        $log->lwrite("All URLs found during crawl for directory listing check:");
        foreach ($urlsFound as $currentUrl) {
            $log->lwrite($currentUrl);
        }
        $relativePathUrls = array();
        foreach ($urlsFound as $currentUrl) {
            $currentUrl = str_replace($urlToScan, '', $currentUrl);
            array_push($relativePathUrls, $currentUrl);
        }
        $directories = array();
        //Check if relative path contain a directory and if they do, add it to a list of directories
        foreach ($relativePathUrls as $relativePathUrl) {
            if (dirname($relativePathUrl) != '.') {
                $dir = dirname($relativePathUrl);
                if (!in_array($dir, $directories) && !empty($dir) && !strpos($dir, '?')) {
                    array_push($directories, $dir);
                    $log->lwrite("Found directory {$dir}");
                }
            }
        }
    } else {
        $directories = array(1);
    }
    //Just need to make an array of size one so the for loop below iterates once
    $http = new http_class();
    $http->timeout = 0;
    $http->data_timeout = 0;
    //$http->debug=1;
    $http->user_agent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)";
    $http->follow_redirect = 1;
    $http->redirection_limit = 5;
    $http->setTestId($testId);
    //Regular expressions that will indicate directory listing is enabled
    $regexs = array("/Parent Directory/", "/\\bDirectory Listing\\b.*(Tomcat|Apache)/", "/Parent directory/", "/\\bDirectory\\b/", "/[\\s<]+IMG\\s*=/");
    //General
    foreach ($directories as $directory) {
        if ($crawlUrlFlag) {
            $testUrl = $urlToScan . $directory . '/';
        } else {
            $testUrl = $siteBeingTested;
        }
        $error = $http->GetRequestArguments($testUrl, $arguments);
        $error = $http->Open($arguments);
        $log->lwrite("URL to be requested is: {$testUrl}");
        if ($error == "") {
            $log->lwrite("Sending HTTP request to {$testUrl}");
            $error = $http->SendRequest($arguments);
            if ($error == "") {
                $headers = array();
                $error = $http->ReadReplyHeaders($headers);
                if ($error == "") {
                    $responseCode = $http->response_status;
                    //This is a string
                    $log->lwrite("Received response code: {$responseCode}");
                    if (intval($responseCode) >= 200 && intval($responseCode) < 300) {
                        $vulnerabilityFound = false;
                        $error = $http->ReadWholeReplyBody($body);
                        if (strlen($error) == 0) {
                            $indicatorStr = '';
                            if (preg_match($regexs[0], $body)) {
                                $vulnerabilityFound = true;
                                $indicatorStr = $regexs[0];
                            } else {
                                if (preg_match($regexs[1], $body)) {
                                    $vulnerabilityFound = true;
                                    $indicatorStr = $regexs[1];
                                } else {
                                    if (preg_match($regexs[2], $body)) {
                                        $vulnerabilityFound = true;
                                        $indicatorStr = $regexs[2];
                                    } else {
                                        if (preg_match($regexs[3], $body)) {
                                            if (preg_match($regexs[4], $body)) {
                                                $vulnerabilityFound = true;
                                                $indicatorStr = $regexs[3] . ' and ' . $regexs[4];
                                            }
                                        }
                                    }
                                }
                            }
                            if ($vulnerabilityFound) {
                                //The echo's are for testing function on its own
                                echo '<br>Directory Listing Enabled!<br>Url: ' . $testUrl . '<br>';
                                echo 'Method: GET <br>';
                                echo 'Url Requested: ' . $testUrl . '<br>';
                                echo "Error: Received response code: {$responseCode} after requesting a directory and regular expression: {$indicatorStr}<br>";
                                $tableName = 'test' . $testId;
                                //Check if this vulnerability has already been found and added to DB. If it hasn't, add it to DB.
                                $query = "SELECT * FROM test_results WHERE test_id = {$testId} AND type = 'dirlist' AND method = 'get' AND url = '{$testUrl}' AND attack_str = '{$testUrl}'";
                                $result = $db->query($query);
                                if (!$result) {
                                    $log->lwrite("Could not execute query {$query}");
                                } else {
                                    $log->lwrite("Successfully executed query {$query}");
                                    $numRows = $result->num_rows;
                                    if ($numRows == 0) {
                                        $log->lwrite("Number of rows is {$numRows} for query: {$query}");
                                        insertTestResult($db, $testId, 'dirlist', 'get', $testUrl, $testUrl);
                                    }
                                }
                            }
                        }
                    }
                }
            }
            $http->Close();
        }
        if (strlen($error)) {
            echo "<H2 align=\"center\">Error: ", $error, "</H2>\n";
            $log->lwrite("Error: {$error}");
        }
    }
}
function testHttpBannerDisclosure($urlToCheck, $testId)
{
    connectToDb($db);
    updateStatus($db, "Testing {$urlToCheck} for HTTP Banner Disclosure...", $testId);
    $log = new Logger();
    $log->lfile('logs/eventlogs');
    $log->lwrite("Starting HTTP Banner Disclosure test function on {$urlToCheck}");
    $http = new http_class();
    $http->timeout = 0;
    $http->data_timeout = 0;
    //$http->debug=1;
    $http->user_agent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)";
    $http->follow_redirect = 1;
    $http->redirection_limit = 5;
    $http->setTestId($testId);
    $error = $http->GetRequestArguments($urlToCheck, $arguments);
    $error = $http->Open($arguments);
    $log->lwrite("URL to be requested is: {$urlToCheck}");
    //TODO: add more to these arrays
    $serverHeaders = array('Apache', 'Win32', 'mod_ssl', 'OpenSSL', 'PHP', 'mod_perl', 'Perl', 'Ubuntu', 'Python', 'mod_python', 'Microsoft', 'IIS', 'Unix', 'Linux');
    $xPowByHeaders = array('PHP', 'ASP', 'NET', 'JSP', 'JBoss', 'Perl', 'Python');
    if ($error == "") {
        $log->lwrite("Sending HTTP request to {$urlToCheck}");
        $error = $http->SendRequest($arguments);
        if ($error == "") {
            $headers = array();
            $error = $http->ReadReplyHeaders($headers);
            if ($error == "") {
                if (isset($headers['server'])) {
                    $serverHeader = $headers['server'];
                    foreach ($serverHeaders as $currentHeader) {
                        if (stripos($serverHeader, $currentHeader) !== false) {
                            echo "<br>Found {$currentHeader} in {$serverHeader}";
                            echo '<br>HTTP Banner Disclosure Present!<br>Url: ' . $urlToCheck . '<br>';
                            echo 'Method: GET <br>';
                            echo 'Url Requested: ' . $urlToCheck . '<br>';
                            echo 'Info Disclosed: Server: ' . $serverHeader . '<br>';
                            $tableName = 'test' . $testId;
                            //Check if this vulnerability has already been found and added to DB. If it hasn't, add it to DB.
                            $query = "SELECT * FROM test_results WHERE test_id = {$testId} AND type = 'bannerdis' AND method = 'get' AND url = '{$urlToCheck}' AND attack_str = '{$serverHeader}'";
                            $result = $db->query($query);
                            if (!$result) {
                                $log->lwrite("Could not execute query {$query}");
                            } else {
                                $log->lwrite("Successfully executed query {$query}");
                                $numRows = $result->num_rows;
                                if ($numRows == 0) {
                                    $log->lwrite("Number of rows is {$numRows} for query: {$query}");
                                    insertTestResult($db, $testId, 'bannerdis', 'get', $urlToCheck, $serverHeader);
                                }
                            }
                            break;
                        }
                    }
                } else {
                    $log->lwrite("Server header for {$urlToCheck} is empty");
                    echo "Server header for {$urlToCheck} is empty<br>";
                }
                if (isset($headers['x-powered-by'])) {
                    $xPowByHeader = $headers['x-powered-by'];
                    foreach ($xPowByHeaders as $currentHeader) {
                        if (stripos($xPowByHeader, $currentHeader) !== false) {
                            //The echo's here are for testing/debugging the function on its own
                            echo "<br>Found {$currentHeader} in {$xPowByHeader} ";
                            echo '<br>HTTP Banner Disclosure Present!<br>Url: ' . $urlToCheck . '<br>';
                            echo 'Method: GET <br>';
                            echo 'Url Requested: ' . $urlToCheck . '<br>';
                            echo 'Info Disclosed: X-Powered-by: ' . $xPowByHeader . '<br>';
                            $tableName = 'test' . $testId;
                            //Check if this vulnerability has already been found and added to DB. If it hasn't, add it to DB.
                            $query = "SELECT * FROM test_results WHERE test_id = {$testId} AND type = 'bannerdis' AND method = 'get' AND url = '{$urlToCheck}' AND attack_str = '{$xPowByHeader}'";
                            $result = $db->query($query);
                            if (!$result) {
                                $log->lwrite("Could not execute query {$query}");
                            } else {
                                $log->lwrite("Successfully executed query {$query}");
                                $numRows = $result->num_rows;
                                if ($numRows == 0) {
                                    $log->lwrite("Number of rows is {$numRows} for query: {$query}");
                                    insertTestResult($db, $testId, 'bannerdis', 'get', $urlToCheck, $xPowByHeader);
                                }
                            }
                            break;
                        }
                    }
                } else {
                    $log->lwrite("X-Powered-by header for {$urlToCheck} is empty");
                    echo "X-Powered-by header for {$urlToCheck} is empty<br>";
                }
            }
        }
        $http->Close();
    }
    if (strlen($error)) {
        echo "<H2 align=\"center\">Error: ", $error, "</H2>\n";
        $log->lwrite("Error: {$error}");
    }
}
Example #6
0
function testSslCertificate($urlsToTest, $testId)
{
    connectToDb($db);
    updateStatus($db, "Testing {$urlsToTest} for untrustworthy SSL certificates...", $testId);
    $log = new Logger();
    $log->lfile('logs/eventlogs');
    $log->lwrite("Starting SSL certificate verification function on {$urlsToTest}");
    //Identify which URLs, if any, begin with https
    $log->lwrite("Identifying which URLs, if any, begin with HTTPS");
    updateStatus($db, "Identifying which URLs, if any, begin with HTTPS...", $testId);
    $usingHttps = false;
    $httpsUrl = '';
    foreach ($urlsToTest as $currentUrl) {
        if (substr($currentUrl, 0, 5) == 'https') {
            $usingHttps = true;
            $httpsUrl = $currentUrl;
            echo "https url = {$currentUrl} <br>";
            $log->lwrite("Found HTTPS URL: {$currentUrl}");
            break;
        }
    }
    if ($usingHttps) {
        //Check if Mozilla's cacert.pem file is online and update our version of it if needed
        $log->lwrite("Checking if cacert.pem is up to date");
        $http = new http_class();
        $http->timeout = 0;
        $http->data_timeout = 0;
        //$http->debug=1;
        $http->user_agent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)";
        $http->follow_redirect = 1;
        $http->redirection_limit = 5;
        $cacertsUrl = "http://curl.haxx.se/ca/cacert.pem";
        $error = $http->GetRequestArguments($cacertsUrl, $arguments);
        $error = $http->Open($arguments);
        $log->lwrite("URL to be requested is: {$cacertsUrl}");
        if ($error == "") {
            $log->lwrite("Sending HTTP request to {$cacertsUrl}");
            $error = $http->SendRequest($arguments);
            if ($error == "") {
                $headers = array();
                $error = $http->ReadReplyHeaders($headers);
                if ($error == "") {
                    $responseCode = $http->response_status;
                    //This is a string
                    $log->lwrite("Received response code: {$responseCode}");
                    if (intval($responseCode) == 200) {
                        //Update cacerts.pem file
                        $cacerts = file_get_contents($cacertsUrl);
                        $oldCacerts = file_get_contents('tests/cacert.pem');
                        if ($cacerts != $oldCacerts) {
                            file_put_contents('tests/cacert.pem', $cacerts);
                            $log->lwrite("cacert.pem file updated");
                        } else {
                            $log->lwrite("cacert.pem is already up to date so was not updated");
                        }
                    } else {
                        $log->lwrite("Problem accessing Mozilla's URL containing cacert.pem file");
                    }
                }
            }
        }
        // Initialize session and set URL.
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $httpsUrl);
        // Set so curl_exec returns the result instead of outputting it.
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        $user_agent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)";
        curl_setopt($ch, CURLOPT_USERAGENT, $user_agent);
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
        //Check server's certificate against certificates specified in .pem file below
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
        //If last parameter is 1, checks the SSL certificate for a comman name (the domain of the site sometimes specified in the certificate), e.g. the site that acquired the certificate
        //If last parameter is 2, checks for the common name and, if it exists, checks that it matches the hostname provided
        //Default is 2
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
        //Using Mozillas certificate file with trusted certificates
        curl_setopt($ch, CURLOPT_CAINFO, getcwd() . "/cacert.pem");
        // Get the response and close the channel.
        $response = curl_exec($ch);
        if ($db) {
            incrementHttpRequests($db, $testId);
        }
        if (empty($response)) {
            //The echo's here are for testing/debugging the function on its own
            echo '<br>SSL Certificate is not trusted!<br>Url: ' . $httpsUrl . '<br>';
            echo 'Method: GET <br>';
            //echo 'Url Requested: ' . $testUrl . '<br>';
            echo 'Error: ' . curl_error($ch) . '<br>';
            $tableName = 'test' . $testId;
            //Check if this vulnerability has already been found and added to DB. If it hasn't, add it to DB.
            $query = "SELECT * FROM test_results WHERE test_id = {$testId} AND type = 'sslcert' AND method = 'get' AND url = '{$httpsUrl}' AND attack_str = '{$httpsUrl}'";
            $result = $db->query($query);
            if (!$result) {
                $log->lwrite("Could not execute query {$query}");
            } else {
                $log->lwrite("Successfully executed query {$query}");
                $numRows = $result->num_rows;
                if ($numRows == 0) {
                    $log->lwrite("Number of rows is {$numRows} for query: {$query}");
                    insertTestResult($db, $testId, 'sslcert', 'get', $httpsUrl, $httpsUrl);
                }
            }
        }
        curl_close($ch);
    }
}
Example #7
0
function testAutoComplete($urlToCheck, $testId)
{
    connectToDb($db);
    updateStatus($db, "Testing {$urlToCheck} for autocomplete enabled ...", $testId);
    $log = new Logger();
    $log->lfile('logs/eventlogs');
    $log->lwrite("Starting autocomplete test function on {$urlToCheck}");
    //Array containing all input fields
    $arrayOfInputFields = array();
    $log->lwrite("Searching {$urlToCheck} for input fields");
    //Check URL is not responding with 5xx codes
    $log->lwrite("Checking what response code is received from {$urlToCheck}");
    $http = new http_class();
    $http->timeout = 0;
    $http->data_timeout = 0;
    //$http->debug=1;
    $http->user_agent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)";
    $http->follow_redirect = 1;
    $http->redirection_limit = 5;
    $http->setTestId($testId);
    $error = $http->GetRequestArguments($urlToCheck, $arguments);
    $error = $http->Open($arguments);
    $log->lwrite("URL to be requested is: {$urlToCheck}");
    if ($error == "") {
        $log->lwrite("Sending HTTP request to {$urlToCheck}");
        $error = $http->SendRequest($arguments);
        if ($error == "") {
            $headers = array();
            $error = $http->ReadReplyHeaders($headers);
            if ($error == "") {
                $responseCode = $http->response_status;
                //This is a string
                $log->lwrite("Received response code: {$responseCode}");
                if (intval($responseCode) >= 500 && intval($responseCode) < 600) {
                    $log->lwrite("Response code: {$responseCode} received from: {$urlToCheck}");
                    return;
                }
            }
        }
        $http->Close();
    }
    if (strlen($error)) {
        echo "<H2 align=\"center\">Error: ", $error, "</H2>\n";
        $log->lwrite("Error: {$error}");
    }
    $html = file_get_html($urlToCheck, $testId);
    if (empty($html)) {
        //This can happen due to file_get_contents returning a 500 code. Then the parser won't parse it
        updateStatus($db, "Problem getting contents from {$urlToCheck}...", $testId);
        $log->lwrite("Problem getting contents from {$urlToCheck}");
        return;
    }
    foreach ($html->find('input') as $input) {
        $vulnerabilityFound = false;
        if (isset($input->attr['type'])) {
            $inputType = $input->attr['type'];
            if ($inputType == 'password') {
                if (isset($input->attr['autocomplete'])) {
                    $inputAutoComplete = $input->attr['autocomplete'];
                    if (strcasecmp($inputAutoComplete, 'off') != 0) {
                        $vulnerabilityFound = true;
                    }
                } else {
                    $vulnerabilityFound = true;
                }
                if ($vulnerabilityFound) {
                    $inputName = $input->attr['name'];
                    echo 'Autocomplete enabled!<br>';
                    echo 'Method: get <br>';
                    echo 'Url: $urlToCheck<br>';
                    echo "Error: Input field with name: {$inputName} is of type: password and does not have autocomplete disabled";
                    $tableName = 'test' . $testId;
                    //Check if this vulnerability has already been found and added to DB. If it hasn't, add it to DB.
                    $query = "SELECT * FROM test_results WHERE test_id = {$testId} AND type = 'autoc' AND method = 'get' AND url = '{$urlToCheck}' AND attack_str = '{$inputName}'";
                    $result = $db->query($query);
                    if (!$result) {
                        $log->lwrite("Could not execute query {$query}");
                    } else {
                        $log->lwrite("Successfully executed query {$query}");
                        $numRows = $result->num_rows;
                        if ($numRows == 0) {
                            $log->lwrite("Number of rows is {$numRows} for query: {$query}");
                            insertTestResult($db, $testId, 'autoc', 'get', $urlToCheck, $inputName);
                        }
                    }
                }
            }
        }
    }
}
function testUnvalidatedRedirects($arrayOfUrls, $testId)
{
    connectToDb($db);
    updateStatus($db, "Testing all URLs for Unvalidated Redirects...", $testId);
    $log = new Logger();
    $log->lfile('logs/eventlogs');
    $log->lwrite("Starting Unvalidated Redirects test function on all URLs");
    $http = new http_class();
    $http->timeout = 0;
    $http->data_timeout = 0;
    //$http->debug=1;
    $http->user_agent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)";
    $http->follow_redirect = 0;
    $http->setTestId($testId);
    //Identify which URLs, if any, cause redirects
    $log->lwrite("Identifying which URLs, if any, cause redirects");
    updateStatus($db, "Identifying which URLs, if any, cause redirects...", $testId);
    $potentiallyVulnUrls = array();
    foreach ($arrayOfUrls as $currentUrl) {
        $error = $http->GetRequestArguments($currentUrl, $arguments);
        $error = $http->Open($arguments);
        $log->lwrite("URL to be requested is: {$currentUrl}");
        if ($error == "") {
            $log->lwrite("Sending HTTP request to {$currentUrl}");
            $error = $http->SendRequest($arguments);
            if ($error == "") {
                $headers = array();
                $error = $http->ReadReplyHeaders($headers);
                if ($error == "") {
                    $responseCode = $http->response_status;
                    //This is a string
                    $log->lwrite("Received response code: {$responseCode}");
                    if (intval($responseCode) >= 300 && intval($responseCode) < 400) {
                        array_push($potentiallyVulnUrls, $currentUrl);
                    }
                }
            }
            $http->Close();
        }
        if (strlen($error)) {
            echo "<H2 align=\"center\">Error: ", $error, "</H2>\n";
            $log->lwrite("Error: {$error}");
        }
    }
    $log->lwrite("Potentially Vulnerable URLs:");
    foreach ($potentiallyVulnUrls as $currentUrl) {
        $log->lwrite("{$currentUrl}");
    }
    updateStatus($db, "Beginning testing each potentially vulnerable URL for unvalidated redirects ...", $testId);
    $redirectDomain = 'www.whatismyip.com';
    foreach ($potentiallyVulnUrls as $currentUrl) {
        updateStatus($db, "Testing {$currentUrl} for Unvalidated Redirects...", $testId);
        $log->lwrite("Testing {$currentUrl} for unvalidated redirects");
        echo "<br>Testing: {$currentUrl} <br>";
        $parsedUrl = parse_url($currentUrl);
        $query = $parsedUrl['query'];
        $parameters = array();
        parse_str($query, $parameters);
        $newQuery = '';
        $query = urldecode($query);
        $originalQuery = $query;
        if ($parsedUrl) {
            foreach ($parameters as $para) {
                $query = $originalQuery;
                if (stripos($para, 'http') || stripos($para, 'www')) {
                    if (stripos($para, 'http') === 0) {
                        $newRedirectDomain = 'http://' . $redirectDomain;
                        $newQuery = str_replace($para, $newRedirectDomain, $query);
                        $query = $newQuery;
                        $newRedirectDomain = '';
                    } else {
                        if (stripos($para, 'www') === 0 && !strpos($para, 'http') === 0) {
                            $newQuery = str_replace($para, $redirectDomain, $query);
                            $query = $newQuery;
                        }
                    }
                } else {
                    $newRedirectDomain = 'http://' . $redirectDomain;
                    $newQuery = str_replace($para, $newRedirectDomain, $query);
                    $query = $newQuery;
                    $newRedirectDomain = '';
                }
                $scheme = $parsedUrl['scheme'];
                $host = $parsedUrl['host'];
                $path = $parsedUrl['path'];
                $testUrl = $scheme . '://' . $host . $path . '?' . $newQuery;
                $log->lwrite("URL to be requested is: {$testUrl}");
                $error = $http->GetRequestArguments($testUrl, $arguments);
                $error = $http->Open($arguments);
                if ($error == "") {
                    $log->lwrite("Sending HTTP request to {$testUrl}");
                    $error = $http->SendRequest($arguments);
                    if ($error == "") {
                        $headers = array();
                        $error = $http->ReadReplyHeaders($headers);
                        if ($error == "") {
                            $error = $http->ReadWholeReplyBody($body);
                            if (strlen($error) == 0) {
                                //Check if the location in the HTTP response is the URL added as a parameter
                                //If it is this would cause the browser to redirect to the parameter, therefore the vulnerability is present
                                echo 'Location header is ' . $headers['location'] . '<br>';
                                $redirectTarget = $headers['location'];
                                if (strpos($redirectTarget, $redirectDomain) || $redirectTarget == $redirectDomain) {
                                    //The echo's here are for testing/debugging the function on its own
                                    echo '<br>Unvalidated Redirects Present!<br>Url: ' . $currentUrl . '<br>';
                                    echo 'Method: GET <br>';
                                    echo 'Url Requested: ' . $testUrl . '<br>';
                                    echo 'Error: Successfully Redirected to www.whatsmyip.com<br>';
                                    $tableName = 'test' . $testId;
                                    //Check if this vulnerability has already been found and added to DB. If it hasn't, add it to DB.
                                    $query = "SELECT * FROM test_results WHERE test_id = {$testId} AND type = 'unredir' AND method = 'get' AND url = '{$currentUrl}' AND attack_str = '{$testUrl}'";
                                    $result = $db->query($query);
                                    if (!$result) {
                                        $log->lwrite("Could not execute query {$query}");
                                    } else {
                                        $log->lwrite("Successfully executed query {$query}");
                                        $numRows = $result->num_rows;
                                        if ($numRows == 0) {
                                            $log->lwrite("Number of rows is {$numRows} for query: {$query}");
                                            insertTestResult($db, $testId, 'unredir', 'get', $currentUrl, $testUrl);
                                        }
                                    }
                                    $http->Close();
                                    break;
                                }
                            }
                        }
                    }
                    $http->Close();
                }
                if (strlen($error)) {
                    echo "<H2 align=\"center\">Error: ", $error, "</H2>\n";
                }
            }
        } else {
            $log->lwrite("Could not parse malformed URL: {$currentUrl}");
        }
    }
}
Example #9
0
function testForSQLi($urlToCheck, $urlOfSite, $testId)
{
    connectToDb($db);
    updateStatus($db, "Testing {$urlToCheck} for SQL Injection...", $testId);
    $log = new Logger();
    $log->lfile('logs/eventlogs');
    $log->lwrite("Starting SQL Injection test function on {$urlToCheck}");
    $postUrl = $urlToCheck;
    $postUrlPath = parse_url($postUrl, PHP_URL_PATH);
    //Check URL is not responding with 5xx codes
    $log->lwrite("Checking what response code is received from {$urlToCheck}");
    $http = new http_class();
    $http->timeout = 0;
    $http->data_timeout = 0;
    //$http->debug=1;
    $http->user_agent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)";
    $http->follow_redirect = 1;
    $http->redirection_limit = 5;
    $http->setTestId($testId);
    $error = $http->GetRequestArguments($urlToCheck, $arguments);
    $error = $http->Open($arguments);
    $log->lwrite("URL to be requested is: {$urlToCheck}");
    if ($error == "") {
        $log->lwrite("Sending HTTP request to {$urlToCheck}");
        $error = $http->SendRequest($arguments);
        if ($error == "") {
            $headers = array();
            $error = $http->ReadReplyHeaders($headers);
            if ($error == "") {
                $responseCode = $http->response_status;
                //This is a string
                $log->lwrite("Received response code: {$responseCode}");
                if (intval($responseCode) >= 500 && intval($responseCode) < 600) {
                    $log->lwrite("Response code: {$responseCode} received from: {$urlToCheck}");
                    return;
                }
            }
        }
        $http->Close();
    }
    if (strlen($error)) {
        echo "<H2 align=\"center\">Error: ", $error, "</H2>\n";
        $log->lwrite("Error: {$error}");
    }
    $html = file_get_html($postUrl, $testId);
    if (empty($html)) {
        //This can happen due to file_get_contents returning a 500 code. Then the parser won't parse it
        updateStatus($db, "Problem getting contents from {$urlToCheck}...", $testId);
        $log->lwrite("Problem getting contents from {$urlToCheck}");
        return;
    }
    $log->lwrite("Successfully got contents from {$urlToCheck}");
    //Defintion of all payloads used and warnings to examine for
    $arrayOfPayloads = array("'", '"', ';', ')', '(', '.', '--');
    //specified in webfuzz library (lib.webfuzz.js) from WebSecurify
    //From lib.webfuzz, some added by myself
    //The function checks for these errors after a payload is submitted
    $arrayOfSQLWarnings = array("supplied argument is not a valid MySQL", "mysql_fetch_array\\(\\)", "on MySQL result index", "You have an error in your SQL syntax;", "You have an error in your SQL syntax near", "MySQL server version for the right syntax to use", "\\[MySQL\\]\\[ODBC", "Column count doesn't match", "the used select statements have different number of columns", "Table '[^']+' doesn't exist", "DB Error: unknown error", ":[\\s]*mysql", "mysql_fetch", "System\\.Data\\.OleDb\\.OleDbException", "\\[SQL Server\\]", "\\[Microsoft\\]\\[ODBC SQL Server Driver\\]", "\\[SQLServer JDBC Driver\\]", "\\[SqlException", "System.Data.SqlClient.SqlException", "Unclosed quotation mark after the character string", "'80040e14'", "mssql_query\\(\\)", "odbc_exec\\(\\)", "Microsoft OLE DB Provider for ODBC Drivers", "Microsoft OLE DB Provider for SQL Server", "Incorrect syntax near", "Syntax error in string in query expression", "ADODB\\.Field \\(0x800A0BCD\\)<br>", "Procedure '[^']+' requires parameter '[^']+'", "ADODB\\.Recordset'", "Microsoft SQL Native Client error", "Unclosed quotation mark after the character string", "SQLCODE", "DB2 SQL error:", "SQLSTATE", "Sybase message:", "Syntax error in query expression", "Data type mismatch in criteria expression.", "Microsoft JET Database Engine", "\\[Microsoft\\]\\[ODBC Microsoft Access Driver\\]", "(PLS|ORA)-[0-9][0-9][0-9][0-9]", "PostgreSQL query failed:", "supplied argument is not a valid PostgreSQL result", "pg_query\\(\\) \\[:", "pg_exec\\(\\) \\[:", "com\\.informix\\.jdbc", "Dynamic Page Generation Error:", "Dynamic SQL Error", "\\[DM_QUERY_E_SYNTAX\\]", "has occurred in the vicinity of:", "A Parser Error \\(syntax error\\)", "java\\.sql\\.SQLException", "\\[Macromedia\\]\\[SQLServer JDBC Driver\\]");
    //First check does the URL passed into this function contain parameters and submit payloads as those parameters if it does
    $parsedUrl = parse_url($urlToCheck);
    $log->lwrite("Check if {$urlToCheck} contains parameters");
    if ($parsedUrl) {
        if (isset($parsedUrl['query'])) {
            $log->lwrite("{$urlToCheck} does contain parameters");
            $scheme = $parsedUrl['scheme'];
            $host = $parsedUrl['host'];
            $path = $parsedUrl['path'];
            $query = $parsedUrl['query'];
            parse_str($query, $parameters);
            $originalQuery = $query;
            foreach ($arrayOfPayloads as $currentPayload) {
                $http = new http_class();
                $http->timeout = 0;
                $http->data_timeout = 0;
                //$http->debug=1;
                $http->user_agent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)";
                $http->follow_redirect = 1;
                $http->redirection_limit = 5;
                $http->setTestId($testId);
                foreach ($parameters as $para) {
                    $query = $originalQuery;
                    $newQuery = str_replace($para, $currentPayload, $query);
                    $query = $newQuery;
                    $testUrl = $scheme . '://' . $host . $path . '?' . $query;
                    $log->lwrite("URL to be requested is: {$testUrl}");
                    $error = $http->GetRequestArguments($testUrl, $arguments);
                    $error = $http->Open($arguments);
                    if ($error == "") {
                        $log->lwrite("Sending HTTP request to {$testUrl}");
                        $error = $http->SendRequest($arguments);
                        if ($error == "") {
                            $headers = array();
                            $error = $http->ReadReplyHeaders($headers);
                            if ($error == "") {
                                $error = $http->ReadWholeReplyBody($body);
                                if (strlen($error) == 0) {
                                    $vulnerabilityFound = false;
                                    for ($warningIndex = 0; $warningIndex < sizeof($arrayOfSQLWarnings); $warningIndex++) {
                                        $regularExpression = "/{$arrayOfSQLWarnings[$warningIndex]}/";
                                        if (preg_match($regularExpression, $body)) {
                                            $log->lwrite("Found regular expression: {$regularExpression}, in body of HTTP response");
                                            $vulnerabilityFound = true;
                                            break;
                                        }
                                    }
                                    if ($vulnerabilityFound) {
                                        echo '<br>SQL Injection Present!<br>Query: ' . HtmlSpecialChars($urlToCheck) . '<br>';
                                        echo 'Method: GET <br>';
                                        echo 'Url: ' . HtmlSpecialChars($testUrl) . '<br>';
                                        echo 'Error: ' . $regularExpression . '<br>';
                                        $tableName = 'test' . $testId;
                                        //Check if this vulnerability has already been found and added to DB. If it hasn't, add it to DB.
                                        $sql = "SELECT * FROM test_results WHERE test_id = {$testId} AND type = 'sqli' AND method = 'get' AND url = '" . addslashes($testUrl) . "' AND attack_str = '" . addslashes($query) . "'";
                                        $result = $db->query($sql);
                                        if (!$result) {
                                            $log->lwrite("Could not execute query {$sql}");
                                        } else {
                                            $log->lwrite("Successfully executed query {$sql}");
                                            $numRows = $result->num_rows;
                                            if ($numRows == 0) {
                                                $log->lwrite("Number of rows is {$numRows} for query: {$sql}");
                                                insertTestResult($db, $testId, 'sqli', 'get', addslashes($testUrl), addslashes($query));
                                            }
                                            $result->free();
                                        }
                                        $http->Close();
                                        break 2;
                                    }
                                }
                            }
                        }
                        $http->Close();
                    }
                    if (strlen($error)) {
                        echo "<H2 align=\"center\">Error: ", $error, "</H2>\n";
                    }
                }
            }
        }
    } else {
        $log->lwrite("Could not parse malformed URL: {$urlToCheck}");
    }
    //Array containing all form objects found
    $arrayOfForms = array();
    //Array containing all input fields
    $arrayOfInputFields = array();
    $log->lwrite("Searching {$postUrl} for forms");
    $formNum = 1;
    //Must use an integer to identify form as forms could have same names and ids
    foreach ($html->find('form') as $form) {
        isset($form->attr['id']) ? $formId = htmlspecialchars($form->attr['id']) : ($formId = '');
        isset($form->attr['name']) ? $formName = htmlspecialchars($form->attr['name']) : ($formName = '');
        isset($form->attr['method']) ? $formMethod = htmlspecialchars($form->attr['method']) : ($formMethod = 'get');
        isset($form->attr['action']) ? $formAction = htmlspecialchars($form->attr['action']) : ($formAction = '');
        $formMethod = strtolower($formMethod);
        //If the action of the form is empty, set the action equal to everything
        //after the URL that the user entered
        if (empty($formAction)) {
            $strLengthUrl = strlen($urlToCheck);
            $strLengthSite = strlen($urlOfSite);
            $firstIndexOfSlash = strpos($urlToCheck, '/', $strLengthSite - 1);
            $formAction = substr($urlToCheck, $firstIndexOfSlash + 1, $strLengthUrl);
        }
        $log->lwrite("Found form on {$postUrl}: {$formId} {$formName} {$formMethod} {$formAction} {$formNum}");
        $newForm = new Form($formId, $formName, $formMethod, $formAction, $formNum);
        array_push($arrayOfForms, $newForm);
        foreach ($form->find('input') as $input) {
            isset($input->attr['id']) ? $inputId = htmlspecialchars($input->attr['id']) : ($inputId = '');
            isset($input->attr['name']) ? $inputName = htmlspecialchars($input->attr['name']) : ($inputName = '');
            isset($input->attr['value']) ? $inputValue = htmlspecialchars($input->attr['value']) : ($inputValue = '');
            isset($input->attr['type']) ? $inputType = htmlspecialchars($input->attr['type']) : ($inputType = '');
            $log->lwrite("Found input field on {$postUrl}: {$inputId} {$inputName} {$formId} {$formName} {$inputValue} {$inputType} {$formNum}");
            $inputField = new InputField($inputId, $inputName, $formId, $formName, $inputValue, $inputType, $formNum);
            array_push($arrayOfInputFields, $inputField);
        }
        $formNum++;
    }
    //Begin testing each of the forms
    $log->lwrite('Beginning testing of forms');
    for ($i = 0; $i < sizeof($arrayOfForms); $i++) {
        $currentForm = $arrayOfForms[$i];
        $currentFormId = $currentForm->getId();
        $currentFormName = $currentForm->getName();
        $currentFormMethod = $currentForm->getMethod();
        $currentFormAction = $currentForm->getAction();
        $currentFormNum = $currentForm->getFormNum();
        $arrayOfCurrentFormsInputs = array();
        $log->lwrite("Beginning testing of form on {$postUrl}: {$currentFormId} {$currentFormName} {$currentFormMethod} {$currentFormAction}");
        echo sizeof($arrayOfInputFields) . "<br>";
        for ($j = 0; $j < sizeof($arrayOfInputFields); $j++) {
            $currentInput = $arrayOfInputFields[$j];
            $currentInputIdOfForm = $currentInput->getIdOfForm();
            $currentInputNameOfForm = $currentInput->getNameOfForm();
            $currentInputFormNum = $currentInput->getFormNum();
            //Check if the current input field belongs to the current form and add to array if it does
            if ($currentFormNum == $currentInputFormNum) {
                array_push($arrayOfCurrentFormsInputs, $currentInput);
            }
        }
        $log->lwrite("Beginning testing input fields of form on {$postUrl}: {$currentFormId} {$currentFormName} {$currentFormMethod} {$currentFormAction}");
        for ($k = 0; $k < sizeof($arrayOfCurrentFormsInputs); $k++) {
            echo sizeof($arrayOfCurrentFormsInputs) . '<br>';
            for ($plIndex = 0; $plIndex < sizeof($arrayOfPayloads); $plIndex++) {
                $currentFormInput = $arrayOfCurrentFormsInputs[$k];
                $currentFormInputName = $currentFormInput->getName();
                $currentFormInputType = $currentFormInput->getType();
                $currentFormInputValue = $currentFormInput->getValue();
                if ($currentFormInputType != 'reset') {
                    $http = new http_class();
                    $http->timeout = 0;
                    $http->data_timeout = 0;
                    //$http->debug=1;
                    $http->user_agent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)";
                    $http->follow_redirect = 1;
                    $http->redirection_limit = 5;
                    $http->setTestId($testId);
                    $defaultStr = 'Abc123';
                    $arrayOfValues = array();
                    //Array of PostOrGetObject objects
                    //Get the other input values and set them equal to the default string
                    $otherInputs = array();
                    for ($l = 0; $l < sizeof($arrayOfCurrentFormsInputs); $l++) {
                        if ($currentFormInput->getName() != $arrayOfCurrentFormsInputs[$l]->getName()) {
                            array_push($otherInputs, $arrayOfCurrentFormsInputs[$l]);
                        }
                    }
                    $postObject = new PostOrGetObject($currentFormInputName, $arrayOfPayloads[$plIndex]);
                    $log->lwrite("Submitting payload: {$arrayOfPayloads[$plIndex]}, to input field: {$currentFormInputName}");
                    //Add current input and other to array of post values and set their values
                    array_push($arrayOfValues, $postObject);
                    for ($m = 0; $m < sizeof($otherInputs); $m++) {
                        $currentOther = $otherInputs[$m];
                        $currentOtherType = $currentOther->getType();
                        $currentOtherName = $currentOther->getName();
                        $currentOtherValue = $currentOther->getValue();
                        if ($currentOtherType == 'text' || $currentOtherType == 'password') {
                            $postObject = new PostOrGetObject($currentOtherName, $defaultStr);
                            array_push($arrayOfValues, $postObject);
                        } else {
                            if ($currentOtherType == 'checkbox' || $currentOtherType == 'submit') {
                                $postObject = new PostOrGetObject($currentOtherName, $currentOtherValue);
                                array_push($arrayOfValues, $postObject);
                            } else {
                                if ($currentOtherType == 'radio') {
                                    $postObject = new PostOrGetObject($currentOtherName, $currentOtherValue);
                                    //Check if a radio button in the radio group has already been added
                                    $found = false;
                                    for ($n = 0; $n < sizeof($arrayOfValues); $n++) {
                                        if ($arrayOfValues[$n]->getName() == $postObject->getName()) {
                                            $found = true;
                                            break;
                                        }
                                    }
                                    if (!$found) {
                                        array_push($arrayOfValues, $postObject);
                                    }
                                }
                            }
                        }
                    }
                    echo '<br><br>';
                    if ($currentFormMethod == 'get') {
                        //Build query string and submit it at end of URL
                        if ($urlOfSite[strlen($urlOfSite) - 1] == '/') {
                            $actionUrl = $urlOfSite . $currentFormAction;
                        } else {
                            $actionUrl = $urlOfSite . '/' . $currentFormAction;
                        }
                        $totalTestStr = '';
                        //Compile a test string to show the user how the vulnerability was tested for
                        for ($p = 0; $p < sizeof($arrayOfValues); $p++) {
                            $currentPostValue = $arrayOfValues[$p];
                            $currentPostValueName = $currentPostValue->getName();
                            $currentPostValueValue = $currentPostValue->getValue();
                            $totalTestStr .= $currentPostValueName;
                            $totalTestStr .= '=';
                            $totalTestStr .= $currentPostValueValue;
                            if ($p != sizeof($arrayOfValues) - 1) {
                                $totalTestStr .= '&';
                            }
                        }
                        if (strpos($actionUrl, '?') !== false) {
                            //url may be something like domain.com?id=111 so don't want to add another question mark if it is
                            $actionUrl .= '&';
                        } else {
                            $actionUrl .= '?';
                        }
                        $actionUrl .= $totalTestStr;
                        $error = $http->GetRequestArguments($actionUrl, $arguments);
                        $error = $http->Open($arguments);
                        $log->lwrite("URL to be requested is: {$actionUrl}");
                        if ($error == "") {
                            $log->lwrite("Sending HTTP request to {$actionUrl}");
                            $error = $http->SendRequest($arguments);
                            if ($error == "") {
                                $headers = array();
                                $error = $http->ReadReplyHeaders($headers);
                                if ($error == "") {
                                    $error = $http->ReadWholeReplyBody($body);
                                    if (strlen($error) == 0) {
                                        $vulnerabilityFound = false;
                                        for ($warningIndex = 0; $warningIndex < sizeof($arrayOfSQLWarnings); $warningIndex++) {
                                            $regularExpression = "/{$arrayOfSQLWarnings[$warningIndex]}/";
                                            if (preg_match($regularExpression, $body)) {
                                                $log->lwrite("Found regular expression: {$regularExpression}, in body of HTTP response");
                                                $vulnerabilityFound = true;
                                                break;
                                            }
                                        }
                                        if ($vulnerabilityFound) {
                                            //If the body returned from the request contains ones of the errors, the
                                            //SQL Injection vulnerabiltiy is present
                                            $totalTestStr = '';
                                            //Compile a test string to show the user how the vulnerability was tested for
                                            for ($p = 0; $p < sizeof($arrayOfValues); $p++) {
                                                $currentPostValue = $arrayOfValues[$p];
                                                $currentPostValueName = $currentPostValue->getName();
                                                $currentPostValueValue = $currentPostValue->getValue();
                                                $totalTestStr .= $currentPostValueName;
                                                $totalTestStr .= '=';
                                                $totalTestStr .= $currentPostValueValue;
                                                if ($p != sizeof($arrayOfValues) - 1) {
                                                    $totalTestStr .= '&';
                                                }
                                            }
                                            $currentFormMethod = strtolower($currentFormMethod);
                                            echo 'SQL Injection Present!<br>Query: ' . HtmlSpecialChars($totalTestStr) . '<br>';
                                            echo 'Method: ' . $currentFormMethod . '<br>';
                                            echo 'Url: ' . HtmlSpecialChars($actionUrl) . '<br>';
                                            echo 'Error: ' . $regularExpression . '';
                                            $tableName = 'test' . $testId;
                                            //Check if this vulnerability has already been found and added to DB. If it hasn't, add it to DB.
                                            $query = "SELECT * FROM test_results WHERE test_id = {$testId} AND type = 'sqli' AND method = '{$currentFormMethod}' AND url = '" . addslashes($actionUrl) . "' AND attack_str = '" . addslashes($totalTestStr) . "'";
                                            $result = $db->query($query);
                                            if (!$result) {
                                                $log->lwrite("Could not execute query {$query}");
                                            } else {
                                                $log->lwrite("Successfully executed query {$query}");
                                                $numRows = $result->num_rows;
                                                if ($numRows == 0) {
                                                    $log->lwrite("Number of rows is {$numRows} for query: {$query}");
                                                    insertTestResult($db, $testId, 'sqli', $currentFormMethod, addslashes($actionUrl), addslashes($totalTestStr));
                                                }
                                                $result->free();
                                            }
                                            $http->Close();
                                            break;
                                        }
                                    }
                                }
                            }
                            $http->Close();
                        }
                        if (strlen($error)) {
                            echo "<H2 align=\"center\">Error: ", $error, "</H2>\n";
                        }
                    } else {
                        if ($currentFormMethod == 'post') {
                            //Start sending requests with the values in the post values array
                            //Build query string and submit it at end of URL
                            if ($urlOfSite[strlen($urlOfSite) - 1] == '/') {
                                $actionUrl = $urlOfSite . $currentFormAction;
                            } else {
                                $actionUrl = $urlOfSite . '/' . $currentFormAction;
                            }
                            $error = $http->GetRequestArguments($actionUrl, $arguments);
                            $arguments["RequestMethod"] = "POST";
                            $arguments["PostValues"] = array();
                            for ($p = 0; $p < sizeof($arrayOfValues); $p++) {
                                $currentPostValue = $arrayOfValues[$p];
                                $currentPostValueName = $currentPostValue->getName();
                                $currentPostValueValue = $currentPostValue->getValue();
                                $tempArray = array($currentPostValueName => $currentPostValueValue);
                                $arguments["PostValues"] = array_merge($arguments["PostValues"], $tempArray);
                            }
                            $error = $http->Open($arguments);
                            $log->lwrite("URL to be requested is: {$actionUrl}");
                            if ($error == "") {
                                $log->lwrite("Sending HTTP request to {$actionUrl}");
                                $error = $http->SendRequest($arguments);
                                if ($error == "") {
                                    $headers = array();
                                    $error = $http->ReadReplyHeaders($headers);
                                    if ($error == "") {
                                        $error = $http->ReadWholeReplyBody($body);
                                        if (strlen($error) == 0) {
                                            $vulnerabilityFound = false;
                                            for ($warningIndex = 0; $warningIndex < sizeof($arrayOfSQLWarnings); $warningIndex++) {
                                                $regularExpression = "/{$arrayOfSQLWarnings[$warningIndex]}/";
                                                if (preg_match($regularExpression, $body)) {
                                                    $log->lwrite("Found regular expression: {$regularExpression}, in body of HTTP response");
                                                    $vulnerabilityFound = true;
                                                    break;
                                                }
                                            }
                                            if ($vulnerabilityFound) {
                                                //If the body returned from the request contains one of the errors specified, the
                                                //SQL Injection vulnerabiltiy is present
                                                $totalTestStr = '';
                                                //Compile a test string to show the user how the vulnerability was tested for
                                                for ($p = 0; $p < sizeof($arrayOfValues); $p++) {
                                                    $currentPostValue = $arrayOfValues[$p];
                                                    $currentPostValueName = $currentPostValue->getName();
                                                    $currentPostValueValue = $currentPostValue->getValue();
                                                    $totalTestStr .= $currentPostValueName;
                                                    $totalTestStr .= '=';
                                                    $totalTestStr .= $currentPostValueValue;
                                                    if ($p != sizeof($arrayOfValues) - 1) {
                                                        $totalTestStr .= '&';
                                                    }
                                                }
                                                $currentFormMethod = strtolower($currentFormMethod);
                                                echo 'SQL Injection Present!<br>Query: ' . HtmlSpecialChars($totalTestStr) . '<br>';
                                                echo 'Method: ' . $currentFormMethod . '<br>';
                                                echo 'Url: ' . HtmlSpecialChars($actionUrl) . '<br>';
                                                echo 'Error: ' . $regularExpression . '';
                                                $tableName = 'test' . $testId;
                                                //Check if this vulnerability has already been found and added to DB. If it hasn't, add it to DB.
                                                $query = "SELECT * FROM test_results WHERE test_id = {$testId} AND type = 'sqli' AND method = '{$currentFormMethod}' AND url = '{$actionUrl}' AND attack_str = '" . addslashes($totalTestStr) . "'";
                                                $result = $db->query($query);
                                                if (!$result) {
                                                    $log->lwrite("Could not execute query {$query}");
                                                } else {
                                                    $log->lwrite("Successfully executed query {$query}");
                                                    $numRows = $result->num_rows;
                                                    if ($numRows == 0) {
                                                        $log->lwrite("Number of rows is {$numRows} for query: {$query}");
                                                        insertTestResult($db, $testId, 'sqli', $currentFormMethod, $actionUrl, addslashes($totalTestStr));
                                                    }
                                                    $result->free();
                                                }
                                                $http->Close();
                                                break;
                                            }
                                        }
                                    }
                                }
                                $http->Close();
                            }
                            if (strlen($error)) {
                                echo "<H2 align=\"center\">Error: ", $error, "</H2>\n";
                            }
                        }
                    }
                }
            }
        }
    }
}