home *** CD-ROM | disk | FTP | other *** search
- #
- # autopsy gui server
- # Autopsy Forensic Browser
- #
- #
- # This file requires The Sleuth Kit
- # www.sleuthkit.org
- #
- # version 1.71+
- # Brian Carrier [carrier@sleuthkit.org]
- # Copyright (c) 2003 by Brian Carrier. All rights reserved
- #
- # version 1.5, 1.6, 1.7
- # Copyright (c) 2001-2003 by Brian Carrier, @stake Inc. All rights reserved
- #
- # version 1.0
- # Brian Carrier [carrier@cerias.purdue.edu]
- # Copyright (c) 2001 by Brian Carrier. All rights reserved
- #
- #
- # This file is part of the Autopsy Forensic Browser (Autopsy)
- #
- # Autopsy is free software; you can redistribute it and/or modify
- # it under the terms of the GNU General Public License as published by
- # the Free Software Foundation; either version 2 of the License, or
- # (at your option) any later version.
- #
- # Autopsy is distributed in the hope that it will be useful,
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- # GNU General Public License for more details.
- #
- # You should have received a copy of the GNU General Public License
- # along with Autopsy; if not, write to the Free Software
- # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- #
- #
- # THIS SOFTWARE IS NOT AFFILIATED WITH PURDUE UNIVERSITY OR THE CENTER FOR
- # EDUCATION IN INFORMATION ASSURANCE AND SECURITY (CERIAS) AND THEY BEAR
- # NO RESPONSIBILITY FOR ITS USE OR MISUSE.
- #
- #
- # THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
- # WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- # MERCHANTABILITY AND FITNESS FOR ANY PARTICULAR PURPOSE.
- # IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
- # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- # (INCLUDING, BUT NOT LIMITED TO, LOSS OF USE, DATA, OR PROFITS OR
- # BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- # WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- # ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- #
-
- #
- # refer to Security Considerations in README for a description of the
- # cookie authentication
- #
-
- require 5.002;
-
- use autopsyfunc;
- use strict;
- use Socket;
-
- require 'conf.pl';
- require 'define.pl';
-
- # Import variables from conf.pl
- use vars '$PROGNAME', '$TASKDIR';
- use vars '$LOCKDIR', '$INSTALLDIR', '$PICTDIR';
- use vars '$SANITIZE_TAG', '$SANITIZE_PICT';
- use vars '$USE_STIMEOUT', '$STIMEOUT', '$CTIMEOUT';
- use vars '$USE_COOKIE', '$USE_LOG';
- use vars '$SAVE_COOKIE', '$STRINGS_EXE', '$GREP_EXE';
- use vars '$AUT_HOME_PAGE';
- use vars '$HTTP_NL', '$NSRLDB';
-
-
- # remove environment stuff that we don't need and that could be insecure
- $ENV{PATH} = '';
- delete @ENV{ 'IFS', 'CDPATH', 'ENV', 'BASH_ENV'};
- $| = 1;
-
- sub usage {
- print "usage: $0 [-C] [-d evid_locker] [port [remoteaddr]]\n";
- exit 1;
- }
-
- if (scalar(@ARGV) > 5) {
- usage();
- }
-
- # Were options given?
- while ((scalar (@ARGV) > 0) && ($ARGV[0] =~ /^-/)) {
- my $f = shift;
-
- # Evidence Locker
- if ($f eq '-d') {
- if (scalar (@ARGV) == 0) {
- print "Missing Directory\n";
- usage();
- }
-
- my $d = shift;
- # We need to do this for the tainting
- # We don't need to check for special characters in this case because
- # all commands will be run with the same permissions as the
- # original user. We will check for the obvious ';' though
- if ($d =~ /;/) {
- print "Illegal argument\n";
- exit (1);
- }
-
- # If the path is relative, autopsyfunc will get screwed up when
- # this is run from a directory other than where autopsyfunc is
- # so force full paths
- elsif ($d !~ /^\//) {
- print "The evidence locker must be full path (i.e. begin with /)\n";
- exit(1);
- }
- elsif ($d =~ /(.*)/) {
- $LOCKDIR = $1;
- }
- }
-
- # Force no cookie
- elsif ($f eq '-C') {
- $USE_COOKIE = 0;
- }
- else {
- print "Invalid flag: $f\n";
- usage();
- }
- }
-
-
- # Port Number
- my $port;
- if (scalar (@ARGV) > 0) {
- $port = shift;
- if ($port =~ /(\d+)/) {
- $port = $1;
- }
- else {
- print "invalid port: $port\n";
- usage();
- }
- }
- else {
- $port = 9999;
- }
-
- # remote address
- my $rema;
- if (scalar (@ARGV) > 0) {
- $rema = shift;
- }
- else {
- $rema = 'localhost';
- }
-
-
- # Get remote address
- my @acl_addr; # Array of host addresses
- my $hn; # Host name
- my $tmp;
- if ($rema =~ /(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})/) {
- $acl_addr[0] = pack('C4', ($1, $2, $3, $4));
- $hn = $rema;
- }
- else {
- ($hn, $tmp, $tmp, $tmp, @acl_addr) = gethostbyname($rema);
- unless (defined $tmp) {
- print "Host not found: $rema\n";
- usage();
- }
- }
-
- # Determine the address that will be used to access this server
- my $lclhost;
- my @ta = unpack('C4', $acl_addr[0]);
-
- # If we are being accessed by localhost, we need that and not the hostname
- if (($ta[0] == 127) && ($ta[1] == 0) &&
- ($ta[2] == 0) && ($ta[3] == 1)) {
- $lclhost = "localhost";
- }
- else {
- $lclhost = `/bin/hostname`;
- chop $lclhost;
- }
-
-
- # Verify the variables defined in the configuration files
- check_vars();
-
-
- # Make sure TASKDIR ends with '/'
- if ($TASKDIR !~ /.*?\/$/) {
- $TASKDIR .= '/';
- }
-
- # Make sure LOCKDIR ends with '/'
- if ($LOCKDIR !~ /.*?\/$/) {
- $LOCKDIR .= '/';
- }
-
-
- #
- # Verify that all of the required executables exist
- #
-
-
- check_tools();
-
- my $date = localtime;
- print <<EOF;
-
- ============================================================================
-
- Autopsy Forensic Browser
- http://www.sleuthkit.org/autopsy/
- ver $VER
-
- ============================================================================
-
- Evidence Locker: $LOCKDIR
- Start Time: $date
- EOF
-
-
-
- # Setup socket
- my $proto = getprotobyname('tcp');
- socket (Server, PF_INET, SOCK_STREAM, $proto)
- or die "Create socket failed: $!";
-
- setsockopt(Server, SOL_SOCKET, SO_REUSEADDR, 1)
- or die "Setsockopt failed: $!";
-
- setsockopt(Server, SOL_SOCKET, SO_KEEPALIVE, 1)
- or die "Setsockopt failed: $!";
-
- bind(Server, sockaddr_in($port, INADDR_ANY))
- or die "Bind to port $port failed: $!";
-
- listen(Server, SOMAXCONN)
- or die "Listen to socket failed: $!";
-
-
- my $magic; # magic authentication cookie
- my $cook_file;
- my $cookie_url = "";
-
- if ($USE_COOKIE == 1) {
-
- # Try for a real random device, or use rand if all else fails
- if (-e "/dev/urandom") {
- my $r;
- open RAND, "</dev/urandom" or die "can not open /dev/urandom";
- read RAND, $r, 4;
- $magic = unpack "I", $r;
- read RAND, $r, 4;
- $magic .= unpack "I", $r;
- close RAND;
- }
- else {
- $magic = int(rand 0xffffffff).int(rand 0xffffffff);
- }
-
- $cookie_url = "$magic/";
-
- # Save to file in case the stdout gets overwritten
- if ($SAVE_COOKIE == 1) {
- $cook_file = "$LOCKDIR/.$port.cookie";
- open COOK, ">$cook_file" or
- die "can not open $cook_file";
- chmod 0600, "$cook_file";
- print COOK "$magic\n";
- close COOK;
- }
- }
-
- print "Remote Host: $rema\n";
- print "Local Port: $port\n\n";
- print "Open an HTML browser on the remote host and paste this URL in it:\n\n";
- print "\thttp://$lclhost:${port}/${cookie_url}${PROGNAME}\n";
- print "\nKeep this process running and use <ctrl-c> to exit\n";
-
- log_session_info("Starting session on port $port and $hn\n");
-
- # Set the server alarm
- $SIG{ALRM} = \&sig_alarm_server;
- $SIG{INT} = \&sig_close;
- $SIG{CHLD} = sub {
- my $p = wait;
- };
-
- # Wait for Connections
- while (1) {
-
- alarm ($STIMEOUT) if ($USE_STIMEOUT == 1);
-
- my $raddr = accept(CLIENT, Server);
- next unless ($raddr);
- my ($rport, $riaddr) = sockaddr_in($raddr);
-
- die "Error creating child" unless (defined (my $pid = fork()));
-
- if (0 == $pid) {
- open(STDOUT, ">&CLIENT") or die "Can't dup client to stdout";
- open(STDERR, ">&CLIENT") or die "Can't dup client to stdout";
- open(STDIN, "<&CLIENT") or die "Can't dup client to stdin";
- $| = 1;
-
- my @rip = unpack('C4', $riaddr);
-
- # Check ACL
- foreach $tmp (@acl_addr) {
- if ($tmp eq $riaddr) {
- spawn_cli($riaddr);
- close CLIENT;
- exit 0;
- }
- }
-
- forbid ();
- log_session_info("ERROR: Unauthorized Connection from:".
- "$rip[0].$rip[1].$rip[2].$rip[3]\n");
-
- close CLIENT;
- exit 1;
- }
- else {
- close CLIENT;
- }
- }
-
-
- # Error messages
- sub forbid
- {
- print "HTTP/1.0 403 Forbidden${HTTP_NL}".
- "Content-type: text/html${HTTP_NL}${HTTP_NL}".
- "<HTML><CENTER><BR>\n".
- "<H2>Access Denied</H2></CENTER></HTML>${HTTP_NL}${HTTP_NL}${HTTP_NL}";
- return;
- }
-
- sub bad_req
- {
- print "HTTP/1.0 404 Bad Request${HTTP_NL}".
- "Content-type: text/html${HTTP_NL}${HTTP_NL}".
- "<HTML><CENTER><BR>\n".
- "<H2>Invalid Location: <TT>".shift()."</TT></H2></CENTER></HTML>".
- "${HTTP_NL}${HTTP_NL}${HTTP_NL}";
- return;
- }
-
-
- sub sterile
- {
- my $url = shift();
- my $lurl = $url;
- $lurl =~ tr/[A-Z]/[a-z]/;
-
- print "HTTP/1.0 200 OK${HTTP_NL}";
- if (($lurl =~ /.jpg/i) || ($lurl =~ /.jpeg/i) || ($lurl =~ /.gif/i) ||
- ($lurl =~ /.png/i) || ($lurl =~ /.bmp/i)) {
-
- open PICT, "<$PICTDIR/$SANITIZE_PICT" or
- die "can not open $PICTDIR/$SANITIZE_PICT";
-
- print "Content-type: image/jpeg${HTTP_NL}${HTTP_NL}";
- while (<PICT>) {
- print "$_";
- }
- close (PICT);
- }
- else {
- $url =~ tr/\+/ /;
- $url =~ s/%([a-f0-9][a-f0-9])/chr( hex( $1 ) )/eig;
-
- print "Content-type: text/html${HTTP_NL}${HTTP_NL}".
- "<HTML><H1><CENTER>Unable to Complete Request</H1><BR>\n".
- "<TT>Autopsy</TT> will not follow links from ".
- "untrusted HTML pages:<BR><TT>$url</TT><BR>\n";
- }
- print "${HTTP_NL}${HTTP_NL}";
- }
-
-
- # Alarm Functions
- sub sig_alarm_client
- {
- log_session_info("Connection timed out\n");
- close CLIENT;
- exit 1;
- }
-
- sub sig_alarm_server
- {
- print "Server Timeout ($STIMEOUT seconds), Exiting\n";
- log_session_info("Server Timeout ($STIMEOUT seconds), Exiting\n");
- exit 0;
- }
-
- # Close the system down when Control-C is given
- sub sig_close
- {
- # delete the cookie file
- if (($USE_COOKIE == 1) && ($SAVE_COOKIE == 1)) {
- unlink "$cook_file";
- }
-
- print "End Time: ".localtime()."\n";
- log_session_info("Ending session on port $port and $hn\n");
- exit 0;
- }
-
- # Pass the remote IP address as the argument for logging
- sub spawn_cli
- {
- # Set timeout for 10 seconds if we dont get any input
- alarm ($CTIMEOUT);
- $SIG{ALRM} = \&sig_alarm_client;
-
- while (<STDIN>) {
-
- if (/^GET \/+(\S*)\s?HTTP/) {
- my $url = $1;
- my $script;
- my $args;
-
- if (/\x0d\x0a$/) {
- $HTTP_NL = "\x0d\x0a";
- }
- else {
- $HTTP_NL = "\x0a";
- }
-
- # Magic Cookie
- # If we are using cookies, then the url should be:
- # cookie/autopsy?var=val ...
- if ($USE_COOKIE == 1) {
-
- if (($url =~ /^(\d+)\/+([\w\.\/]+)(?:\?(.*))?$/) &&
- ($1 == $magic)) {
- $script = $2;
- $args = $3;
- }
- else {
- my @rip = unpack('C4', shift());
- log_session_info("ERROR: Incorrect Cookie from:".
- "$rip[0].$rip[1].$rip[2].$rip[3]\n");
- forbid();
- return 1;
- }
- }
-
- # if we aren't using cookies, then it should be:
- # autopsy?var=val ...
- else {
- if ($url =~ /^\/?([\w\.\/]+)(?:\?(.*))?$/) {
- $script = $1;
- $args = $2;
- }
- else {
- bad_req($url);
- return 1;
- }
- }
-
- if ($script eq $PROGNAME) {
- $args = "" unless (defined $args);
-
- # Turn timer off
- alarm (0);
-
- # Print status
- print "HTTP/1.0 200 OK${HTTP_NL}";
- autopsy_main($args);
- }
- # Display the sanitized picture or reference error
- elsif ($script eq $SANITIZE_TAG) {
- sterile($args);
- return 1;
- }
- # Display a picture or help file
- elsif ( ($script =~ /^(pict\/[\w\.\/]+)/) ||
- ($script =~ /^(help\/[\w\.\/]+)/) ) {
- show_file ($1);
- }
- elsif ($script eq 'about') {
- about();
- }
- else {
- bad_req($url);
- log_session_info("Unknown function: $script\n");
- return 1;
- }
- return 0;
- }
- } # end of while (<>)
-
- } # end of spawn_cli
-
-
- # Print the contents of a local picture or help file
- sub show_file
- {
- my $file = "$INSTALLDIR/".shift;
-
- if (-e "$file") {
- print "HTTP/1.0 200 OK${HTTP_NL}";
-
- open FILE, "<$file" or
- die "can not open $file";
-
- if ($file =~ /\.jpg$/i) {
- print "Content-type: image/jpeg${HTTP_NL}${HTTP_NL}";
- } elsif ($file =~ /\.gif$/i) {
- print "Content-type: image/gif${HTTP_NL}${HTTP_NL}";
- } elsif ($file =~ /\.html$/i) {
- print "Content-type: text/html${HTTP_NL}${HTTP_NL}";
- } else {
- print "HTTP/1.0 404 Bad Request${HTTP_NL}".
- "Content-type: text/html${HTTP_NL}${HTTP_NL}".
- "<HTML><H2><CENTER>Unknown Extension</H2>".
- "</CENTER></HTML>${HTTP_NL}${HTTP_NL}${HTTP_NL}";
- exit(1);
- }
-
- while (<FILE>) {
- print "$_";
- }
- close (FILE);
-
- print "${HTTP_NL}${HTTP_NL}";
- }
- else {
- print "HTTP/1.0 404 Bad Request${HTTP_NL}".
- "Content-type: text/html${HTTP_NL}${HTTP_NL}".
- "<HTML><H2><CENTER>File Not Found</H2>".
- "</CENTER></HTML>${HTTP_NL}${HTTP_NL}${HTTP_NL}";
- exit(1);
- }
-
- return;
- }
-
- sub about
- {
-
- print "HTTP/1.0 200 OK${HTTP_NL}".
- "Content-type: text/html${HTTP_NL}${HTTP_NL}";
-
-
- print <<EOF;
-
- <HTML>
- <HEAD><TITLE>About Autopsy</TITLE></HEAD>
-
- <BODY BGCOLOR=#CCCC99>
-
- <CENTER><H2>About Autopsy</H2>
- <BR>
- <IMG SRC=\"pict/logo.jpg\">
- <BR><BR>
- <B>Version</B>: $VER
- <BR>
- <TT><A HREF=$AUT_HOME_PAGE>$AUT_HOME_PAGE</A></TT>
- <BR>
- </CENTER>
-
-
- <H3>Credits</H3>
- <UL>
- <LI>Code Development: Brian Carrier
- <LI>Interface: Samir Kapuria
- </UL>
-
- <H3>Configuration</H3>
- <B>Evidence Locker</B>: <TT>$LOCKDIR</TT><BR>
- <B>Sleuth Kit</B>: <TT>$TASKDIR</TT><BR>
- <B>strings</B>: <TT>$STRINGS_EXE</TT><BR>
- <B>grep</B>: <TT>$GREP_EXE</TT><BR>
- <B>NSRL</B>: <TT>$NSRLDB</TT><BR>
-
- </BODY></HTML>
-
- EOF
- return 0;
- }
-
-
- ### Check that the required tools are there
- sub check_tools
- {
- # Sleuth Kit execs
- unless (-x "${TASKDIR}icat") {
- print "ERROR: Sleuth Kit icat executable missing\n";
- exit (1);
- }
- unless (-x "${TASKDIR}istat") {
- print "ERROR: Sleuth Kit istat executable missing\n";
- exit (1);
- }
- unless (-x "${TASKDIR}ifind") {
- print "ERROR: Sleuth Kit ifind executable missing\n";
- exit (1);
- }
- unless (-x "${TASKDIR}ils") {
- print "ERROR: Sleuth Kit ils executable missing\n";
- exit (1);
- }
- unless (-x "${TASKDIR}fls") {
- print "ERROR: Sleuth Kit fls executable missing\n";
- exit (1);
- }
- unless (-x "${TASKDIR}ffind") {
- print "ERROR: Sleuth Kit ffind executable missing\n";
- exit (1);
- }
- unless (-x "${TASKDIR}dcat") {
- print "ERROR: Sleuth Kit dcat executable missing\n";
- exit (1);
- }
- unless (-x "${TASKDIR}dcalc") {
- print "ERROR: Sleuth Kit dcalc executable missing\n";
- exit (1);
- }
- unless (-x "${TASKDIR}dls") {
- print "ERROR: Sleuth Kit dls executable missing\n";
- exit (1);
- }
- unless (-x "${TASKDIR}file") {
- print "ERROR: Sleuth Kit file executable missing\n";
- exit (1);
- }
- unless (-x "${TASKDIR}fsstat") {
- print "ERROR: Sleuth Kit fsstat executable missing\n";
- exit (1);
- }
- unless (-x "${TASKDIR}md5") {
- print "ERROR: Sleuth Kit md5 executable missing\n";
- exit (1);
- }
- unless (-x "${TASKDIR}sorter") {
- print "ERROR: Sleuth Kit sorter executable missing\n";
- exit (1);
- }
- unless (-x "${TASKDIR}hfind") {
- print "ERROR: Sleuth Kit hfind executable missing\n";
- print " You likely have an old version of The Sleuth Kit or TASK\n";
- exit (1);
- }
-
- unless (-x "$STRINGS_EXE") {
- print "ERROR: strings executable missing\n";
- exit (1);
- }
-
- unless (-x "$GREP_EXE") {
- print "ERROR: grep executable missing\n";
- exit (1);
- }
- }
-
- # check values that should be defined in the configuration files
- # This will show incomplete installations
- sub check_vars
- {
- unless ( (defined $TASKDIR) && ($TASKDIR ne "") ) {
- print "ERROR: TASKDIR variable not set in configuration file\n";
- print " This could been caused by an incomplete installation\n";
- exit (1);
- }
-
- unless (-d "$TASKDIR") {
- print "Invalid Sleuth Kit binary directory: $TASKDIR\n";
- exit (1);
- }
-
- # Verify The evidence locker directory
- unless ( (defined $LOCKDIR) && ($LOCKDIR ne "") ) {
- print "ERROR: LOCKDIR variable not set in configuration file\n";
- print " This could been caused by an incomplete installation\n";
- exit (1);
- }
-
- unless (-d "$LOCKDIR") {
- print "Invalid evidence locker directory: $LOCKDIR\n";
- exit (1);
- }
-
- # Directory Names
- unless ( (defined $IMGDIR) && ($IMGDIR ne "") ) {
- print "ERROR: IMGDIR variable not set in configuration file\n";
- print " This could been caused by an incomplete installation\n";
- exit (1);
- }
- unless ( (defined $DATADIR) && ($DATADIR ne "") ) {
- print "ERROR: DATADIR variable not set in configuration file\n";
- print " This could been caused by an incomplete installation\n";
- exit (1);
- }
- unless ( (defined $LOGDIR) && ($LOGDIR ne "") ) {
- print "ERROR: LOGDIR variable not set in configuration file\n";
- print " This could been caused by an incomplete installation\n";
- exit (1);
- }
- unless ( (defined $REPDIR) && ($REPDIR ne "") ) {
- print "ERROR: REPDIR variable not set in configuration file\n";
- print " This could been caused by an incomplete installation\n";
- exit (1);
- }
- }
-