Revision 126
- Date:
- 2010/01/05 15:13:31
- Files:
Legend:
- Added
- Removed
- Modified
-
trunk/mitm-ssl.pl
1 #!/usr/bin/perl 2 # SSL Man-In-The-Middle v0.1. Copyright (C) Vlatko Kosturjak, Kost 3 # Distributed under GPL v2+. 4 5 use strict; 6 use POSIX; 7 use IO::Socket::SSL; 8 use Getopt::Long; 9 10 my $localport; 11 my $localaddr; 12 my $help; 13 my $host; 14 my $port; 15 my $daemon; 16 my $buffersize= 2048; 17 my $logtype; 18 my $logdir; 19 my $daemon; 20 my $serverkey; my $servercert; my $serverdh; 21 22 $| = 1; 23 24 my $goresult = GetOptions ( "lport=i" => \$localport, 25 "laddr=s" => \$localaddr, 26 "rport=i" => \$port, 27 "raddr=s" => \$host, 28 "logtype=i" => \$logtype, 29 "logdir=s" => \$logdir, 30 "daemon" => \$daemon, 31 "serverkey=s" => \$serverkey, 32 "servercert=s" => \$servercert, 33 "serverdh=s" => \$serverdh, 34 "help" => \$help 35 ); 36 37 if ($help) { 38 print <<"END"; 39 SSL Man-In-The-Middle v0.1. Copyright (C) Vlatko Kosturjak, Kost 40 Distributed under GPL v2+. 41 42 Usage: $0 [OPTIONS] 43 44 --lport <port> Listening port (default 80) 45 --laddr <address> Listening address (default localhost) 46 --rport <port> Remote port to connect to (default 8080) 47 --raddr <address> Remote address to connect to (default localhost) 48 --serverkey <file> Certificate key file for local SSL server 49 --servercert <file> Certificate file for local SSL server 50 --serverdh <file> Diffie-Helman file for key exchange 51 --log <type> Type of log where 0 is no log (default 0) 52 --logdir Directory to log to (default .) 53 --daemon Daemonize (work in background) 54 --help Display this help message 55 END 56 exit; 57 } 58 59 # set default values 60 $localport=8080 unless ($localport); 61 $localaddr="127.0.0.1" unless ($localaddr); 62 $port=80 unless ($port); 63 $host="127.0.0.1" unless ($host); 64 $logdir="." unless ($logdir); 65 66 my %o = ( 'dir' => $logdir, 'port' => $localport, 'toport' => $port, 'tohost' => $host ); 67 68 if ($daemon) { 69 my $pid = fork; 70 exit if $pid; 71 die "$!" unless defined($pid); 72 POSIX::setsid() or die "$!"; 73 } 74 75 my $ah = IO::Socket::SSL->new( 76 'LocalPort' => $localport, 77 'LocalAddr' => $localaddr, 78 'Reuse' => 1, 79 'Proto' => 'tcp', 80 'SSL_verify_mode' => '0', 81 'SSLdhfile' => $serverdh, 82 'SSL_cert_file' => $servercert, 83 'SSL_key_file' => $serverkey, 84 'Listen' => 10 85 ) || die "$!"; 86 87 $SIG{'CHLD'} = 'IGNORE'; 88 my $num = 0; 89 90 while (1) { 91 my $ch = $ah->accept(); 92 if ( !$ch ) { print STDERR "cannot accept: $!\n"; next; } 93 ++$num; 94 my $pid = fork(); 95 if ( !defined($pid) ) { print STDERR "cannot fork while(1) $!\n"; } 96 elsif ( $pid == 0 ) { $ah->close(SSL_no_shutdown => 1); Run( \%o, $ch, $num ); } 97 else { $ch->close(SSL_no_shutdown => 1); } 98 } 99 100 sub Run { 101 my ( $o, $ch, $num ) = @_; 102 my $th = IO::Socket::SSL->new( 103 'PeerAddr' => $o->{'tohost'}, 104 'PeerPort' => $o->{'toport'}, 105 'SSL_use_cert' => '0', 106 'SSL_verify_mode' => '0', 107 # 'SSL_cipher_list' => 'NUL:LOW:EXP:ADH', 108 'SSL_version' => 'SSLv3', # SSLv3, SSLv2, TLSv1 109 'Proto' => 'tcp' 110 ); 111 if ( !$th ) { print "cannot connect th: $!"; exit 0; } 112 else { print "connected!"; } 113 my $fh; 114 if ( $o->{'dir'} ) { 115 $fh = Symbol::gensym(); 116 open( $fh, ">$o->{'dir'}/tunnel$num.log" ) or die "$!"; 117 } 118 $ch->autoflush(); 119 $th->autoflush(); 120 my $httpheader=""; 121 my $httpbuf=""; 122 while ( $ch || $th ) { 123 my $rin = ""; 124 vec( $rin, fileno($ch), 1 ) = 1 if $ch; 125 vec( $rin, fileno($th), 1 ) = 1 if $th; 126 my ( $rout, $eout ); 127 select( $rout = $rin, undef, $eout = $rin, 120 ); 128 if ( !$rout && !$eout ) { } 129 my $cbuffer = ""; 130 my $tbuffer = ""; 131 132 if ( $ch 133 && ( vec( $eout, fileno($ch), 1 ) || vec( $rout, fileno($ch), 1 ) ) 134 ) 135 { 136 my $result = sysread( $ch, $tbuffer, $buffersize ); 137 if ( !defined($result) ) { 138 print STDERR "$!\n"; 139 exit 0; 140 } 141 if ( $result == 0 ) { exit 0; } 142 } 143 if ( $th 144 && ( vec( $eout, fileno($th), 1 ) || vec( $rout, fileno($th), 1 ) ) 145 ) 146 { 147 my $result = sysread( $th, $cbuffer, $buffersize ); 148 if ( !defined($result) ) { print STDERR "$!\n"; exit 0; } 149 if ( $result == 0 ) { exit 0; } 150 } 151 if ( $fh && $tbuffer ) { ( print $fh "[c]".$tbuffer."[/c]" ); } 152 while ( my $len = length($tbuffer) ) { 153 my $res = syswrite( $th, $tbuffer, $len ); 154 if ( $res > 0 ) { $tbuffer = substr( $tbuffer, $res ); } 155 else { print STDERR "$!\n"; } 156 } 157 if ( $fh && $cbuffer ) { ( print $fh "[s]".$cbuffer."[/s]"); } 158 while ( my $len = length($cbuffer) ) { 159 my $res = syswrite( $ch, $cbuffer, $len ); 160 if ( $res > 0 ) { $cbuffer = substr( $cbuffer, $res ); } 161 else { print STDERR "$!\n"; } 162 } 163 } 164 } 165