Wednesday, January 6, 2010
Sybase Version Tool
Sybase Version Tool
The following is the source code to the Sybase
version-grabbing tool mentioned earlier in this chapter. It is written
for the Windows platform.
// sybaseversion.cpp
// Chris Anley [chris@ngssoftware.com]
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <winsock.h>
#include <time.h>
int syntax()
{
printf("syntax: sybaseversion <host> <port>\n");
return 1;
}
int err( char *psz )
{
printf("%s\n", psz );
return 0;
}
int init_sockets()
{
int ret=0;
WORD wVersionRequested;
WSADATA wsaData;
// Initialise Winsock in this thread
wVersionRequested = MAKEWORD( 2, 0 );
ret = WSAStartup( wVersionRequested, &wsaData );
if ( ret != 0 )
return err( "Couldn't start sockets" );
if ( LOBYTE( wsaData.wVersion ) != 2 ||
HIBYTE( wsaData.wVersion ) != 0 )
return err( "Wrong version of sockets" );
return 1;
}
int create_tcp_socket()
{
return (int)socket( AF_INET, SOCK_STREAM, 0 );
}
int set_timeout( int socket, int timeout_milliseconds )
{
if ( setsockopt( socket, SOL_SOCKET, SO_RCVTIMEO, (const char
*)&timeout_milliseconds, sizeof( int ) ) != 0 )
return 0;
if ( setsockopt( socket, SOL_SOCKET, SO_SNDTIMEO, (const char
*)&timeout_milliseconds, sizeof( int ) ) != 0 )
return 0;
return 1;
}
int bind_to_port( int socket, int port )
{
struct sockaddr_in sa;
int ret;
sa.sin_port = htons( (short)port );
sa.sin_family=AF_INET;
sa.sin_addr.s_addr = INADDR_ANY;
ret = bind( socket, (struct sockaddr *)&sa, sizeof( struct
sockaddr ) );
if ( ret != 0 )
return err("Couldn't bind to port. Maybe something is already"
" using it?");
return 1;
}
int set_listen( int socket )
{
if ( listen( socket, SOMAXCONN ) != 0 )
return 0;
return 1;
}
int get_new_connection_socket( int socket, unsigned int *connectinghost,
int *ps )
{
int sc;
struct sockaddr_in client;
sc = (int)accept( socket, (struct sockaddr *)&client, NULL );
if ( sc == INVALID_SOCKET )
{
//ret = WSAGetLastError();
return err( "Error immediately after receiving"
"connection\n" );
}
*connectinghost = (unsigned int)client.sin_addr.S_un.S_addr;
*ps = sc;
return 1;
}
int connect_to( int socket, char *host, unsigned short port )
{
struct sockaddr_in sa;
int i, len, alpha = 0;
struct hostent *he;
unsigned long addr;
len = (int)strlen( host );
for( i = 0; i < len; i++ )
{
if( isalpha(host[i]) )
{
alpha = 1;
break;
}
}
if( alpha )
{
he = gethostbyname(host);
if ( he == NULL)
return 0;
}
else
{
if ( len > 16 ) // xxx.xxx.xxx.xxx
return 0;
// just use the ip address
addr = inet_addr( host );
if ( addr == INADDR_NONE )
return 0;
he = gethostbyaddr( (char *)&addr, 4, AF_INET );
sa.sin_addr.s_addr = addr;
}
sa.sin_family=AF_INET;
sa.sin_port = htons( port );
if ( connect( socket, (struct sockaddr *)&sa, sizeof( struct
sockaddr ) ) == SOCKET_ERROR )
return 0;
return 1;
}
int receive_data( int socket, char *buffer, int length, int *bytes )
{
int ret;
ret = recv( socket, buffer, length, 0 );
*bytes = ret;
if ( ret > 0 )
return 1;
return 0;
}
int send_data( int socket, char *buffer, int length, int *bytes )
{
int ret = send( socket, buffer, length, 0 );
*bytes = ret;
if ( ret == 0 )
return 0;
return 1;
}
int close_socket( int socket )
{
closesocket( socket );
return 1;
}
int dump_buff( unsigned char *psz, int bytes, int file_no )
{
for( int i = 0; i < bytes; i++ )
{
printf("\\x%02x", psz[i] );
}
printf("\n\n");
return 1;
}
int main( int argc, char * argv[] )
{
unsigned char auth[] =
"\x02" // packet type = TDS 4.2 or 5.0 login packet
"\x01" // last packet indicator = 1 : last packet
"\x02\x00" // packet size: 512 bytes
"\x00\x00\x00\x00" // 4 bytes; purpose unknown
"XXXXXXX\x00\x00\x00" // 30 bytes: Host name (XXXXXXX)
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x07" // host name length
"XX\x00\x00\x00\x00\x00\x00\x00\x00" // 30 bytes: User name
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x02" // user name length
"XXXXXXXXXX" // 30 bytes: password
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x0a" // password length
// 30 bytes: process
"\x31\x31\x35\x32\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x04" // process length
"\x03\x01\x06\x0a\x09\x01" // 6 bytes of mystery stuff
"\x01" // bulk copy = 1
"\x00\x00\x00\x00\x00\x00\x00\x00\x00" // 9 bytes
"SQL_Advant"
"age\x00\x00\x00\x00\x00\x00\x00" // 30 bytes: app name
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x0d" // app name length
"XXXXXXX\x00\x00\x00" // 30 bytes: server name
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x07" // server name length
"\x00" // 1 mystery byte
"\x0a" // password2 length
"XXXXXXXXXX" // 30 bytes: password 2
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
// 223 bytes of null (?)
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00" // end 223 null bytes
"\x0c" // password2 length + 2
"\x05\x00" // TDS Major version = 5
"\x00\x00" // TDS Minor version = 0
"CT-Library" // Library name
"\x0a" // Library name length
"\x05\x00" // program major version = 5
"\x00\x00" // program minor version = 0
"\x00\x0d\x11" // Magic 3 bytes
// language 30 bytes... except we truncate
"\x00s_english"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00";
int s, sent, received, i;
char buff[ 8192 ];
memset( buff, 0, sizeof( buff ) );
if( !init_sockets() )
return err("Couldn't initialise sockets");
s = create_tcp_socket();
if (!connect_to( s, argv[1], atoi( argv[2]) ))
return err("Couldn't connect");
if( !send_data( s, (char *)auth, sizeof( auth ), &sent ))
return err("Couldn't send auth packet");
if( !receive_data( s, buff, 8180, &received ))
return err("No data received");
if( !close_socket( s ))
return err("Error closing socket");
dump_buff( (unsigned char *)buff, received, 0 );
for( i = 0; i < received; i++ )
{
if( strnicmp( &(buff[i]), "SQL Server", strlen("SQL Server")) == 0 )
{
i += (int)strlen( "SQL Server" );
printf("Sybase Version: %d.%d.%d.%d\n",
buff[i], buff[i+1], buff[i+2], buff[i+3] );
break;
}
}
return 0;
}
No comments:
Post a Comment