#!/usr/bin/perl -w #Proxy MultiProtocolo #sha0proxy.pl v1.0 coded by sha0@badchecksum.net #TODO: capturar SIGINT # ncurses para modificar los bytes directamente # udp # formato shellcode # logear # fuzz # quit #perl -MCPAN -e shell #cpan>install threads #... #cpan>install IO::Socket #... #cpan>install IO::Select #... use IO::Socket; use IO::Select; #use Net::UDP; my %color=( red=>"\x1b[31;01m", green=>"\x1b[32;02m", yellow=>"\x1b[33;01m", blue=>"\x1b[34;01m", magenta=>"\x1b[35;01m", cyan=>"\x1b[36;01m", white=>"\x1b[37;00m" ); die "$0 \nmodes: view trap fuzz\ntrap sample: where>3A1 what>AAA\\x00 (enter for change nothing)\ntrap also can be used inline with extra params: \nor: \nfuzz: not tested!\n" if (@ARGV!=4 && @ARGV !=5 && @ARGV!=7); die "Valid modes are: view, trap & fuzz\n" if ($ARGV[3] ne 'view' && $ARGV[3] ne 'trap' && $ARGV[3] ne 'fuzz'); #my $lport=(int(rand(500))+10000); my $lport=$ARGV[0]; my $rport=$ARGV[2]; my $rhost=$ARGV[1]; my $buff; my $vulnerable=0; my $mode=$ARGV[3]; my @sended; my $packet_num=1; my @inline_num; my @inline_where; my @inline_what; if (@ARGV == 7) { push @inline_num, $ARGV[4]; push @inline_where, $ARGV[5]; push @inline_what, $ARGV[6]; } if (@ARGV == 5) { $file = $ARGV[4]; print "loading $file\n"; open F,"<$file"; while () { chomp; next if (/^\#/); if (/([0-9]{1,5})[ \t]([0-9a-f]{1,5})[ \t](.*)/i) { push @inline_num, $1; push @inline_where, $2; push @inline_what, $3; } } } sub doFuzz { print "START FUZZING!!!"; } my $out; my $in=IO::Socket::INET->new ( LocalAddr=>'0.0.0.0', LocalPort=>$lport, Proto=>'tcp', Listen=>1, Reuse=>100 ) or die "cannot open port $!\n"; print "listening $lport port\n"; #print "\x1b[?25l"; #no cursor while (my $welcome=$in->accept()) { $out=IO::Socket::INET->new ( PeerAddr=>$rhost, PeerPort=>$rport, Timeout=>20 ) or die "cannot connect $!\n"; print "connected to $rhost:$rport\n"; #proxy if (!fork()) { $out->blocking(1); $welcome->blocking(1); $out->autoflush(1); $welcome->autoflush(1); $s=IO::Select->new($out, $welcome); proxy: while(1) { my @ready = $s->can_read; foreach my $ready (@ready) { if($ready == $welcome) { my $data; $welcome->recv($data, 81920); last proxy if (! length($data)); last proxy if(!$out || !$out->connected); &muestra($data,1); push @sended, $data; $data=&changeData($data,1); $packet_num++; eval { $out->send($data); }; last proxy if $@; } elsif ($ready == $out) { my $data; $out->recv($data, 81920); last proxy if(!length($data)); last proxy if(!$welcome || !$welcome->connected); &muestra($data,0); $data=&changeData($data,0); $packet_num++; eval { $welcome->send($data); }; last proxy if $@; } }#foreach if (!$welcome || !$out) { close $out; close $welcome; return; } }#while 1 } #fork } sub changeData { my $data = $_[0]; my $alserver = $_[1]; my $changes=0; my $what=''; my $where=0; #print "-------------------"; for (local $z=0; $z<= $#inline_num; $z++) { if ($inline_num[$z] == $packet_num) { $where = hex($inline_where[$z]); $what = $inline_what[$z]; $data = &reemplaza($data,$alserver,$where,$what); $changes=1; #print "we ".$where." ".$what." ".$data."\n"; #&muestra($data); } } #print "fin-------------"; if ($mode eq 'trap') { print "where>"; $where = ; chomp $where; $where = hex($where); print "what>"; $what = ; chomp $what; $data = &reemplaza($data,$alserver,$where,$what); $changes = 1 if ($what); } &muestra($data,$alserver) if ($changes); return $data; } sub reemplaza () { my $d=0; my $cleanwtf; my ($data,$alserver,$where,$what) = @_; @databytes = split('',$data); @wtf = split('',$what); $cleanwtf=''; for ($i = 0; $i < length($what); $i++) { #If user enter byte mode if ($wtf[$i] eq '\\' && $wtf[$i+1] eq 'x') { #print "byte".chr(hex($wtf[$i+2].$wtf[$i+3]))."\n"; $cleanwtf.=chr(hex($wtf[$i+2].$wtf[$i+3])); $i+=3; } else { $cleanwtf.=$wtf[$i]; } } @wtf = split('',$cleanwtf); for ($i = 0; $i < length($cleanwtf); $i++) { $databytes[$i+$where] = $wtf[$i]; } $data = join('',@databytes); return $data; } sub muestra { my $data = $_[0]; my @bytes = split(//,$data); my $b; my $alserver = $_[1]; my $count=0; my $str=""; my $lin=1; print $color{white}; $banner=">"x33 if ($alserver); $banner="<"x33 if (!$alserver); printf "\n%d%s",$packet_num,$banner; print "\n |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f |"; print "\n---+------------------------------------------------+---\n"; print "000|"; foreach $b (@bytes) { print $color{green} if (($b ge 'a' && $b le 'z') ||($b ge 'A' && $b le 'Z') || $b eq "\x20"); print $color{blue} if ($b ge '0' && $b le '9'); print $color{red} if ($b eq "\x00"); print $color{cyan} if ($b eq "\x0a" || $b eq "\x0d"); printf "%.2x ",ord($b); print $color{white}; $b = "." if ($b lt "\x20" || $b gt "\x7e"); $count++; $str.=$b; if ($count==16) { #$str=~s/[^a-z^A-Z^0-9^#^@^:^]/\./ig; printf "%s\n%.3x|",$str,$count*$lin; $lin++; $str=""; $count = 0; } } $str=~s/[^a-z^A-Z^0-9^#^@]/\./ig; for ($b=$count;$b<16;$b++){ print " "; } print $str."\n"; #print "\n"."-"x33; #$data=~s/[^a-z^A-Z^0-9]/\./ig; #print "\n$data\n"; }