Securing your Database and Protecting User Data

Download Report

Transcript Securing your Database and Protecting User Data

Securing your Databases and Protecting
User Data: A risk-based approach
MSSD-3 — третья по счету
конференция, посвященная
всестороннему обсуждению
популярной и важной темы –
минимизация уязвимостей
программного обеспечения при его
разработке.
About me
 Principal Program Manager, Business Platform Security
Services
 Formerly worked on security training and policy for Microsoft
Security Engineering Center
 Former vulnerability team leader, CERT/CC
 Former database administrator and developer
About this deck
 Database systems are complex
 I use the word systems intentionally
 You have to secure the servers and the applications that
access the server
 Priority and degree of scrutiny depend on risk
 We’ll look at some problems through the eyes of some great
historical figures to illustrate some security development
principles
Great figures in history as security engineers
William Shakespeare
Eleanor Roosevelt
Jawaharlal Nehru
William Shakespeare as security engineer
We will demonstrate
Shakespeare's credibility as
a security engineer by
looking at the history of
SQL injection and a 1996era vulnerability in a
popular CGI webform
string Status = "No";
SQL injection – C#
string sqlstring ="";
Embedded, hard to guess
try {
password!
SqlConnection sql= new SqlConnection(
@"data source=localhost;" +
"user id=sa;password=password;");
String concat
sql.Open();
for dynamic SQL
Connecting
sqlstring="SELECT HasShipped" +
as sysadmin
" FROM Shipment WHERE ID='" + Id + "'";
SqlCommand cmd = new SqlCommand(sqlstring,sql);
if ((int)cmd.ExecuteScalar() != 0)
Status = "Yes";
} catch (SqlException se) {
Status = sqlstring + " failed\n\r";
foreach (SqlError e in se.Errors) {
Status += e.Message + "\n\r";
Telling the
}
bad guy
} catch (Exception e) {
too much on failure
Status = e.ToString();
}
Why it’s wrong (1)
sqlstring="SELECT HasShipped" +
" FROM Shipment WHERE ID='" + Id + "'";
Good guy
SELECT HasShipped
FROM Shipment
WHERE ID='1001'
Not so good guy
SELECT HasShipped
FROM Shipment
WHERE ID= '1001' or 2>1 -- '
Why it’s wrong (2)
sqlstring="SELECT HasShipped" +
" FROM Shipment WHERE ID='" + Id + "'";
Really bad guy
SELECT HasShipped
FROM Shipment
WHERE ID= '1001' drop table orders -- '
Downright evil guy
xp_cmdshell is not enabled by
default on recent versions of SQL
SELECT HasShipped
FROM Shipment
WHERE ID= '1001' exec xp_cmdshell('...') -- '
SQL injection hits the big time
 For many years, “common wisdom” held that SQL injection
required detailed knowledge of the victim’s application
 By 2008, however, attackers had figured out how to
automatically identify the structure of a web application to
perform mass SQL injection without a priori detailed
knowledge of the victim
 There are (in hindsight) clear trends that could have predicted
this
SQL injection “heat map”
Source: Microsoft Security Intelligence Report, Volume 9
http://www.microsoft.com/security/sir/default.aspx
Not including TLDs
Was there a warning for SQL injection?
 Yes
 “SQL Injection” is just a sub class of a class of vulnerabilities
known as command injection
 Command injection has its own long history, of which SQL
injection is just one prominent part
 The name "SQL injection" may cause database security
activities to be limited to SQL injection
An early command injection vul: PhF
 CVE-1999-0067 (disclosed 1996)
 PhF takes an argument from a web page, usually a name, and constructs a
UNIX shell command to look up the name in the phone book, something
like
$ ph hernan
 This returns directory information about 'hernan'
 Shipped with NCSA httpd and Apache httpd
Command injection in PhF
 Command injection was well known at the time PhF was
written, and the authors guarded against some attacks such
as
$ ph hernan ; rm *
 Here the attacker entered 'hernan ; rm *' as the argument,
