/[scripts]/trunk/mitm-ssl.pl
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Diff of /trunk/mitm-ssl.pl

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 128 by dpavlin, Wed Jan 6 15:02:57 2010 UTC revision 133 by dpavlin, Fri Jan 8 13:52:41 2010 UTC
# Line 4  Line 4 
4    
5  use strict;  use strict;
6  use POSIX;  use POSIX;
7  use IO::Socket::SSL;  use IO::Socket::SSL qw(debug3);
8  use Getopt::Long;  use Getopt::Long;
9    use Time::HiRes qw(time);
10    
11    my $debug = 0;
12    
13    my $laddr = "127.0.0.1";
14    my $lport = 8080;
15    my $raddr      = "127.0.0.1";
16    my $rport      = 80;
17    
18    my $logdir;
19    
 my $localport;  
 my $localaddr;  
20  my $help;  my $help;
 my $host;  
 my $port;  
21  my $daemon;  my $daemon;
22  my $buffersize= 2048;  my $buffersize = 2048;
23  my $logtype;  my $logtype;
 my $logdir;  
24  my $daemon;  my $daemon;
25  my $serverkey; my $servercert; my $serverdh;  my $serverkey;
26    my $servercert;
27    my $serverdh;
28    
29  $| = 1;  $| = 1;
30    
31  my $goresult = GetOptions ( "lport=i" => \$localport,  my $goresult = GetOptions(
32                          "laddr=s" => \$localaddr,          "lport=i"      => \$lport,
33                          "rport=i" => \$port,          "laddr=s"      => \$laddr,
34                          "raddr=s" => \$host,          "rport=i"      => \$rport,
35                          "logtype=i" => \$logtype,          "raddr=s"      => \$raddr,
36                          "logdir=s" => \$logdir,          "logtype=i"    => \$logtype,
37                          "daemon" => \$daemon,          "logdir=s"     => \$logdir,
38                          "serverkey=s" => \$serverkey,          "daemon"       => \$daemon,
39                          "servercert=s" => \$servercert,          "serverkey=s"  => \$serverkey,
40                          "serverdh=s" => \$serverdh,          "servercert=s" => \$servercert,
41                          "help" => \$help          "serverdh=s"   => \$serverdh,
42                  );          "help"         => \$help,
43            'debug!'        => \$debug,
44    );
45    
46  if ($help) {  if ($help) {
47          print <<"END";          print <<"END";
48  SSL Man-In-The-Middle v0.1. Copyright (C) Vlatko Kosturjak, Kost  SSL Man-In-The-Middle v0.1. Copyright (C) Vlatko Kosturjak, Kost
49  Distributed under GPL v2+.  Distributed under GPL v2+.
50    
# Line 53  Usage: $0 [OPTIONS] Line 62  Usage: $0 [OPTIONS]
62          --daemon                Daemonize (work in background)          --daemon                Daemonize (work in background)
63          --help                  Display this help message          --help                  Display this help message
64  END  END
65          exit;          exit;
66  }  }
67    
68  # set default values  $Net::SSLeay::trace = 4 if $debug;
69  $localport=8080 unless ($localport);  
70  $localaddr="127.0.0.1" unless ($localaddr);  $logdir  ||= "$laddr:$lport-$raddr:$rport";
71  $port=80 unless ($port);  $serverkey ||= "$logdir/ssl.key";
72  $host="127.0.0.1" unless ($host);  $servercert ||= "$logdir/ssl.cert";
73  $logdir="." unless ($logdir);  
74    mkdir $logdir;
75    
76    system "openssl req -new -x509 -days 365 -nodes -out $servercert -keyout $serverkey"
77            if ! -e $serverkey && ! -e $servercert;
78    
 my %o = ( 'dir' => $logdir, 'port' => $localport, 'toport' => $port, 'tohost' => $host );  
