#!/usr/bin/perl
# filer, a HTTPush plugin by Lluis Mora
# Scans for variables and cookies with values that look like files and records them.
#
# $Id: filer,v 1.2 2001/10/28 21:44:51 jfs Exp $

use plugins::httpush;
use IO::Socket;

use strict;

$|=1;

my %req;

my $FILE_PATTERN=qr/\.|\/|\\|%2F|%2E|%5C/io;
my $VARIABLE_PATTERN=qr/template|\/|\\|%2F|%2E|%5C/io;

&main;
exit;

sub main {

  my $line;

  while($line=<STDIN>) {

    chomp($line);

    if(! $line) {
      ProcessRequest(\%req);
      # Clean req;
      %req=undef;
    }

    if(! $req{'opcode'}) {
      if($line=~/(\w+)\s+(\d+)\.(\d+)/) {
        $req{'opcode'}=$1;
        $req{'version'}="$2.$3";
      }
    } else {
      my ($key, $val) = split(":",$line,2);
      $val=MIME::Base64::decode_base64($val);
    
      if($key && $val) {
  		  my %kv;
        $kv{'k'}=$key;
        $kv{'v'}=$val;

        push (@{$req{kv}}, \%kv);
      }
    }

  }
}

sub ProcessRequest {
  my %req=%{shift(@_)};
  my (@kvl,@cookies);

  if($req{'opcode'} eq "identify") {
    my $plugin_name=httpush::encode("filer");
    my $plugin_description=httpush::encode("Detects possible file references in application parameters");
    my $plugin_event=httpush::encode("request");
    my $plugin_noise=httpush::encode("0");

    chomp($plugin_name);
    chomp($plugin_description);
    chomp($plugin_event);
    chomp($plugin_noise);

    print "register 1.0\n";
    print "name:$plugin_name\n";
    print "description:$plugin_description\n";
    print "event:$plugin_event\n";
    print "noise:$plugin_noise\n";
    print "\n";
  } elsif($req{'opcode'} eq "request") {
    my $timestamp=time();
    my ($content, $who, $id, $x);


    foreach $x (@{$req{'kv'}}) {
      my %kv=%$x;

      if($kv{'k'} eq "sent") {
        $content=$kv{'v'};
      } elsif ($kv{'k'} eq "who") {
        $who=$kv{'v'};
      } elsif ($kv{'k'} eq "id") {
        $id=$kv{'v'};
      }
    }

  $id=httpush::encode($id);
  my $zero=httpush::encode('0');

  my $vuln=undef;

  if($content) {
    my @content=split("\n",$content);

    # Check request URI

    my $req_line=@content[0];

    if($req_line) {
      if($req_line=~/^[^\s]+\s+([^\s]+)/) {
        my $uri=$1;
        my ($path,$query)=split('\?',$uri,2);

        if($query) {
          my @vars=split('&',$query);
          my $var;

          foreach $var (@vars) {
            my ($name, $value)=split("=",$var, 2);
            if($name=~ $VARIABLE_PATTERN) {
              $vuln.="<LI>Variable \"$name\" may accept files as parameters (e.g. \"$value\")";
            }

            if($value=~ $FILE_PATTERN) {
              $vuln.="<LI>Variable \"$name\" may accept files as parameters (e.g. \"$value\")";
            }
          }
        }
      }
    }

    # Check request body

    my $body=undef;
	  my $line;

    while($line=shift(@content)) {
      chomp($line);
      if($line=~/^Cookie:\s*(.*)$/) {
        @cookies=split("\s*;\s*",$1);
      }
    }

    $body=join("\n",@content);

    if($body) {
      my @vars=split('&',$body);
      my $var;

      foreach $var (@vars) {
        my ($name, $value)=split("=",$var, 2);
        if($name=~ $VARIABLE_PATTERN) {
          $vuln.="<LI>Variable \"$name\" may accept files as parameters (e.g. \"$value\")";
        }
        if($value=~ $FILE_PATTERN ) {
          $vuln.="<LI>Variable \"$name\" may accept files as parameters (e.g. \"$value\")";
        }
      }
    }

    my $cookie;

    foreach $cookie (@cookies) {
      my ($name, $value)=split("=",$cookie, 2);
        if($name=~ $VARIABLE_PATTERN) {
          $vuln.="<LI>Cookie \"$name\" may accept files as parameters (e.g. \"$value\")";
        }
      if($value=~ $FILE_PATTERN ) {
        $vuln.="<LI>Cookie \"$name\" may accept files as parameters (e.g. \"$value\")";
      }
    }


    if($vuln) {
      my $vuln=httpush::encode("The application may accept files as parameters in the following cases:<BR><BR>$vuln");
      my $title=httpush::encode("Files passed as parameters may allow arbitrary file access/command execution");

      print "vuln 1.0\n";
      print "level:$zero\n";
      print "title:$title\n";
      print "content:$vuln\n";
      print "id:$id\n";
      print "\n";
    }
  }
#  print "end 1.0\n\n";

}
}