but PhF filtered semicolons and other metacharacters …
except one: newline
Exploiting PhF
 So, to exploit PhF, all you needed was to enter a newline in
the argument, which was easy with URL encoding
$ ph hernan
$ rm *
 Here the attacker entered 'hernan<cr>rm *'
Similarities
 Command injection in PhF and SQL injection in PhF are
extremely similar
 A web interface takes a string and gives it to a command subsystem
 That subsystem uses that string to build a command
 Nothing sanitizes characters that have special meaning to the command
subsystem
 SQL is a much richer, more powerful environment however,
which has led to a longer lifetime of SQL injection attacks as
compared to PhF command injection
What’s this have to do with Shakespeare?
“What’s past is
prologue”
I
—The Tempest, Act 2, Scene
Eleanor Roosevelt as security engineer
We will demonstrate Mrs.
Roosevelt’s credibility as a
security engineer by
looking at padding oracles
in database systems
Basic oracle model
“What is the
meaning of
life?”
“42”
Informally, an “oracle” answers a question
for you. A “padding oracle” gives you
information about the padding bits in an
encrypted text. When a padding oracle
exists, it is quite powerful.
A padding oracle
“Yes”
“Are you able to
successfully decrypt
this text?”
or
“No, because the
padding is invalid.”
When an oracle will answer a question in this
fashion, it is a “padding oracle,” and attackers
can use it to decrypt a ciphertext or encrypt
a plaintext without access to the key. I’ll give
an intuitive understanding of how it works.
Understanding padding oracles
Cipher-block chaining (CBC) decryption:
P1
IV
Plaintext
P2
P3
P4
Intermediate
decrypted
Text
Intermediate
decrypted
Text
Intermediate
decrypted
Text
Intermediate
decrypted
Text
C1
C2
C3
C4
Ciphertext
For the attack to be meaningful, the attacker has to be able to submit an arbitrary
ciphertext for decryption
Padding formats
 There are a variety of ways to pad the data
 One format looks like this
Length of data
Data
Padding (possibly empty)
All of this gets encrypted in CBC mode
Revisiting decryption
P1
IV
Plaintext
The decryption engine flips the
corresponding bit here
P2
P3
P4
Intermediate
decrypted
Text
Intermediate
decrypted
Text
Intermediate
decrypted
Text
Intermediate
decrypted
Text
C1
C2
C3
C4
Attacker flips a
bit here
Ciphertext
Encrypted padding
block
Remember that the attacker controls the cipher text he submits for decryption.
Bit flips
 Now flip a bit in the next-to-last ciphertext block
 This will flip a bit in the last plaintext block
 This last bit is either
 Part of the data
 Part of the padding
 If it is part of the data, the decryption will succeed
 If it is part of the padding, the decryption will fail
 If the application lets the attacker tell the difference between
success and failure, you leak information about one bit in the last
block
What can you do with the length?
By choosing the IV, the attacker can make the decrypted
length be whatever he wants with a little Boolean algebra
Attacker can
manipulate IV
IV
Plaintext
Intermediate
decrypted
text
Intermediate
decrypted
text
Intermediate
decrypted
text
Intermediate
decrypted
text
Length
Data
Data
Data|Pad
Encrypted length
block
Ciphertext
Encrypted padding
block
Getting the first (last) bit
 Submit to the oracle the following ciphertext
 C’ = IV’ | C1 | R | Ck where




C1 is the length block
R is a random block
Ck is the block you want to decrypt
IV’ is (2n -1)
(L)
(IV)
 This results in a decrypted length of 2n-1, meaning that there
should be a ‘0’ in the last bit
 If the last bit is 0, the decryption succeeds, otherwise, the
decryption fails
Graphically
Choose the IV such that the length is (2n-1),
meaning that the last bit here must be a '0'
Attacker can
manipulate IV
Plaintext
Decrypted
text
Chosen IV
Length
Decrypted
text
Decrypted
text
Random
Target
Ciphertext
Getting the next bit
 Choose IV’ such that the length is (2n-2)
 This means that there must be two ‘0’s at the end of the last
