0290280 - MacKay Wilford

Weekly assignment for lesson 5

What am I ... a cracker?

A cracker is a person that breaks into a computer system, typically for an illegitimate purpose. Sometimes these people are improperly referred to as hackers. A cracker is just a bad and evil hacker.

This week we will introduce a mechanism for testing your scripts, by simulating harmless cracking attempts. The goal of these exercises is to help you understand the vulnerabilities of HTML forms and PHP scripts. Anyone can set up fake forms to access your PHP scripts, and if you don't take the appropriate countermeasures, such attempts can result in damage to a database or reveal sensitive password, server or filesystem information.

Of course, none of these exercises will attempt anything like that. Their only purpose is to illustrate how easy it is for a cracker to infiltrate an unprotected script. If you're curious about the exact methods that we're using, all you have to do is to view the source of this page in your editor or browser, focusing on the test buttons' HTML.

In order for you to work these exercises successfully, you must have access to PHP errors. Before you proceed, be sure that full error reporting capabilities are enabled on your server. (The base file for each script contains the correct runtime code. Do not remove this code.)

Before submitting your work, be sure that you have run all of the tests and that your script handles them successfully. This means that your script must perform the tasks required without warnings or notices from the PHP interpreter. To run the tests, all you have to do is press the buttons that accompany each exercise.

Example no. 1

Example

This is not an exercise. It's just an example script to help you see how cracking attempts work. Under normal conditions, this script works well; however, simple cracking attempts show how vulnerable it is.

Please look at the example1.php file. This script is an intentional mix of bad programming techniques and weak security defenses.

The form contains a select box (identified by the NAME="bands" attribute) which lists a few famous rock bands. Look at the source code, then play with the test buttons you find below to see how the script reacts to the cracking attempt. Note that all we're doing to crack this script is to call it with a different form.

One thing that you'll notice immediately is that the example intentionally lacks any sort of string cleaning procedure.

This is for illustration only. We want you to see for yourself how simple it is to crack a form and to understand why you should always clean incoming data. In the real world, we would never create a form-processing script that does not clean its input.

Look at the source code of the script. When it works properly it should perform the following tasks:

  1. If the bands variable has been set, is an array and has at least one element, the script should loop through each of the array elements and display the value(s) in an unordered list;
  2. otherwise, display a message that no data has been submitted.
No HTML output preparation is performed. Pay attention to what this implies, especially when you run test #3.

Tests

Read and run the following tests and observe the warnings/errors in the source code. Note any strange or bad behaviour and locate the possible cause in the source code. This will give you useful hints for the real assignment.

Test one

This test calls the example script using the POST method, but without sending any data.

Test two

This test calls the example script using the POST method, but passes a variable called bands which is not an array.

Test three

