--- trunk/mitm-ssl.pl 2010/01/06 15:02:57 128 +++ trunk/mitm-ssl.pl 2010/01/06 23:17:32 129 @@ -13,29 +13,32 @@ my $host; my $port; my $daemon; -my $buffersize= 2048; +my $buffersize = 2048; my $logtype; my $logdir; my $daemon; -my $serverkey; my $servercert; my $serverdh; +my $serverkey; +my $servercert; +my $serverdh; $| = 1; -my $goresult = GetOptions ( "lport=i" => \$localport, - "laddr=s" => \$localaddr, - "rport=i" => \$port, - "raddr=s" => \$host, - "logtype=i" => \$logtype, - "logdir=s" => \$logdir, - "daemon" => \$daemon, - "serverkey=s" => \$serverkey, - "servercert=s" => \$servercert, - "serverdh=s" => \$serverdh, - "help" => \$help - ); +my $goresult = GetOptions( + "lport=i" => \$localport, + "laddr=s" => \$localaddr, + "rport=i" => \$port, + "raddr=s" => \$host, + "logtype=i" => \$logtype, + "logdir=s" => \$logdir, + "daemon" => \$daemon, + "serverkey=s" => \$serverkey, + "servercert=s" => \$servercert, + "serverdh=s" => \$serverdh, + "help" => \$help +); if ($help) { - print <<"END"; + print <<"END"; SSL Man-In-The-Middle v0.1. Copyright (C) Vlatko Kosturjak, Kost Distributed under GPL v2+. @@ -53,114 +56,134 @@ --daemon Daemonize (work in background) --help Display this help message END - exit; + exit; } # set default values -$localport=8080 unless ($localport); -$localaddr="127.0.0.1" unless ($localaddr); -$port=80 unless ($port); -$host="127.0.0.1" unless ($host); -$logdir="." unless ($logdir); - -my %o = ( 'dir' => $logdir, 'port' => $localport, 'toport' => $port, 'tohost' => $host ); +$localport = 8080 unless ($localport); +$localaddr = "127.0.0.1" unless ($localaddr); +$port = 80 unless ($port); +$host = "127.0.0.1" unless ($host); +$logdir = "." unless ($logdir); + +my %o = ( + 'dir' => $logdir, + 'port' => $localport, + 'toport' => $port, + 'tohost' => $host +); if ($daemon) { - my $pid = fork; - exit if $pid; - die "$!" unless defined($pid); - POSIX::setsid() or die "$!"; + my $pid = fork; + exit if $pid; + die "$!" unless defined($pid); + POSIX::setsid() or die "$!"; } my $ah = IO::Socket::SSL->new( - 'LocalPort' => $localport, - 'LocalAddr' => $localaddr, - 'Reuse' => 1, - 'Proto' => 'tcp', - 'SSL_verify_mode' => '0', - 'SSLdhfile' => $serverdh, - 'SSL_cert_file' => $servercert, - 'SSL_key_file' => $serverkey, - 'Listen' => 10 + 'LocalPort' => $localport, + 'LocalAddr' => $localaddr, + 'Reuse' => 1, + 'Proto' => 'tcp', + 'SSL_verify_mode' => '0', + 'SSLdhfile' => $serverdh, + 'SSL_cert_file' => $servercert, + 'SSL_key_file' => $serverkey, + 'Listen' => 10 ) || die "$!"; $SIG{'CHLD'} = 'IGNORE'; my $num = 0; while (1) { - my $ch = $ah->accept(); - if ( !$ch ) { print STDERR "cannot accept: $! ", IO::Socket::SSL::errstr(), "\n" ; next; } - if ( !$ch ) { print STDERR "cannot accept: $!\n"; next; } - ++$num; - my $pid = fork(); - if ( !defined($pid) ) { print STDERR "cannot fork while(1) $!\n"; } - elsif ( $pid == 0 ) { $ah->close(SSL_no_shutdown => 1); Run( \%o, $ch, $num ); } - else { $ch->close(SSL_no_shutdown => 1); } + my $ch = $ah->accept(); + if ( !$ch ) { + print STDERR "cannot accept: $! ", IO::Socket::SSL::errstr(), + "\n"; + next; + } + if ( !$ch ) { print STDERR "cannot accept: $!\n"; next; } + ++$num; + my $pid = fork(); + if ( !defined($pid) ) { print STDERR "cannot fork while(1) $!\n"; } + elsif ( $pid == 0 ) { + $ah->close( SSL_no_shutdown => 1 ); + Run( \%o, $ch, $num ); + } else { + $ch->close( SSL_no_shutdown => 1 ); + } } sub Run { - my ( $o, $ch, $num ) = @_; - my $th = IO::Socket::SSL->new( - 'PeerAddr' => $o->{'tohost'}, - 'PeerPort' => $o->{'toport'}, - 'SSL_use_cert' => '0', - 'SSL_verify_mode' => '0', -# 'SSL_cipher_list' => 'NUL:LOW:EXP:ADH', - 'SSL_version' => 'SSLv3', # SSLv3, SSLv2, TLSv1 - 'Proto' => 'tcp' - ); - if ( !$th ) { print "cannot connect th: $!"; exit 0; } - else { print "connected!"; } - my $fh; - if ( $o->{'dir'} ) { - $fh = Symbol::gensym(); - open( $fh, ">$o->{'dir'}/tunnel$num.log" ) or die "$!"; - } - $ch->autoflush(); - $th->autoflush(); - my $httpheader=""; - my $httpbuf=""; - while ( $ch || $th ) { - my $rin = ""; - vec( $rin, fileno($ch), 1 ) = 1 if $ch; - vec( $rin, fileno($th), 1 ) = 1 if $th; - my ( $rout, $eout ); - select( $rout = $rin, undef, $eout = $rin, 120 ); - if ( !$rout && !$eout ) { } - my $cbuffer = ""; - my $tbuffer = ""; - - if ( $ch - && ( vec( $eout, fileno($ch), 1 ) || vec( $rout, fileno($ch), 1 ) ) - ) - { - my $result = sysread( $ch, $tbuffer, $buffersize ); - if ( !defined($result) ) { - print STDERR "$!\n"; - exit 0; - } - if ( $result == 0 ) { exit 0; } - } - if ( $th - && ( vec( $eout, fileno($th), 1 ) || vec( $rout, fileno($th), 1 ) ) - ) - { - my $result = sysread( $th, $cbuffer, $buffersize ); - if ( !defined($result) ) { print STDERR "$!\n"; exit 0; } - if ( $result == 0 ) { exit 0; } - } - if ( $fh && $tbuffer ) { ( print $fh "[c]".$tbuffer."[/c]" ); } - while ( my $len = length($tbuffer) ) { - my $res = syswrite( $th, $tbuffer, $len ); - if ( $res > 0 ) { $tbuffer = substr( $tbuffer, $res ); } - else { print STDERR "$!\n"; } - } - if ( $fh && $cbuffer ) { ( print $fh "[s]".$cbuffer."[/s]"); } - while ( my $len = length($cbuffer) ) { - my $res = syswrite( $ch, $cbuffer, $len ); - if ( $res > 0 ) { $cbuffer = substr( $cbuffer, $res ); } - else { print STDERR "$!\n"; } - } - } + my ( $o, $ch, $num ) = @_; + my $th = IO::Socket::SSL->new( + 'PeerAddr' => $o->{'tohost'}, + 'PeerPort' => $o->{'toport'}, + 'SSL_use_cert' => '0', + 'SSL_verify_mode' => '0', + + # 'SSL_cipher_list' => 'NUL:LOW:EXP:ADH', + 'SSL_version' => 'SSLv3', # SSLv3, SSLv2, TLSv1 + 'Proto' => 'tcp' + ); + if ( !$th ) { print "cannot connect th: $!"; exit 0; } + else { print "connected!"; } + my $fh; + if ( $o->{'dir'} ) { + $fh = Symbol::gensym(); + open( $fh, ">$o->{'dir'}/tunnel$num.log" ) or die "$!"; + } + $ch->autoflush(); + $th->autoflush(); + my $httpheader = ""; + my $httpbuf = ""; + while ( $ch || $th ) { + my $rin = ""; + vec( $rin, fileno($ch), 1 ) = 1 if $ch; + vec( $rin, fileno($th), 1 ) = 1 if $th; + my ( $rout, $eout ); + select( $rout = $rin, undef, $eout = $rin, 120 ); + if ( !$rout && !$eout ) { } + my $cbuffer = ""; + my $tbuffer = ""; + + if ($ch + && ( vec( $eout, fileno($ch), 1 ) + || vec( $rout, fileno($ch), 1 ) ) + ) + { + my $result = sysread( $ch, $tbuffer, $buffersize ); + if ( !defined($result) ) { + print STDERR "$!\n"; + exit 0; + } + if ( $result == 0 ) { exit 0; } + } + if ($th + && ( vec( $eout, fileno($th), 1 ) + || vec( $rout, fileno($th), 1 ) ) + ) + { + my $result = sysread( $th, $cbuffer, $buffersize ); + if ( !defined($result) ) { print STDERR "$!\n"; exit 0; } + if ( $result == 0 ) { exit 0; } + } + if ( $fh && $tbuffer ) { + ( print $fh "[c]" . $tbuffer . "[/c]" ); + } + while ( my $len = length($tbuffer) ) { + my $res = syswrite( $th, $tbuffer, $len ); + if ( $res > 0 ) { $tbuffer = substr( $tbuffer, $res ); } + else { print STDERR "$!\n"; } + } + if ( $fh && $cbuffer ) { + ( print $fh "[s]" . $cbuffer . "[/s]" ); + } + while ( my $len = length($cbuffer) ) { + my $res = syswrite( $ch, $cbuffer, $len ); + if ( $res > 0 ) { $cbuffer = substr( $cbuffer, $res ); } + else { print STDERR "$!\n"; } + } + } }