block to get a valid decryption
 You can ensure that the last bit is ‘0’ by flipping (or not) the
last bit of the random ciphertext block
 Then, if you get a valid decryption, you know the next-tolast bit is 0; otherwise it must be a 1
In summary
“Are you able to successfully decrypt this
text? Okay, let me change it a bit. What
about this one? And this one? And this
one?”
“Yes”
or
“No, because the
padding is invalid.”
By repeatedly asking the padding oracle
about the padding of the attacker’s
chosen ciphtertext, the attacker can
recover the original ciphertext text bit by
bit.
Do padding oracles exist in Microsoft SQL
Server?
 No, they do not
 In order to encrypt and decrypt anything in SQL, you need access to the key,
which is itself a securable object
 Anyone who has access to the key is by definition not an attacker
 But someone could write an application that created a
padding oracle
A SQL padding oracle
Create symmetric key DemoKey with algorithm = AES_256 encryption by password = 'Do not use this password!';
CREATE TABLE CryptoTable( PlainText varchar(200), CipherText varbinary (200))
open symmetric key DemoKey decryption by password = 'Do not use this password!';
insert into CryptoTable values (N'Some Data is Better than No Data', encryptbykey(key_guid('DemoKey'), N'Some Data is
Better than No Data'))
SELECT CONVERT( nvarchar(100), decryptbykey(CryptoTable.CipherText)) FROM CryptoTable
select * from CryptoTable
insert into CryptoTable values ('Some Data',
0x00643BF967FEA64684B38BBF5E874A7C010000006AE8686787135388420E2CD90AD450EE02D17AA8622B52A517E9D493
D3ED8801CCF36BA3B8AECD919023443C7EF6A2CD7B952527292D7BDDDE1DFA7A3E4BB493958408CCE66AEBF5CE54C23
7CFEEDE006C506BAD3829EA4BE8C7FD84AAF252C5);
What does this have to do with Eleanor Roosevelt?
“Learn from the mistakes
of others. You can’t live
long enough to make
them all yourself.”
Nehru as security engineer
We’ll explore the
capabilities of Jawaharlal
Nehru as a security
engineer by looking at
some code and data flows
Math is hard, especially for computers
What will these two snippets produce? By show of hands…
unsigned short c = 10;
signed int x;
unsigned short c = 10;
signed int x;
x = c = ~c;
x = ~c;
c = ~c;
if (x ==c) printf("True")
else printf("False");
True
if (x ==c) printf("True")
else printf("False");
False
See SQL injection?
CREATE PROCEDURE sp_setPassword
@username varchar(25),
@old varchar(25),
@new varchar(25)
AS
DECLARE @command varchar(100)
SET @command= ‘update Users set password=‘ +
QUOTENAME(@new,’’’’) + ‘ where username=‘ +
QUOTENAME(@username,’’’’) + ‘ AND password = ‘ +
QUOTENAME(@old,’’’’)
EXEC (@command)
GO
What’s this have to do with Nehru?
“Let us be a little humble;
let us think that the truth
may not perhaps be
entirely with us.“
Database systems are complex
 A database system is not just the server, but also all the
applications
 Too often, people want to secure the data by simply enabling
features in the database
 Necessary, but not sufficient
 Evaluate the risks in the system as a whole, do not merely
“secure the database”
 Do not build steel doors in paper walls
 Evaluate the applications as thoroughly as the database server, commensurate
with the risk
Conclusions
 Learn from history: Encode and embed your collected wisdom in
your development process to never make the same mistake twice
 Learn from the mistakes of others: Practice active threat modeling
to bring the benefits of others mistakes to your own systems and
services
 Be humble: Constantly improve your processes and practices to
respond to contemporary problems and don’t mistake compliance
for security—security is a journey, compliance is a state
 A formalized Security Development Lifecycle process addresses all
of these and should be applied to all database systems
Questions?
 Questions?
Thank you
Спасибо за внимание