This test calls the example script using the POST method and passes an array called bands with two values. One value contains special HTML characters (an ampersand (&). The other value attempts to inject a JavaScript. (Depending on your magic quotes setting, the JavaScript may or may not execute.)

Quick Link

Exercise no. 1

Required

Please use the exercise1.php file as base for your exercise. The main objective for this exercise is for you to become familiar with check boxes and multi-select fields, which result in arrays.

You have been given an associative array called $rock_bands which contains the names of rock bands from the sixties onwards.

The structure of the array is very simple: the key of the array is a two characters string which uniquely identifies the band; the associated value is the full band name.

Example: $rock_bands['be'] is 'The Beatles'.

$rock_bands = array( 'be' => 'The Beatles', 'rs' => 'The Rolling Stones', 'cc' => 'Creedence Clearwater Revival', 'lz' => 'Led Zeppelin', 'ls' => 'Lynyrd Skynyrd', 'do' => 'The Doors', 'jt' => 'Jethro Tull', 'oa' => 'Oasis', 'ac' => 'ACDC', 'pf' => 'Pink Floyd', 'u2' => 'U2', 'gr' => 'Guns n\' Roses', 'dm' => 'Dave Matthews Band' );

Your objective is to use the same array (data source) for three distinct purposes:

  1. Automatically generate the select box (or check box if you prefer).
  2. Perform deep validation of incoming data by matching the submitted values against the expected values that are defined in the array.
  3. Display user-friendly descriptions, in this case the full name of each selected band.
Using one single data source for multiple purposes reduces coding errors.

In order to pass the exercise, your script must accomplish the following tasks and pass the tests (below) without generating any PHP warnings, notices or errors.

  1. Write the select box (or a set of checkboxes), which displays the full band name as the OPTION text (or checkbox label) but sends the $rock_bands key as the value.
  2. Perform a generic cleaning procedure for both scalar and array values. (See the lollipolooza3.php example from the lecture for more detailed information.)
  3. Test the $_POST['bands'] array to be sure it has been properly submitted: It must be set; it must be an array; and it must contain at least one element. (See the lecture and the comments in the first example's source to get an idea of what this means.)
    1. If it fails any of these tests, set the $errors['bands'] variable to the literal 'Please select a band.'
    2. Otherwise perform deep validation on the data. That is, foreach submitted value:
      1. Test to be sure the submitted value exists as a key in the $rock_bands array.
      2. The first time that you encounter an entry that is not allowed, set the $errors['bands'] variable to the literal 'Please use the form to submit a vote' and exit the loop. (You can use the break statement for this.)
  4. If there are no errors, properly display the results using a loop.
  5. Otherwise, display the error.

Tests

The buttons below are examples of cracking attempts. In order to pass the assignment, your script must resist to all of them. Your script shouldn't produce any PHP parser errors or warnings or HTML validation problems (such as incomplete termination). Instead, the script itself should trap problems and writing out error messages that deal with those problems. Here's what you should see:

Your exercise is complete when you have completed all of the tasks in the task list and your script passes all of the test buttons successfully.

Test one

This test calls your script using the POST method, but without sending any data. Your script should be able to intercept it properly.

Test two

This test calls your script using the POST method, but passes a variable called bands which is not an array.

Test three

This test calls your script using the POST method and passes an array called bands with a value that is not one of the valid values.

Test four

This test calls your script using the POST method and passes an array called bands with a few valid values.

Quick Link

Grading (for instructors)

Exercise no. 2

Required

Description

Please use the exercise2.php file as base for your exercise. The main objectives for this exercise are for you to practice creating a sticky form with select boxes and practice validating a date (optional).

First, take a look at the online solution. Play with it a bit and observe its behaviour. Observe carefully because your exercise will involves exactly reproducing that behaviour.

  1. Write a form with the following three named select boxes. Automatically generate the OPTIONs using a while loop.

    1. dd: day of the month (loop from 1 to 31)
    2. mm: month (loop from 1 to 12)
    3. yy: year (loop from 1945 to 2020)
  2. Make the form sticky. How? Within each of the three while loops (above),
    1. check to see if the user has submitted the data.
      1. If so,test the data to see if it matches the value that is currently being looped.
        1. If so,properly set the selected HTML attribute for the current option.
  3. In the submitted state:
    1. Check to be sure all three fields are set; if not, issue an error.
    2. Check to be sure all three submitted fields are numbers. There is more than one way to do this: You can use the is_numeric or you can explicitly cast the incoming values as integers. This latter is strongly recommended because it make string cleaning procedures unnecessary for security reasons. If you detect anything that is not a number, issue an error.
  4. OPTIONAL: Use checkdate() to check the data that the user just submitted.
  5. Required for all: Be sure your script passes the test buttons (below) without parser errors, warnings or notices.

Hints and Restrictions

  1. The form METHOD must be POST and the ACTION should be set to $_SERVER['PHP_SELF'].
  2. The three SELECTs must be named as indicated above (dd, mm, yy): This is not optional; failure to follow this naming protocol will cause you a great deal of grief when you attempt to test your script against the test buttons (below).
  3. Share the same form HTML code for both the GET and POST phases. Note to experienced programmers: Please do this without creating a function.
  4. If you use explicit casting on the incoming data, it will insure that you either have a number to work with or 0 (which would indicate a cracking attempt).

Tests

In order to pass the assignment, your script must resist to all of the cracking attempts below without producing any PHP errors, warnings or notices. IMPORTANT: When generating SELECT lists, PHP errors can become "buried" between OPTION tags. When this happens, the only way to see the errors is to view the HTML source. Be sure to check your HTML source as well as the browser display.

Test one

This test calls your script using the POST method, but without sending any data. Your script should be able to intercept it properly (by using of the isset function)and display a (generic) warning or error message.

Test two

This test submits three "junk" strings instead of three numbers. Your script should detect the invalid submission and issue a generic error.

Test three (optional only)

Now it's time to check whether the date that's been submitted is valid. In this case, we're using the (invalid) date, February 31 2007. In order to pass this test, your script should implement a sticky form, which means that the form selects should be set to 31 (day), 2 (month) and 2007 (year), and it should issue an error. (Hint: When you get an invalid value, it's not a good idea to print that value; merely indicate that the submitted value was invalid.)

Test four

Finally, let's check for a valid date, January 1 2007. If you have not implemented the optional task, your form should still be sticky. That is, it should properly show the selected values—1 for the day, 1 for the month and 2007 for the year—in the SELECT option windows.

Quick Link

Grading (for instructors)

Exercise no. 3

Optional

Description

Please use the exercise3.php file as base for your exercise. The main objectives for this exercise are for you to:

You may be as creative as you like for this exercise. As with last week's optional exercise, the online solutionis quite simple and does not represent a real life scenario. Observe its behaviour and, using reverse-engineering, build your own application. Part of your exercise is to find a real life scenario that allows you to use:

Quick Link

Grading (for instructors)