Jonathan "Duke" Leto
12 years ago
commit
f342accefe
3 changed files with 235 additions and 0 deletions
@ -0,0 +1,6 @@ |
|||
|
|||
all: |
|||
gcc -Wall yoursql.c -o yoursql -lpcap |
|||
|
|||
clean: |
|||
rm yoursql |
@ -0,0 +1,9 @@ |
|||
yoursql.c - Ascertain Mysql Version |
|||
----------------------------------- |
|||
by Jonathan Leto <jonathan@leto.net> |
|||
|
|||
This will only work on hosts that actually let you connect, |
|||
if you are blocked by an ACL, this won't work. |
|||
|
|||
Patches/whatever welcome. |
|||
|
@ -0,0 +1,220 @@ |
|||
/* Tested on Linux 2.2,OpenBSD 2.6,FreeBSD 4.0 */ |
|||
/* By Jonathan Leto <jonathan@leto.net> */ |
|||
/* October 30 2000 v0.3 */ |
|||
/* Thanks to ngrep.c and sniffconv.c for moral support */ |
|||
|
|||
#include <pcap.h> |
|||
#include <ctype.h> |
|||
#include <errno.h> |
|||
#include <fcntl.h> |
|||
#include <netdb.h> |
|||
#include <stdio.h> |
|||
#include <string.h> |
|||
#include <stdlib.h> |
|||
#include <unistd.h> |
|||
#include <signal.h> |
|||
#include <sys/socket.h> |
|||
#include <sys/types.h> |
|||
#include <netinet/in.h> |
|||
#include <netinet/in_systm.h> |
|||
#include <netinet/ip.h> |
|||
#define __FAVOR_BSD 1 |
|||
#include <netinet/tcp.h> |
|||
#include <netinet/udp.h> |
|||
#include <net/if.h> |
|||
#include <arpa/inet.h> |
|||
#if !(__linux__) |
|||
#include <netinet/ip_var.h> |
|||
#endif |
|||
|
|||
#define ETHHDR_SIZE 14 |
|||
#define PPPHDR_SIZE 4 |
|||
#define SLIPHDR_SIZE 16 |
|||
#define RAWHDR_SIZE 0 |
|||
#define LOOPHDR_SIZE 4 |
|||
#define FDDIHDR_SIZE 21 |
|||
#ifndef IP_OFFMASK |
|||
#define IP_OFFMASK 0x1fff |
|||
#endif |
|||
|
|||
#define MYSQL_PORT 3306 |
|||
#define TIMEOUT 5 // seconds
|
|||
|
|||
int strlenx(char *s,char d); |
|||
void prod_packet (u_char * data1, struct pcap_pkthdr *h, u_char * p); |
|||
void get_mysql_version (char *data, int len); |
|||
void errquit(char *quitmsg); |
|||
void mysql_connect(char *host); |
|||
|
|||
int link_offset; |
|||
pcap_t *pd = NULL; |
|||
|
|||
int main (int argc, char **argv) { |
|||
|
|||
int snaplen = 65535, promisc = 0, to = 1000 ; |
|||
char pc_err[PCAP_ERRBUF_SIZE]; |
|||
char *filter = NULL,*dev; |
|||
struct bpf_program pcapfilter; |
|||
struct in_addr net, mask; |
|||
|
|||
if( argc != 2 ) |
|||
errquit("usage: ./yoursql host \n"); |
|||
|
|||
filter = "tcp and src port 3306"; |
|||
|
|||
if (!(dev = pcap_lookupdev(pc_err))) |
|||
errquit("Could not find valid device.\n"); |
|||
|
|||
if ((pd = pcap_open_live (dev, snaplen, promisc, to, pc_err)) == NULL) |
|||
errquit("Couldn't open_live.\n"); |
|||
|
|||
if (pcap_lookupnet (dev, &net.s_addr, &mask.s_addr, pc_err) == -1) { |
|||
memset (&net, 0, sizeof (net)); |
|||
memset (&mask, 0, sizeof (mask)); |
|||
errquit("coulnd't lookup network/netmask.\n"); |
|||
} |
|||
if (pcap_compile (pd, &pcapfilter, filter, 0, mask.s_addr)) |
|||
errquit("Error in filter syntax.\n"); |
|||
|
|||
if (pcap_setfilter (pd, &pcapfilter)) |
|||
errquit("pcap_setfilter error.\n"); |
|||
|
|||
switch (pcap_datalink (pd)) { |
|||
case DLT_EN10MB: |
|||
case DLT_IEEE802: |
|||
link_offset = ETHHDR_SIZE; |
|||
break; |
|||
|
|||
case DLT_FDDI: |
|||
link_offset = FDDIHDR_SIZE; |
|||
break; |
|||
|
|||
case DLT_SLIP: |
|||
link_offset = SLIPHDR_SIZE; |
|||
break; |
|||
|
|||
case DLT_PPP: |
|||
link_offset = PPPHDR_SIZE; |
|||
break; |
|||
|
|||
case DLT_RAW: |
|||
link_offset = RAWHDR_SIZE; |
|||
break; |
|||
|
|||
case DLT_NULL: |
|||
link_offset = LOOPHDR_SIZE; |
|||
break; |
|||
|
|||
default: |
|||
errquit("Unsupported interface type.\n"); |
|||
return 1; |
|||
} |
|||
printf("%s",argv[1]); |
|||
mysql_connect(argv[1]); |
|||
return 0; |
|||
} |
|||
|
|||
void mysql_connect(char *host){ |
|||
int sockfd,flags,n; |
|||
struct sockaddr_in servaddr; |
|||
struct hostent *hostp; |
|||
char *connstring; |
|||
|
|||
if ( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) |
|||
errquit("Couldn't create socket\n"); |
|||
|
|||
bzero(&servaddr,sizeof(servaddr)); |
|||
servaddr.sin_family = AF_INET; |
|||
servaddr.sin_port = htons(MYSQL_PORT); |
|||
|
|||
hostp = gethostbyname(host); |
|||
|
|||
memcpy(&servaddr.sin_addr,hostp->h_addr,hostp->h_length); |
|||
|
|||
flags = fcntl(sockfd,F_GETFL,0); |
|||
fcntl(sockfd, F_SETFL, flags | O_NONBLOCK); |
|||
|
|||
if ( connect(sockfd, (struct sockaddr *) &servaddr, sizeof(servaddr)) < 0) |
|||
if( errno != EINPROGRESS ){ |
|||
printf("Got a ERROR %d error\n",errno); |
|||
return; |
|||
} |
|||
|
|||
/* 0x0a is the protocol version (10)
|
|||
the last characters 5 are "test\0" |
|||
we don't need no steekin' API */ |
|||
connstring = "\x0a\x00\x00\x01\x85\x04\x00\x00\x80\x74\x65\x73\x74\x00\xff"; |
|||
|
|||
/* version string is in second packet */ |
|||
while (pcap_loop (pd, 2, (pcap_handler) prod_packet, 0)); |
|||
|
|||
|
|||
if ( (n = write(sockfd,connstring,strlenx(connstring,0xff))) < 0 ){ |
|||
printf("write error %d\n",errno); |
|||
} |
|||
|
|||
close(sockfd); |
|||
} |
|||
int strlenx(char *s, char d){ |
|||
int i; |
|||
|
|||
for(i=0;;i++) |
|||
if( s[i] == d ) |
|||
break; |
|||
return i; |
|||
} |
|||
void prod_packet (u_char * data1, struct pcap_pkthdr *h, u_char * p) { |
|||
|
|||
struct ip *ip_packet = (struct ip *) (p + link_offset); |
|||
unsigned ip_hl = ip_packet->ip_hl * 4; |
|||
unsigned ip_off = ntohs (ip_packet->ip_off); |
|||
unsigned fragmented = ip_off & (IP_MF | IP_OFFMASK); |
|||
char *data; |
|||
int len; |
|||
|
|||
switch (ip_packet->ip_p) { |
|||
case IPPROTO_TCP:{ |
|||
struct tcphdr *tcp = (struct tcphdr *) (((char *) ip_packet) + ip_hl); |
|||
|
|||
unsigned tcphdr_offset = fragmented ? 0 : (tcp->th_off * 4); |
|||
|
|||
data = ((char *) tcp) + tcphdr_offset; |
|||
len = ntohs (ip_packet->ip_len) - ip_hl - tcphdr_offset; |
|||
/* our packet is small , most are 28 bytes, a few are 32 or 33 */ |
|||
if (len > 64 || len == 0) |
|||
return; |
|||
get_mysql_version(data, len); |
|||
} break; |
|||
default: |
|||
errquit("Shouldn't be receiving non-tcp packets.\n"); |
|||
} |
|||
} |
|||
|
|||
void errquit(char *quitmsg){ |
|||
printf("%s",quitmsg); |
|||
exit(1); |
|||
} |
|||
|
|||
void get_mysql_version (char *data, int len) { |
|||
|
|||
char *str = data; |
|||
int j; |
|||
|
|||
/* the 2nd to the fifth byte will be 0x00 0x00 0x00 PROTOCOL, followed by
|
|||
the version string delimited by another null |
|||
Almost all recent mysql servers use protocol 10 (0x0a), but I found one that |
|||
uses 9 (0x09) |
|||
*/ |
|||
|
|||
for(j=1;j<len;j++){ |
|||
if(str[j] == '\0' && str[j+1] == '\0' && str[j+2] == '\0' && (str[j+3] == 0x09 || str[j+3] == 0x0a) ){ |
|||
j+=4; |
|||
printf(" mysql version is "); |
|||
while( str[j] != '\0' ){ |
|||
printf("%c",str[j]); |
|||
j++; |
|||
} |
|||
printf(" (protocol version %d)\n", str[4]); |
|||
} |
|||
} |
|||
} |
Loading…
Reference in new issue