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. We move on to examining authentication and authorization and then move to the logical layout of the database.

Oracle Processes and Oracle on the Network

This section describes the major components of Oracle and their interaction with the network. We begin with perhaps the most crucial network- facing component, the TNS Listener.

The Oracle TNS Listener

The TNS Listener is the hub of all communications in Oracle. "TNS" stands for Transparent Network Substrate and this is the protocol that Oracle uses to communicate between client and server. The TNS protocol is described on the Ethereal web site at http://www.ethereal.com/docs/dfref/t/tns.html .

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. This lets the TNS Listener know that the database server is ready to accept connections. Incidentally, although the service_register_NSGR command is intended to be used locally the command can be sent over the network. In the past there have been denial of service issues with this command that can kill the TNS Listener.

When a client wishes to access the database server, the client connects first to the Listener. The Listener replies back with a TCP port that the client should connect to. The client connects to this port and then authenticates to the database server. If, however, the database has been configured in MTS, or Multi Threaded Server, mode then no port is assigned as such and communication with the database server takes place over the same TCP port that the Listener is listening on. The TNS Listener usually listens on TCP port 1521 but, depending upon the version of Oracle and what applications have been installed this port may be different, for example 1526. Regardless, the TNS Listener can be configured to listen on any TCP port.

The TNS Listener is also integral to PL/SQL and external procedures that we'll talk about later. 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. Extproc loads the library and executes the required function. As you'll see later this can be abused by attackers to run commands without a user ID or password.

If the XML Database is enabled ”and it is by default in Oracle 9 and later ”the TNS Listener holds open TCP port 2100 and 8080. The former allows querying of XML data over the FTP protocol and the latter over HTTP. The Listener proxies traffic on these ports to the RDBMS.

In versions of Oracle prior to 10g, the TNS Listener could be administered remotely. What makes this particularly dangerous is the fact that by default the Listener is installed without a password so it is possible for anyone to administer the Listener. A password should be set to help secure the system. The Listener Control Utility, lsnrctl, is the tool used to manage the Listener. 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.2.0.1.0 - Production on 10-OCT-2004 17:31:49 Copyright (c) 1991, 2002, Oracle Corporation.  All rights reserved. Welcome to LSNRCTL, type "help" for information. LSNRCTL> set current_listener 10.1.1.1 Current Listener is 192.168.0.34 LSNRCTL> status Connecting to (DESCRIPTION=(CONNECT_DATA=(SID=*)(SERVICE_NAME=10.1.1.1)) (ADDRESS=(PROTOCOL=TCP)(HOST=10.1.1.1)(PORT=1521))) STATUS of the LISTENER ------------------------ Alias                     LISTENER Version                   TNSLSNR for 32-bit Windows: Version 9.2.0.1.0 - Production Start Date                10-OCT-2004 16:12:50 Uptime                    0 days 1 hr. 19 min. 23 sec Trace Level               off Security                  ON SNMP                      OFF Listener Parameter File   C:\oracle\ora92\network\admin\listener.ora Listener Log File         C:\oracle\ora92\network\log\listener.log Listening Endpoints Summary...   (DESCRIPTION=(ADDRESS=(PROTOCOL=ipc)(PIPENAME=\.\pipe\EXTPROC0ipc)))   (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=GLADIUS)(PORT=1521)))   (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=GLADIUS)(PORT=8080)) (Presentation=HTTP)(Session=RAW))   (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=GLADIUS)(PORT=2100)) (Presentation=FTP)(Session=RAW)) Services Summary... Service "ORAXP" has 1 instance(s).   Instance "ORAXP", status UNKNOWN, has 1 handler(s) for this service... Service "PLSExtProc" has 1 instance(s).   Instance "PLSExtProc", status UNKNOWN, has 1 handler(s) for this service... Service "oraxp.ngssoftware.com" has 1 instance(s).   Instance "oraxp", status READY, has 1 handler(s) for this service... Service "oraxpXDB.ngssoftware.com" has 1 instance(s).   Instance "oraxp", status READY, has 1 handler(s) for this service... The command completed successfully LSNRCTL> 

As you can see this leaks all kinds of useful information. 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.1       Dest 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  ( 6      "  *(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))) 

Looking at the value of VSNNUM, 151000065 in this case, we can derive the version of the server. When 151000065 is converted into hex we begin to see it better: 9001401. This equates to Oracle version 9.0.1.4.1. The following code can be used to query this information:

 /************************************ / Compile from a command line / / C:\>cl /TC oraver.c /link wsock32.lib / */ #include <stdio.h> #include <windows.h> #include <winsock.h>     int GetOracleVersion(void); int StartWinsock(void); struct hostent *he; struct sockaddr_in s_sa; int ListenerPort=1521; char host[260]=""; unsigned char TNSPacket[200]= "\x00\x46\x00\x00\x01\x00\x00\x00\x01\x37\x01\x2C\x00\x00\x08\x00" "\x7F\xFF\x86\x0E\x00\x00\x01\x00\x00\x0C\x00\x3A\x00\x00\x07\xF8" "\x0C\x0C\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0A\x4C\x00\x00" "\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00";     int main(int argc, char *argv[]) {       unsigned int err=0;       if(argc == 1)       {             printf("\n\t*** OraVer ***");             printf("\n\n\tGets the Oracle version number.");             printf("\n\n\tC:\>%s host [port]",argv[0]);             printf("\n\n\tDavid Litchfield\n\tdavidl@ngssoftware.com\n\t22th April 2003\n");             return 0;       }       strncpy(host,argv[1],256);       if(argc == 3)             ListenerPort = atoi(argv[2]);       err = StartWinsock();       if(err==0)             printf("Error starting Winsock.\n");       else             GetOracleVersion();       WSACleanup();       return 0; }                 int StartWinsock() {       int err=0;       unsigned int addr;       WORD wVersionRequested;       WSADATA wsaData;       wVersionRequested = MAKEWORD( 2, 0 );       err = WSAStartup( wVersionRequested, &wsaData );       if ( err != 0 )             return 0;              if ( LOBYTE( wsaData.wVersion ) != 2  HIBYTE( wsaData.wVersion ) != 0 )             return 0;              s_sa.sin_addr.s_addr=INADDR_ANY;       s_sa.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,he->h_addr,he->h_length);       }       else       {             addr = inet_addr(host);             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.\n");              s_sa.sin_port=htons((unsigned short)ListenerPort);       if (connect(cli_sock,(LPSOCKADDR)&s_sa,sizeof(s_sa))==SOCKET_ERROR)       {             printf("\nFailed to connect to the Listener.\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;       }       while(count < rcv)       {             if(resp[count]==0x00)                   resp[count]=0x20;             count++;       }              ptr = strstr(resp,"(VSNNUM=");       if(!ptr)       {             printf("\nFailed to get the version.\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.%d.%d\n",h,l,ver[2],p,q); The_End:       closesocket(cli_sock);       return 0; } 


Database Hacker's Handbook. Defending Database Servers
The Database Hackers Handbook: Defending Database Servers
ISBN: 0764578014
EAN: 2147483647
Year: 2003
Pages: 156

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net