79    
80  if ($daemon) {  if ($daemon) {
81      my $pid = fork;          my $pid = fork;
82      exit if $pid;          exit if $pid;
83      die "$!" unless defined($pid);          die "$!" unless defined($pid);
84      POSIX::setsid() or die "$!";          POSIX::setsid() or die "$!";
85  }  }
86    
87  my $ah = IO::Socket::SSL->new(  my $ah = IO::Socket::SSL->new(
88      'LocalPort' => $localport,          'LocalPort'       => $lport,
89      'LocalAddr' => $localaddr,          'LocalAddr'       => $laddr,
90      'Reuse'     => 1,          'Reuse'           => 1,
91      'Proto'     => 'tcp',          'Proto'           => 'tcp',
92      'SSL_verify_mode' => '0',          'SSL_verify_mode' => '0',
93      'SSLdhfile' => $serverdh,          'SSLdhfile'       => $serverdh,
94      'SSL_cert_file' => $servercert,          'SSL_cert_file'   => $servercert,
95      'SSL_key_file' => $serverkey,          'SSL_key_file'    => $serverkey,
96      'Listen'    => 10          'Listen'          => 10,
97    #       'SSL_version' => 'SSLv3',    # SSLv3, SSLv2, TLSv1
98    #       'SSL_cipher_list' => 'RC4-MD5',
99  ) || die "$!";  ) || die "$!";
100    
101  $SIG{'CHLD'} = 'IGNORE';  $SIG{'CHLD'} = 'IGNORE';
102  my $num = 0;  my $num = 0;
103    
104  while (1) {  while (1) {
105      my $ch = $ah->accept();          my $ch = $ah->accept();
106      if ( !$ch ) { print STDERR "cannot accept: $! ", IO::Socket::SSL::errstr(), "\n" ; next; }          if ( !$ch ) {
107      if ( !$ch ) { print STDERR "cannot accept: $!\n"; next; }                  print STDERR "cannot accept: $! ", IO::Socket::SSL::errstr(),
108      ++$num;                          "\n";
109      my $pid = fork();                  next;
110      if ( !defined($pid) ) { print STDERR "cannot fork while(1) $!\n"; }          }
111      elsif ( $pid == 0 ) { $ah->close(SSL_no_shutdown => 1); Run( \%o, $ch, $num ); }          if ( !$ch ) { print STDERR "cannot accept: $!\n"; next; }
112      else { $ch->close(SSL_no_shutdown => 1); }          ++$num;
113            my $pid = fork();
114            if ( !defined($pid) ) { print STDERR "cannot fork while(1) $!\n"; }
115            elsif ( $pid == 0 ) {
116                    $ah->close( SSL_no_shutdown => 1 );
117                    Run( $ch, $num );
118            } else {
119                    $ch->close( SSL_no_shutdown => 1 );
120            }
121    }
122    
123    sub hexdump {
124            my $bytes = shift;
125            my $hex = unpack('H*', $bytes);
126            $hex =~ s/(.{8})/$1 /g;
127            return $hex;
128  }  }
129    
130  sub Run {  sub Run {
131      my ( $o, $ch, $num ) = @_;          my ( $ch, $num ) = @_;
132      my $th = IO::Socket::SSL->new(          my $th = IO::Socket::SSL->new(
133          'PeerAddr' => $o->{'tohost'},                  'PeerAddr'        => $raddr,
134          'PeerPort' => $o->{'toport'},                  'PeerPort'        => $rport,
135          'SSL_use_cert' => '0',  #               'SSL_use_cert'    => '0',
136          'SSL_verify_mode' => '0',  #               'SSL_verify_mode' => '0',
137  #       'SSL_cipher_list' => 'NUL:LOW:EXP:ADH',  
138          'SSL_version' => 'SSLv3', # SSLv3, SSLv2, TLSv1                  'SSL_version' => 'SSLv3',    # SSLv3, SSLv2, TLSv1
139          'Proto' => 'tcp'                  'SSL_cipher_list' => 'RC4-MD5',
140      );                  'Proto'       => 'tcp'
141      if ( !$th ) { print "cannot connect th: $!"; exit 0; }          );
142      else { print "connected!"; }          if ( !$th ) { print "cannot connect $raddr:$rport th: $!"; exit 0; }
143      my $fh;          else        { print "connected to $raddr:$rport\n"; }
144      if ( $o->{'dir'} ) {          my $fh;
145          $fh = Symbol::gensym();          if ( -d $logdir ) {
146          open( $fh, ">$o->{'dir'}/tunnel$num.log" ) or die "$!";                  $fh = Symbol::gensym();
147      }                  my $path = sprintf("%s/%15.5f", $logdir, Time::HiRes::time() );
148      $ch->autoflush();                  open( $fh, '>', $path ) or die "$!";
149      $th->autoflush();          }
150          my $httpheader="";          $ch->autoflush();
151          my $httpbuf="";          $th->autoflush();
152      while ( $ch || $th ) {          my $httpheader = "";
153          my $rin = "";          my $httpbuf    = "";
154          vec( $rin, fileno($ch), 1 ) = 1 if $ch;          while ( $ch || $th ) {
155          vec( $rin, fileno($th), 1 ) = 1 if $th;                  my $rin = "";
156          my ( $rout, $eout );                  vec( $rin, fileno($ch), 1 ) = 1 if $ch;
157          select( $rout = $rin, undef, $eout = $rin, 120 );                  vec( $rin, fileno($th), 1 ) = 1 if $th;
158          if ( !$rout && !$eout ) { }                  my ( $rout, $eout );
159          my $cbuffer = "";                  select( $rout = $rin, undef, $eout = $rin, 120 );
160          my $tbuffer = "";                  if ( !$rout && !$eout ) { }
161                    my $cbuffer = "";
162          if ( $ch                  my $tbuffer = "";
163              && ( vec( $eout, fileno($ch), 1 ) || vec( $rout, fileno($ch), 1 ) )  
164            )                  if ($ch
165          {                          && (   vec( $eout, fileno($ch), 1 )
166              my $result = sysread( $ch, $tbuffer, $buffersize );                                  || vec( $rout, fileno($ch), 1 ) )
167              if ( !defined($result) ) {                          )
168                  print STDERR "$!\n";                  {
169                  exit 0;                          my $result = sysread( $ch, $tbuffer, $buffersize );
170              }                          if ( !defined($result) ) {
171              if ( $result == 0 ) { exit 0; }                                  print STDERR "$!\n";
172          }                                  exit 0;
173          if ( $th                          }
174              && ( vec( $eout, fileno($th), 1 ) || vec( $rout, fileno($th), 1 ) )                          if ( $result == 0 ) { exit 0; }
175            )                  }
176          {                  if ($th
177              my $result = sysread( $th, $cbuffer, $buffersize );                          && (   vec( $eout, fileno($th), 1 )
178              if ( !defined($result) ) { print STDERR "$!\n"; exit 0; }                                  || vec( $rout, fileno($th), 1 ) )
179              if ( $result == 0 ) { exit 0; }                          )
180          }                  {
181          if ( $fh && $tbuffer ) { ( print $fh "[c]".$tbuffer."[/c]" ); }                          my $result = sysread( $th, $cbuffer, $buffersize );
182          while ( my $len = length($tbuffer) ) {                          if ( !defined($result) ) { print STDERR "$!\n"; exit 0; }
183              my $res = syswrite( $th, $tbuffer, $len );                          if ( $result == 0 ) { exit 0; }
184              if ( $res > 0 ) { $tbuffer = substr( $tbuffer, $res ); }                  }
185              else { print STDERR "$!\n"; }                  if ( $fh && $tbuffer ) {
186          }                          print $fh "\n# <<< client\n$tbuffer";
187          if ( $fh && $cbuffer ) { ( print $fh "[s]".$cbuffer."[/s]"); }                          warn "C>S ", hexdump($tbuffer), "\n";
188          while ( my $len = length($cbuffer) ) {                  }
189              my $res = syswrite( $ch, $cbuffer, $len );                  while ( my $len = length($tbuffer) ) {
190              if ( $res > 0 ) { $cbuffer = substr( $cbuffer, $res ); }                          my $res = syswrite( $th, $tbuffer, $len );
191              else { print STDERR "$!\n"; }                          if ( $res > 0 ) { $tbuffer = substr( $tbuffer, $res ); }
192          }                          else            { print STDERR "$!\n"; }
193      }                  }
194                    if ( $fh && $cbuffer ) {
195                            print $fh "\n# >>> server\n$cbuffer";
196                            warn "S>C ", hexdump($cbuffer), "\n";
197                    }
198                    while ( my $len = length($cbuffer) ) {
199                            my $res = syswrite( $ch, $cbuffer, $len );
200                            if ( $res > 0 ) { $cbuffer = substr( $cbuffer, $res ); }
201                            else            { print STDERR "$!\n"; }
202                    }
203            }
204  }  }
205    

Legend:
Removed from v.128  
changed lines
  Added in v.133

  ViewVC Help
Powered by ViewVC 1.1.26