commit f342accefe0a752cfad6f1d6b7051763f0575a1c Author: Jonathan "Duke" Leto Date: Wed Feb 1 22:13:22 2012 -0800 Initial commit of yoursql 0.3 diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..6a70822 --- /dev/null +++ b/Makefile @@ -0,0 +1,6 @@ + +all: + gcc -Wall yoursql.c -o yoursql -lpcap + +clean: + rm yoursql diff --git a/README b/README new file mode 100644 index 0000000..af6bb23 --- /dev/null +++ b/README @@ -0,0 +1,9 @@ +yoursql.c - Ascertain Mysql Version +----------------------------------- +by Jonathan Leto + +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. + diff --git a/yoursql.c b/yoursql.c new file mode 100644 index 0000000..8a3089a --- /dev/null +++ b/yoursql.c @@ -0,0 +1,220 @@ +/* Tested on Linux 2.2,OpenBSD 2.6,FreeBSD 4.0 */ +/* By Jonathan Leto */ +/* October 30 2000 v0.3 */ +/* Thanks to ngrep.c and sniffconv.c for moral support */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#define __FAVOR_BSD 1 +#include +#include +#include +#include +#if !(__linux__) + #include +#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