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:oracleora92in>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:oracleora92
etworkadminlistener.ora
Listener Log File         C:oracleora92
etworkloglistener.log
Listening Endpoints Summary...
  (DESCRIPTION=(ADDRESS=(PROTOCOL=ipc)(PIPENAME=\.pipeEXTPROC0ipc)))
  (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]=
"x00x46x00x00x01x00x00x00x01x37x01x2Cx00x00x08x00"
"x7FxFFx86x0Ex00x00x01x00x00x0Cx00x3Ax00x00x07xF8"
"x0Cx0Cx00x00x00x00x00x00x00x00x00x00x0Ax4Cx00x00"
"x00x03x00x00x00x00x00x00x00x00";

int main(int argc, char *argv[])
{
      unsigned int err=0;
      if(argc == 1)
      {
            printf("
	*** OraVer ***");
            printf("

	Gets the Oracle version number.");
            printf("

	C:\>%s host [port]",argv[0]);
            printf("

	David
Litchfield
	[email protected]
	22th April 2003
");
            return 0;
      }
      strncpy(host,argv[1],256);
      if(argc == 3)
            ListenerPort = atoi(argv[2]);
      err = StartWinsock();
      if(err==0)
            printf("Error starting Winsock.
");
      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
",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("
Failed to create the socket.
");

      s_sa.sin_port=htons((unsigned short)ListenerPort);
if (connect(cli_sock,(LPSOCKADDR)&s_sa,sizeof(s_sa))==
SOCKET_ERROR)
      {
            printf("
Failed to connect to the Listener.
");
            goto The_End;
      }
      snd=send(cli_sock, TNSPacket , 0x3A , 0);
      snd=send(cli_sock, "NGSSoftwarex00" , 12 , 0);
      rcv = recv(cli_sock,resp,196,0);
      if(rcv == SOCKET_ERROR)
      {
            printf("
There was a receive error.
");
            goto The_End;
      }
      while(count < rcv)
      {
            if(resp[count]==0x00)
                  resp[count]=0x20;
            count++;
      }

      ptr = strstr(resp,"(VSNNUM=");
      if(!ptr)
      {
            printf("
Failed to get the version.
");
            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("
Version of Oracle is %d.%d.%d.%d.%d
",h,l,ver[2],p,q);
The_End:
      closesocket(cli_sock);
      return 0;
}
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.135.239.111